From 8f567c373c4b3dbfd62714cb27ad2bb91cf48761 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 3 Aug 2012 10:28:18 -0700 Subject: staging: comedi: new adl_pci7x3x driver Currently the ADLink PCI-7230 and PCI-7432 Isolated Digital I/O Boards are supported using two drivers (adl_pci7230 and adl_pci7432). These drivers are very similar and only differ in the total number of di/do channels provided. This driver combines the support for both boards into one common driver. In addition, it adds PCI PnP support for the other boards in the ADLink PCI-723x and PCI-743x series. This driver only supports the comedi PCI auto config attach mechanism. The legacy attach using the comedi_config utility is not supported or required by this driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 6cee785..d8b0065 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -676,6 +676,17 @@ config COMEDI_ADL_PCI6208 To compile this driver as a module, choose M here: the module will be called adl_pci6208. +config COMEDI_ADL_PCI7X3X + tristate "ADLink PCI-723X/743X isolated digital i/o board support" + ---help--- + Enable support for ADlink PCI-723X/743X isolated digital i/o boards. + Supported boards include the 32-channel PCI-7230 (16 in/16 out), + PCI-7233 (32 in), and PCI-7234 (32 out) as well as the 64-channel + PCI-7432 (32 in/32 out), PCI-7433 (64 in), and PCI-7434 (64 out). + + To compile this driver as a module, choose M here: the module will be + called adl_pci7x3x. + config COMEDI_ADL_PCI7230 tristate "ADLink PCI-7230 digital io board support" ---help--- diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile index 57b19e4..d13d5a9 100644 --- a/drivers/staging/comedi/drivers/Makefile +++ b/drivers/staging/comedi/drivers/Makefile @@ -69,6 +69,7 @@ obj-$(CONFIG_COMEDI_ADDI_APCI_3120) += addi_apci_3120.o obj-$(CONFIG_COMEDI_ADDI_APCI_3501) += addi_apci_3501.o obj-$(CONFIG_COMEDI_ADDI_APCI_3XXX) += addi_apci_3xxx.o obj-$(CONFIG_COMEDI_ADL_PCI6208) += adl_pci6208.o +obj-$(CONFIG_COMEDI_ADL_PCI7X3X) += adl_pci7x3x.o obj-$(CONFIG_COMEDI_ADL_PCI7230) += adl_pci7230.o obj-$(CONFIG_COMEDI_ADL_PCI7296) += adl_pci7296.o obj-$(CONFIG_COMEDI_ADL_PCI7432) += adl_pci7432.o diff --git a/drivers/staging/comedi/drivers/adl_pci7x3x.c b/drivers/staging/comedi/drivers/adl_pci7x3x.c new file mode 100644 index 0000000..990670a --- /dev/null +++ b/drivers/staging/comedi/drivers/adl_pci7x3x.c @@ -0,0 +1,342 @@ +/* + * COMEDI driver for the ADLINK PCI-723x/743x series boards. + * Copyright (C) 2012 H Hartley Sweeten + * + * Based on the adl_pci7230 driver written by: + * David Fernandez + * and the adl_pci7432 driver written by: + * Michel Lachaine + * + * COMEDI - Linux Control and Measurement Device Interface + * Copyright (C) 2000 David A. Schleef + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* +Driver: adl_pci7x3x +Description: 32/64-Channel Isolated Digital I/O Boards +Devices: (ADLink) PCI-7230 [adl_pci7230] - 16 input / 16 output + (ADLink) PCI-7233 [adl_pci7233] - 32 input + (ADLink) PCI-7234 [adl_pci7234] - 32 output + (ADLink) PCI-7432 [adl_pci7432] - 32 input / 32 output + (ADLink) PCI-7433 [adl_pci7433] - 64 input + (ADLink) PCI-7434 [adl_pci7434] - 64 output +Author: H Hartley Sweeten +Updated: Thu, 02 Aug 2012 14:27:46 -0700 +Status: untested + +This driver only attaches using the PCI PnP auto config support +in the comedi core. The module parameter 'comedi_autoconfig' +must be 1 (default) to enable this feature. The COMEDI_DEVCONFIG +ioctl, used by the comedi_config utility, is not supported by +this driver. + +The PCI-7230, PCI-7432 and PCI-7433 boards also support external +interrupt signals on digital input channels 0 and 1. The PCI-7233 +has dual-interrupt sources for change-of-state (COS) on any 16 +digital input channels of LSB and for COS on any 16 digital input +lines of MSB. Interrupts are not currently supported by this +driver. + +Configuration Options: not applicable +*/ + +#include "../comedidev.h" + +/* + * PCI Device ID's supported by this driver + */ +#define PCI_DEVICE_ID_PCI7230 0x7230 +#define PCI_DEVICE_ID_PCI7233 0x7233 +#define PCI_DEVICE_ID_PCI7234 0x7234 +#define PCI_DEVICE_ID_PCI7432 0x7432 +#define PCI_DEVICE_ID_PCI7433 0x7433 +#define PCI_DEVICE_ID_PCI7434 0x7434 + +/* + * Register I/O map (32-bit access only) + */ +#define PCI7X3X_DIO_REG 0x00 +#define PCI743X_DIO_REG 0x04 + +struct adl_pci7x3x_boardinfo { + const char *name; + unsigned short device; + int nsubdevs; + int di_nchan; + int do_nchan; +}; + +static const struct adl_pci7x3x_boardinfo adl_pci7x3x_boards[] = { + { + .name = "adl_pci7230", + .device = PCI_DEVICE_ID_PCI7230, + .nsubdevs = 2, + .di_nchan = 16, + .do_nchan = 16, + }, { + .name = "adl_pci7233", + .device = PCI_DEVICE_ID_PCI7233, + .nsubdevs = 1, + .di_nchan = 32, + }, { + .name = "adl_pci7234", + .device = PCI_DEVICE_ID_PCI7234, + .nsubdevs = 1, + .do_nchan = 32, + }, { + .name = "adl_pci7432", + .device = PCI_DEVICE_ID_PCI7432, + .nsubdevs = 2, + .di_nchan = 32, + .do_nchan = 32, + }, { + .name = "adl_pci7433", + .device = PCI_DEVICE_ID_PCI7433, + .nsubdevs = 2, + .di_nchan = 64, + }, { + .name = "adl_pci7434", + .device = PCI_DEVICE_ID_PCI7434, + .nsubdevs = 2, + .do_nchan = 64, + } +}; + +static int adl_pci7x3x_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + unsigned int reg = (unsigned int)s->private; + unsigned int mask = data[0]; + unsigned int bits = data[1]; + + if (mask) { + s->state &= ~mask; + s->state |= (bits & mask); + + outl(s->state, dev->iobase + reg); + } + + /* + * NOTE: The output register is not readable. + * This returned state will not be correct until all the + * outputs have been updated. + */ + data[1] = s->state; + + return insn->n; +} + +static int adl_pci7x3x_di_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + unsigned int reg = (unsigned int)s->private; + + data[1] = inl(dev->iobase + reg); + + return insn->n; +} + +static const void *adl_pci7x3x_find_boardinfo(struct comedi_device *dev, + struct pci_dev *pcidev) +{ + const struct adl_pci7x3x_boardinfo *board; + int i; + + for (i = 0; i < ARRAY_SIZE(adl_pci7x3x_boards); i++) { + board = &adl_pci7x3x_boards[i]; + if (pcidev->device == board->device) + return board; + } + return NULL; +} + +static int adl_pci7x3x_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) +{ + const struct adl_pci7x3x_boardinfo *board; + struct comedi_subdevice *s; + int subdev; + int nchan; + int ret; + + comedi_set_hw_dev(dev, &pcidev->dev); + + board = adl_pci7x3x_find_boardinfo(dev, pcidev); + if (!board) + return -ENODEV; + dev->board_ptr = board; + dev->board_name = board->name; + + ret = comedi_pci_enable(pcidev, dev->board_name); + if (ret) + return ret; + dev->iobase = pci_resource_start(pcidev, 2); + + /* + * One or two subdevices are setup by this driver depending on + * the number of digital inputs and/or outputs provided by the + * board. Each subdevice has a maximum of 32 channels. + * + * PCI-7230 - 2 subdevices: 0 - 16 input, 1 - 16 output + * PCI-7233 - 1 subdevice: 0 - 32 input + * PCI-7234 - 1 subdevice: 0 - 32 output + * PCI-7432 - 2 subdevices: 0 - 32 input, 1 - 32 output + * PCI-7433 - 2 subdevices: 0 - 32 input, 1 - 32 input + * PCI-7434 - 2 subdevices: 0 - 32 output, 1 - 32 output + */ + ret = comedi_alloc_subdevices(dev, board->nsubdevs); + if (ret) + return ret; + + subdev = 0; + + if (board->di_nchan) { + nchan = min(board->di_nchan, 32); + + s = dev->subdevices + subdev; + /* Isolated digital inputs 0 to 15/31 */ + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE; + s->n_chan = nchan; + s->maxdata = 1; + s->insn_bits = adl_pci7x3x_di_insn_bits; + s->range_table = &range_digital; + + s->private = (void *)PCI7X3X_DIO_REG; + + subdev++; + + nchan = board->di_nchan - nchan; + if (nchan) { + s = dev->subdevices + subdev; + /* Isolated digital inputs 32 to 63 */ + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE; + s->n_chan = nchan; + s->maxdata = 1; + s->insn_bits = adl_pci7x3x_di_insn_bits; + s->range_table = &range_digital; + + s->private = (void *)PCI743X_DIO_REG; + + subdev++; + } + } + + if (board->do_nchan) { + nchan = min(board->do_nchan, 32); + + s = dev->subdevices + subdev; + /* Isolated digital outputs 0 to 15/31 */ + s->type = COMEDI_SUBD_DO; + s->subdev_flags = SDF_WRITABLE; + s->n_chan = nchan; + s->maxdata = 1; + s->insn_bits = adl_pci7x3x_do_insn_bits; + s->range_table = &range_digital; + + s->private = (void *)PCI7X3X_DIO_REG; + + subdev++; + + nchan = board->do_nchan - nchan; + if (nchan) { + s = dev->subdevices + subdev; + /* Isolated digital outputs 32 to 63 */ + s->type = COMEDI_SUBD_DO; + s->subdev_flags = SDF_WRITABLE; + s->n_chan = nchan; + s->maxdata = 1; + s->insn_bits = adl_pci7x3x_do_insn_bits; + s->range_table = &range_digital; + + s->private = (void *)PCI743X_DIO_REG; + + subdev++; + } + } + + dev_info(dev->class_dev, "%s attached (%d inputs/%d outputs)\n", + dev->board_name, board->di_nchan, board->do_nchan); + + return 0; +} + +static int adl_pci7x3x_attach(struct comedi_device *dev, + struct comedi_devconfig *it) +{ + dev_warn(dev->class_dev, + "This driver does not support attach using comedi_config\n"); + + return -ENOSYS; +} + +static void adl_pci7x3x_detach(struct comedi_device *dev) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + + if (pcidev) { + if (dev->iobase) + comedi_pci_disable(pcidev); + } +} + +static struct comedi_driver adl_pci7x3x_driver = { + .driver_name = "adl_pci7x3x", + .module = THIS_MODULE, + .attach = adl_pci7x3x_attach, + .attach_pci = adl_pci7x3x_attach_pci, + .detach = adl_pci7x3x_detach, +}; + +static int __devinit adl_pci7x3x_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &adl_pci7x3x_driver); +} + +static void __devexit adl_pci7x3x_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(adl_pci7x3x_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7230) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7233) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7234) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7432) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7433) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7434) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, adl_pci7x3x_pci_table); + +static struct pci_driver adl_pci7x3x_pci_driver = { + .name = "adl_pci7x3x", + .id_table = adl_pci7x3x_pci_table, + .probe = adl_pci7x3x_pci_probe, + .remove = __devexit_p(adl_pci7x3x_pci_remove), +}; +module_comedi_pci_driver(adl_pci7x3x_driver, adl_pci7x3x_pci_driver); + +MODULE_DESCRIPTION("ADLINK PCI-723x/743x Isolated Digital I/O boards"); +MODULE_AUTHOR("H Hartley Sweeten "); +MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 657f77d173d32d53b8217561446e59160ee0fb91 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 3 Aug 2012 10:29:02 -0700 Subject: staging: comedi: remove adl_pci7230 and adl_pci7432 drivers The boards supported by these drivers are now handled by the adl_pci7x3x driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index d8b0065..159de1d 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -687,14 +687,6 @@ config COMEDI_ADL_PCI7X3X To compile this driver as a module, choose M here: the module will be called adl_pci7x3x. -config COMEDI_ADL_PCI7230 - tristate "ADLink PCI-7230 digital io board support" - ---help--- - Enable support for ADlink PCI-7230 digital io board support - - To compile this driver as a module, choose M here: the module will be - called adl_pci7230. - config COMEDI_ADL_PCI7296 tristate "ADLink PCI-7296 96 ch. digital io board support" select COMEDI_8255 @@ -704,14 +696,6 @@ config COMEDI_ADL_PCI7296 To compile this driver as a module, choose M here: the module will be called adl_pci7296. -config COMEDI_ADL_PCI7432 - tristate "ADLink PCI-7432 64 ch. isolated digital io board support" - ---help--- - Enable support for ADlink PCI-7432 64 ch. isolated digital io board - - To compile this driver as a module, choose M here: the module will be - called adl_pci7432. - config COMEDI_ADL_PCI8164 tristate "ADLink PCI-8164 4 Axes Motion Control board support" ---help--- diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile index d13d5a9..849ea7f 100644 --- a/drivers/staging/comedi/drivers/Makefile +++ b/drivers/staging/comedi/drivers/Makefile @@ -70,9 +70,7 @@ obj-$(CONFIG_COMEDI_ADDI_APCI_3501) += addi_apci_3501.o obj-$(CONFIG_COMEDI_ADDI_APCI_3XXX) += addi_apci_3xxx.o obj-$(CONFIG_COMEDI_ADL_PCI6208) += adl_pci6208.o obj-$(CONFIG_COMEDI_ADL_PCI7X3X) += adl_pci7x3x.o -obj-$(CONFIG_COMEDI_ADL_PCI7230) += adl_pci7230.o obj-$(CONFIG_COMEDI_ADL_PCI7296) += adl_pci7296.o -obj-$(CONFIG_COMEDI_ADL_PCI7432) += adl_pci7432.o obj-$(CONFIG_COMEDI_ADL_PCI8164) += adl_pci8164.o obj-$(CONFIG_COMEDI_ADL_PCI9111) += adl_pci9111.o obj-$(CONFIG_COMEDI_ADL_PCI9118) += adl_pci9118.o diff --git a/drivers/staging/comedi/drivers/adl_pci7230.c b/drivers/staging/comedi/drivers/adl_pci7230.c deleted file mode 100644 index 7df4c96..0000000 --- a/drivers/staging/comedi/drivers/adl_pci7230.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - comedi/drivers/adl_pci7230.c - - Hardware comedi driver fot PCI7230 Adlink card - Copyright (C) 2010 David Fernandez - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ -/* -Driver: adl_pci7230 -Description: Driver for the Adlink PCI-7230 32 ch. isolated digital io board -Devices: [ADLink] PCI-7230 (adl_pci7230) -Author: David Fernandez -Status: experimental -Updated: Mon, 14 Apr 2008 15:08:14 +0100 - -Configuration Options: - [0] - PCI bus of device (optional) - [1] - PCI slot of device (optional) - If bus/slot is not specified, the first supported - PCI device found will be used. -*/ - -#include "../comedidev.h" -#include - -#define PCI7230_DI 0x00 -#define PCI7230_DO 0x00 - -#define PCI_DEVICE_ID_PCI7230 0x7230 - -static int adl_pci7230_do_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - if (data[0]) { - s->state &= ~data[0]; - s->state |= (data[0] & data[1]); - - outl((s->state << 16) & 0xffffffff, dev->iobase + PCI7230_DO); - } - - return insn->n; -} - -static int adl_pci7230_di_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - data[1] = inl(dev->iobase + PCI7230_DI) & 0xffffffff; - - return insn->n; -} - -static struct pci_dev *adl_pci7230_find_pci(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - struct pci_dev *pcidev = NULL; - int bus = it->options[0]; - int slot = it->options[1]; - - for_each_pci_dev(pcidev) { - if (pcidev->vendor != PCI_VENDOR_ID_ADLINK || - pcidev->device != PCI_DEVICE_ID_PCI7230) - continue; - if (bus || slot) { - /* requested particular bus/slot */ - if (pcidev->bus->number != bus || - PCI_SLOT(pcidev->devfn) != slot) - continue; - } - return pcidev; - } - printk(KERN_ERR "comedi%d: no supported board found! (req. bus/slot : %d/%d)\n", - dev->minor, bus, slot); - return NULL; -} - -static int adl_pci7230_attach(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - struct comedi_subdevice *s; - struct pci_dev *pcidev; - int ret; - - printk(KERN_INFO "comedi%d: adl_pci7230\n", dev->minor); - - dev->board_name = "pci7230"; - - ret = comedi_alloc_subdevices(dev, 2); - if (ret) - return ret; - - pcidev = adl_pci7230_find_pci(dev, it); - if (!pcidev) - return -EIO; - comedi_set_hw_dev(dev, &pcidev->dev); - - if (comedi_pci_enable(pcidev, "adl_pci7230") < 0) { - printk(KERN_ERR "comedi%d: Failed to enable PCI device and request regions\n", - dev->minor); - return -EIO; - } - dev->iobase = pci_resource_start(pcidev, 2); - printk(KERN_DEBUG "comedi: base addr %4lx\n", dev->iobase); - - s = dev->subdevices + 0; - /* Isolated do */ - s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = 16; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = adl_pci7230_do_insn_bits; - - s = dev->subdevices + 1; - /* Isolated di */ - s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = 16; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = adl_pci7230_di_insn_bits; - - printk(KERN_DEBUG "comedi: attached\n"); - - return 1; -} - -static void adl_pci7230_detach(struct comedi_device *dev) -{ - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - pci_dev_put(pcidev); - } -} - -static struct comedi_driver adl_pci7230_driver = { - .driver_name = "adl_pci7230", - .module = THIS_MODULE, - .attach = adl_pci7230_attach, - .detach = adl_pci7230_detach, -}; - -static int __devinit adl_pci7230_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) -{ - return comedi_pci_auto_config(dev, &adl_pci7230_driver); -} - -static void __devexit adl_pci7230_pci_remove(struct pci_dev *dev) -{ - comedi_pci_auto_unconfig(dev); -} - -static DEFINE_PCI_DEVICE_TABLE(adl_pci7230_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7230) }, - { 0 } -}; -MODULE_DEVICE_TABLE(pci, adl_pci7230_pci_table); - -static struct pci_driver adl_pci7230_pci_driver = { - .name = "adl_pci7230", - .id_table = adl_pci7230_pci_table, - .probe = adl_pci7230_pci_probe, - .remove = __devexit_p(adl_pci7230_pci_remove), -}; -module_comedi_pci_driver(adl_pci7230_driver, adl_pci7230_pci_driver); - -MODULE_AUTHOR("Comedi http://www.comedi.org"); -MODULE_DESCRIPTION("Comedi low-level driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/adl_pci7432.c b/drivers/staging/comedi/drivers/adl_pci7432.c deleted file mode 100644 index 6b8d940..0000000 --- a/drivers/staging/comedi/drivers/adl_pci7432.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - comedi/drivers/adl_pci7432.c - - Hardware comedi driver fot PCI7432 Adlink card - Copyright (C) 2004 Michel Lachine - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ -/* -Driver: adl_pci7432 -Description: Driver for the Adlink PCI-7432 64 ch. isolated digital io board -Devices: [ADLink] PCI-7432 (adl_pci7432) -Author: Michel Lachaine -Status: experimental -Updated: Mon, 14 Apr 2008 15:08:14 +0100 - -Configuration Options: - [0] - PCI bus of device (optional) - [1] - PCI slot of device (optional) - If bus/slot is not specified, the first supported - PCI device found will be used. -*/ - -#include "../comedidev.h" -#include - -#define PCI7432_DI 0x00 -#define PCI7432_DO 0x00 - -#define PCI_DEVICE_ID_PCI7432 0x7432 - -static int adl_pci7432_do_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - printk(KERN_DEBUG "comedi: pci7432_do_insn_bits called\n"); - printk(KERN_DEBUG "comedi: data0: %8x data1: %8x\n", data[0], data[1]); - - if (data[0]) { - s->state &= ~data[0]; - s->state |= (data[0] & data[1]); - - printk(KERN_DEBUG "comedi: out: %8x on iobase %4lx\n", s->state, - dev->iobase + PCI7432_DO); - outl(s->state & 0xffffffff, dev->iobase + PCI7432_DO); - } - return insn->n; -} - -static int adl_pci7432_di_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - printk(KERN_DEBUG "comedi: pci7432_di_insn_bits called\n"); - printk(KERN_DEBUG "comedi: data0: %8x data1: %8x\n", data[0], data[1]); - - data[1] = inl(dev->iobase + PCI7432_DI) & 0xffffffff; - printk(KERN_DEBUG "comedi: data1 %8x\n", data[1]); - - return insn->n; -} - -static struct pci_dev *adl_pci7432_find_pci(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - struct pci_dev *pcidev = NULL; - int bus = it->options[0]; - int slot = it->options[1]; - - for_each_pci_dev(pcidev) { - if (pcidev->vendor != PCI_VENDOR_ID_ADLINK || - pcidev->device != PCI_DEVICE_ID_PCI7432) - continue; - if (bus || slot) { - /* requested particular bus/slot */ - if (pcidev->bus->number != bus || - PCI_SLOT(pcidev->devfn) != slot) - continue; - } - return pcidev; - } - printk(KERN_ERR - "comedi%d: no supported board found! (req. bus/slot : %d/%d)\n", - dev->minor, bus, slot); - return NULL; -} - -static int adl_pci7432_attach(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - struct pci_dev *pcidev; - struct comedi_subdevice *s; - int ret; - - printk(KERN_INFO "comedi%d: attach adl_pci7432\n", dev->minor); - - dev->board_name = "pci7432"; - - ret = comedi_alloc_subdevices(dev, 2); - if (ret) - return ret; - - pcidev = adl_pci7432_find_pci(dev, it); - if (!pcidev) - return -EIO; - comedi_set_hw_dev(dev, &pcidev->dev); - - if (comedi_pci_enable(pcidev, "adl_pci7432") < 0) { - printk(KERN_ERR "comedi%d: Failed to enable PCI device and request regions\n", - dev->minor); - return -EIO; - } - dev->iobase = pci_resource_start(pcidev, 2); - printk(KERN_INFO "comedi: base addr %4lx\n", dev->iobase); - - s = dev->subdevices + 0; - s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = 32; - s->maxdata = 1; - s->len_chanlist = 32; - s->io_bits = 0x00000000; - s->range_table = &range_digital; - s->insn_bits = adl_pci7432_di_insn_bits; - - s = dev->subdevices + 1; - s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = 32; - s->maxdata = 1; - s->len_chanlist = 32; - s->io_bits = 0xffffffff; - s->range_table = &range_digital; - s->insn_bits = adl_pci7432_do_insn_bits; - - printk(KERN_DEBUG "comedi%d: adl_pci7432 attached\n", dev->minor); - return 0; -} - -static void adl_pci7432_detach(struct comedi_device *dev) -{ - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - pci_dev_put(pcidev); - } -} - -static struct comedi_driver adl_pci7432_driver = { - .driver_name = "adl_pci7432", - .module = THIS_MODULE, - .attach = adl_pci7432_attach, - .detach = adl_pci7432_detach, -}; - -static int __devinit adl_pci7432_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) -{ - return comedi_pci_auto_config(dev, &adl_pci7432_driver); -} - -static void __devexit adl_pci7432_pci_remove(struct pci_dev *dev) -{ - comedi_pci_auto_unconfig(dev); -} - -static DEFINE_PCI_DEVICE_TABLE(adl_pci7432_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7432) }, - { 0 } -}; -MODULE_DEVICE_TABLE(pci, adl_pci7432_pci_table); - -static struct pci_driver adl_pci7432_pci_driver = { - .name = "adl_pci7432", - .id_table = adl_pci7432_pci_table, - .probe = adl_pci7432_pci_probe, - .remove = __devexit_p(adl_pci7432_pci_remove), -}; -module_comedi_pci_driver(adl_pci7432_driver, adl_pci7432_pci_driver); - -MODULE_AUTHOR("Comedi http://www.comedi.org"); -MODULE_DESCRIPTION("Comedi low-level driver"); -MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 32bb1544800c6d08c9a682548c94a27d1eb41875 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 3 Aug 2012 11:33:01 -0700 Subject: staging: comedi: update adl_pci7296 driver Currently this driver only supports the 96-channel PCI-7296. The 24 and 48 channel PCI-7224 and PCI-7248 boards share the same register map and just have less 8255 devices providing the i/o channels. This adds the PCI PnP support for the other boards in the ADLink PCI-72xx series. Also, remove the legacy attach using the comedi_config utility. This driver now supports the comedi PCI auto config attach mechanism and the legacy attach is not supported or required by this driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 159de1d..d36486e 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -688,10 +688,12 @@ config COMEDI_ADL_PCI7X3X called adl_pci7x3x. config COMEDI_ADL_PCI7296 - tristate "ADLink PCI-7296 96 ch. digital io board support" + tristate "ADLink PCI-72xx opto-22 compatible digital i/o board support" select COMEDI_8255 ---help--- - Enable support for ADlink PCI-7296 96 ch. digital io board support + Enable support for ADlink PCI-72xx opto-22 compatible digital i/o + boards. Supported boards include the 24-channel PCI-7224, 48-channel + PCI-7248, and 96-channel PCI-7296. To compile this driver as a module, choose M here: the module will be called adl_pci7296. diff --git a/drivers/staging/comedi/drivers/adl_pci7296.c b/drivers/staging/comedi/drivers/adl_pci7296.c index 19b47af..1b9ea54 100644 --- a/drivers/staging/comedi/drivers/adl_pci7296.c +++ b/drivers/staging/comedi/drivers/adl_pci7296.c @@ -1,148 +1,163 @@ /* - comedi/drivers/adl_pci7296.c + * COMEDI driver for the ADLINK PCI-72xx series boards. + * + * COMEDI - Linux Control and Measurement Device Interface + * Copyright (C) 2000 David A. Schleef + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ - COMEDI - Linux Control and Measurement Device Interface - Copyright (C) 2000 David A. Schleef - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ /* Driver: adl_pci7296 -Description: Driver for the Adlink PCI-7296 96 ch. digital io board -Devices: [ADLink] PCI-7296 (adl_pci7296) +Description: 24/48/96-Channel Opto-22 Compatible Digital I/O Boards +Devices: (ADLink) PCI-7224 [adl_pci7224] - 24 channels + (ADLink) PCI-7248 [adl_pci7248] - 48 channels + (ADLink) PCI-7296 [adl_pci7296] - 96 channels Author: Jon Grierson Updated: Mon, 14 Apr 2008 15:05:56 +0100 Status: testing -Configuration Options: - [0] - PCI bus of device (optional) - [1] - PCI slot of device (optional) - If bus/slot is not specified, the first supported - PCI device found will be used. +This driver only attaches using the PCI PnP auto config support +in the comedi core. The module parameter 'comedi_autoconfig' +must be 1 (default) to enable this feature. The COMEDI_DEVCONFIG +ioctl, used by the comedi_config utility, is not supported by +this driver. + +These boards also have an 8254 programmable timer/counter chip. +This chip is not currently supported by this driver. + +Interrupt support for these boards is also not currently supported. + +Configuration Options: not applicable */ #include "../comedidev.h" -#include #include "8255.h" -/* #include "8253.h" */ -#define PORT1A 0 -#define PORT2A 4 -#define PORT3A 8 -#define PORT4A 12 +/* + * PCI Device ID's supported by this driver + */ +#define PCI_DEVICE_ID_PCI7224 0x7224 +#define PCI_DEVICE_ID_PCI7248 0x7248 +#define PCI_DEVICE_ID_PCI7296 0x7296 + +struct adl_pci7296_boardinfo { + const char *name; + unsigned short device; + int nsubdevs; +}; -#define PCI_DEVICE_ID_PCI7296 0x7296 +static const struct adl_pci7296_boardinfo adl_pci7296_boards[] = { + { + .name = "adl_pci7224", + .device = PCI_DEVICE_ID_PCI7224, + .nsubdevs = 1, + }, { + .name = "adl_pci7248", + .device = PCI_DEVICE_ID_PCI7248, + .nsubdevs = 2, + }, { + .name = "adl_pci7296", + .device = PCI_DEVICE_ID_PCI7296, + .nsubdevs = 4, + }, +}; -static struct pci_dev *adl_pci7296_find_pci(struct comedi_device *dev, - struct comedi_devconfig *it) +static const void *adl_pci7296_find_boardinfo(struct comedi_device *dev, + struct pci_dev *pcidev) { - struct pci_dev *pcidev = NULL; - int bus = it->options[0]; - int slot = it->options[1]; - - for_each_pci_dev(pcidev) { - if (pcidev->vendor != PCI_VENDOR_ID_ADLINK || - pcidev->device != PCI_DEVICE_ID_PCI7296) - continue; - if (bus || slot) { - /* requested particular bus/slot */ - if (pcidev->bus->number != bus || - PCI_SLOT(pcidev->devfn) != slot) - continue; - } - return pcidev; + const struct adl_pci7296_boardinfo *board; + int i; + + for (i = 0; i < ARRAY_SIZE(adl_pci7296_boards); i++) { + board = &adl_pci7296_boards[i]; + if (pcidev->device == board->device) + return board; } - printk(KERN_ERR - "comedi%d: no supported board found! (req. bus/slot : %d/%d)\n", - dev->minor, bus, slot); return NULL; } -static int adl_pci7296_attach(struct comedi_device *dev, - struct comedi_devconfig *it) +static int adl_pci7296_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) { - struct pci_dev *pcidev; + const struct adl_pci7296_boardinfo *board; struct comedi_subdevice *s; int ret; + int i; - printk(KERN_INFO "comedi%d: attach adl_pci7432\n", dev->minor); + comedi_set_hw_dev(dev, &pcidev->dev); - dev->board_name = "pci7432"; + board = adl_pci7296_find_boardinfo(dev, pcidev); + if (!board) + return -ENODEV; + dev->board_ptr = board; + dev->board_name = board->name; - ret = comedi_alloc_subdevices(dev, 4); + ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) return ret; - - pcidev = adl_pci7296_find_pci(dev, it); - if (!pcidev) - return -EIO; - comedi_set_hw_dev(dev, &pcidev->dev); - - if (comedi_pci_enable(pcidev, "adl_pci7296") < 0) { - printk(KERN_ERR - "comedi%d: Failed to enable PCI device and request regions\n", - dev->minor); - return -EIO; - } - dev->iobase = pci_resource_start(pcidev, 2); - printk(KERN_INFO "comedi: base addr %4lx\n", dev->iobase); - - /* four 8255 digital io subdevices */ - s = dev->subdevices + 0; - subdev_8255_init(dev, s, NULL, (unsigned long)(dev->iobase)); - s = dev->subdevices + 1; - ret = subdev_8255_init(dev, s, NULL, - (unsigned long)(dev->iobase + PORT2A)); - if (ret < 0) - return ret; - - s = dev->subdevices + 2; - ret = subdev_8255_init(dev, s, NULL, - (unsigned long)(dev->iobase + PORT3A)); - if (ret < 0) + /* + * One, two, or four subdevices are setup by this driver depending + * on the number of channels provided by the board. Each subdevice + * has 24 channels supported by the 8255 module. + */ + ret = comedi_alloc_subdevices(dev, board->nsubdevs); + if (ret) return ret; - s = dev->subdevices + 3; - ret = subdev_8255_init(dev, s, NULL, - (unsigned long)(dev->iobase + PORT4A)); - if (ret < 0) - return ret; + for (i = 0; i < board->nsubdevs; i++) { + s = dev->subdevices + i; + ret = subdev_8255_init(dev, s, NULL, dev->iobase + (i * 4)); + if (ret) + return ret; + } - printk(KERN_DEBUG "comedi%d: adl_pci7432 attached\n", dev->minor); + dev_info(dev->class_dev, "%s attached (%d digital i/o channels)\n", + dev->board_name, board->nsubdevs * 24); return 0; } +static int adl_pci7296_attach(struct comedi_device *dev, + struct comedi_devconfig *it) +{ + dev_warn(dev->class_dev, + "This driver does not support attach using comedi_config\n"); + + return -ENOSYS; +} + static void adl_pci7296_detach(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); + const struct adl_pci7296_boardinfo *board = comedi_board(dev); + struct comedi_subdevice *s; + int i; + if (dev->subdevices) { + for (i = 0; i < board->nsubdevs; i++) { + s = dev->subdevices + i; + subdev_8255_cleanup(dev, s); + } + } if (pcidev) { if (dev->iobase) comedi_pci_disable(pcidev); - pci_dev_put(pcidev); - } - if (dev->subdevices) { - subdev_8255_cleanup(dev, dev->subdevices + 0); - subdev_8255_cleanup(dev, dev->subdevices + 1); - subdev_8255_cleanup(dev, dev->subdevices + 2); - subdev_8255_cleanup(dev, dev->subdevices + 3); } } @@ -150,6 +165,7 @@ static struct comedi_driver adl_pci7296_driver = { .driver_name = "adl_pci7296", .module = THIS_MODULE, .attach = adl_pci7296_attach, + .attach_pci = adl_pci7296_attach_pci, .detach = adl_pci7296_detach, }; @@ -165,6 +181,8 @@ static void __devexit adl_pci7296_pci_remove(struct pci_dev *dev) } static DEFINE_PCI_DEVICE_TABLE(adl_pci7296_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7224) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7248) }, { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7296) }, { 0 } }; @@ -178,6 +196,6 @@ static struct pci_driver adl_pci7296_pci_driver = { }; module_comedi_pci_driver(adl_pci7296_driver, adl_pci7296_pci_driver); +MODULE_DESCRIPTION("ADLINK PCI-72xx Opto-22 Compatible Digital I/O Boards"); MODULE_AUTHOR("Comedi http://www.comedi.org"); -MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 744a8398e1f48d5349409b1fa9232a109b223458 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 9 Aug 2012 14:50:35 -0700 Subject: staging: comedi: adl_pci6208: use attach_pci callback Convert this PCI driver to use the comedi PCI auto config attach mechanism by adding an attach_pci callback function. Since the driver does not require any external configuration options, disable the legacy attach by making the attach callback simply return -ENOSYS. This removes the need to walk the pci bus to find the pci_dev and the need for the pci_dev_put() in the detach. For aesthetic reasons, rename the local variable 'thisboard' to 'boardinfo'. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c index 3bec0f6..6d887f7 100644 --- a/drivers/staging/comedi/drivers/adl_pci6208.c +++ b/drivers/staging/comedi/drivers/adl_pci6208.c @@ -33,8 +33,7 @@ Author: nsyeow Updated: Fri, 30 Jan 2004 14:44:27 +0800 Status: untested -Configuration Options: - none +Configuration Options: not applicable, uses PCI auto config References: - ni_660x.c @@ -155,67 +154,41 @@ static int pci6208_dio_insn_config(struct comedi_device *dev, return insn->n; } -static struct pci_dev *pci6208_find_device(struct comedi_device *dev, - struct comedi_devconfig *it) +static const void *pci6208_find_boardinfo(struct comedi_device *dev, + struct pci_dev *pcidev) { - const struct pci6208_board *thisboard; - struct pci_dev *pci_dev = NULL; - int bus = it->options[0]; - int slot = it->options[1]; + const struct pci6208_board *boardinfo; int i; - for_each_pci_dev(pci_dev) { - if (pci_dev->vendor != PCI_VENDOR_ID_ADLINK) - continue; - for (i = 0; i < ARRAY_SIZE(pci6208_boards); i++) { - thisboard = &pci6208_boards[i]; - if (thisboard->dev_id != pci_dev->device) - continue; - /* was a particular bus/slot requested? */ - if (bus || slot) { - /* are we on the wrong bus/slot? */ - if (pci_dev->bus->number != bus || - PCI_SLOT(pci_dev->devfn) != slot) - continue; - } - dev_dbg(dev->class_dev, - "Found %s on bus %d, slot, %d, irq=%d\n", - thisboard->name, - pci_dev->bus->number, - PCI_SLOT(pci_dev->devfn), - pci_dev->irq); - dev->board_ptr = thisboard; - return pci_dev; - } + for (i = 0; i < ARRAY_SIZE(pci6208_boards); i++) { + boardinfo = &pci6208_boards[i]; + if (boardinfo->dev_id == pcidev->device) + return boardinfo; } - dev_err(dev->class_dev, - "No supported board found! (req. bus %d, slot %d)\n", - bus, slot); return NULL; } -static int pci6208_attach(struct comedi_device *dev, - struct comedi_devconfig *it) +static int pci6208_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) { - const struct pci6208_board *thisboard; + const struct pci6208_board *boardinfo; struct pci6208_private *devpriv; - struct pci_dev *pcidev; struct comedi_subdevice *s; int ret; + comedi_set_hw_dev(dev, &pcidev->dev); + + boardinfo = pci6208_find_boardinfo(dev, pcidev); + if (!boardinfo) + return -ENODEV; + dev->board_ptr = boardinfo; + dev->board_name = boardinfo->name; + ret = alloc_private(dev, sizeof(*devpriv)); if (ret < 0) return ret; devpriv = dev->private; - pcidev = pci6208_find_device(dev, it); - if (!pcidev) - return -EIO; - comedi_set_hw_dev(dev, &pcidev->dev); - thisboard = comedi_board(dev); - - dev->board_name = thisboard->name; - ret = comedi_pci_enable(pcidev, dev->driver->driver_name); if (ret) { dev_err(dev->class_dev, @@ -232,7 +205,7 @@ static int pci6208_attach(struct comedi_device *dev, /* analog output subdevice */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; - s->n_chan = thisboard->ao_chans; + s->n_chan = boardinfo->ao_chans; s->maxdata = 0xffff; s->range_table = &range_bipolar10; s->insn_write = pci6208_ao_winsn; @@ -257,6 +230,15 @@ static int pci6208_attach(struct comedi_device *dev, return 0; } +static int pci6208_attach(struct comedi_device *dev, + struct comedi_devconfig *it) +{ + dev_warn(dev->class_dev, + "This driver does not support attach using comedi_config\n"); + + return -ENOSYS; +} + static void pci6208_detach(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -264,7 +246,6 @@ static void pci6208_detach(struct comedi_device *dev) if (pcidev) { if (dev->iobase) comedi_pci_disable(pcidev); - pci_dev_put(pcidev); } } @@ -272,6 +253,7 @@ static struct comedi_driver adl_pci6208_driver = { .driver_name = "adl_pci6208", .module = THIS_MODULE, .attach = pci6208_attach, + .attach_pci = pci6208_attach_pci, .detach = pci6208_detach, }; -- cgit v0.10.2 From 0a1e6c1fdbdcdbbf9457bc812e145062d59a68c2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 9 Aug 2012 14:51:07 -0700 Subject: staging: comedi: adl_pci6208: add support for the PCI-6216 card Add the boardinfo and pci device table information for the PCI-6216 card. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c index 6d887f7..43e23e1 100644 --- a/drivers/staging/comedi/drivers/adl_pci6208.c +++ b/drivers/staging/comedi/drivers/adl_pci6208.c @@ -27,8 +27,9 @@ */ /* Driver: adl_pci6208 -Description: ADLink PCI-6208A -Devices: [ADLink] PCI-6208A (adl_pci6208) +Description: ADLink PCI-6208/6216 Series Multi-channel Analog Output Cards +Devices: (ADLink) PCI-6208 [adl_pci6208] + (ADLink) PCI-6216 [adl_pci6216] Author: nsyeow Updated: Fri, 30 Jan 2004 14:44:27 +0800 Status: untested @@ -44,6 +45,12 @@ References: #include "../comedidev.h" /* + * ADLINK PCI Device ID's supported by this driver + */ +#define PCI_DEVICE_ID_PCI6208 0x6208 +#define PCI_DEVICE_ID_PCI6216 0x6216 + +/* * PCI-6208/6216-GL register map */ #define PCI6208_AO_CONTROL(x) (0x00 + (2 * (x))) @@ -55,7 +62,7 @@ References: #define PCI6208_DIO_DI_MASK (0xf0) #define PCI6208_DIO_DI_SHIFT (4) -#define PCI6208_MAX_AO_CHANNELS 8 +#define PCI6208_MAX_AO_CHANNELS 16 struct pci6208_board { const char *name; @@ -65,9 +72,13 @@ struct pci6208_board { static const struct pci6208_board pci6208_boards[] = { { - .name = "pci6208a", - .dev_id = 0x6208, + .name = "adl_pci6208", + .dev_id = PCI_DEVICE_ID_PCI6208, .ao_chans = 8, + }, { + .name = "adl_pci6216", + .dev_id = PCI_DEVICE_ID_PCI6216, + .ao_chans = 16, }, }; @@ -269,7 +280,8 @@ static void __devexit adl_pci6208_pci_remove(struct pci_dev *dev) } static DEFINE_PCI_DEVICE_TABLE(adl_pci6208_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, 0x6208) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI6208) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI6216) }, { 0 } }; MODULE_DEVICE_TABLE(pci, adl_pci6208_pci_table); -- cgit v0.10.2 From 270809a80fb610b54de5ee792a607dc37a71195c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 9 Aug 2012 14:51:26 -0700 Subject: staging: comedi: adl_pci6208: split the digital i/o subdevice The PCI-6208/6216 cards have 4 digital inputs and 4 digital outputs. These are currently being handled by an 8 channel COMEDI_SUBD_DIO subdevice in this driver. This causes the 4 digital outputs to appear as channels 0 thru 3 and the 4 digital inputs to appear as channels 4 thru 7. Userspace can only work out part thisby doing the COMEDI_INSNLIST ioctl with the INSN_CONFIG_DIO_QUERY instruction for each channel to determine the io direction. Make things a bit cleaner for userspace by creating two subdevices instead. One for the 4 digital inputs and one for the 4 digital outputs. For both subdevices the channel number indicates the actual digital input/output signal. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c index 43e23e1..74695bb 100644 --- a/drivers/staging/comedi/drivers/adl_pci6208.c +++ b/drivers/staging/comedi/drivers/adl_pci6208.c @@ -125,46 +125,41 @@ static int pci6208_ao_rinsn(struct comedi_device *dev, return insn->n; } -static int pci6208_dio_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) +static int pci6208_di_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - unsigned int mask = data[0] & PCI6208_DIO_DO_MASK; + unsigned int val; + + val = inw(dev->iobase + PCI6208_DIO); + val = (val & PCI6208_DIO_DI_MASK) >> PCI6208_DIO_DI_SHIFT; + + data[1] = val; + + return insn->n; +} + +static int pci6208_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + unsigned int mask = data[0]; unsigned int bits = data[1]; if (mask) { s->state &= ~mask; - s->state |= bits & mask; + s->state |= (bits & mask); outw(s->state, dev->iobase + PCI6208_DIO); } - s->state = inw(dev->iobase + PCI6208_DIO); data[1] = s->state; return insn->n; } -static int pci6208_dio_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - int chan = CR_CHAN(insn->chanspec); - unsigned int mask = 1 << chan; - - switch (data[0]) { - case INSN_CONFIG_DIO_QUERY: - data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT; - break; - default: - return -EINVAL; - } - - return insn->n; -} - static const void *pci6208_find_boardinfo(struct comedi_device *dev, struct pci_dev *pcidev) { @@ -185,6 +180,7 @@ static int pci6208_attach_pci(struct comedi_device *dev, const struct pci6208_board *boardinfo; struct pci6208_private *devpriv; struct comedi_subdevice *s; + unsigned int val; int ret; comedi_set_hw_dev(dev, &pcidev->dev); @@ -208,7 +204,7 @@ static int pci6208_attach_pci(struct comedi_device *dev, } dev->iobase = pci_resource_start(pcidev, 2); - ret = comedi_alloc_subdevices(dev, 2); + ret = comedi_alloc_subdevices(dev, 3); if (ret) return ret; @@ -223,17 +219,31 @@ static int pci6208_attach_pci(struct comedi_device *dev, s->insn_read = pci6208_ao_rinsn; s = dev->subdevices + 1; - /* digital i/o subdevice */ - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 8; + /* digital input subdevice */ + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE; + s->n_chan = 4; s->maxdata = 1; s->range_table = &range_digital; - s->insn_bits = pci6208_dio_insn_bits; - s->insn_config = pci6208_dio_insn_config; + s->insn_bits = pci6208_di_insn_bits; + s = dev->subdevices + 2; + /* digital output subdevice */ + s->type = COMEDI_SUBD_DO; + s->subdev_flags = SDF_WRITABLE; + s->n_chan = 4; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = pci6208_do_insn_bits; + + /* + * Get the read back signals from the digital outputs + * and save it as the initial state for the subdevice. + */ + val = inw(dev->iobase + PCI6208_DIO); + val = (val & PCI6208_DIO_DO_MASK) >> PCI6208_DIO_DO_SHIFT; + s->state = val; s->io_bits = 0x0f; - s->state = inw(dev->iobase + PCI6208_DIO); dev_info(dev->class_dev, "%s: %s, I/O base=0x%04lx\n", dev->driver->driver_name, dev->board_name, dev->iobase); -- cgit v0.10.2 From 3cf05ddb0d7c5612ee70f250f22427462d820fe1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 9 Aug 2012 14:51:51 -0700 Subject: staging: comedi: adl_pci6208: use the 'board_name' for the resource name Use the 'dev->board_name' instead of the 'dev->driver->driver_name' as the resource name used when requesing the pci regions in comedi_pci_enable(). The board_name has a closer affinity to the card. Also, remove the dev_err() message when comedi_pci_enable() fails. It's just noise and doesn't actually tell the real reason why the call failed. It could have failed either the pci_enable_device() or the pci_request_regions(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c index 74695bb..3abff556 100644 --- a/drivers/staging/comedi/drivers/adl_pci6208.c +++ b/drivers/staging/comedi/drivers/adl_pci6208.c @@ -196,12 +196,9 @@ static int pci6208_attach_pci(struct comedi_device *dev, return ret; devpriv = dev->private; - ret = comedi_pci_enable(pcidev, dev->driver->driver_name); - if (ret) { - dev_err(dev->class_dev, - "Failed to enable PCI device and request regions\n"); + ret = comedi_pci_enable(pcidev, dev->board_name); + if (ret) return ret; - } dev->iobase = pci_resource_start(pcidev, 2); ret = comedi_alloc_subdevices(dev, 3); -- cgit v0.10.2 From 53fa8c46881a5a500fdcc4cf86359d92211b1e9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCng=C3=B6r=20Erseymen?= Date: Fri, 10 Aug 2012 15:54:40 +0300 Subject: Staging: comedi: ssv_dnp: fix checkpatch.pl warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix checkpatch.pl warning about printk issue by merging two printk calls into one dev_info call. Signed-off-by: Güngör Erseymen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ssv_dnp.c b/drivers/staging/comedi/drivers/ssv_dnp.c index 84b9f2a..d1f5118 100644 --- a/drivers/staging/comedi/drivers/ssv_dnp.c +++ b/drivers/staging/comedi/drivers/ssv_dnp.c @@ -177,8 +177,6 @@ static int dnp_attach(struct comedi_device *dev, struct comedi_devconfig *it) struct comedi_subdevice *s; int ret; - printk(KERN_INFO "comedi%d: dnp: ", dev->minor); - dev->board_name = board->name; ret = comedi_alloc_subdevices(dev, 1); @@ -195,8 +193,6 @@ static int dnp_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->insn_bits = dnp_dio_insn_bits; s->insn_config = dnp_dio_insn_config; - printk("attached\n"); - /* We use the I/O ports 0x22,0x23 and 0xa3-0xa9, which are always * allocated for the primary 8259, so we don't need to allocate them * ourselves. */ @@ -209,6 +205,7 @@ static int dnp_attach(struct comedi_device *dev, struct comedi_devconfig *it) outb(PCMR, CSCIR); outb((inb(CSCDR) & 0xAA), CSCDR); + dev_info(dev->class_dev, "%s: attached\n", dev->board_name); return 1; } -- cgit v0.10.2 From d9fc49b2e0c510bf8c54e157a57bac3bb74184f0 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 3 Aug 2012 11:40:01 +0300 Subject: staging: rts5139: substitute rts51x_dump by print_hex_dump Signed-off-by: Andy Shevchenko Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/trace.h b/drivers/staging/rts5139/trace.h index 0584b8a..c9dfb1e 100644 --- a/drivers/staging/rts5139/trace.h +++ b/drivers/staging/rts5139/trace.h @@ -93,35 +93,9 @@ do { \ #endif #ifdef CONFIG_RTS5139_DEBUG -static inline void rts51x_dump(u8 *buf, int buf_len) -{ - int i; - u8 tmp[16] = { 0 }; - u8 *_ptr = buf; - - for (i = 0; i < ((buf_len) / 16); i++) { - RTS51X_DEBUGP("%02x %02x %02x %02x %02x %02x %02x %02x " - "%02x %02x %02x %02x %02x %02x %02x %02x\n", - _ptr[0], _ptr[1], _ptr[2], _ptr[3], _ptr[4], - _ptr[5], _ptr[6], _ptr[7], _ptr[8], _ptr[9], - _ptr[10], _ptr[11], _ptr[12], _ptr[13], _ptr[14], - _ptr[15]); - _ptr += 16; - } - if ((buf_len) % 16) { - memcpy(tmp, _ptr, (buf_len) % 16); - _ptr = tmp; - RTS51X_DEBUGP("%02x %02x %02x %02x %02x %02x %02x %02x " - "%02x %02x %02x %02x %02x %02x %02x %02x\n", - _ptr[0], _ptr[1], _ptr[2], _ptr[3], _ptr[4], - _ptr[5], _ptr[6], _ptr[7], _ptr[8], _ptr[9], - _ptr[10], _ptr[11], _ptr[12], _ptr[13], _ptr[14], - _ptr[15]); - } -} - -#define RTS51X_DUMP(buf, buf_len) \ - rts51x_dump((u8 *)(buf), (buf_len)) +#define RTS51X_DUMP(buf, buf_len) \ + print_hex_dump(KERN_DEBUG, RTS51X_TIP, DUMP_PREFIX_NONE, \ + 16, 1, (buf), (buf_len), false) #define CATCH_TRIGGER(chip) \ do { \ -- cgit v0.10.2 From c197de2bea11cabbd6f9ad8c6e3f82faa5fc8497 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 3 Aug 2012 11:38:05 +0300 Subject: staging: rts_pstor: substitute rtsx_dump by print_hex_dump Signed-off-by: Andy Shevchenko Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/trace.h b/drivers/staging/rts_pstor/trace.h index bc83b49..cf60a1b 100644 --- a/drivers/staging/rts_pstor/trace.h +++ b/drivers/staging/rts_pstor/trace.h @@ -83,33 +83,9 @@ do { \ #endif #ifdef CONFIG_RTS_PSTOR_DEBUG -static inline void rtsx_dump(u8 *buf, int buf_len) -{ - int i; - u8 tmp[16] = {0}; - u8 *_ptr = buf; - - for (i = 0; i < ((buf_len)/16); i++) { - RTSX_DEBUGP("%02x %02x %02x %02x %02x %02x %02x %02x " - "%02x %02x %02x %02x %02x %02x %02x %02x\n", - _ptr[0], _ptr[1], _ptr[2], _ptr[3], _ptr[4], _ptr[5], - _ptr[6], _ptr[7], _ptr[8], _ptr[9], _ptr[10], _ptr[11], - _ptr[12], _ptr[13], _ptr[14], _ptr[15]); - _ptr += 16; - } - if ((buf_len) % 16) { - memcpy(tmp, _ptr, (buf_len) % 16); - _ptr = tmp; - RTSX_DEBUGP("%02x %02x %02x %02x %02x %02x %02x %02x " - "%02x %02x %02x %02x %02x %02x %02x %02x\n", - _ptr[0], _ptr[1], _ptr[2], _ptr[3], _ptr[4], _ptr[5], - _ptr[6], _ptr[7], _ptr[8], _ptr[9], _ptr[10], _ptr[11], - _ptr[12], _ptr[13], _ptr[14], _ptr[15]); - } -} - -#define RTSX_DUMP(buf, buf_len) rtsx_dump((u8 *)(buf), (buf_len)) - +#define RTSX_DUMP(buf, buf_len) \ + print_hex_dump(KERN_DEBUG, RTSX_STOR, DUMP_PREFIX_NONE, \ + 16, 1, (buf), (buf_len), false) #else #define RTSX_DUMP(buf, buf_len) #endif -- cgit v0.10.2 From 9e58d05a1b24d2c0471c3b4df8f473a7543d7647 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20Iglesias=20Gons=C3=A1lvez?= Date: Fri, 20 Jul 2012 09:39:03 +0200 Subject: Staging: ipack/bridges/tpci200: avoid kernel bug when uninstalling a device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 2b83fa8..a7fb2cf 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -604,8 +604,8 @@ static int tpci200_slot_unregister(struct ipack_device *dev) if (mutex_lock_interruptible(&tpci200->mutex)) return -ERESTARTSYS; - ipack_device_unregister(dev); tpci200->slots[dev->slot].dev = NULL; + ipack_device_unregister(dev); mutex_unlock(&tpci200->mutex); return 0; -- cgit v0.10.2 From f45651f9bb22f7ab60d806707be2c75f3d219157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20Iglesias=20Gons=C3=A1lvez?= Date: Fri, 20 Jul 2012 09:39:04 +0200 Subject: Staging: ipack/bridges/tpci200: remove linked list of registered devices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The linked list of registered devices is not needed as the struct tpci200_board is saved in private data field of the pci device. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index a7fb2cf..cee25c7 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -24,28 +24,20 @@ static int control_reg[] = { TPCI200_CONTROL_D_REG }; -/* Linked list to save the registered devices */ -static LIST_HEAD(tpci200_list); - static int tpci200_slot_unregister(struct ipack_device *dev); static struct tpci200_board *check_slot(struct ipack_device *dev) { struct tpci200_board *tpci200; - int found = 0; if (dev == NULL) return NULL; - list_for_each_entry(tpci200, &tpci200_list, list) { - if (tpci200->number == dev->bus_nr) { - found = 1; - break; - } - } - if (!found) { - dev_err(&dev->dev, "Carrier not found\n"); + tpci200 = dev_get_drvdata(dev->bus->parent); + + if (tpci200 == NULL) { + dev_info(&dev->dev, "carrier board not found\n"); return NULL; } @@ -831,8 +823,6 @@ static int tpci200_pciprobe(struct pci_dev *pdev, /* save the bus number given by ipack to logging purpose */ tpci200->number = tpci200->info->ipack_bus->bus_nr; dev_set_drvdata(&pdev->dev, tpci200); - /* add the registered device in an internal linked list */ - list_add_tail(&tpci200->list, &tpci200_list); /* * Give the same IRQ number as the slot number. @@ -847,7 +837,6 @@ static int tpci200_pciprobe(struct pci_dev *pdev, static void __tpci200_pci_remove(struct tpci200_board *tpci200) { tpci200_uninstall(tpci200); - list_del(&tpci200->list); ipack_bus_unregister(tpci200->info->ipack_bus); kfree(tpci200->info); kfree(tpci200); @@ -855,15 +844,9 @@ static void __tpci200_pci_remove(struct tpci200_board *tpci200) static void __devexit tpci200_pci_remove(struct pci_dev *dev) { - struct tpci200_board *tpci200, *next; + struct tpci200_board *tpci200 = pci_get_drvdata(dev); - /* Search the registered device to uninstall it */ - list_for_each_entry_safe(tpci200, next, &tpci200_list, list) { - if (tpci200->info->pdev == dev) { - __tpci200_pci_remove(tpci200); - break; - } - } + __tpci200_pci_remove(tpci200); } static DEFINE_PCI_DEVICE_TABLE(tpci200_idtable) = { @@ -888,11 +871,6 @@ static int __init tpci200_drvr_init_module(void) static void __exit tpci200_drvr_exit_module(void) { - struct tpci200_board *tpci200, *next; - - list_for_each_entry_safe(tpci200, next, &tpci200_list, list) - __tpci200_pci_remove(tpci200); - pci_unregister_driver(&tpci200_pci_drv); } -- cgit v0.10.2 From 5b47f3cbf03f69efc24b34200d6b432fe354b8d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20Iglesias=20Gons=C3=A1lvez?= Date: Fri, 20 Jul 2012 09:39:05 +0200 Subject: Staging: ipack/bridges/tpci200: use ioremap_nocache instead of ioremap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The CPU might write-combine and/or cache memory access. Something that for most modules is not desired. Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index cee25c7..5831af8 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -390,15 +390,15 @@ static int tpci200_register(struct tpci200_board *tpci200) /* Map internal tpci200 driver user space */ tpci200->info->interface_regs = - ioremap(pci_resource_start(tpci200->info->pdev, + ioremap_nocache(pci_resource_start(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR), TPCI200_IFACE_SIZE); tpci200->info->ioidint_space = - ioremap(pci_resource_start(tpci200->info->pdev, + ioremap_nocache(pci_resource_start(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR), TPCI200_IOIDINT_SIZE); tpci200->info->mem8_space = - ioremap(pci_resource_start(tpci200->info->pdev, + ioremap_nocache(pci_resource_start(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR), TPCI200_MEM8_SIZE); @@ -677,7 +677,7 @@ static int tpci200_slot_map_space(struct ipack_device *dev, virt_addr_space->size = size_to_map; virt_addr_space->address = - ioremap((unsigned long)phys_address, size_to_map); + ioremap_nocache((unsigned long)phys_address, size_to_map); out_unlock: mutex_unlock(&tpci200->mutex); -- cgit v0.10.2 From 785526207f4cb7a70a9f3f0b9f991ec9ca63c72d Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 2 Aug 2012 19:05:42 +0300 Subject: staging: csr: print mac address with %pM Signed-off-by: Andy Shevchenko Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/csr/wext_events.c b/drivers/staging/csr/wext_events.c index d356887..9860ea3 100644 --- a/drivers/staging/csr/wext_events.c +++ b/drivers/staging/csr/wext_events.c @@ -194,11 +194,9 @@ _send_michaelmicfailure_event(struct net_device *dev, union iwreq_data wrqu; char buf[128]; - sprintf(buf, - "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr=%02x:%02x:%02x:%02x:%02x:%02x)", - key_idx, (key_type == CSR_GROUP) ? "broad" : "uni", - macaddr[0], macaddr[1], macaddr[2], - macaddr[3], macaddr[4], macaddr[5]); + sprintf(buf, + "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr=%pM)", + key_idx, (key_type == CSR_GROUP) ? "broad" : "uni", macaddr); memset(&wrqu, 0, sizeof(wrqu)); wrqu.data.length = strlen(buf); wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf); -- cgit v0.10.2 From 8c4a12718df3bf67c86d6d372564ab688cbfe7a3 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 2 Aug 2012 19:05:43 +0300 Subject: staging: csr: use %*ph[C] to hexdump small buffers Signed-off-by: Andy Shevchenko Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/csr/csr_wifi_hip_send.c b/drivers/staging/csr/csr_wifi_hip_send.c index 684d304..86aa23c 100644 --- a/drivers/staging/csr/csr_wifi_hip_send.c +++ b/drivers/staging/csr/csr_wifi_hip_send.c @@ -172,13 +172,8 @@ static CsrResult send_signal(card_t *card, const u8 *sigptr, u32 siglen, { const u8 *sig = sigptr; - unifi_error(card->ospriv, "Signal(%d): %02x %02x %02x %02x %02x %02x %02x %02x" - " %02x %02x %02x %02x %02x %02x %02x %02x\n", - siglen, - sig[0], sig[1], sig[2], sig[3], - sig[4], sig[5], sig[6], sig[7], - sig[8], sig[9], sig[10], sig[11], - sig[12], sig[13], sig[14], sig[15]); + unifi_error(card->ospriv, "Signal(%d): %*ph\n", siglen, + 16, sig); unifi_error(card->ospriv, "Bulkdata pointer %p(%d), %p(%d)\n", bulkdata != NULL?bulkdata->d[0].os_data_ptr : NULL, bulkdata != NULL?bulkdata->d[0].data_length : 0, diff --git a/drivers/staging/csr/sme_wext.c b/drivers/staging/csr/sme_wext.c index 7e85907..5689123 100644 --- a/drivers/staging/csr/sme_wext.c +++ b/drivers/staging/csr/sme_wext.c @@ -3043,8 +3043,8 @@ _unifi_siwencodeext(struct net_device *dev, struct iw_request_info *info, memcpy(sme_key.address.a, ext->addr.sa_data, ETH_ALEN); if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { - unifi_trace(priv, UDBG5, "RSC first 6 bytes = %02X:%02X:%02X:%02X:%02X:%02X\n", - ext->rx_seq[0], ext->rx_seq[1], ext->rx_seq[2], ext->rx_seq[3], ext->rx_seq[4], ext->rx_seq[5]); + unifi_trace(priv, UDBG5, "RSC first 6 bytes = %*phC\n", + 6, ext->rx_seq); /* memcpy((u8*)(&sme_key.keyRsc), ext->rx_seq, 8); */ sme_key.keyRsc[0] = ext->rx_seq[1] << 8 | ext->rx_seq[0]; -- cgit v0.10.2 From 02c4be05d9718d5d0f45db39cbef8a927ff4ebb8 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sat, 21 Jul 2012 13:05:32 +0545 Subject: staging/csr: coding style fixes in CsrTimeGet the following warnings were fixed: 1. removed all spaces before the start of a line and used tabs 2. removed the braces around the if as it encloses only a single statement Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/csr/csr_time.c b/drivers/staging/csr/csr_time.c index 83586ca..2043f25 100644 --- a/drivers/staging/csr/csr_time.c +++ b/drivers/staging/csr/csr_time.c @@ -24,20 +24,18 @@ CsrTime CsrTimeGet(CsrTime *high) { - struct timespec ts; - u64 time; - CsrTime low; + struct timespec ts; + u64 time; + CsrTime low; - ts = current_kernel_time(); - time = (u64) ts.tv_sec * 1000000 + ts.tv_nsec / 1000; + ts = current_kernel_time(); + time = (u64) ts.tv_sec * 1000000 + ts.tv_nsec / 1000; - if (high != NULL) - { - *high = (CsrTime) ((time >> 32) & 0xFFFFFFFF); - } + if (high != NULL) + *high = (CsrTime) ((time >> 32) & 0xFFFFFFFF); - low = (CsrTime) (time & 0xFFFFFFFF); + low = (CsrTime) (time & 0xFFFFFFFF); - return low; + return low; } EXPORT_SYMBOL_GPL(CsrTimeGet); -- cgit v0.10.2 From 2dd58c9d8de3858c51a2f903cc40c0d919a7ce27 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sat, 21 Jul 2012 13:06:29 +0545 Subject: staging/csr: coding style fixes at sdio_linux_remove_irq and at install_irq the following coding style problems were fixed: 1. move function return type from top to the starting of the function 2. remove all the spaces at the start of a line and used tabs Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/csr/sdio_mmc.c b/drivers/staging/csr/sdio_mmc.c index d3fd57c..b203d2b 100644 --- a/drivers/staging/csr/sdio_mmc.c +++ b/drivers/staging/csr/sdio_mmc.c @@ -845,19 +845,18 @@ uf_glue_sdio_int_handler(struct sdio_func *func) * Status of the removal. * --------------------------------------------------------------------------- */ -int -csr_sdio_linux_remove_irq(CsrSdioFunction *function) +int csr_sdio_linux_remove_irq(CsrSdioFunction *function) { - struct sdio_func *func = (struct sdio_func *)function->priv; - int r; + struct sdio_func *func = (struct sdio_func *)function->priv; + int r; - unifi_trace(NULL, UDBG1, "csr_sdio_linux_remove_irq\n"); + unifi_trace(NULL, UDBG1, "csr_sdio_linux_remove_irq\n"); - sdio_claim_host(func); - r = sdio_release_irq(func); - sdio_release_host(func); + sdio_claim_host(func); + r = sdio_release_irq(func); + sdio_release_host(func); - return r; + return r; } /* csr_sdio_linux_remove_irq() */ @@ -876,25 +875,23 @@ csr_sdio_linux_remove_irq(CsrSdioFunction *function) * Status of the removal. * --------------------------------------------------------------------------- */ -int -csr_sdio_linux_install_irq(CsrSdioFunction *function) +int csr_sdio_linux_install_irq(CsrSdioFunction *function) { - struct sdio_func *func = (struct sdio_func *)function->priv; - int r; + struct sdio_func *func = (struct sdio_func *)function->priv; + int r; - unifi_trace(NULL, UDBG1, "csr_sdio_linux_install_irq\n"); + unifi_trace(NULL, UDBG1, "csr_sdio_linux_install_irq\n"); - /* Register our interrupt handle */ - sdio_claim_host(func); - r = sdio_claim_irq(func, uf_glue_sdio_int_handler); - sdio_release_host(func); + /* Register our interrupt handle */ + sdio_claim_host(func); + r = sdio_claim_irq(func, uf_glue_sdio_int_handler); + sdio_release_host(func); - /* If the interrupt was installed earlier, is fine */ - if (r == -EBUSY) { - r = 0; - } + /* If the interrupt was installed earlier, is fine */ + if (r == -EBUSY) + r = 0; - return r; + return r; } /* csr_sdio_linux_install_irq() */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) -- cgit v0.10.2 From 08fb73c1c842d32c15806bd9ae89531d5b0e31ea Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sat, 21 Jul 2012 13:07:17 +0545 Subject: staging/csr: remove firmware pointer check before giving to release_firmware we do a check of firmware pointer against the NULL value before we give it to the release_firmware. as release_firmware is actually having a check against NULL, its not needed here. Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/csr/firmware.c b/drivers/staging/csr/firmware.c index d14e118..dc6a04d 100644 --- a/drivers/staging/csr/firmware.c +++ b/drivers/staging/csr/firmware.c @@ -402,9 +402,7 @@ int uf_release_firmware_files(unifi_priv_t *priv) int uf_release_firmware(unifi_priv_t *priv, struct dlpriv *to_free) { if (to_free != NULL) { - if (to_free->fw_desc != NULL) { - release_firmware((const struct firmware *)to_free->fw_desc); - } + release_firmware((const struct firmware *)to_free->fw_desc); to_free->fw_desc = NULL; to_free->dl_data = NULL; to_free->dl_len = 0; -- cgit v0.10.2 From cff9e59f65019428ba8f172dcc8af0154590de42 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sat, 4 Aug 2012 13:01:38 +0545 Subject: staging/csr: clean coding style in uf_start_thread MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit in bh.c the function uf_start_thread needed a coding style fixes. The following fixes: * fix no space at the start of line * fix over 80 character lines * fix no brace needed for single statement blocks (if..else or for and while) * use tabs instead of 4 spaces at the start of every line Cc: Mikko Virkkilä Cc: Lauri Hintsala Cc: Riku Mettälä Cc: Veli-Pekka Peltola Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/csr/bh.c b/drivers/staging/csr/bh.c index b089c28..2b7c4c0 100644 --- a/drivers/staging/csr/bh.c +++ b/drivers/staging/csr/bh.c @@ -32,45 +32,49 @@ * 0 on success or else a Linux error code. * --------------------------------------------------------------------------- */ -int -uf_start_thread(unifi_priv_t *priv, struct uf_thread *thread, int (*func)(void *)) +int uf_start_thread(unifi_priv_t *priv, + struct uf_thread *thread, int (*func)(void *)) { - if (thread->thread_task != NULL) { - unifi_error(priv, "%s thread already started\n", thread->name); - return 0; - } - - /* Start the kernel thread that handles all h/w accesses. */ - thread->thread_task = kthread_run(func, priv, "%s", thread->name); - if (IS_ERR(thread->thread_task)) { - return PTR_ERR(thread->thread_task); - } - - /* Module parameter overides the thread priority */ - if (bh_priority != -1) { - if (bh_priority >= 0 && bh_priority <= MAX_RT_PRIO) { - struct sched_param param; - priv->bh_thread.prio = bh_priority; - unifi_trace(priv, UDBG1, "%s thread (RT) priority = %d\n", - thread->name, bh_priority); - param.sched_priority = bh_priority; - sched_setscheduler(thread->thread_task, SCHED_FIFO, ¶m); - } else if (bh_priority > MAX_RT_PRIO && bh_priority <= MAX_PRIO) { - priv->bh_thread.prio = bh_priority; - unifi_trace(priv, UDBG1, "%s thread priority = %d\n", - thread->name, PRIO_TO_NICE(bh_priority)); - set_user_nice(thread->thread_task, PRIO_TO_NICE(bh_priority)); - } else { - priv->bh_thread.prio = DEFAULT_PRIO; - unifi_warning(priv, "%s thread unsupported (%d) priority\n", - thread->name, bh_priority); - } - } else { - priv->bh_thread.prio = DEFAULT_PRIO; - } - unifi_trace(priv, UDBG2, "Started %s thread\n", thread->name); - - return 0; + if (thread->thread_task != NULL) { + unifi_error(priv, "%s thread already started\n", thread->name); + return 0; + } + + /* Start the kernel thread that handles all h/w accesses. */ + thread->thread_task = kthread_run(func, priv, "%s", thread->name); + if (IS_ERR(thread->thread_task)) + return PTR_ERR(thread->thread_task); + + /* Module parameter overides the thread priority */ + if (bh_priority != -1) { + if (bh_priority >= 0 && bh_priority <= MAX_RT_PRIO) { + struct sched_param param; + priv->bh_thread.prio = bh_priority; + unifi_trace(priv, UDBG1, + "%s thread (RT) priority = %d\n", + thread->name, bh_priority); + param.sched_priority = bh_priority; + sched_setscheduler(thread->thread_task, + SCHED_FIFO, ¶m); + } else if (bh_priority > MAX_RT_PRIO && + bh_priority <= MAX_PRIO) { + priv->bh_thread.prio = bh_priority; + unifi_trace(priv, UDBG1, "%s thread priority = %d\n", + thread->name, + PRIO_TO_NICE(bh_priority)); + set_user_nice(thread->thread_task, + PRIO_TO_NICE(bh_priority)); + } else { + priv->bh_thread.prio = DEFAULT_PRIO; + unifi_warning(priv, + "%s thread unsupported (%d) priority\n", + thread->name, bh_priority); + } + } else + priv->bh_thread.prio = DEFAULT_PRIO; + unifi_trace(priv, UDBG2, "Started %s thread\n", thread->name); + + return 0; } /* uf_start_thread() */ @@ -88,8 +92,7 @@ uf_start_thread(unifi_priv_t *priv, struct uf_thread *thread, int (*func)(void * * * --------------------------------------------------------------------------- */ - void -uf_stop_thread(unifi_priv_t *priv, struct uf_thread *thread) +void uf_stop_thread(unifi_priv_t *priv, struct uf_thread *thread) { if (!thread->thread_task) { unifi_notice(priv, "%s thread is already stopped\n", thread->name); -- cgit v0.10.2 From f7523ab6c0a7c9eefee2ab7fd0df48fca839b490 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sat, 4 Aug 2012 13:02:09 +0545 Subject: staging/csr: fix coding style problems in uf_stop_thread MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The following warnings and errors were fixed: * fix no space at the start of a line * fix line over 80 characters * use tabs instead of spaces Cc: Mikko Virkkilä Cc: Lauri Hintsala Cc: Riku Mettälä Cc: Veli-Pekka Peltola Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/csr/bh.c b/drivers/staging/csr/bh.c index 2b7c4c0..7a00aa8 100644 --- a/drivers/staging/csr/bh.c +++ b/drivers/staging/csr/bh.c @@ -94,15 +94,16 @@ int uf_start_thread(unifi_priv_t *priv, */ void uf_stop_thread(unifi_priv_t *priv, struct uf_thread *thread) { - if (!thread->thread_task) { - unifi_notice(priv, "%s thread is already stopped\n", thread->name); - return; - } + if (!thread->thread_task) { + unifi_notice(priv, "%s thread is already stopped\n", + thread->name); + return; + } - unifi_trace(priv, UDBG2, "Stopping %s thread\n", thread->name); + unifi_trace(priv, UDBG2, "Stopping %s thread\n", thread->name); - kthread_stop(thread->thread_task); - thread->thread_task = NULL; + kthread_stop(thread->thread_task); + thread->thread_task = NULL; } /* uf_stop_thread() */ -- cgit v0.10.2 From b29687fb8857061348db95c13712ca36549725b2 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sat, 4 Aug 2012 13:02:45 +0545 Subject: staging/csr: fix coding style problems in uf_wait_for_thread_to_stop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit the following fixes: * fix no space at the start of line * line over 80 characters * use tabs instead of spaces at starting of every line Cc: Mikko Virkkilä Cc: Lauri Hintsala Cc: Riku Mettälä Cc: Veli-Pekka Peltola Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/csr/bh.c b/drivers/staging/csr/bh.c index 7a00aa8..2597e22 100644 --- a/drivers/staging/csr/bh.c +++ b/drivers/staging/csr/bh.c @@ -122,23 +122,24 @@ void uf_stop_thread(unifi_priv_t *priv, struct uf_thread *thread) * * --------------------------------------------------------------------------- */ - void +void uf_wait_for_thread_to_stop(unifi_priv_t *priv, struct uf_thread *thread) { - /* - * kthread_stop() cannot handle the thread exiting while - * kthread_should_stop() is false, so sleep until kthread_stop() - * wakes us up. - */ - unifi_trace(priv, UDBG2, "%s waiting for the stop signal.\n", thread->name); - set_current_state(TASK_INTERRUPTIBLE); - if (!kthread_should_stop()) { - unifi_trace(priv, UDBG2, "%s schedule....\n", thread->name); - schedule(); - } + /* + * kthread_stop() cannot handle the thread exiting while + * kthread_should_stop() is false, so sleep until kthread_stop() + * wakes us up + */ + unifi_trace(priv, UDBG2, "%s waiting for the stop signal.\n", + thread->name); + set_current_state(TASK_INTERRUPTIBLE); + if (!kthread_should_stop()) { + unifi_trace(priv, UDBG2, "%s schedule....\n", thread->name); + schedule(); + } - thread->thread_task = NULL; - unifi_trace(priv, UDBG2, "%s exiting....\n", thread->name); + thread->thread_task = NULL; + unifi_trace(priv, UDBG2, "%s exiting....\n", thread->name); } /* uf_wait_for_thread_to_stop() */ -- cgit v0.10.2 From be21a084c104de45d8bfab0a0ad3a73ed902db25 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sat, 4 Aug 2012 13:03:05 +0545 Subject: staging/csr: remove the initialisation of interfaceTag and its comment in handle_bh_error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit the interfaceTag is actually initialised in for loop of this function and its not needed to initialise it before for loop. and also remove the comment that is obvious about this variable. Cc: Mikko Virkkilä Cc: Lauri Hintsala Cc: Riku Mettälä Cc: Veli-Pekka Peltola Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/csr/bh.c b/drivers/staging/csr/bh.c index 2597e22..3193df2 100644 --- a/drivers/staging/csr/bh.c +++ b/drivers/staging/csr/bh.c @@ -164,7 +164,7 @@ uf_wait_for_thread_to_stop(unifi_priv_t *priv, struct uf_thread *thread) handle_bh_error(unifi_priv_t *priv) { u8 conf_param = CONFIG_IND_ERROR; - u8 interfaceTag = 0; /* used as a loop counter */ + u8 interfaceTag; /* Block unifi_run_bh() until the error has been handled. */ -- cgit v0.10.2 From a6c42258ac8735aa25a4e5b711df2e516c3aff14 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sat, 4 Aug 2012 13:03:23 +0545 Subject: staging/csr: fix coding style problems in handle_bh_error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit the following fixes: * fix line over 80 * fix no space at start of line * use tabs instead of spaces * no need of opening & closing braces for single statement if block Cc: Mikko Virkkilä Cc: Lauri Hintsala Cc: Riku Mettälä Cc: Veli-Pekka Peltola Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/csr/bh.c b/drivers/staging/csr/bh.c index 3193df2..addee05 100644 --- a/drivers/staging/csr/bh.c +++ b/drivers/staging/csr/bh.c @@ -160,39 +160,41 @@ uf_wait_for_thread_to_stop(unifi_priv_t *priv, struct uf_thread *thread) * None. * --------------------------------------------------------------------------- */ - static void +static void handle_bh_error(unifi_priv_t *priv) { - u8 conf_param = CONFIG_IND_ERROR; - u8 interfaceTag; + netInterface_priv_t *interfacePriv; + u8 conf_param = CONFIG_IND_ERROR; + u8 interfaceTag; - /* Block unifi_run_bh() until the error has been handled. */ - priv->bh_thread.block_thread = 1; + /* Block unifi_run_bh() until the error has been handled. */ + priv->bh_thread.block_thread = 1; - /* Consider UniFi to be uninitialised */ - priv->init_progress = UNIFI_INIT_NONE; + /* Consider UniFi to be uninitialised */ + priv->init_progress = UNIFI_INIT_NONE; - /* Stop the network traffic */ - for( interfaceTag =0; interfaceTag interfacePriv[interfaceTag]; - if (interfacePriv->netdev_registered == 1) { - netif_carrier_off(priv->netdev[interfaceTag]); - } - } + /* Stop the network traffic */ + for (interfaceTag = 0; + interfaceTag < CSR_WIFI_NUM_INTERFACES; interfaceTag++) { + interfacePriv = priv->interfacePriv[interfaceTag]; + if (interfacePriv->netdev_registered) + netif_carrier_off(priv->netdev[interfaceTag]); + } #ifdef CSR_NATIVE_LINUX - /* Force any client waiting on an mlme_wait_for_reply() to abort. */ - uf_abort_mlme(priv); + /* Force any client waiting on an mlme_wait_for_reply() to abort. */ + uf_abort_mlme(priv); - /* Cancel any pending workqueue tasks */ - flush_workqueue(priv->unifi_workqueue); + /* Cancel any pending workqueue tasks */ + flush_workqueue(priv->unifi_workqueue); #endif /* CSR_NATIVE_LINUX */ - unifi_error(priv, "handle_bh_error: fatal error is reported to the SME.\n"); - /* Notify the clients (SME or unifi_manager) for the error. */ - ul_log_config_ind(priv, &conf_param, sizeof(u8)); + unifi_error(priv, + "handle_bh_error: fatal error is reported to the SME.\n"); + /* Notify the clients (SME or unifi_manager) for the error. */ + ul_log_config_ind(priv, &conf_param, sizeof(u8)); } /* handle_bh_error() */ -- cgit v0.10.2 From 3d4e9e57e6da4ccd4c9710c76651175bc756799e Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Fri, 10 Aug 2012 20:49:02 +0200 Subject: staging: csr: Fix up version.h includes Include version.h where actually needed, remove where unneeded. Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/csr/csr_panic.c b/drivers/staging/csr/csr_panic.c index 353a829..095f7fa 100644 --- a/drivers/staging/csr/csr_panic.c +++ b/drivers/staging/csr/csr_panic.c @@ -9,7 +9,6 @@ *****************************************************************************/ #include -#include #include #include "csr_panic.h" diff --git a/drivers/staging/csr/drv.c b/drivers/staging/csr/drv.c index b2c27f4..9834d92 100644 --- a/drivers/staging/csr/drv.c +++ b/drivers/staging/csr/drv.c @@ -15,8 +15,6 @@ * --------------------------------------------------------------------------- */ - - /* * Porting Notes: * Part of this file contains an example for how to glue the OS layer @@ -37,6 +35,7 @@ #include #include #include +#include #include "csr_wifi_hip_unifiversion.h" #include "unifi_priv.h" diff --git a/drivers/staging/csr/io.c b/drivers/staging/csr/io.c index e6503d96..deaff25 100644 --- a/drivers/staging/csr/io.c +++ b/drivers/staging/csr/io.c @@ -31,6 +31,7 @@ * --------------------------------------------------------------------------- */ #include +#include #include "csr_wifi_hip_unifi.h" #include "csr_wifi_hip_unifiversion.h" @@ -38,7 +39,6 @@ #include "unifiio.h" #include "unifi_priv.h" - /* * Array of pointers to context structs for unifi devices that are present. * The index in the array corresponds to the wlan interface number diff --git a/drivers/staging/csr/monitor.c b/drivers/staging/csr/monitor.c index 628782a..ca7559b 100644 --- a/drivers/staging/csr/monitor.c +++ b/drivers/staging/csr/monitor.c @@ -10,6 +10,7 @@ * --------------------------------------------------------------------------- */ +#include #include "unifi_priv.h" #ifdef UNIFI_SNIFF_ARPHRD @@ -23,8 +24,6 @@ #define ETH_P_80211_RAW ETH_P_ALL #endif - - /* * --------------------------------------------------------------------------- * uf_start_sniff diff --git a/drivers/staging/csr/netdev.c b/drivers/staging/csr/netdev.c index 1e6e111..0e34020 100644 --- a/drivers/staging/csr/netdev.c +++ b/drivers/staging/csr/netdev.c @@ -15,7 +15,6 @@ * --------------------------------------------------------------------------- */ - /* * Porting Notes: * This file implements the data plane of the UniFi linux driver. @@ -48,7 +47,7 @@ #include #include #include - +#include #include #include "csr_wifi_hip_unifi.h" #include "csr_wifi_hip_conversions.h" diff --git a/drivers/staging/csr/sdio_mmc.c b/drivers/staging/csr/sdio_mmc.c index b203d2b..dd82ea4 100644 --- a/drivers/staging/csr/sdio_mmc.c +++ b/drivers/staging/csr/sdio_mmc.c @@ -14,7 +14,7 @@ #include #include #include - +#include #include #include #include diff --git a/drivers/staging/csr/sme_native.c b/drivers/staging/csr/sme_native.c index 229268f..845b654 100644 --- a/drivers/staging/csr/sme_native.c +++ b/drivers/staging/csr/sme_native.c @@ -12,7 +12,7 @@ */ #include - +#include #include "unifi_priv.h" #include "csr_wifi_hip_unifi.h" #include "csr_wifi_hip_conversions.h" diff --git a/drivers/staging/csr/sme_sys.c b/drivers/staging/csr/sme_sys.c index 99de27e..7ff3f43 100644 --- a/drivers/staging/csr/sme_sys.c +++ b/drivers/staging/csr/sme_sys.c @@ -14,6 +14,7 @@ * --------------------------------------------------------------------------- */ +#include #include "csr_wifi_hip_unifiversion.h" #include "unifi_priv.h" #include "csr_wifi_hip_conversions.h" @@ -21,7 +22,6 @@ #include "csr_wifi_sme_sef.h" #endif - /* * This file implements the SME SYS API and contains the following functions: * CsrWifiRouterCtrlMediaStatusReqHandler() diff --git a/drivers/staging/csr/ul_int.c b/drivers/staging/csr/ul_int.c index 46d3507..819690d 100644 --- a/drivers/staging/csr/ul_int.c +++ b/drivers/staging/csr/ul_int.c @@ -12,6 +12,7 @@ * * *************************************************************************** */ +#include #include "csr_wifi_hip_unifi.h" #include "csr_wifi_hip_conversions.h" #include "unifi_priv.h" diff --git a/drivers/staging/csr/unifi_pdu_processing.c b/drivers/staging/csr/unifi_pdu_processing.c index 7c7e8d4..c28f4dd 100644 --- a/drivers/staging/csr/unifi_pdu_processing.c +++ b/drivers/staging/csr/unifi_pdu_processing.c @@ -14,7 +14,7 @@ * --------------------------------------------------------------------------- */ - +#include #include #include #include diff --git a/drivers/staging/csr/unifi_wext.h b/drivers/staging/csr/unifi_wext.h index 6d7a995..fc0a06a 100644 --- a/drivers/staging/csr/unifi_wext.h +++ b/drivers/staging/csr/unifi_wext.h @@ -16,6 +16,7 @@ #define __LINUX_UNIFI_WEXT_H__ 1 #include +#include #include #include "csr_wifi_sme_prim.h" -- cgit v0.10.2 From c21be47c834bc411339ee04462ec7c5246e58596 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Fri, 20 Jul 2012 22:45:48 +0545 Subject: staging/android: use module_platform_driver as the init and exit functions just do a platform_driver_register and platform_driver_unregister, and nothing else, so its better to use the module_platform_driver macro rather replicating its implementation Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/android/timed_gpio.c b/drivers/staging/android/timed_gpio.c index 45c522c..e814514 100644 --- a/drivers/staging/android/timed_gpio.c +++ b/drivers/staging/android/timed_gpio.c @@ -161,18 +161,7 @@ static struct platform_driver timed_gpio_driver = { }, }; -static int __init timed_gpio_init(void) -{ - return platform_driver_register(&timed_gpio_driver); -} - -static void __exit timed_gpio_exit(void) -{ - platform_driver_unregister(&timed_gpio_driver); -} - -module_init(timed_gpio_init); -module_exit(timed_gpio_exit); +module_platform_driver(timed_gpio_driver); MODULE_AUTHOR("Mike Lockwood "); MODULE_DESCRIPTION("timed gpio driver"); -- cgit v0.10.2 From 2258937b2137214bae796ec929394a282f531ed7 Mon Sep 17 00:00:00 2001 From: Cruz Julian Bishop Date: Wed, 1 Aug 2012 14:54:16 +1000 Subject: staging: android: ashmem: Fix comment/license formatting Signed-off-by: Cruz Julian Bishop Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c index 69cf2db..94a740d 100644 --- a/drivers/staging/android/ashmem.c +++ b/drivers/staging/android/ashmem.c @@ -1,20 +1,20 @@ /* mm/ashmem.c -** -** Anonymous Shared Memory Subsystem, ashmem -** -** Copyright (C) 2008 Google, Inc. -** -** Robert Love -** -** This software is licensed under the terms of the GNU General Public -** License version 2, as published by the Free Software Foundation, and -** may be copied, distributed, and modified under those terms. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -*/ + * + * Anonymous Shared Memory Subsystem, ashmem + * + * Copyright (C) 2008 Google, Inc. + * + * Robert Love + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ #define pr_fmt(fmt) "ashmem: " fmt -- cgit v0.10.2 From adb913658f5cecc02dd8f36aa9edecb3e9fd3399 Mon Sep 17 00:00:00 2001 From: Cruz Julian Bishop Date: Wed, 1 Aug 2012 14:54:17 +1000 Subject: staging: android: logger.h: Complete documentation of logger_entry Previously, there were simply comments after each part - Now, it is completed properly according to "Kernel doc" Sorry in advance if I made any mistakes. Signed-off-by: Cruz Julian Bishop Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/android/logger.h b/drivers/staging/android/logger.h index 2cb06e9..9b929a8 100644 --- a/drivers/staging/android/logger.h +++ b/drivers/staging/android/logger.h @@ -20,14 +20,24 @@ #include #include +/** + * struct logger_entry - defines a single entry that is given to a logger + * @len: The length of the payload + * @__pad: Two bytes of padding that appear to be required + * @pid: The generating process' process ID + * @tid: The generating process' thread ID + * @sec: The number of seconds that have elapsed since the Epoch + * @nsec: The number of nanoseconds that have elapsed since @sec + * @msg: The message that is to be logged + */ struct logger_entry { - __u16 len; /* length of the payload */ - __u16 __pad; /* no matter what, we get 2 bytes of padding */ - __s32 pid; /* generating process's pid */ - __s32 tid; /* generating process's tid */ - __s32 sec; /* seconds since Epoch */ - __s32 nsec; /* nanoseconds */ - char msg[0]; /* the entry's payload */ + __u16 len; + __u16 __pad; + __s32 pid; + __s32 tid; + __s32 sec; + __s32 nsec; + char msg[0]; }; #define LOGGER_LOG_RADIO "log_radio" /* radio-related messages */ -- cgit v0.10.2 From 0edc6c6d545f2615d9239d5ea350d7ed833ee539 Mon Sep 17 00:00:00 2001 From: Cruz Julian Bishop Date: Wed, 1 Aug 2012 14:54:18 +1000 Subject: staging: android: logger: Finish documentation of two structs Signed-off-by: Cruz Julian Bishop Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c index f7b8237..1d5ed47 100644 --- a/drivers/staging/android/logger.c +++ b/drivers/staging/android/logger.c @@ -32,38 +32,50 @@ #include -/* +/** * struct logger_log - represents a specific log, such as 'main' or 'radio' + * @buffer: The actual ring buffer + * @misc: The "misc" device representing the log + * @wq: The wait queue for @readers + * @readers: This log's readers + * @mutex: The mutex that protects the @buffer + * @w_off: The current write head offset + * @head: The head, or location that readers start reading at. + * @size: The size of the log + * @logs: The list of log channels * * This structure lives from module insertion until module removal, so it does * not need additional reference counting. The structure is protected by the * mutex 'mutex'. */ struct logger_log { - unsigned char *buffer;/* the ring buffer itself */ - struct miscdevice misc; /* misc device representing the log */ - wait_queue_head_t wq; /* wait queue for readers */ - struct list_head readers; /* this log's readers */ - struct mutex mutex; /* mutex protecting buffer */ - size_t w_off; /* current write head offset */ - size_t head; /* new readers start here */ - size_t size; /* size of the log */ - struct list_head logs; /* list of log channels (myself)*/ + unsigned char *buffer; + struct miscdevice misc; + wait_queue_head_t wq; + struct list_head readers; + struct mutex mutex; + size_t w_off; + size_t head; + size_t size; + struct list_head logs; }; static LIST_HEAD(log_list); -/* +/** * struct logger_reader - a logging device open for reading + * @log: The associated log + * @list: The associated entry in @logger_log's list + * @r_off: The current read head offset. * * This object lives from open to release, so we don't need additional * reference counting. The structure is protected by log->mutex. */ struct logger_reader { - struct logger_log *log; /* associated log */ - struct list_head list; /* entry in logger_log's list */ - size_t r_off; /* current read head offset */ + struct logger_log *log; + struct list_head list; + size_t r_off; }; /* logger_offset - returns index 'n' into the log via (optimized) modulus */ -- cgit v0.10.2 From 8cb05f4b54535cb91d7a5f9f8eb230bd4fa86e4e Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 2 Aug 2012 19:05:41 +0300 Subject: staging: tidspbridge: eliminate uuid_uuid_to_string There is native specificator for snprintf to get UUID in human readable format. Signed-off-by: Andy Shevchenko Cc: Omar Ramirez Luna Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/tidspbridge/gen/uuidutil.c b/drivers/staging/tidspbridge/gen/uuidutil.c index b44656c..b7d8313 100644 --- a/drivers/staging/tidspbridge/gen/uuidutil.c +++ b/drivers/staging/tidspbridge/gen/uuidutil.c @@ -26,27 +26,6 @@ /* ----------------------------------- This */ #include -/* - * ======== uuid_uuid_to_string ======== - * Purpose: - * Converts a struct dsp_uuid to a string. - * Note: snprintf format specifier is: - * %[flags] [width] [.precision] [{h | l | I64 | L}]type - */ -void uuid_uuid_to_string(struct dsp_uuid *uuid_obj, char *sz_uuid, - s32 size) -{ - s32 i; /* return result from snprintf. */ - - i = snprintf(sz_uuid, size, - "%.8X_%.4X_%.4X_%.2X%.2X_%.2X%.2X%.2X%.2X%.2X%.2X", - uuid_obj->data1, uuid_obj->data2, uuid_obj->data3, - uuid_obj->data4, uuid_obj->data5, - uuid_obj->data6[0], uuid_obj->data6[1], - uuid_obj->data6[2], uuid_obj->data6[3], - uuid_obj->data6[4], uuid_obj->data6[5]); -} - static s32 uuid_hex_to_bin(char *buf, s32 len) { s32 i; diff --git a/drivers/staging/tidspbridge/include/dspbridge/uuidutil.h b/drivers/staging/tidspbridge/include/dspbridge/uuidutil.h index 9a99475..414bf71 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/uuidutil.h +++ b/drivers/staging/tidspbridge/include/dspbridge/uuidutil.h @@ -22,26 +22,6 @@ #define MAXUUIDLEN 37 /* - * ======== uuid_uuid_to_string ======== - * Purpose: - * Converts a dsp_uuid to an ANSI string. - * Parameters: - * uuid_obj: Pointer to a dsp_uuid object. - * sz_uuid: Pointer to a buffer to receive a NULL-terminated UUID - * string. - * size: Maximum size of the sz_uuid string. - * Returns: - * Requires: - * uuid_obj & sz_uuid are non-NULL values. - * Ensures: - * Lenghth of sz_uuid is less than MAXUUIDLEN. - * Details: - * UUID string limit currently set at MAXUUIDLEN. - */ -void uuid_uuid_to_string(struct dsp_uuid *uuid_obj, char *sz_uuid, - s32 size); - -/* * ======== uuid_uuid_from_string ======== * Purpose: * Converts an ANSI string to a dsp_uuid. diff --git a/drivers/staging/tidspbridge/rmgr/dbdcd.c b/drivers/staging/tidspbridge/rmgr/dbdcd.c index 12a1d34..eba36f4 100644 --- a/drivers/staging/tidspbridge/rmgr/dbdcd.c +++ b/drivers/staging/tidspbridge/rmgr/dbdcd.c @@ -395,7 +395,7 @@ int dcd_get_object_def(struct dcd_manager *hdcd_mgr, } /* Create UUID value to set in registry. */ - uuid_uuid_to_string(obj_uuid, sz_uuid, MAXUUIDLEN); + snprintf(sz_uuid, MAXUUIDLEN, "%pU", obj_uuid); if ((strlen(sz_reg_key) + MAXUUIDLEN) < DCD_MAXPATHLENGTH) strncat(sz_reg_key, sz_uuid, MAXUUIDLEN); -- cgit v0.10.2 From 0142919c583cad4e6c82566f59a95ff1e2a728f5 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 23 Jul 2012 20:40:51 -0700 Subject: staging: tidspbridge: Fix typos. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/tidspbridge/Documentation/error-codes b/drivers/staging/tidspbridge/Documentation/error-codes index 12826e2..ad73cba 100644 --- a/drivers/staging/tidspbridge/Documentation/error-codes +++ b/drivers/staging/tidspbridge/Documentation/error-codes @@ -69,7 +69,7 @@ The error codes used by this driver are: Invalid pointer or handler. [EEXIST] - Attempted to create a channel manager when one already exists. + Attempted to create a channel manager when one already exists. [EINVAL] Invalid argument. diff --git a/drivers/staging/tidspbridge/core/_tiomap.h b/drivers/staging/tidspbridge/core/_tiomap.h index 7cb5871..543a127 100644 --- a/drivers/staging/tidspbridge/core/_tiomap.h +++ b/drivers/staging/tidspbridge/core/_tiomap.h @@ -219,7 +219,7 @@ static const struct map_l4_peripheral l4_peripheral_table[] = { /* MBX_PM_MAX_RESOURCES: CORE 2 Clock Resources. */ #define MBX_CORE2_RESOURCES 1 -/* MBX_PM_MAX_RESOURCES: TOTAL Clock Reosurces. */ +/* MBX_PM_MAX_RESOURCES: TOTAL Clock Resources. */ #define MBX_PM_MAX_RESOURCES 11 /* Power Management Commands */ diff --git a/drivers/staging/tidspbridge/core/chnl_sm.c b/drivers/staging/tidspbridge/core/chnl_sm.c index e0c7e4c..f38950e 100644 --- a/drivers/staging/tidspbridge/core/chnl_sm.c +++ b/drivers/staging/tidspbridge/core/chnl_sm.c @@ -20,7 +20,7 @@ * The lower edge functions must be implemented by the Bridge driver * writer, and are declared in chnl_sm.h. * - * Care is taken in this code to prevent simulataneous access to channel + * Care is taken in this code to prevent simultaneous access to channel * queues from * 1. Threads. * 2. io_dpc(), scheduled from the io_isr() as an event. @@ -34,7 +34,7 @@ * Channel Invariant: * There is an important invariant condition which must be maintained per * channel outside of bridge_chnl_get_ioc() and IO_Dispatch(), violation of - * which may cause timeouts and/or failure offunction sync_wait_on_event. + * which may cause timeouts and/or failure of function sync_wait_on_event. * This invariant condition is: * * list_empty(&pchnl->io_completions) ==> pchnl->sync_event is reset @@ -602,7 +602,7 @@ int bridge_chnl_get_ioc(struct chnl_object *chnl_obj, u32 timeout, /* Since DSPStream_Reclaim() does not take a timeout * parameter, we pass the stream's timeout value to * bridge_chnl_get_ioc. We cannot determine whether or not - * we have waited in User mode. Since the stream's timeout + * we have waited in user mode. Since the stream's timeout * value may be non-zero, we still have to set the event. * Therefore, this optimization is taken out. * diff --git a/drivers/staging/tidspbridge/core/io_sm.c b/drivers/staging/tidspbridge/core/io_sm.c index 480a384..e322fb7 100644 --- a/drivers/staging/tidspbridge/core/io_sm.c +++ b/drivers/staging/tidspbridge/core/io_sm.c @@ -837,8 +837,8 @@ static void io_dispatch_pm(struct io_mgr *pio_mgr) /* * ======== io_dpc ======== * Deferred procedure call for shared memory channel driver ISR. Carries - * out the dispatch of I/O as a non-preemptible event.It can only be - * pre-empted by an ISR. + * out the dispatch of I/O as a non-preemptible event. It can only be + * pre-empted by an ISR. */ void io_dpc(unsigned long ref_data) { @@ -877,7 +877,7 @@ void io_dpc(unsigned long ref_data) pio_mgr->intr_val); } } - /* Proc-copy chanel dispatch */ + /* Proc-copy channel dispatch */ input_chnl(pio_mgr, NULL, IO_SERVICE); output_chnl(pio_mgr, NULL, IO_SERVICE); @@ -938,7 +938,7 @@ int io_mbox_msg(struct notifier_block *self, unsigned long len, void *msg) /* * ======== io_request_chnl ======== * Purpose: - * Request chanenel I/O from the DSP. Sets flags in shared memory, then + * Request channel I/O from the DSP. Sets flags in shared memory, then * interrupts the DSP. */ void io_request_chnl(struct io_mgr *io_manager, struct chnl_object *pchnl, @@ -2208,7 +2208,7 @@ void dump_dl_modules(struct bridge_dev_context *bridge_context) module_struct->num_sects); /* - * The section name strings start immedialty following + * The section name strings start immediately following * the array of dll_sect structures. */ sect_str = (char *) &module_struct-> diff --git a/drivers/staging/tidspbridge/core/sync.c b/drivers/staging/tidspbridge/core/sync.c index 995986a..7bb550a 100644 --- a/drivers/staging/tidspbridge/core/sync.c +++ b/drivers/staging/tidspbridge/core/sync.c @@ -49,7 +49,7 @@ void sync_set_event(struct sync_object *event) * @timeout timeout on waiting for the evetns. * @pu_index index of the event set. * - * This functios will wait until any of the array element is set or until + * These functions will wait until any of the array element is set or until * timeout. In case of success the function will return 0 and * @pu_index will store the index of the array element set or in case * of timeout the function will return -ETIME or in case of diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index f9609ce..a19bf5c 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c @@ -328,7 +328,7 @@ static int bridge_brd_read(struct bridge_dev_context *dev_ctxt, ul_num_bytes, mem_type); return status; } - /* copy the data from DSP memory, */ + /* copy the data from DSP memory */ memcpy(host_buff, (void *)(dsp_base_addr + offset), ul_num_bytes); return status; } @@ -1745,7 +1745,7 @@ static int mem_map_vmalloc(struct bridge_dev_context *dev_context, pa_next = page_to_phys(page[0]); while (!status && (i < num_pages)) { /* - * Reuse pa_next from the previous iteraion to avoid + * Reuse pa_next from the previous iteration to avoid * an extra va2pa call */ pa_curr = pa_next; diff --git a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c b/drivers/staging/tidspbridge/core/tiomap3430_pwr.c index 16a4aaf..58a1d6d 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c +++ b/drivers/staging/tidspbridge/core/tiomap3430_pwr.c @@ -356,7 +356,7 @@ int pre_scale_dsp(struct bridge_dev_context *dev_context, void *pargs) dev_dbg(bridge, "OPP: %s IVA in sleep. No message to DSP\n"); return 0; } else if ((dev_context->brd_state == BRD_RUNNING)) { - /* Send a prenotificatio to DSP */ + /* Send a prenotification to DSP */ dev_dbg(bridge, "OPP: %s sent notification to DSP\n", __func__); sm_interrupt_dsp(dev_context, MBX_PM_SETPOINT_PRENOTIFY); return 0; diff --git a/drivers/staging/tidspbridge/dynload/tramp.c b/drivers/staging/tidspbridge/dynload/tramp.c index 60d22ea..404af18 100644 --- a/drivers/staging/tidspbridge/dynload/tramp.c +++ b/drivers/staging/tidspbridge/dynload/tramp.c @@ -81,7 +81,7 @@ static u8 priv_h2a(u8 value) * Description: Generate a trampoline symbol name (ASCII) using the value * of the symbol. This places the new name into the user buffer. * The name is fixed in length and of the form: __$dbTR__xxxxxxxx - * (where "xxxxxxxx" is the hex value. + * (where "xxxxxxxx" is the hex value). */ static void priv_tramp_sym_gen_name(u32 value, char *dst) { @@ -414,7 +414,7 @@ static int priv_tramp_sym_finalize(struct dload_state *dlthis) /* Copy the symbol contents into the flat table */ *new_sym = cur_sym->sym_info; - /* Now finaize the symbol. If it is in the tramp + /* Now finalize the symbol. If it is in the tramp * section, we need to adjust for the section start. * If it is external then we don't need to adjust at * all. @@ -773,7 +773,7 @@ static int priv_img_pkt_dup(struct dload_state *dlthis, int ret_val = 0; struct tramp_img_dup_relo *dup_relo = NULL; - /* Determinne if this image packet is already being tracked in the + /* Determine if this image packet is already being tracked in the dup list for other trampolines. */ dup_pkt = priv_dup_find(dlthis, secnn, image_offset); @@ -998,7 +998,7 @@ int dload_tramp_generate(struct dload_state *dlthis, s16 secnn, /* * Function: dload_tramp_pkt_update * Description: Update the duplicate copy of this image packet, which the - * trampoline layer is already tracking. This is call is critical + * trampoline layer is already tracking. This call is critical * to make if trampolines were generated anywhere within the * packet and first pass relo continued on the remainder. The * trampoline layer needs the updates image data so when 2nd diff --git a/drivers/staging/tidspbridge/hw/hw_mmu.c b/drivers/staging/tidspbridge/hw/hw_mmu.c index 8a93d55..71cb822 100644 --- a/drivers/staging/tidspbridge/hw/hw_mmu.c +++ b/drivers/staging/tidspbridge/hw/hw_mmu.c @@ -61,7 +61,7 @@ enum hw_mmu_page_size_t { * Type : hw_status * Description : 0 -- No errors occurred * RET_BAD_NULL_PARAM -- A Pointer - * Paramater was set to NULL + * Parameter was set to NULL * * PURPOSE: : Flush the TLB entry pointed by the * lock counter register @@ -103,7 +103,7 @@ static hw_status mmu_flush_entry(const void __iomem *base_address); * * Type : hw_status * Description : 0 -- No errors occurred - * RET_BAD_NULL_PARAM -- A Pointer Paramater + * RET_BAD_NULL_PARAM -- A Pointer Parameter * was set to NULL * RET_PARAM_OUT_OF_RANGE -- Input Parameter out * of Range @@ -148,7 +148,7 @@ static hw_status mmu_set_cam_entry(const void __iomem *base_address, * * Type : hw_status * Description : 0 -- No errors occurred - * RET_BAD_NULL_PARAM -- A Pointer Paramater + * RET_BAD_NULL_PARAM -- A Pointer Parameter * was set to NULL * RET_PARAM_OUT_OF_RANGE -- Input Parameter * out of Range diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h b/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h index 0c7ec04..0fcda19 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h @@ -51,7 +51,7 @@ #define BRDIOCTL_POSTSCALE_NOTIFY (BRDIOCTL_PWRCONTROL + 0xA) #define BRDIOCTL_CONSTRAINT_REQUEST (BRDIOCTL_PWRCONTROL + 0xB) -/* Number of actual DSP-MMU TLB entrries */ +/* Number of actual DSP-MMU TLB entries */ #define BRDIOCTL_NUMOFMMUTLB 32 struct bridge_ioctl_extproc { diff --git a/drivers/staging/tidspbridge/include/dspbridge/mbx_sh.h b/drivers/staging/tidspbridge/include/dspbridge/mbx_sh.h index 7424c88..d4cb394 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/mbx_sh.h +++ b/drivers/staging/tidspbridge/include/dspbridge/mbx_sh.h @@ -22,7 +22,7 @@ * mailbox interrupt's cmd value received. The class value are defined * as a bit (10 thru 15) being set. * - * Note: Only 16 bits of each is used. Other 16 bit data reg available. + * Note: Only 16 bits of each is used. Other 16 bit data reg available. * * 16 bit Mbx bit defns: * diff --git a/drivers/staging/tidspbridge/include/dspbridge/node.h b/drivers/staging/tidspbridge/include/dspbridge/node.h index 7397b7a..68ed74a 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/node.h +++ b/drivers/staging/tidspbridge/include/dspbridge/node.h @@ -220,7 +220,7 @@ extern int node_create_mgr(struct node_mgr **node_man, * Parameters: * noderes: Node resource info handle returned from * node_allocate(). - * pr_ctxt: Poninter to process context data. + * pr_ctxt: Pointer to process context data. * Returns: * 0: Success. * -EFAULT: Invalid hnode. diff --git a/drivers/staging/tidspbridge/include/dspbridge/ntfy.h b/drivers/staging/tidspbridge/include/dspbridge/ntfy.h index cbc8819..6bb94d2 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/ntfy.h +++ b/drivers/staging/tidspbridge/include/dspbridge/ntfy.h @@ -78,7 +78,7 @@ static inline void ntfy_init(struct ntfy_object *no) * ntfy_delete() - delete list of nofy events registered. * @ntfy_obj: Pointer to the ntfy object structure. * - * This function is used to remove all the notify events registered. + * This function is used to remove all the notify events registered. * unregister function is not needed in this function, to unregister * a ntfy_event please look at ntfy_register function. * diff --git a/drivers/staging/tidspbridge/include/dspbridge/proc.h b/drivers/staging/tidspbridge/include/dspbridge/proc.h index a82380e..851b356 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/proc.h +++ b/drivers/staging/tidspbridge/include/dspbridge/proc.h @@ -263,7 +263,7 @@ extern int proc_get_processor_id(void *proc, u32 * proc_id); * Returns: * 0 : Success. * -EFAULT : Invalid processor handle. - * -EPERM : General failure while retireving processor trace + * -EPERM : General failure while retrieving processor trace * Buffer. * Requires: * pbuf is not NULL diff --git a/drivers/staging/tidspbridge/include/dspbridge/strm.h b/drivers/staging/tidspbridge/include/dspbridge/strm.h index dacf0c2..97aee4c 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/strm.h +++ b/drivers/staging/tidspbridge/include/dspbridge/strm.h @@ -203,7 +203,7 @@ extern int strm_issue(struct strm_object *stream_obj, u8 * pbuf, * index: Stream index. * pattr: Pointer to structure containing attributes to be * applied to stream. Cannot be NULL. - * strmres: Location to store stream resuorce info handle on output. + * strmres: Location to store stream resource info handle on output. * Returns: * 0: Success. * -EFAULT: Invalid hnode. diff --git a/drivers/staging/tidspbridge/include/dspbridge/sync.h b/drivers/staging/tidspbridge/include/dspbridge/sync.h index b1e75eb..58a0d5c 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/sync.h +++ b/drivers/staging/tidspbridge/include/dspbridge/sync.h @@ -78,7 +78,7 @@ void sync_set_event(struct sync_object *event); * @event: events to wait for it. * @timeout timeout on waiting for the evetn. * - * This functios will wait until @event is set or until timeout. In case of + * This function will wait until @event is set or until timeout. In case of * success the function will return 0 and * in case of timeout the function will return -ETIME * in case of signal the function will return -ERESTARTSYS @@ -106,7 +106,7 @@ static inline int sync_wait_on_event(struct sync_object *event, * @timeout timeout on waiting for the evetns. * @pu_index index of the event set. * - * This functios will wait until any of the array element is set or until + * This function will wait until any of the array element is set or until * timeout. In case of success the function will return 0 and * @pu_index will store the index of the array element set and in case * of timeout the function will return -ETIME. diff --git a/drivers/staging/tidspbridge/rmgr/dbdcd.c b/drivers/staging/tidspbridge/rmgr/dbdcd.c index eba36f4..e05670d 100644 --- a/drivers/staging/tidspbridge/rmgr/dbdcd.c +++ b/drivers/staging/tidspbridge/rmgr/dbdcd.c @@ -463,7 +463,7 @@ int dcd_get_object_def(struct dcd_manager *hdcd_mgr, status = cod_read_section(lib, sz_sect_name, psz_coff_buf, ul_len); #endif if (!status) { - /* Compres DSP buffer to conform to PC format. */ + /* Compress DSP buffer to conform to PC format. */ if (strstr(dcd_key->path, "iva") == NULL) { compress_buf(psz_coff_buf, ul_len, DSPWORDSIZE); } else { diff --git a/drivers/staging/tidspbridge/rmgr/dspdrv.c b/drivers/staging/tidspbridge/rmgr/dspdrv.c index dc767b1..d460f58 100644 --- a/drivers/staging/tidspbridge/rmgr/dspdrv.c +++ b/drivers/staging/tidspbridge/rmgr/dspdrv.c @@ -72,7 +72,7 @@ u32 dsp_init(u32 *init_status) /* Unwind whatever was loaded */ if (status) { - /* irrespective of the status of dev_remove_device we conitinue + /* irrespective of the status of dev_remove_device we continue * unloading. Get the Driver Object iterate through and remove. * Reset the status to E_FAIL to avoid going through * api_init_complete2. */ @@ -92,7 +92,7 @@ u32 dsp_init(u32 *init_status) func_cont: /* Attempt to Start the Board */ if (!status) { - /* BRD_AutoStart could fail if the dsp execuetable is not the + /* BRD_AutoStart could fail if the dsp executable is not the * correct one. We should not propagate that error * into the device loader. */ (void)api_init_complete2(); diff --git a/drivers/staging/tidspbridge/rmgr/mgr.c b/drivers/staging/tidspbridge/rmgr/mgr.c index 8a1e928..b32ba0a 100644 --- a/drivers/staging/tidspbridge/rmgr/mgr.c +++ b/drivers/staging/tidspbridge/rmgr/mgr.c @@ -262,8 +262,8 @@ int mgr_enum_processor_info(u32 processor_id, IVAPROCTYPE_ARM7) proc_detect = true; } - /* User applciatiuons aonly check for chip type, so - * this clumsy overwrite */ + /* User applications only check for chip type, so + * this is a clumsy overwrite */ processor_info->processor_type = DSPTYPE64; } else { dev_dbg(bridge, "%s: Failed to get DCD processor info " diff --git a/drivers/staging/tidspbridge/rmgr/nldr.c b/drivers/staging/tidspbridge/rmgr/nldr.c index 30d5480..6309221b 100644 --- a/drivers/staging/tidspbridge/rmgr/nldr.c +++ b/drivers/staging/tidspbridge/rmgr/nldr.c @@ -898,7 +898,7 @@ static int add_ovly_info(void *handle, struct dbll_sect_info *sect_info, nldr_obj->ovly_table[i].execute_sects++; } else { - /* Put in "other" sectins */ + /* Put in "other" sections */ status = add_ovly_sect(nldr_obj, &nldr_obj-> diff --git a/drivers/staging/tidspbridge/rmgr/node.c b/drivers/staging/tidspbridge/rmgr/node.c index 7fb426c..f17c128 100644 --- a/drivers/staging/tidspbridge/rmgr/node.c +++ b/drivers/staging/tidspbridge/rmgr/node.c @@ -1613,7 +1613,7 @@ int node_get_attr(struct node_object *hnode, return -EFAULT; hnode_mgr = hnode->node_mgr; - /* Enter hnode_mgr critical section (since we're accessing + /* Enter hnode_mgr critical section since we're accessing * data that could be changed by node_change_priority() and * node_connect(). */ mutex_lock(&hnode_mgr->node_mgr_lock); diff --git a/drivers/staging/tidspbridge/rmgr/proc.c b/drivers/staging/tidspbridge/rmgr/proc.c index 7e4f12f..5e43938 100644 --- a/drivers/staging/tidspbridge/rmgr/proc.c +++ b/drivers/staging/tidspbridge/rmgr/proc.c @@ -300,7 +300,7 @@ proc_attach(u32 processor_id, if (status) goto func_end; - /* If we made it this far, create the Proceesor object: */ + /* If we made it this far, create the Processor object: */ p_proc_object = kzalloc(sizeof(struct proc_object), GFP_KERNEL); /* Fill out the Processor Object: */ if (p_proc_object == NULL) { -- cgit v0.10.2 From b95dd03df2b9f20b4df35ae5f18430849908a7ed Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sat, 21 Jul 2012 14:41:00 +0545 Subject: staging/tidspbridge: use module_platform_driver the code under _init and _exit does platform_driver_register and platform_driver_unregister respectively only, so its better to use the module_platform_driver than just replicating the module_platform_driver's implementation Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/tidspbridge/rmgr/drv_interface.c b/drivers/staging/tidspbridge/rmgr/drv_interface.c index 3cac014..6acea2b 100644 --- a/drivers/staging/tidspbridge/rmgr/drv_interface.c +++ b/drivers/staging/tidspbridge/rmgr/drv_interface.c @@ -613,16 +613,6 @@ static struct platform_driver bridge_driver = { #endif }; -static int __init bridge_init(void) -{ - return platform_driver_register(&bridge_driver); -} - -static void __exit bridge_exit(void) -{ - platform_driver_unregister(&bridge_driver); -} - /* To remove all process resources before removing the process from the * process context list */ int drv_remove_all_resources(void *process_ctxt) @@ -636,6 +626,4 @@ int drv_remove_all_resources(void *process_ctxt) return status; } -/* Bridge driver initialization and de-initialization functions */ -module_init(bridge_init); -module_exit(bridge_exit); +module_platform_driver(bridge_driver); -- cgit v0.10.2 From fb841d676bdb266e151398db2c28a1c4d0999219 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Thu, 26 Jul 2012 23:43:22 +0200 Subject: staging: vt6656: don't leak 'param' in vt6656_hostap_ioctl() when returning -EOPNOTSUPP Don't return -EOPNOTSUPP directly in switch case's since it'll leak the memory allocated to 'param' when that variable goes out of scope without having been assigned to anything. Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/vt6656/hostap.c b/drivers/staging/vt6656/hostap.c index 682002a..9f2ca17 100644 --- a/drivers/staging/vt6656/hostap.c +++ b/drivers/staging/vt6656/hostap.c @@ -732,8 +732,8 @@ int vt6656_hostap_ioctl(PSDevice pDevice, struct iw_point *p) break; case VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR: DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR \n"); - return -EOPNOTSUPP; - break; + ret = -EOPNOTSUPP; + goto out; case VIAWGET_HOSTAPD_FLUSH: DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_FLUSH \n"); spin_lock_irq(&pDevice->lock); @@ -777,13 +777,13 @@ int vt6656_hostap_ioctl(PSDevice pDevice, struct iw_point *p) case VIAWGET_HOSTAPD_STA_CLEAR_STATS: DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_STA_CLEAR_STATS \n"); - return -EOPNOTSUPP; - + ret = -EOPNOTSUPP; + goto out; default: DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "vt6656_hostap_ioctl: unknown cmd=%d\n", (int)param->cmd); - return -EOPNOTSUPP; - break; + ret = -EOPNOTSUPP; + goto out; } -- cgit v0.10.2 From 0f9206fefc730751c2b481900b445eb52c657f85 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 2 Aug 2012 19:05:50 +0300 Subject: staging: vt6656: print small buffers with %*ph Signed-off-by: Andy Shevchenko Cc: Forest Bond Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/vt6656/ioctl.c b/drivers/staging/vt6656/ioctl.c index 5b9a84f..d67b29f 100644 --- a/drivers/staging/vt6656/ioctl.c +++ b/drivers/staging/vt6656/ioctl.c @@ -526,11 +526,8 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) pMgmt->abyIBSSSuppRates[3] |= BIT7; } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Support Rate= %x %x %x %x\n", - pMgmt->abyIBSSSuppRates[2], - pMgmt->abyIBSSSuppRates[3], - pMgmt->abyIBSSSuppRates[4], - pMgmt->abyIBSSSuppRates[5]); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Support Rate= %*ph\n", + 4, pMgmt->abyIBSSSuppRates + 2); netif_stop_queue(pDevice->dev); spin_lock_irq(&pDevice->lock); -- cgit v0.10.2 From a13aa83c6ba1f2ec9586ed851a7b66764674197e Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 2 Aug 2012 19:05:49 +0300 Subject: staging: vt6655: print small buffers with %*ph Signed-off-by: Andy Shevchenko Cc: Forest Bond Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/vt6655/ioctl.c b/drivers/staging/vt6655/ioctl.c index ef197ef..ac15d38 100644 --- a/drivers/staging/vt6655/ioctl.c +++ b/drivers/staging/vt6655/ioctl.c @@ -539,11 +539,8 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) pMgmt->abyIBSSSuppRates[3] |= BIT7; } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Support Rate= %x %x %x %x\n", - pMgmt->abyIBSSSuppRates[2], - pMgmt->abyIBSSSuppRates[3], - pMgmt->abyIBSSSuppRates[4], - pMgmt->abyIBSSSuppRates[5]); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Support Rate= %*ph\n", + 4, pMgmt->abyIBSSSuppRates + 2); netif_stop_queue(pDevice->dev); spin_lock_irq(&pDevice->lock); -- cgit v0.10.2 From 931846901c08a53b43590dd99bbf53026c4f0890 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Mon, 13 Aug 2012 21:21:50 +0900 Subject: staging: vt6656: Fix typo in vt6656 Correct spelling typo in staging/vt6656 Signed-off-by: Masanari Iida Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/vt6656/rf.c b/drivers/staging/vt6656/rf.c index 3fd0478..c82b3e6 100644 --- a/drivers/staging/vt6656/rf.c +++ b/drivers/staging/vt6656/rf.c @@ -26,7 +26,7 @@ * Date: Feb. 19, 2004 * * Functions: - * IFRFbWriteEmbeded - Embeded write RF register via MAC + * IFRFbWriteEmbeded - Embedded write RF register via MAC * * Revision History: * @@ -711,7 +711,7 @@ const BYTE RFaby11aChannelIndex[200] = { /*--------------------- Export Functions --------------------------*/ /* - * Description: Write to IF/RF, by embeded programming + * Description: Write to IF/RF, by embedded programming * * Parameters: * In: diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index bb46452..dd28b91 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -987,7 +987,7 @@ s_vFillRTSHead ( uRTSFrameLen -= 4; } - // Note: So far RTSHead dosen't appear in ATIM & Beacom DMA, so we don't need to take them into account. + // Note: So far RTSHead doesn't appear in ATIM & Beacom DMA, so we don't need to take them into account. // Otherwise, we need to modified codes for them. if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) { if (byFBOption == AUTO_FB_NONE) { @@ -2770,7 +2770,7 @@ int nsDMA_tx_packet(PSDevice pDevice, unsigned int uDMAIdx, struct sk_buff *skb) pMgmt->abyPSTxMap[0] |= byMask[0]; return 0; } - // muticast/broadcast data rate + // multicast/broadcast data rate if (pDevice->byBBType != BB_TYPE_11A) pDevice->wCurrentRate = RATE_2M; diff --git a/drivers/staging/vt6656/wcmd.c b/drivers/staging/vt6656/wcmd.c index 9d2caa8..23ed03c 100644 --- a/drivers/staging/vt6656/wcmd.c +++ b/drivers/staging/vt6656/wcmd.c @@ -751,7 +751,7 @@ void vRunCommand(void *hDeviceContext) pDevice->nTxDataTimeCout = 0; } else { - // printk("mike:-->First time triger TimerTxData InSleep\n"); + // printk("mike:-->First time trigger TimerTxData InSleep\n"); } pDevice->IsTxDataTrigger = TRUE; add_timer(&pDevice->sTimerTxData); diff --git a/drivers/staging/vt6656/wmgr.c b/drivers/staging/vt6656/wmgr.c index f08e2d1..9469c9e 100644 --- a/drivers/staging/vt6656/wmgr.c +++ b/drivers/staging/vt6656/wmgr.c @@ -54,7 +54,7 @@ * bMgrPrepareBeaconToSend - Prepare Beacon frame * s_vMgrLogStatus - Log 802.11 Status * vMgrRxManagePacket - Rcv management frame dispatch function - * s_vMgrFormatTIM- Assember TIM field of beacon + * s_vMgrFormatTIM- Assembler TIM field of beacon * vMgrTimerInit- Initial 1-sec and command call back funtions * * Revision History: @@ -2032,7 +2032,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE) } // - // Preamble may change dynamiclly + // Preamble may change dynamically // byOldPreambleType = pDevice->byPreambleType; if (WLAN_GET_CAP_INFO_SHORTPREAMBLE(pBSSList->wCapInfo)) { @@ -2044,7 +2044,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE) if (pDevice->byPreambleType != byOldPreambleType) CARDvSetRSPINF(pDevice, (BYTE)pDevice->byBBType); // - // Basic Rate Set may change dynamiclly + // Basic Rate Set may change dynamically // if (pBSSList->eNetworkTypeInUse == PHY_TYPE_11B) { uRateLen = WLAN_RATES_MAXLEN_11B; -- cgit v0.10.2 From fd025b8fd819751496e53acdc22a5d3c9b7bfe2d Mon Sep 17 00:00:00 2001 From: Chandrabhanu Mahapatra Date: Wed, 1 Aug 2012 18:50:34 +0530 Subject: staging: drm/omap: remove reclaim_buffers callback The reclaim_buffers callback has already been removed by Daniel Vetter with his patch "drm: kill reclaim_buffers callback" (b0071efe82). As a result the kernel compilation fails with omapdrm support and so the callback for reclaim_buffers is being removed from omapdrm. Signed-off-by: Chandrabhanu Mahapatra Reviewed-by: Sumit Semwal Signed-off-by: Rob Clark Acked-by: Paul Menzel Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/omapdrm/omap_drv.c b/drivers/staging/omapdrm/omap_drv.c index 4beab94..44149ee 100644 --- a/drivers/staging/omapdrm/omap_drv.c +++ b/drivers/staging/omapdrm/omap_drv.c @@ -761,7 +761,6 @@ static struct drm_driver omap_drm_driver = { .irq_postinstall = dev_irq_postinstall, .irq_uninstall = dev_irq_uninstall, .irq_handler = dev_irq_handler, - .reclaim_buffers = drm_core_reclaim_buffers, #ifdef CONFIG_DEBUG_FS .debugfs_init = omap_debugfs_init, .debugfs_cleanup = omap_debugfs_cleanup, -- cgit v0.10.2 From d7de993503aa23f34d58b7945cf00ad9a9486bda Mon Sep 17 00:00:00 2001 From: Andy Gross Date: Thu, 9 Aug 2012 00:14:56 -0500 Subject: staging: omapdrm: Fix DMM sparse warnings Fix the following sparse warnings: drivers/staging/omapdrm/omap_dmm_tiler.c:123:13: warning: symbol 'omap_dmm_irq_handler' was not declared. Should it be static? drivers/staging/omapdrm/omap_dmm_tiler.c:370:24: warning: Using plain integer as NULL pointer Signed-off-by: Andy Gross Signed-off-by: Rob Clark Reviewed-by: Sumit Semwal Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c b/drivers/staging/omapdrm/omap_dmm_tiler.c index 8619783..ec7a5c8 100644 --- a/drivers/staging/omapdrm/omap_dmm_tiler.c +++ b/drivers/staging/omapdrm/omap_dmm_tiler.c @@ -120,7 +120,7 @@ static int wait_status(struct refill_engine *engine, uint32_t wait_mask) return 0; } -irqreturn_t omap_dmm_irq_handler(int irq, void *arg) +static irqreturn_t omap_dmm_irq_handler(int irq, void *arg) { struct dmm *dmm = arg; uint32_t status = readl(dmm->base + DMM_PAT_IRQSTATUS); @@ -367,7 +367,7 @@ struct tiler_block *tiler_reserve_1d(size_t size) int num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; if (!block) - return 0; + return ERR_PTR(-ENOMEM); block->fmt = TILFMT_PAGE; -- cgit v0.10.2 From cdf5e55124e4804fc0027df7e89567a3f5eed8bf Mon Sep 17 00:00:00 2001 From: Johannes Thumshirn Date: Mon, 6 Aug 2012 14:08:50 +0200 Subject: staging: line6: pcm.c: Changed simple_strtoul to kstrtoint Changed call to simple_strtoul to kstrtoint in pcm_set_impulse_volume(...) Signed-off-by: Johannes Thumshirn Reviewed-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/line6/pcm.c b/drivers/staging/line6/pcm.c index 5e319e3..7fe44a6 100644 --- a/drivers/staging/line6/pcm.c +++ b/drivers/staging/line6/pcm.c @@ -48,7 +48,13 @@ static ssize_t pcm_set_impulse_volume(struct device *dev, const char *buf, size_t count) { struct snd_line6_pcm *line6pcm = dev2pcm(dev); - int value = simple_strtoul(buf, NULL, 10); + int value; + int rv; + + rv = kstrtoint(buf, 10, &value); + if (rv < 0) + return rv; + line6pcm->impulse_volume = value; if (value > 0) -- cgit v0.10.2 From 3b2f1fbec9218f24425eaaeedd4fd3e6ef3e9f44 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Mon, 6 Aug 2012 02:58:47 +0545 Subject: staging/crystalhd: assign PTR_ERR at fail cases to rc in chd_dec_init_chdev the rc assignment to PTR_ERR at fail cases of class_create and device_create are missed out, return proper error rather than returning -ENODEV. Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/crystalhd/crystalhd_lnx.c b/drivers/staging/crystalhd/crystalhd_lnx.c index d9e3d61..0582ac0 100644 --- a/drivers/staging/crystalhd/crystalhd_lnx.c +++ b/drivers/staging/crystalhd/crystalhd_lnx.c @@ -373,6 +373,7 @@ static int __devinit chd_dec_init_chdev(struct crystalhd_adp *adp) /* register crystalhd class */ crystalhd_class = class_create(THIS_MODULE, "crystalhd"); if (IS_ERR(crystalhd_class)) { + rc = PTR_ERR(crystalhd_class); BCMLOG_ERR("failed to create class\n"); goto fail; } @@ -380,6 +381,7 @@ static int __devinit chd_dec_init_chdev(struct crystalhd_adp *adp) dev = device_create(crystalhd_class, NULL, MKDEV(adp->chd_dec_major, 0), NULL, "crystalhd"); if (IS_ERR(dev)) { + rc = PTR_ERR(crystalhd_class); BCMLOG_ERR("failed to create device\n"); goto device_create_fail; } -- cgit v0.10.2 From 675fe097568894708afd3b264e4122589e879f40 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Mon, 6 Aug 2012 02:59:56 +0545 Subject: staging/crystalhd: unregister chardev when class_create fails in chd_dec_init_chdev we missed a unregiser_chrdev if the class_create and subsequent function calls / checks fail Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/crystalhd/crystalhd_lnx.c b/drivers/staging/crystalhd/crystalhd_lnx.c index 0582ac0..5909d8d 100644 --- a/drivers/staging/crystalhd/crystalhd_lnx.c +++ b/drivers/staging/crystalhd/crystalhd_lnx.c @@ -375,7 +375,7 @@ static int __devinit chd_dec_init_chdev(struct crystalhd_adp *adp) if (IS_ERR(crystalhd_class)) { rc = PTR_ERR(crystalhd_class); BCMLOG_ERR("failed to create class\n"); - goto fail; + goto class_create_fail; } dev = device_create(crystalhd_class, NULL, MKDEV(adp->chd_dec_major, 0), @@ -412,6 +412,8 @@ elem_pool_fail: device_destroy(crystalhd_class, MKDEV(adp->chd_dec_major, 0)); device_create_fail: class_destroy(crystalhd_class); +class_create_fail: + unregister_chrdev(adp->chd_dec_major, CRYSTALHD_API_NAME); fail: return rc; } -- cgit v0.10.2 From 28a722958878da5edd563f9393225fa3128c5647 Mon Sep 17 00:00:00 2001 From: Rupesh Gujare Date: Mon, 23 Jul 2012 18:49:43 +0100 Subject: staging: ozwpan: buffer frame if urb not available. For interrupt end point buffer frames, if urb is not available & give back as soon as urb is received from usb core. Signed-off-by: Rupesh Gujare Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ozwpan/ozhcd.c b/drivers/staging/ozwpan/ozhcd.c index 251f07c..617bfed 100644 --- a/drivers/staging/ozwpan/ozhcd.c +++ b/drivers/staging/ozwpan/ozhcd.c @@ -417,6 +417,44 @@ static void oz_ep_free(struct oz_port *port, struct oz_endpoint *ep) /*------------------------------------------------------------------------------ * Context: softirq */ +void oz_complete_buffered_urb(struct oz_port *port, struct oz_endpoint *ep, + struct urb *urb) +{ + u8 data_len, available_space, copy_len; + + memcpy(&data_len, &ep->buffer[ep->out_ix], sizeof(u8)); + if (data_len <= urb->transfer_buffer_length) + available_space = data_len; + else + available_space = urb->transfer_buffer_length; + + if (++ep->out_ix == ep->buffer_size) + ep->out_ix = 0; + copy_len = ep->buffer_size - ep->out_ix; + if (copy_len >= available_space) + copy_len = available_space; + memcpy(urb->transfer_buffer, &ep->buffer[ep->out_ix], copy_len); + + if (copy_len < available_space) { + memcpy((urb->transfer_buffer + copy_len), ep->buffer, + (available_space - copy_len)); + ep->out_ix = available_space - copy_len; + } else { + ep->out_ix += copy_len; + } + urb->actual_length = available_space; + if (ep->out_ix == ep->buffer_size) + ep->out_ix = 0; + + ep->buffered_units--; + oz_trace("Trying to give back buffered frame of size=%d\n", + available_space); + oz_complete_urb(port->ozhcd->hcd, urb, 0, 0); +} + +/*------------------------------------------------------------------------------ + * Context: softirq + */ static int oz_enqueue_ep_urb(struct oz_port *port, u8 ep_addr, int in_dir, struct urb *urb, u8 req_id) { @@ -452,6 +490,18 @@ static int oz_enqueue_ep_urb(struct oz_port *port, u8 ep_addr, int in_dir, ep = port->in_ep[ep_addr]; else ep = port->out_ep[ep_addr]; + + /*For interrupt endpoint check for buffered data + * & complete urb + */ + if (((ep->attrib & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) + && ep->buffered_units > 0) { + oz_free_urb_link(urbl); + spin_unlock_bh(&port->ozhcd->hcd_lock); + oz_complete_buffered_urb(port, ep, urb); + return 0; + } + if (ep && port->hpd) { list_add_tail(&urbl->link, &ep->urb_list); if (!in_dir && ep_addr && (ep->credit < 0)) { @@ -961,6 +1011,9 @@ void oz_hcd_data_ind(void *hport, u8 endpoint, u8 *data, int data_len) urb->actual_length = copy_len; oz_complete_urb(port->ozhcd->hcd, urb, 0, 0); return; + } else { + oz_trace("buffering frame as URB is not available\n"); + oz_hcd_buffer_data(ep, data, data_len); } break; case USB_ENDPOINT_XFER_ISOC: @@ -1167,10 +1220,16 @@ static int oz_build_endpoints_for_interface(struct usb_hcd *hcd, int buffer_size = 0; oz_trace("%d bEndpointAddress = %x\n", i, ep_addr); - if ((ep_addr & USB_ENDPOINT_DIR_MASK) && - ((hep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) - == USB_ENDPOINT_XFER_ISOC)) { - buffer_size = 24*1024; + if (ep_addr & USB_ENDPOINT_DIR_MASK) { + switch (hep->desc.bmAttributes & + USB_ENDPOINT_XFERTYPE_MASK) { + case USB_ENDPOINT_XFER_ISOC: + buffer_size = 24*1024; + break; + case USB_ENDPOINT_XFER_INT: + buffer_size = 128; + break; + } } ep = oz_ep_alloc(mem_flags, buffer_size); -- cgit v0.10.2 From 24168911bedc23b02a0fa5043befa37580e6a9cb Mon Sep 17 00:00:00 2001 From: Rupesh Gujare Date: Mon, 23 Jul 2012 18:49:44 +0100 Subject: staging: ozwpan: Insulate driver from HZ value This patch fixes issue caused due to different HZ value on system which do not have HZ=1000 Signed-off-by: Rupesh Gujare Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ozwpan/ozhcd.c b/drivers/staging/ozwpan/ozhcd.c index 617bfed..4ac1f27 100644 --- a/drivers/staging/ozwpan/ozhcd.c +++ b/drivers/staging/ozwpan/ozhcd.c @@ -1053,7 +1053,7 @@ int oz_hcd_heartbeat(void *hport) ep = ep_from_link(e); if (ep->credit < 0) continue; - ep->credit += (now - ep->last_jiffies); + ep->credit += jiffies_to_msecs(now - ep->last_jiffies); if (ep->credit > ep->credit_ceiling) ep->credit = ep->credit_ceiling; oz_event_log(OZ_EVT_EP_CREDIT, ep->ep_num, 0, 0, ep->credit); @@ -1062,7 +1062,7 @@ int oz_hcd_heartbeat(void *hport) urbl = list_first_entry(&ep->urb_list, struct oz_urb_link, link); urb = urbl->urb; - if (ep->credit < urb->number_of_packets) + if ((ep->credit + 1) < urb->number_of_packets) break; ep->credit -= urb->number_of_packets; oz_event_log(OZ_EVT_EP_CREDIT, ep->ep_num, 0, 0, @@ -1105,7 +1105,7 @@ int oz_hcd_heartbeat(void *hport) } continue; } - ep->credit += (now - ep->last_jiffies); + ep->credit += jiffies_to_msecs(now - ep->last_jiffies); oz_event_log(OZ_EVT_EP_CREDIT, ep->ep_num | USB_DIR_IN, 0, 0, ep->credit); ep->last_jiffies = now; @@ -1117,7 +1117,7 @@ int oz_hcd_heartbeat(void *hport) int len = 0; int copy_len; int i; - if (ep->credit < urb->number_of_packets) + if ((ep->credit + 1) < urb->number_of_packets) break; if (ep->buffered_units < urb->number_of_packets) break; diff --git a/drivers/staging/ozwpan/ozproto.h b/drivers/staging/ozwpan/ozproto.h index 89aea28..7d5b476 100644 --- a/drivers/staging/ozwpan/ozproto.h +++ b/drivers/staging/ozwpan/ozproto.h @@ -14,7 +14,7 @@ /* Converts millisecs to jiffies. */ -#define oz_ms_to_jiffies(__x) (((__x)*1000)/HZ) +#define oz_ms_to_jiffies(__x) msecs_to_jiffies(__x) /* Quantum milliseconds. */ -- cgit v0.10.2 From 5494ebdf3c1ac634b133369736632be82a0255f8 Mon Sep 17 00:00:00 2001 From: Rupesh Gujare Date: Mon, 23 Jul 2012 18:49:45 +0100 Subject: staging: ozwpan: Return correct actual_length to userland This fixes issue where wrong retrun value was received by userland application after writing data to raw hid device. Signed-off-by: Rupesh Gujare Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ozwpan/ozhcd.c b/drivers/staging/ozwpan/ozhcd.c index 4ac1f27..76821cb 100644 --- a/drivers/staging/ozwpan/ozhcd.c +++ b/drivers/staging/ozwpan/ozhcd.c @@ -933,13 +933,14 @@ void oz_hcd_control_cnf(void *hport, u8 req_id, u8 rcode, u8 *data, } else { int copy_len; oz_trace("VENDOR-CLASS - cnf\n"); - if (data_len <= urb->transfer_buffer_length) - copy_len = data_len; - else - copy_len = urb->transfer_buffer_length; - if (copy_len) + if (data_len) { + if (data_len <= urb->transfer_buffer_length) + copy_len = data_len; + else + copy_len = urb->transfer_buffer_length; memcpy(urb->transfer_buffer, data, copy_len); - urb->actual_length = copy_len; + urb->actual_length = copy_len; + } oz_complete_urb(hcd, urb, 0, 0); } } @@ -1517,6 +1518,7 @@ static void oz_process_ep0_urb(struct oz_hcd *ozhcd, struct urb *urb, int data_len = 0; if ((setup->bRequestType & USB_DIR_IN) == 0) data_len = wlength; + urb->actual_length = data_len; if (oz_usb_control_req(port->hpd, req_id, setup, urb->transfer_buffer, data_len)) { rc = -ENOMEM; -- cgit v0.10.2 From 86d03a0f4f575dda7988800a3da8d6e9f776a819 Mon Sep 17 00:00:00 2001 From: Rupesh Gujare Date: Mon, 23 Jul 2012 18:49:46 +0100 Subject: staging: ozwpan: isoc latency for audio burst Set audio latency. This fixes issue where audio clips heard during link outage. Signed-off-by: Rupesh Gujare Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ozwpan/ozpd.c b/drivers/staging/ozwpan/ozpd.c index 6c287ac..f546b5a 100644 --- a/drivers/staging/ozwpan/ozpd.c +++ b/drivers/staging/ozwpan/ozpd.c @@ -24,12 +24,6 @@ /*------------------------------------------------------------------------------ */ #define OZ_MAX_TX_POOL_SIZE 6 -/* Maximum number of uncompleted isoc frames that can be pending in network. - */ -#define OZ_MAX_SUBMITTED_ISOC 16 -/* Maximum number of uncompleted isoc frames that can be pending in Tx Queue. - */ -#define OZ_MAX_TX_QUEUE_ISOC 32 /*------------------------------------------------------------------------------ */ static struct oz_tx_frame *oz_tx_frame_alloc(struct oz_pd *pd); @@ -854,7 +848,7 @@ int oz_send_isoc_unit(struct oz_pd *pd, u8 ep_num, u8 *data, int len) if (!(pd->mode & OZ_F_ISOC_ANYTIME)) { struct oz_tx_frame *isoc_unit = NULL; int nb = pd->nb_queued_isoc_frames; - if (nb >= OZ_MAX_TX_QUEUE_ISOC) { + if (nb >= pd->isoc_latency) { oz_trace2(OZ_TRACE_TX_FRAMES, "Dropping ISOC Unit nb= %d\n", nb); diff --git a/drivers/staging/ozwpan/ozpd.h b/drivers/staging/ozwpan/ozpd.h index ddf1341..d35b0ea 100644 --- a/drivers/staging/ozwpan/ozpd.h +++ b/drivers/staging/ozwpan/ozpd.h @@ -82,6 +82,7 @@ struct oz_pd { u8 heartbeat_requested; u8 mode; u8 ms_per_isoc; + unsigned isoc_latency; unsigned max_stream_buffering; int nb_queued_frames; int nb_queued_isoc_frames; diff --git a/drivers/staging/ozwpan/ozproto.c b/drivers/staging/ozwpan/ozproto.c index a50ab18..cfb5160 100644 --- a/drivers/staging/ozwpan/ozproto.c +++ b/drivers/staging/ozwpan/ozproto.c @@ -220,6 +220,19 @@ static struct oz_pd *oz_connect_req(struct oz_pd *cur_pd, struct oz_elt *elt, pd->ms_per_isoc = body->ms_per_isoc; if (!pd->ms_per_isoc) pd->ms_per_isoc = 4; + + switch (body->ms_isoc_latency & OZ_LATENCY_MASK) { + case OZ_ONE_MS_LATENCY: + pd->isoc_latency = (body->ms_isoc_latency & + ~OZ_LATENCY_MASK) / pd->ms_per_isoc; + break; + case OZ_TEN_MS_LATENCY: + pd->isoc_latency = ((body->ms_isoc_latency & + ~OZ_LATENCY_MASK) * 10) / pd->ms_per_isoc; + break; + default: + pd->isoc_latency = OZ_MAX_TX_QUEUE_ISOC; + } } if (body->max_len_div16) pd->max_tx_size = ((u16)body->max_len_div16)<<4; diff --git a/drivers/staging/ozwpan/ozproto.h b/drivers/staging/ozwpan/ozproto.h index 7d5b476..755a08d 100644 --- a/drivers/staging/ozwpan/ozproto.h +++ b/drivers/staging/ozwpan/ozproto.h @@ -30,6 +30,12 @@ /* Maximun sizes of tx frames. */ #define OZ_MAX_TX_SIZE 1514 +/* Maximum number of uncompleted isoc frames that can be pending in network. */ +#define OZ_MAX_SUBMITTED_ISOC 16 + +/* Maximum number of uncompleted isoc frames that can be pending in Tx Queue. */ +#define OZ_MAX_TX_QUEUE_ISOC 32 + /* Application handler functions. */ typedef int (*oz_app_init_fn_t)(void); diff --git a/drivers/staging/ozwpan/ozprotocol.h b/drivers/staging/ozwpan/ozprotocol.h index 1e4edbe..17b09b9 100644 --- a/drivers/staging/ozwpan/ozprotocol.h +++ b/drivers/staging/ozwpan/ozprotocol.h @@ -65,6 +65,10 @@ struct oz_hdr { #define OZ_LAST_PN_HALF_CYCLE 127 +#define OZ_LATENCY_MASK 0xc0 +#define OZ_ONE_MS_LATENCY 0x40 +#define OZ_TEN_MS_LATENCY 0x80 + /* Connect request data structure. */ struct oz_elt_connect_req { @@ -73,7 +77,7 @@ struct oz_elt_connect_req { u8 pd_info; u8 session_id; u8 presleep; - u8 resv2; + u8 ms_isoc_latency; u8 host_vendor; u8 keep_alive; u16 apps; -- cgit v0.10.2 From 3c1669d8a7b771cec1013cbfb5a7d390464c1d53 Mon Sep 17 00:00:00 2001 From: Rupesh Gujare Date: Mon, 23 Jul 2012 18:49:47 +0100 Subject: staging: ozwpan: Bump version number Bump version numbers to keep in sync with internal version information. Signed-off-by: Rupesh Gujare Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ozwpan/ozmain.c b/drivers/staging/ozwpan/ozmain.c index c1ed6b2..ef6c5ab 100644 --- a/drivers/staging/ozwpan/ozmain.c +++ b/drivers/staging/ozwpan/ozmain.c @@ -59,6 +59,6 @@ module_exit(ozwpan_exit); MODULE_AUTHOR("Chris Kelly"); MODULE_DESCRIPTION("Ozmo Devices USB over WiFi hcd driver"); -MODULE_VERSION("1.0.10"); +MODULE_VERSION("1.0.13"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 472aba5f91fd6413c9c75e71366f133aa8c7f2f2 Mon Sep 17 00:00:00 2001 From: Ben Chan Date: Tue, 24 Jul 2012 07:49:42 -0700 Subject: staging: gdm72xx: fix reference counting in gdm_wimax_event_init This patch fixes the commit "staging/gdm72xx: cleanup little at gdm_wimax_event_rcv" (8df858ea76b76dde9a39d4edd9aaded983582cfe), which mishandles the reference counting of wm_event. Signed-off-by: Ben Chan Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/gdm72xx/gdm_wimax.c b/drivers/staging/gdm72xx/gdm_wimax.c index 0716efc..6cb8107 100644 --- a/drivers/staging/gdm72xx/gdm_wimax.c +++ b/drivers/staging/gdm72xx/gdm_wimax.c @@ -258,12 +258,16 @@ static int gdm_wimax_event_init(void) if (!wm_event.ref_cnt) { wm_event.sock = netlink_init(NETLINK_WIMAX, gdm_wimax_event_rcv); - if (wm_event.sock) - wm_event.ref_cnt++; - INIT_LIST_HEAD(&wm_event.evtq); - INIT_LIST_HEAD(&wm_event.freeq); - INIT_WORK(&wm_event.ws, __gdm_wimax_event_send); - spin_lock_init(&wm_event.evt_lock); + if (wm_event.sock) { + INIT_LIST_HEAD(&wm_event.evtq); + INIT_LIST_HEAD(&wm_event.freeq); + INIT_WORK(&wm_event.ws, __gdm_wimax_event_send); + spin_lock_init(&wm_event.evt_lock); + } + } + + if (wm_event.sock) { + wm_event.ref_cnt++; return 0; } -- cgit v0.10.2 From e996f9de8534522a4ab0472e19f214cf3c7ca863 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Wed, 8 Aug 2012 22:14:38 +0200 Subject: staging:ccg: Fix missing brackets for sizeof (found by sparse). Fix following: WARNING: sizeof fsg should be sizeof(fsg) + memset(&fsg, 0, sizeof fsg); Signed-off-by: Marek Belisko Reviewed-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ccg/ccg.c b/drivers/staging/ccg/ccg.c index 6a7aab8..81ac6bb 100644 --- a/drivers/staging/ccg/ccg.c +++ b/drivers/staging/ccg/ccg.c @@ -728,7 +728,7 @@ static int mass_storage_function_init(struct ccg_usb_function *f, struct fsg_common *common; int err; - memset(&fsg, 0, sizeof fsg); + memset(&fsg, 0, sizeof(fsg)); fsg.nluns = 1; fsg.luns[0].removable = 1; fsg.vendor_name = iManufacturer; -- cgit v0.10.2 From 977310bbc3751ae507d4570cc556193bfbd7f9e7 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 2 Aug 2012 19:05:52 +0300 Subject: staging: xgifb: print small buffers via %*ph Signed-off-by: Andy Shevchenko Cc: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 64ffd70..0c859ae 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -913,17 +913,10 @@ static void XGIfb_post_setmode(struct xgifb_video_info *xgifb_info) } if ((filter >= 0) && (filter <= 7)) { - pr_debug("FilterTable[%d]-%d: %02x %02x %02x %02x\n", + pr_debug("FilterTable[%d]-%d: %*ph\n", filter_tb, filter, - XGI_TV_filter[filter_tb]. - filter[filter][0], - XGI_TV_filter[filter_tb]. - filter[filter][1], - XGI_TV_filter[filter_tb]. - filter[filter][2], - XGI_TV_filter[filter_tb]. - filter[filter][3] - ); + 4, XGI_TV_filter[filter_tb]. + filter[filter]); xgifb_reg_set( XGIPART2, 0x35, -- cgit v0.10.2 From 6a371978836049656525bb0719187362c5114232 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 2 Aug 2012 19:05:46 +0300 Subject: staging: nvec: use %*ph to dump small buffers Signed-off-by: Andy Shevchenko Cc: ac100@lists.launchpad.net Acked-by: Julian Andres Klode Acked-By: Marc Dietrich Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index 695ea35..3655d86 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -366,8 +366,7 @@ static void nvec_request_master(struct work_struct *work) static int parse_msg(struct nvec_chip *nvec, struct nvec_msg *msg) { if ((msg->data[0] & 1 << 7) == 0 && msg->data[3]) { - dev_err(nvec->dev, "ec responded %02x %02x %02x %02x\n", - msg->data[0], msg->data[1], msg->data[2], msg->data[3]); + dev_err(nvec->dev, "ec responded %*ph\n", 4, msg->data); return -EINVAL; } -- cgit v0.10.2 From bcb6ef660f00ca33e43bd1183e9767c58e85f161 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 2 Aug 2012 19:05:44 +0300 Subject: staging: bcm: print small buffers with %*ph Signed-off-by: Andy Shevchenko Acked-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c index b54ec97..b6c20a9 100644 --- a/drivers/staging/bcm/CmHost.c +++ b/drivers/staging/bcm/CmHost.c @@ -999,13 +999,10 @@ static VOID DumpCmControlPacket(PVOID pvBuffer) #ifdef VERSION_D5 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPv6FlowLableLength: 0x%X ", psfCSType->cCPacketClassificationRule.u8IPv6FlowLableLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPv6FlowLable[6]: 0x %02X %02X %02X %02X %02X %02X ", - psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[0], - psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[1], - psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[2], - psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[3], - psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[4], - psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[5]); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, + DBG_LVL_ALL, "u8IPv6FlowLable[6]: 0x%*ph ", + 6, psfCSType->cCPacketClassificationRule. + u8IPv6FlowLable); #endif } @@ -1015,13 +1012,9 @@ static VOID DumpCmControlPacket(PVOID pvBuffer) BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16CID: 0x%X", pstAddIndication->sfAdmittedSet.u16CID); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassNameLength: 0x%X", pstAddIndication->sfAdmittedSet.u8ServiceClassNameLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassName: 0x %02X %02X %02X %02X %02X %02X", - pstAddIndication->sfAdmittedSet.u8ServiceClassName[0], - pstAddIndication->sfAdmittedSet.u8ServiceClassName[1], - pstAddIndication->sfAdmittedSet.u8ServiceClassName[2], - pstAddIndication->sfAdmittedSet.u8ServiceClassName[3], - pstAddIndication->sfAdmittedSet.u8ServiceClassName[4], - pstAddIndication->sfAdmittedSet.u8ServiceClassName[5]); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, + "u8ServiceClassName: 0x%*ph", + 6, pstAddIndication->sfAdmittedSet.u8ServiceClassName); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8MBSService: 0x%02X", pstAddIndication->sfAdmittedSet.u8MBSService); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8QosParamSet: 0x%02X", pstAddIndication->sfAdmittedSet.u8QosParamSet); @@ -1074,10 +1067,10 @@ static VOID DumpCmControlPacket(PVOID pvBuffer) psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPTypeOfServiceLength: 0x%02X", psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPTypeOfService[3]: 0x%02X %02X %02X", - psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0], - psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1], - psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, + DBG_LVL_ALL, "u8IPTypeOfService[3]: 0x%*ph", + 3, psfCSType->cCPacketClassificationRule. + u8IPTypeOfService); for (uiLoopIndex = 0; uiLoopIndex < 1; uiLoopIndex++) BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Protocol: 0x%02X ", psfCSType->cCPacketClassificationRule.u8Protocol); @@ -1098,20 +1091,20 @@ static VOID DumpCmControlPacket(PVOID pvBuffer) BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolSourcePortRangeLength: 0x%02X ", psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolSourcePortRange[4]: 0x %02X %02X %02X %02X ", - psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[0], - psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[1], - psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[2], - psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[3]); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, + DBG_LVL_ALL, "u8ProtocolSourcePortRange[4]: " + "0x%*ph ", 4, psfCSType-> + cCPacketClassificationRule. + u8ProtocolSourcePortRange); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolDestPortRangeLength: 0x%02X ", psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolDestPortRange[4]: 0x %02X %02X %02X %02X ", - psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[0], - psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[1], - psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[2], - psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[3]); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, + DBG_LVL_ALL, "u8ProtocolDestPortRange[4]: " + "0x%*ph ", 4, psfCSType-> + cCPacketClassificationRule. + u8ProtocolDestPortRange); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetDestMacAddressLength: 0x%02X ", psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength); @@ -1130,10 +1123,10 @@ static VOID DumpCmControlPacket(PVOID pvBuffer) u8EthernetSourceMACAddress); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthertypeLength: 0x%02X ", psfCSType->cCPacketClassificationRule.u8EthertypeLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Ethertype[3]: 0x%02X %02X %02X", - psfCSType->cCPacketClassificationRule.u8Ethertype[0], - psfCSType->cCPacketClassificationRule.u8Ethertype[1], - psfCSType->cCPacketClassificationRule.u8Ethertype[2]); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, + DBG_LVL_ALL, "u8Ethertype[3]: 0x%*ph", + 3, psfCSType->cCPacketClassificationRule. + u8Ethertype); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16UserPriority: 0x%X ", psfCSType->cCPacketClassificationRule.u16UserPriority); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16VLANID: 0x%X ", psfCSType->cCPacketClassificationRule.u16VLANID); @@ -1147,13 +1140,10 @@ static VOID DumpCmControlPacket(PVOID pvBuffer) #ifdef VERSION_D5 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPv6FlowLableLength: 0x%X ", psfCSType->cCPacketClassificationRule.u8IPv6FlowLableLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPv6FlowLable[6]: 0x %02X %02X %02X %02X %02X %02X ", - psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[0], - psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[1], - psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[2], - psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[3], - psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[4], - psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[5]); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, + DBG_LVL_ALL, "u8IPv6FlowLable[6]: 0x%*ph ", + 6, psfCSType->cCPacketClassificationRule. + u8IPv6FlowLable); #endif } @@ -1162,13 +1152,9 @@ static VOID DumpCmControlPacket(PVOID pvBuffer) BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32SFID: 0x%X", pstAddIndication->sfActiveSet.u32SFID); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16CID: 0x%X", pstAddIndication->sfActiveSet.u16CID); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassNameLength: 0x%X", pstAddIndication->sfActiveSet.u8ServiceClassNameLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassName: 0x %02X %02X %02X %02X %02X %02X", - pstAddIndication->sfActiveSet.u8ServiceClassName[0], - pstAddIndication->sfActiveSet.u8ServiceClassName[1], - pstAddIndication->sfActiveSet.u8ServiceClassName[2], - pstAddIndication->sfActiveSet.u8ServiceClassName[3], - pstAddIndication->sfActiveSet.u8ServiceClassName[4], - pstAddIndication->sfActiveSet.u8ServiceClassName[5]); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, + "u8ServiceClassName: 0x%*ph", + 6, pstAddIndication->sfActiveSet.u8ServiceClassName); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8MBSService: 0x%02X", pstAddIndication->sfActiveSet.u8MBSService); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8QosParamSet: 0x%02X", pstAddIndication->sfActiveSet.u8QosParamSet); diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index f545716..f13a958 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -752,7 +752,10 @@ VOID DumpPackInfo(struct bcm_mini_adapter *Adapter) BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "AuthzSet: %x\n", Adapter->PackInfo[uiLoopIndex].bAuthorizedSet); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ClassifyPrority: %x\n", Adapter->PackInfo[uiLoopIndex].bClassifierPriority); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiMaxLatency: %x\n", Adapter->PackInfo[uiLoopIndex].uiMaxLatency); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ServiceClassName: %x %x %x %x\n", Adapter->PackInfo[uiLoopIndex].ucServiceClassName[0], Adapter->PackInfo[uiLoopIndex].ucServiceClassName[1], Adapter->PackInfo[uiLoopIndex].ucServiceClassName[2], Adapter->PackInfo[uiLoopIndex].ucServiceClassName[3]); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, + DBG_LVL_ALL, "ServiceClassName: %*ph\n", + 4, Adapter->PackInfo[uiLoopIndex]. + ucServiceClassName); /* BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "bHeaderSuppressionEnabled :%X\n", Adapter->PackInfo[uiLoopIndex].bHeaderSuppressionEnabled); * BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiTotalTxBytes:%X\n", Adapter->PackInfo[uiLoopIndex].uiTotalTxBytes); * BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiTotalRxBytes:%X\n", Adapter->PackInfo[uiLoopIndex].uiTotalRxBytes); -- cgit v0.10.2 From 1deef918ec5f5f17bdf41876a30a67a29a87807b Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 2 Aug 2012 19:05:51 +0300 Subject: staging: wlan-ng: use %*phC to hexdump small buffers Signed-off-by: Andy Shevchenko Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlan-ng/p80211wep.c b/drivers/staging/wlan-ng/p80211wep.c index 80c2d3b..77e50a4 100644 --- a/drivers/staging/wlan-ng/p80211wep.c +++ b/drivers/staging/wlan-ng/p80211wep.c @@ -134,10 +134,8 @@ int wep_change_key(wlandevice_t *wlandev, int keynum, u8 *key, int keylen) return -1; #ifdef WEP_DEBUG - printk(KERN_DEBUG - "WEP key %d len %d = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", - keynum, keylen, key[0], key[1], key[2], key[3], key[4], key[5], - key[6], key[7]); + printk(KERN_DEBUG "WEP key %d len %d = %*phC\n", keynum, keylen, + 8, key); #endif wlandev->wep_keylens[keynum] = keylen; @@ -184,10 +182,8 @@ int wep_decrypt(wlandevice_t *wlandev, u8 *buf, u32 len, int key_override, keylen += 3; /* add in IV bytes */ #ifdef WEP_DEBUG - printk(KERN_DEBUG - "D %d: %02x %02x %02x (%d %d) %02x:%02x:%02x:%02x:%02x\n", len, - key[0], key[1], key[2], keyidx, keylen, key[3], key[4], key[5], - key[6], key[7]); + printk(KERN_DEBUG "D %d: %*ph (%d %d) %*phC\n", len, 3, key, + keyidx, keylen, 5, key + 3); #endif /* set up the RC4 state */ @@ -263,10 +259,8 @@ int wep_encrypt(wlandevice_t *wlandev, u8 *buf, u8 *dst, u32 len, int keynum, keylen += 3; /* add in IV bytes */ #ifdef WEP_DEBUG - printk(KERN_DEBUG - "E %d (%d/%d %d) %02x %02x %02x %02x:%02x:%02x:%02x:%02x\n", len, - iv[3], keynum, keylen, key[0], key[1], key[2], key[3], key[4], - key[5], key[6], key[7]); + printk(KERN_DEBUG "E %d (%d/%d %d) %*ph %*phC\n", len, + iv[3], keynum, keylen, 3, key, 5, key + 3); #endif /* set up the RC4 state */ -- cgit v0.10.2 From 7f34f412896aa493fd99a8dc745cfd2ec3a55103 Mon Sep 17 00:00:00 2001 From: Tim Gardner Date: Wed, 25 Jul 2012 13:08:47 -0600 Subject: staging rtl8192e: Declare MODULE_FIRMWARE usage Cc: Larry Finger Cc: Mike McCormack Cc: wlanfae Cc: Sean MacLennan Signed-off-by: Tim Gardner Acked-by: Sean MacLennan Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c index b526fa4..dd2a96b 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c @@ -265,10 +265,11 @@ bool init_firmware(struct net_device *dev) case FW_SOURCE_IMG_FILE: { if (pfirmware->firmware_buf_size[init_step] == 0) { - const char *fw_name[3] = { "RTL8192E/boot.img", - "RTL8192E/main.img", - "RTL8192E/data.img" - }; + const char *fw_name[3] = { + RTL8192E_BOOT_IMG_FW, + RTL8192E_MAIN_IMG_FW, + RTL8192E_DATA_IMG_FW + }; const struct firmware *fw_entry; int rc; rc = request_firmware(&fw_entry, diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.h b/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.h index caa8788..06d6abc 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.h +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.h @@ -23,6 +23,10 @@ #define GET_COMMAND_PACKET_FRAG_THRESHOLD(v) (4*(v/4) - 8) +#define RTL8192E_BOOT_IMG_FW "RTL8192E/boot.img" +#define RTL8192E_MAIN_IMG_FW "RTL8192E/main.img" +#define RTL8192E_DATA_IMG_FW "RTL8192E/data.img" + enum firmware_init_step { FW_INIT_STEP0_BOOT = 0, FW_INIT_STEP1_MAIN = 1, diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 4f602b2..42e5c5c 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -3125,6 +3125,9 @@ MODULE_DESCRIPTION("Linux driver for Realtek RTL819x WiFi cards"); MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); MODULE_VERSION(DRV_VERSION); MODULE_LICENSE("GPL"); +MODULE_FIRMWARE(RTL8192E_BOOT_IMG_FW); +MODULE_FIRMWARE(RTL8192E_MAIN_IMG_FW); +MODULE_FIRMWARE(RTL8192E_DATA_IMG_FW); module_param(ifname, charp, S_IRUGO|S_IWUSR); module_param(hwwep, int, S_IRUGO|S_IWUSR); -- cgit v0.10.2 From 103b748e21ced078f868f9218cef85b0917cebb2 Mon Sep 17 00:00:00 2001 From: Marc Dietrich Date: Sun, 22 Jul 2012 12:28:36 +0200 Subject: Staging: nvec: fix coding style issues This commit fixes coding style issues that includes long lines. Based on the original patch submitted by Adnan Ali Signed-off-by: Marc Dietrich Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index 3655d86..fb52fe0 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -736,12 +736,14 @@ static int __devinit tegra_nvec_probe(struct platform_device *pdev) nvec->gpio = pdata->gpio; nvec->i2c_addr = pdata->i2c_addr; } else if (nvec->dev->of_node) { - nvec->gpio = of_get_named_gpio(nvec->dev->of_node, "request-gpios", 0); + nvec->gpio = of_get_named_gpio(nvec->dev->of_node, + "request-gpios", 0); if (nvec->gpio < 0) { dev_err(&pdev->dev, "no gpio specified"); return -ENODEV; } - if (of_property_read_u32(nvec->dev->of_node, "slave-addr", &nvec->i2c_addr)) { + if (of_property_read_u32(nvec->dev->of_node, + "slave-addr", &nvec->i2c_addr)) { dev_err(&pdev->dev, "no i2c address specified"); return -ENODEV; } -- cgit v0.10.2 From c50037496113e2eb04cfeec86a5c2490786c3dd5 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sat, 28 Jul 2012 11:39:48 -0500 Subject: staging: r8712u: Reduce maximum receive buffer size to a more sensible value The current value for the maximum receive buffer size is 30720, which is too large. For long-running systems, memory fragmentation may make it difficult to obtain the buffers of O(2) needed for aggregation. Buffers of O(3) are even worse, particularly when not needed. The new size is set to 9100, which will allow aggregation. Signed-off-by: Larry Finger Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8712/rtl8712_recv.h b/drivers/staging/rtl8712/rtl8712_recv.h index 8efbd1f..fd9e3fc 100644 --- a/drivers/staging/rtl8712/rtl8712_recv.h +++ b/drivers/staging/rtl8712/rtl8712_recv.h @@ -41,7 +41,7 @@ #define RECV_BLK_SZ 512 #define RECV_BLK_CNT 16 #define RECV_BLK_TH RECV_BLK_CNT -#define MAX_RECVBUF_SZ (30720) /* 30K */ +#define MAX_RECVBUF_SZ 9100 #define RECVBUFF_ALIGN_SZ 512 #define RSVD_ROOM_SZ (0) /*These definition is used for Rx packet reordering.*/ -- cgit v0.10.2 From 6ebb56d974b2c0b31effd1bb2bde554582a9ebd8 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Wed, 25 Jul 2012 12:18:12 +0900 Subject: staging: panel: fix checkpatch warnings Now checkpatch clean. $ find drivers/staging/panel -name "*.[ch]"|xargs ./scripts/checkpatch.pl \ -f --terse --nosummary|cut -f3- -d":"|sort |uniq -c|sort -n 2 WARNING: Single statement macros should not use a do {} while (0) loop Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c index 39f9982..d9fec5b 100644 --- a/drivers/staging/panel/panel.c +++ b/drivers/staging/panel/panel.c @@ -137,8 +137,8 @@ #define r_ctr(x) (parport_read_control((x)->port)) #define r_dtr(x) (parport_read_data((x)->port)) #define r_str(x) (parport_read_status((x)->port)) -#define w_ctr(x, y) do { parport_write_control((x)->port, (y)); } while (0) -#define w_dtr(x, y) do { parport_write_data((x)->port, (y)); } while (0) +#define w_ctr(x, y) (parport_write_control((x)->port, (y))) +#define w_dtr(x, y) (parport_write_data((x)->port, (y))) /* this defines which bits are to be used and which ones to be ignored */ /* logical or of the output bits involved in the scan matrix */ -- cgit v0.10.2 From 6539a36c0cb9ec7f1c1633b535ac83b2bdf0ae6d Mon Sep 17 00:00:00 2001 From: Seth Jennings Date: Wed, 18 Jul 2012 11:55:54 -0500 Subject: staging: zsmalloc: s/firstpage/page in new copy map funcs firstpage already has precedent and meaning the first page of a zspage. In the case of the copy mapping functions, it is the first of a pair of pages needing to be mapped. This patch just renames the firstpage argument to "page" to avoid confusion. Signed-off-by: Seth Jennings Acked-by: Minchan Kim Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/zsmalloc/zsmalloc-main.c b/drivers/staging/zsmalloc/zsmalloc-main.c index 8b0bcb6..3c83c65 100644 --- a/drivers/staging/zsmalloc/zsmalloc-main.c +++ b/drivers/staging/zsmalloc/zsmalloc-main.c @@ -470,15 +470,15 @@ static struct page *find_get_zspage(struct size_class *class) return page; } -static void zs_copy_map_object(char *buf, struct page *firstpage, +static void zs_copy_map_object(char *buf, struct page *page, int off, int size) { struct page *pages[2]; int sizes[2]; void *addr; - pages[0] = firstpage; - pages[1] = get_next_page(firstpage); + pages[0] = page; + pages[1] = get_next_page(page); BUG_ON(!pages[1]); sizes[0] = PAGE_SIZE - off; @@ -493,15 +493,15 @@ static void zs_copy_map_object(char *buf, struct page *firstpage, kunmap_atomic(addr); } -static void zs_copy_unmap_object(char *buf, struct page *firstpage, +static void zs_copy_unmap_object(char *buf, struct page *page, int off, int size) { struct page *pages[2]; int sizes[2]; void *addr; - pages[0] = firstpage; - pages[1] = get_next_page(firstpage); + pages[0] = page; + pages[1] = get_next_page(page); BUG_ON(!pages[1]); sizes[0] = PAGE_SIZE - off; -- cgit v0.10.2 From c60369f011251c60de506994aab088f1afb90bf4 Mon Sep 17 00:00:00 2001 From: Seth Jennings Date: Wed, 18 Jul 2012 11:55:55 -0500 Subject: staging: zsmalloc: prevent mappping in interrupt context Because we use per-cpu mapping areas shared among the pools/users, we can't allow mapping in interrupt context because it can corrupt another users mappings. Signed-off-by: Seth Jennings Acked-by: Minchan Kim Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/zsmalloc/zsmalloc-main.c b/drivers/staging/zsmalloc/zsmalloc-main.c index 3c83c65..b86133f 100644 --- a/drivers/staging/zsmalloc/zsmalloc-main.c +++ b/drivers/staging/zsmalloc/zsmalloc-main.c @@ -75,6 +75,7 @@ #include #include #include +#include #include "zsmalloc.h" #include "zsmalloc_int.h" @@ -761,6 +762,13 @@ void *zs_map_object(struct zs_pool *pool, unsigned long handle, BUG_ON(!handle); + /* + * Because we use per-cpu mapping areas shared among the + * pools/users, we can't allow mapping in interrupt context + * because it can corrupt another users mappings. + */ + BUG_ON(in_interrupt()); + obj_handle_to_location(handle, &page, &obj_idx); get_zspage_mapping(get_first_page(page), &class_idx, &fg); class = &pool->size_class[class_idx]; -- cgit v0.10.2 From f553646a67cb215577402cb702b67c8cf8fdb46f Mon Sep 17 00:00:00 2001 From: Seth Jennings Date: Wed, 18 Jul 2012 11:55:56 -0500 Subject: staging: zsmalloc: add page table mapping method This patchset provides page mapping via the page table. On some archs, most notably ARM, this method has been demonstrated to be faster than copying. The logic controlling the method selection (copy vs page table) is controlled by the definition of USE_PGTABLE_MAPPING which is/can be defined for any arch that performs better with page table mapping. Signed-off-by: Seth Jennings Acked-by: Minchan Kim Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/zsmalloc/zsmalloc-main.c b/drivers/staging/zsmalloc/zsmalloc-main.c index b86133f..defe350 100644 --- a/drivers/staging/zsmalloc/zsmalloc-main.c +++ b/drivers/staging/zsmalloc/zsmalloc-main.c @@ -89,6 +89,30 @@ #define CLASS_IDX_MASK ((1 << CLASS_IDX_BITS) - 1) #define FULLNESS_MASK ((1 << FULLNESS_BITS) - 1) +/* + * By default, zsmalloc uses a copy-based object mapping method to access + * allocations that span two pages. However, if a particular architecture + * 1) Implements local_flush_tlb_kernel_range() and 2) Performs VM mapping + * faster than copying, then it should be added here so that + * USE_PGTABLE_MAPPING is defined. This causes zsmalloc to use page table + * mapping rather than copying + * for object mapping. +*/ +#if defined(CONFIG_ARM) +#define USE_PGTABLE_MAPPING +#endif + +struct mapping_area { +#ifdef USE_PGTABLE_MAPPING + struct vm_struct *vm; /* vm area for mapping object that span pages */ +#else + char *vm_buf; /* copy buffer for objects that span pages */ +#endif + char *vm_addr; /* address of kmap_atomic()'ed pages */ + enum zs_mapmode vm_mm; /* mapping mode */ +}; + + /* per-cpu VM mapping areas for zspage accesses that cross page boundaries */ static DEFINE_PER_CPU(struct mapping_area, zs_map_area); @@ -471,16 +495,83 @@ static struct page *find_get_zspage(struct size_class *class) return page; } -static void zs_copy_map_object(char *buf, struct page *page, - int off, int size) +#ifdef USE_PGTABLE_MAPPING +static inline int __zs_cpu_up(struct mapping_area *area) +{ + /* + * Make sure we don't leak memory if a cpu UP notification + * and zs_init() race and both call zs_cpu_up() on the same cpu + */ + if (area->vm) + return 0; + area->vm = alloc_vm_area(PAGE_SIZE * 2, NULL); + if (!area->vm) + return -ENOMEM; + return 0; +} + +static inline void __zs_cpu_down(struct mapping_area *area) +{ + if (area->vm) + free_vm_area(area->vm); + area->vm = NULL; +} + +static inline void *__zs_map_object(struct mapping_area *area, + struct page *pages[2], int off, int size) +{ + BUG_ON(map_vm_area(area->vm, PAGE_KERNEL, &pages)); + area->vm_addr = area->vm->addr; + return area->vm_addr + off; +} + +static inline void __zs_unmap_object(struct mapping_area *area, + struct page *pages[2], int off, int size) +{ + unsigned long addr = (unsigned long)area->vm_addr; + unsigned long end = addr + (PAGE_SIZE * 2); + + flush_cache_vunmap(addr, end); + unmap_kernel_range_noflush(addr, PAGE_SIZE * 2); + local_flush_tlb_kernel_range(addr, end); +} + +#else /* USE_PGTABLE_MAPPING */ + +static inline int __zs_cpu_up(struct mapping_area *area) +{ + /* + * Make sure we don't leak memory if a cpu UP notification + * and zs_init() race and both call zs_cpu_up() on the same cpu + */ + if (area->vm_buf) + return 0; + area->vm_buf = (char *)__get_free_page(GFP_KERNEL); + if (!area->vm_buf) + return -ENOMEM; + return 0; +} + +static inline void __zs_cpu_down(struct mapping_area *area) +{ + if (area->vm_buf) + free_page((unsigned long)area->vm_buf); + area->vm_buf = NULL; +} + +static void *__zs_map_object(struct mapping_area *area, + struct page *pages[2], int off, int size) { - struct page *pages[2]; int sizes[2]; void *addr; + char *buf = area->vm_buf; - pages[0] = page; - pages[1] = get_next_page(page); - BUG_ON(!pages[1]); + /* disable page faults to match kmap_atomic() return conditions */ + pagefault_disable(); + + /* no read fastpath */ + if (area->vm_mm == ZS_MM_WO) + goto out; sizes[0] = PAGE_SIZE - off; sizes[1] = size - sizes[0]; @@ -492,18 +583,20 @@ static void zs_copy_map_object(char *buf, struct page *page, addr = kmap_atomic(pages[1]); memcpy(buf + sizes[0], addr, sizes[1]); kunmap_atomic(addr); +out: + return area->vm_buf; } -static void zs_copy_unmap_object(char *buf, struct page *page, - int off, int size) +static void __zs_unmap_object(struct mapping_area *area, + struct page *pages[2], int off, int size) { - struct page *pages[2]; int sizes[2]; void *addr; + char *buf = area->vm_buf; - pages[0] = page; - pages[1] = get_next_page(page); - BUG_ON(!pages[1]); + /* no write fastpath */ + if (area->vm_mm == ZS_MM_RO) + goto out; sizes[0] = PAGE_SIZE - off; sizes[1] = size - sizes[0]; @@ -515,34 +608,31 @@ static void zs_copy_unmap_object(char *buf, struct page *page, addr = kmap_atomic(pages[1]); memcpy(addr, buf + sizes[0], sizes[1]); kunmap_atomic(addr); + +out: + /* enable page faults to match kunmap_atomic() return conditions */ + pagefault_enable(); } +#endif /* USE_PGTABLE_MAPPING */ + static int zs_cpu_notifier(struct notifier_block *nb, unsigned long action, void *pcpu) { - int cpu = (long)pcpu; + int ret, cpu = (long)pcpu; struct mapping_area *area; switch (action) { case CPU_UP_PREPARE: area = &per_cpu(zs_map_area, cpu); - /* - * Make sure we don't leak memory if a cpu UP notification - * and zs_init() race and both call zs_cpu_up() on the same cpu - */ - if (area->vm_buf) - return 0; - area->vm_buf = (char *)__get_free_page(GFP_KERNEL); - if (!area->vm_buf) - return -ENOMEM; - return 0; + ret = __zs_cpu_up(area); + if (ret) + return notifier_from_errno(ret); break; case CPU_DEAD: case CPU_UP_CANCELED: area = &per_cpu(zs_map_area, cpu); - if (area->vm_buf) - free_page((unsigned long)area->vm_buf); - area->vm_buf = NULL; + __zs_cpu_down(area); break; } @@ -759,6 +849,7 @@ void *zs_map_object(struct zs_pool *pool, unsigned long handle, enum fullness_group fg; struct size_class *class; struct mapping_area *area; + struct page *pages[2]; BUG_ON(!handle); @@ -775,19 +866,19 @@ void *zs_map_object(struct zs_pool *pool, unsigned long handle, off = obj_idx_to_offset(page, obj_idx, class->size); area = &get_cpu_var(zs_map_area); + area->vm_mm = mm; if (off + class->size <= PAGE_SIZE) { /* this object is contained entirely within a page */ area->vm_addr = kmap_atomic(page); return area->vm_addr + off; } - /* disable page faults to match kmap_atomic() return conditions */ - pagefault_disable(); + /* this object spans two pages */ + pages[0] = page; + pages[1] = get_next_page(page); + BUG_ON(!pages[1]); - if (mm != ZS_MM_WO) - zs_copy_map_object(area->vm_buf, page, off, class->size); - area->vm_addr = NULL; - return area->vm_buf; + return __zs_map_object(area, pages, off, class->size); } EXPORT_SYMBOL_GPL(zs_map_object); @@ -801,17 +892,6 @@ void zs_unmap_object(struct zs_pool *pool, unsigned long handle) struct size_class *class; struct mapping_area *area; - area = &__get_cpu_var(zs_map_area); - /* single-page object fastpath */ - if (area->vm_addr) { - kunmap_atomic(area->vm_addr); - goto out; - } - - /* no write fastpath */ - if (area->vm_mm == ZS_MM_RO) - goto pfenable; - BUG_ON(!handle); obj_handle_to_location(handle, &page, &obj_idx); @@ -819,12 +899,18 @@ void zs_unmap_object(struct zs_pool *pool, unsigned long handle) class = &pool->size_class[class_idx]; off = obj_idx_to_offset(page, obj_idx, class->size); - zs_copy_unmap_object(area->vm_buf, page, off, class->size); + area = &__get_cpu_var(zs_map_area); + if (off + class->size <= PAGE_SIZE) + kunmap_atomic(area->vm_addr); + else { + struct page *pages[2]; + + pages[0] = page; + pages[1] = get_next_page(page); + BUG_ON(!pages[1]); -pfenable: - /* enable page faults to match kunmap_atomic() return conditions */ - pagefault_enable(); -out: + __zs_unmap_object(area, pages, off, class->size); + } put_cpu_var(zs_map_area); } EXPORT_SYMBOL_GPL(zs_unmap_object); diff --git a/drivers/staging/zsmalloc/zsmalloc_int.h b/drivers/staging/zsmalloc/zsmalloc_int.h index 52805176..8c0b344 100644 --- a/drivers/staging/zsmalloc/zsmalloc_int.h +++ b/drivers/staging/zsmalloc/zsmalloc_int.h @@ -109,12 +109,6 @@ enum fullness_group { */ static const int fullness_threshold_frac = 4; -struct mapping_area { - char *vm_buf; /* copy buffer for objects that span pages */ - char *vm_addr; /* address of kmap_atomic()'ed pages */ - enum zs_mapmode vm_mm; /* mapping mode */ -}; - struct size_class { /* * Size of objects stored in this class. Must be multiple -- cgit v0.10.2 From 18978952c1815c0d6c25f0d8849c67204074b3e2 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Mon, 30 Jul 2012 23:07:16 +0200 Subject: staging: ft1000: Fix ft1000_control function timeout argument usage. Function ft1000_control have input argument timeout which was not passed to usb_control_msg instead hardcoded to LARGE_TIMEOUT. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 31929ef..21c5ed6 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -73,7 +73,7 @@ static int ft1000_control(struct ft1000_device *ft1000dev, unsigned int pipe, } ret = usb_control_msg(ft1000dev->dev, pipe, request, requesttype, - value, index, data, size, LARGE_TIMEOUT); + value, index, data, size, timeout); if (ret > 0) ret = 0; -- cgit v0.10.2 From b0add95059a87baa855633412075475e100575ca Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Mon, 30 Jul 2012 23:07:17 +0200 Subject: staging: ft1000: Replace timeout values with USB_CTRL_G(S)ET_TIMEOUT. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 21c5ed6..809fa48 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -110,7 +110,7 @@ int ft1000_read_register(struct ft1000_device *ft1000dev, u16* Data, nRegIndx, Data, 2, - LARGE_TIMEOUT); + USB_CTRL_GET_TIMEOUT); return ret; } @@ -143,7 +143,7 @@ int ft1000_write_register(struct ft1000_device *ft1000dev, u16 value, nRegIndx, NULL, 0, - LARGE_TIMEOUT); + USB_CTRL_SET_TIMEOUT); return ret; } @@ -178,7 +178,7 @@ int ft1000_read_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, indx, buffer, cnt, - LARGE_TIMEOUT); + USB_CTRL_GET_TIMEOUT); return ret; } @@ -215,7 +215,7 @@ int ft1000_write_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, indx, buffer, cnt, - LARGE_TIMEOUT); + USB_CTRL_SET_TIMEOUT); return ret; } @@ -255,7 +255,7 @@ int ft1000_read_dpram16(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, indx, buffer, 2, - LARGE_TIMEOUT); + USB_CTRL_GET_TIMEOUT); return ret; } @@ -294,7 +294,7 @@ int ft1000_write_dpram16(struct ft1000_device *ft1000dev, u16 indx, u16 value, u indx, NULL, 0, - LARGE_TIMEOUT); + USB_CTRL_SET_TIMEOUT); return ret; } diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h index 642bb89..2aa6a1c 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h @@ -36,8 +36,6 @@ struct app_info_block { #define FT1000_STATUS_CLOSING 0x01 -#define LARGE_TIMEOUT 5000 - #define DSPBCMSGID 0x10 /* Electrabuzz specific DPRAM mapping */ -- cgit v0.10.2 From db2c8da02a2175fe2d129aa55fb0b790ec07a1ac Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Fri, 10 Aug 2012 01:37:31 +0900 Subject: staging: rtl8192e: Fix typo in staging/rtl8192e Correct spelling typo in staging/rtl8192e. Signed-off-by: Masanari Iida Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c index 481b1e4..1853665 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c @@ -202,7 +202,7 @@ static void dm_check_ac_dc_power(struct net_device *dev) if (priv->ResetProgress == RESET_TYPE_SILENT) { RT_TRACE((COMP_INIT | COMP_POWER | COMP_RF), - "GPIOChangeRFWorkItemCallBack(): Silent Reseting!!!!!!!\n"); + "GPIOChangeRFWorkItemCallBack(): Silent Reset!!!!!!!\n"); return; } diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h index d7460ae..9ac8d8e 100644 --- a/drivers/staging/rtl8192e/rtllib.h +++ b/drivers/staging/rtl8192e/rtllib.h @@ -2397,12 +2397,12 @@ struct rtllib_device { struct rtllib_network *network, u16 type); int (*is_qos_active)(struct net_device *dev, struct sk_buff *skb); - /* Softmac-generated frames (mamagement) are TXed via this + /* Softmac-generated frames (management) are TXed via this * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is * not set. As some cards may have different HW queues that * one might want to use for data and management frames * the option to have two callbacks might be useful. - * This fucntion can't sleep. + * This function can't sleep. */ int (*softmac_hard_start_xmit)(struct sk_buff *skb, struct net_device *dev); @@ -2441,9 +2441,9 @@ struct rtllib_device { * it is called in a work_queue when switching to ad-hoc mode * or in behalf of iwlist scan when the card is associated * and root user ask for a scan. - * the fucntion stop_scan should stop both the syncro and + * the function stop_scan should stop both the syncro and * background scanning and can sleep. - * The fucntion start_scan should initiate the background + * The function start_scan should initiate the background * scanning and can't sleep. */ void (*scan_syncro)(struct net_device *dev); diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c index a21b4d9..7c95518 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac.c +++ b/drivers/staging/rtl8192e/rtllib_softmac.c @@ -1687,7 +1687,7 @@ inline void rtllib_softmac_new_net(struct rtllib_device *ieee, * if the network does broadcast and the user did set essid * check if essid match * if the ap is not set, check that the user set the bssid - * and the network does bradcast and that those two bssid match + * and the network does broadcast and that those two bssid match */ if ((apset && apmatch && ((ssidset && ssidbroad && ssidmatch) || @@ -2442,7 +2442,7 @@ inline int rtllib_rx_frame_softmac(struct rtllib_device *ieee, return 0; } -/* following are for a simplier TX queue management. +/* following are for a simpler TX queue management. * Instead of using netif_[stop/wake]_queue the driver * will use these two functions (plus a reset one), that * will internally use the kernel netif_* and takes -- cgit v0.10.2 From 3d604a398c2b9b7c2df06228da77ea293047d31f Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Fri, 10 Aug 2012 01:06:54 +0900 Subject: staging: rtl8187se: Fix typo in staging/rtl8187se Correct spelling typo and adjust comment line length. Signed-off-by: Masanari Iida Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211.h b/drivers/staging/rtl8187se/ieee80211/ieee80211.h index b94c48b..5f5a3022 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211.h @@ -1094,7 +1094,7 @@ struct ieee80211_device { int (*reset_port)(struct net_device *dev); - /* Softmac-generated frames (mamagement) are TXed via this + /* Softmac-generated frames (management) are TXed via this * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is * not set. As some cards may have different HW queues that * one might want to use for data and management frames diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index fd22b75..20e5fb5 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c @@ -2377,7 +2377,7 @@ void rtl8180_wmm_param_update(struct work_struct *work) u8 u1bAIFS; u32 u4bAcParam; pAcParam = (PAC_PARAM)(&AcParam); - /* Retrieve paramters to update. */ + /* Retrieve parameters to update. */ u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN * (((mode&IEEE_G) == IEEE_G) ? 9 : 20) + aSifsTime; u4bAcParam = ((((u32)(pAcParam->f.TXOPLimit))<f.Ecw.f.ECWmax))<f.AciAifsn.f.ACI; /* Mode G/A: slotTimeTimer = 9; Mode B: 20 */ u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN * (((mode&IEEE_G) == IEEE_G) ? 9 : 20) + aSifsTime; diff --git a/drivers/staging/rtl8187se/r8180_hw.h b/drivers/staging/rtl8187se/r8180_hw.h index 3fca144..5339381 100644 --- a/drivers/staging/rtl8187se/r8180_hw.h +++ b/drivers/staging/rtl8187se/r8180_hw.h @@ -554,11 +554,16 @@ /* by amy for power save */ /* by amy for antenna */ #define EEPROM_SW_REVD_OFFSET 0x3f -/* BIT[8-9] is for SW Antenna Diversity. Only the value EEPROM_SW_AD_ENABLE means enable, other values are diable. */ + +/* BIT[8-9] is for SW Antenna Diversity. + * Only the value EEPROM_SW_AD_ENABLE means enable, other values are disable. + */ #define EEPROM_SW_AD_MASK 0x0300 #define EEPROM_SW_AD_ENABLE 0x0100 -/* BIT[10-11] determine if Antenna 1 is the Default Antenna. Only the value EEPROM_DEF_ANT_1 means TRUE, other values are FALSE. */ +/* BIT[10-11] determine if Antenna 1 is the Default Antenna. + * Only the value EEPROM_DEF_ANT_1 means TRUE, other values are FALSE. + */ #define EEPROM_DEF_ANT_MASK 0x0C00 #define EEPROM_DEF_ANT_1 0x0400 /*by amy for antenna */ diff --git a/drivers/staging/rtl8187se/r8185b_init.c b/drivers/staging/rtl8187se/r8185b_init.c index 9144957..bf34319 100644 --- a/drivers/staging/rtl8187se/r8185b_init.c +++ b/drivers/staging/rtl8187se/r8185b_init.c @@ -1008,7 +1008,7 @@ void ActUpdateChannelAccessSetting(struct net_device *dev, u8 u1bAIFS; u32 u4bAcParam; - /* Retrieve paramters to update. */ + /* Retrieve parameters to update. */ eACI = pAcParam->f.AciAifsn.f.ACI; u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN * ChnlAccessSetting->SlotTimeTimer + aSifsTime; u4bAcParam = ((((u32)(pAcParam->f.TXOPLimit)) << AC_PARAM_TXOP_LIMIT_OFFSET) | -- cgit v0.10.2 From 935d59ff255896515741c1e5f00f28e630d1c3cf Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Fri, 10 Aug 2012 23:24:11 +0900 Subject: staging: rtl8192u: Fix typo in staging/rtl8192u Correct spelling typo in staging/rtl8192u Signed-off-by: Masanari Iida Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211.h b/drivers/staging/rtl8192u/ieee80211/ieee80211.h index 1c0a1db..13f45c3 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211.h @@ -2114,7 +2114,7 @@ struct ieee80211_device { struct ieee80211_network * network, u16 type); int (*is_qos_active) (struct net_device *dev, struct sk_buff *skb); - /* Softmac-generated frames (mamagement) are TXed via this + /* Softmac-generated frames (management) are TXed via this * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is * not set. As some cards may have different HW queues that * one might want to use for data and management frames @@ -2192,7 +2192,7 @@ struct ieee80211_device { int (*handle_assoc_response) (struct net_device * dev, struct ieee80211_assoc_response_frame * resp, struct ieee80211_network * network); - /* check whether Tx hw resouce available */ + /* check whether Tx hw resource available */ short (*check_nic_enough_desc)(struct net_device *dev, int queue_index); //added by wb for HT related // void (*SwChnlByTimerHandler)(struct net_device *dev, int channel); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c index f6ff8cf..a6adfc9 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c @@ -1448,7 +1448,7 @@ inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee ( apset && apmatch && ((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset)) ) || /* if the ap is not set, check that the user set the bssid - * and the network does bradcast and that those two bssid matches + * and the network does broadcast and that those two bssid matches */ (!apset && ssidset && ssidbroad && ssidmatch) ){ @@ -2520,7 +2520,7 @@ void ieee80211_associate_retry_wq(struct work_struct *work) /* until we do not set the state to IEEE80211_NOLINK * there are no possibility to have someone else trying - * to start an association procdure (we get here with + * to start an association procedure (we get here with * ieee->state = IEEE80211_ASSOCIATING). * When we set the state to IEEE80211_NOLINK it is possible * that the RX path run an attempt to associate, but diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c index 27d083a..1ebea3d 100644 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c +++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c @@ -1,6 +1,6 @@ /******************************************************************************************************************************** * This file is created to process BA Action Frame. According to 802.11 spec, there are 3 BA action types at all. And as BA is - * related to TS, this part need some struture defined in QOS side code. Also TX RX is going to be resturctured, so how to send + * related to TS, this part need some structure defined in QOS side code. Also TX RX is going to be resturctured, so how to send * ADDBAREQ ADDBARSP and DELBA packet is still on consideration. Temporarily use MANAGE QUEUE instead of Normal Queue. * WB 2008-05-27 * *****************************************************************************************************************************/ diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_HT.h b/drivers/staging/rtl8192u/ieee80211/rtl819x_HT.h index 0b1a1fc..a60b39c 100644 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_HT.h +++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_HT.h @@ -15,7 +15,7 @@ #define HT_OPMODE_MIXED 3 // -// MIMO Power Save Setings +// MIMO Power Save Settings // #define MIMO_PS_STATIC 0 #define MIMO_PS_DYNAMIC 1 @@ -242,7 +242,7 @@ typedef struct _RT_HIGH_THROUGHPUT{ u8 bEnableHT; u8 bCurrentHTSupport; - u8 bRegBW40MHz; // Tx 40MHz channel capablity + u8 bRegBW40MHz; // Tx 40MHz channel capability u8 bCurBW40MHz; // Tx 40MHz channel capability u8 bRegShortGI40MHz; // Tx Short GI for 40Mhz diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c index e88a839..ebb5239 100644 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c +++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c @@ -912,7 +912,7 @@ u8 HTFilterMCSRate( struct ieee80211_device* ieee, u8* pSupportMCS, u8* pOperate u8 i=0; - // filter out operational rate set not supported by AP, the lenth of it is 16 + // filter out operational rate set not supported by AP, the length of it is 16 for(i=0;i<=15;i++){ pOperateMCS[i] = ieee->Regdot11HTOperationalRateSet[i]&pSupportMCS[i]; } diff --git a/drivers/staging/rtl8192u/r819xU_HTType.h b/drivers/staging/rtl8192u/r819xU_HTType.h index e07f8b1..6c1d05e 100644 --- a/drivers/staging/rtl8192u/r819xU_HTType.h +++ b/drivers/staging/rtl8192u/r819xU_HTType.h @@ -16,7 +16,7 @@ #define HT_OPMODE_MIXED 3 // -// MIMO Power Save Setings +// MIMO Power Save Settings // #define MIMO_PS_STATIC 0 #define MIMO_PS_DYNAMIC 1 diff --git a/drivers/staging/rtl8192u/r819xU_phyreg.h b/drivers/staging/rtl8192u/r819xU_phyreg.h index 50f24dc..cca34c0 100644 --- a/drivers/staging/rtl8192u/r819xU_phyreg.h +++ b/drivers/staging/rtl8192u/r819xU_phyreg.h @@ -443,7 +443,7 @@ #define bCCKRxIG 0x7f00 #define bCCKLNAPolarity 0x800000 #define bCCKRx1stGain 0x7f0000 -#define bCCKRFExtend 0x20000000 //CCK Rx inital gain polarity +#define bCCKRFExtend 0x20000000 //CCK Rx initial gain polarity #define bCCKRxAGCSatLevel 0x1f000000 #define bCCKRxAGCSatCount 0xe0 #define bCCKRxRFSettle 0x1f //AGCsamp_dly -- cgit v0.10.2 From fafbc202cd3c6ff1dc77430176c4c41102ebbdfd Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Tue, 7 Aug 2012 21:44:54 +0200 Subject: staging: speakup: i18n.c: Fix leak in msg_set() If we end up returning -EINVAL from the function we will leak the memory allocated to 'newstr' which has been allocated but not yet assigned to anything. Fix the leak by properly freeing the memory again before we return. Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/speakup/i18n.c b/drivers/staging/speakup/i18n.c index ca01734..7c1658b 100644 --- a/drivers/staging/speakup/i18n.c +++ b/drivers/staging/speakup/i18n.c @@ -555,6 +555,7 @@ ssize_t msg_set(enum msg_index_t index, char *text, size_t length) && index <= MSG_FORMATTED_END) && !fmt_validate(speakup_default_msgs[index], newstr)) { + kfree(newstr); return -EINVAL; } spk_lock(flags); -- cgit v0.10.2 From 4ec2601f6f383c8684f21562c0906e15c0dbccdd Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 6 Aug 2012 08:00:27 -0700 Subject: staging "usbip" Fix typos. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/usbip/stub_rx.c b/drivers/staging/usbip/stub_rx.c index 1d5b3fc..694cfd7 100644 --- a/drivers/staging/usbip/stub_rx.c +++ b/drivers/staging/usbip/stub_rx.c @@ -155,7 +155,7 @@ static int tweak_set_configuration_cmd(struct urb *urb) * eventually reassigned to the device as far as driver matching * condition is kept. * - * Unfortunatelly, an existing usbip connection will be dropped + * Unfortunately, an existing usbip connection will be dropped * due to this driver unbinding. So, skip here. * A user may need to set a special configuration value before * exporting the device. diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c index 12a9a5f..a5b028d 100644 --- a/drivers/staging/usbip/vhci_hcd.c +++ b/drivers/staging/usbip/vhci_hcd.c @@ -828,11 +828,11 @@ static void vhci_shutdown_connection(struct usbip_device *ud) * disable endpoints. pending urbs are unlinked(dequeued). * * NOTE: After calling rh_port_disconnect(), the USB device drivers of a - * deteched device should release used urbs in a cleanup function(i.e. + * detached device should release used urbs in a cleanup function (i.e. * xxx_disconnect()). Therefore, vhci_hcd does not need to release * pushed urbs and their private data in this function. * - * NOTE: vhci_dequeue() must be considered carefully. When shutdowning + * NOTE: vhci_dequeue() must be considered carefully. When shutting down * a connection, vhci_shutdown_connection() expects vhci_dequeue() * gives back pushed urbs and frees their private data by request of * the cleanup function of a USB driver. When unlinking a urb with an -- cgit v0.10.2 From 0959c63f11c3bbef0a7d6c5011be8d25503f547c Mon Sep 17 00:00:00 2001 From: Seth Jennings Date: Wed, 8 Aug 2012 15:12:17 +0900 Subject: zsmalloc: collapse internal .h into .c The patch collapses in the internal zsmalloc_int.h into the zsmalloc-main.c file. This is done in preparation for the promotion to mm/ where separate internal headers are discouraged. Signed-off-by: Seth Jennings Signed-off-by: Minchan Kim Acked-by: Nitin Gupta Reviewed-by: Konrad Rzeszutek Wilk Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/zsmalloc/zsmalloc-main.c b/drivers/staging/zsmalloc/zsmalloc-main.c index defe350..09a9d35 100644 --- a/drivers/staging/zsmalloc/zsmalloc-main.c +++ b/drivers/staging/zsmalloc/zsmalloc-main.c @@ -76,9 +76,139 @@ #include #include #include +#include +#include #include "zsmalloc.h" -#include "zsmalloc_int.h" + +/* + * This must be power of 2 and greater than of equal to sizeof(link_free). + * These two conditions ensure that any 'struct link_free' itself doesn't + * span more than 1 page which avoids complex case of mapping 2 pages simply + * to restore link_free pointer values. + */ +#define ZS_ALIGN 8 + +/* + * A single 'zspage' is composed of up to 2^N discontiguous 0-order (single) + * pages. ZS_MAX_ZSPAGE_ORDER defines upper limit on N. + */ +#define ZS_MAX_ZSPAGE_ORDER 2 +#define ZS_MAX_PAGES_PER_ZSPAGE (_AC(1, UL) << ZS_MAX_ZSPAGE_ORDER) + +/* + * Object location (, ) is encoded as + * as single (void *) handle value. + * + * Note that object index is relative to system + * page it is stored in, so for each sub-page belonging + * to a zspage, obj_idx starts with 0. + * + * This is made more complicated by various memory models and PAE. + */ + +#ifndef MAX_PHYSMEM_BITS +#ifdef CONFIG_HIGHMEM64G +#define MAX_PHYSMEM_BITS 36 +#else /* !CONFIG_HIGHMEM64G */ +/* + * If this definition of MAX_PHYSMEM_BITS is used, OBJ_INDEX_BITS will just + * be PAGE_SHIFT + */ +#define MAX_PHYSMEM_BITS BITS_PER_LONG +#endif +#endif +#define _PFN_BITS (MAX_PHYSMEM_BITS - PAGE_SHIFT) +#define OBJ_INDEX_BITS (BITS_PER_LONG - _PFN_BITS) +#define OBJ_INDEX_MASK ((_AC(1, UL) << OBJ_INDEX_BITS) - 1) + +#define MAX(a, b) ((a) >= (b) ? (a) : (b)) +/* ZS_MIN_ALLOC_SIZE must be multiple of ZS_ALIGN */ +#define ZS_MIN_ALLOC_SIZE \ + MAX(32, (ZS_MAX_PAGES_PER_ZSPAGE << PAGE_SHIFT >> OBJ_INDEX_BITS)) +#define ZS_MAX_ALLOC_SIZE PAGE_SIZE + +/* + * On systems with 4K page size, this gives 254 size classes! There is a + * trader-off here: + * - Large number of size classes is potentially wasteful as free page are + * spread across these classes + * - Small number of size classes causes large internal fragmentation + * - Probably its better to use specific size classes (empirically + * determined). NOTE: all those class sizes must be set as multiple of + * ZS_ALIGN to make sure link_free itself never has to span 2 pages. + * + * ZS_MIN_ALLOC_SIZE and ZS_SIZE_CLASS_DELTA must be multiple of ZS_ALIGN + * (reason above) + */ +#define ZS_SIZE_CLASS_DELTA 16 +#define ZS_SIZE_CLASSES ((ZS_MAX_ALLOC_SIZE - ZS_MIN_ALLOC_SIZE) / \ + ZS_SIZE_CLASS_DELTA + 1) + +/* + * We do not maintain any list for completely empty or full pages + */ +enum fullness_group { + ZS_ALMOST_FULL, + ZS_ALMOST_EMPTY, + _ZS_NR_FULLNESS_GROUPS, + + ZS_EMPTY, + ZS_FULL +}; + +/* + * We assign a page to ZS_ALMOST_EMPTY fullness group when: + * n <= N / f, where + * n = number of allocated objects + * N = total number of objects zspage can store + * f = 1/fullness_threshold_frac + * + * Similarly, we assign zspage to: + * ZS_ALMOST_FULL when n > N / f + * ZS_EMPTY when n == 0 + * ZS_FULL when n == N + * + * (see: fix_fullness_group()) + */ +static const int fullness_threshold_frac = 4; + +struct size_class { + /* + * Size of objects stored in this class. Must be multiple + * of ZS_ALIGN. + */ + int size; + unsigned int index; + + /* Number of PAGE_SIZE sized pages to combine to form a 'zspage' */ + int pages_per_zspage; + + spinlock_t lock; + + /* stats */ + u64 pages_allocated; + + struct page *fullness_list[_ZS_NR_FULLNESS_GROUPS]; +}; + +/* + * Placed within free objects to form a singly linked list. + * For every zspage, first_page->freelist gives head of this list. + * + * This must be power of 2 and less than or equal to ZS_ALIGN + */ +struct link_free { + /* Handle of next free chunk (encodes ) */ + void *next; +}; + +struct zs_pool { + struct size_class size_class[ZS_SIZE_CLASSES]; + + gfp_t flags; /* allocation flags used when growing pool */ + const char *name; +}; /* * A zspage's class index and fullness group diff --git a/drivers/staging/zsmalloc/zsmalloc_int.h b/drivers/staging/zsmalloc/zsmalloc_int.h deleted file mode 100644 index 8c0b344..0000000 --- a/drivers/staging/zsmalloc/zsmalloc_int.h +++ /dev/null @@ -1,149 +0,0 @@ -/* - * zsmalloc memory allocator - * - * Copyright (C) 2011 Nitin Gupta - * - * This code is released using a dual license strategy: BSD/GPL - * You can choose the license that better fits your requirements. - * - * Released under the terms of 3-clause BSD License - * Released under the terms of GNU General Public License Version 2.0 - */ - -#ifndef _ZS_MALLOC_INT_H_ -#define _ZS_MALLOC_INT_H_ - -#include -#include -#include - -/* - * This must be power of 2 and greater than of equal to sizeof(link_free). - * These two conditions ensure that any 'struct link_free' itself doesn't - * span more than 1 page which avoids complex case of mapping 2 pages simply - * to restore link_free pointer values. - */ -#define ZS_ALIGN 8 - -/* - * A single 'zspage' is composed of up to 2^N discontiguous 0-order (single) - * pages. ZS_MAX_ZSPAGE_ORDER defines upper limit on N. - */ -#define ZS_MAX_ZSPAGE_ORDER 2 -#define ZS_MAX_PAGES_PER_ZSPAGE (_AC(1, UL) << ZS_MAX_ZSPAGE_ORDER) - -/* - * Object location (, ) is encoded as - * as single (void *) handle value. - * - * Note that object index is relative to system - * page it is stored in, so for each sub-page belonging - * to a zspage, obj_idx starts with 0. - * - * This is made more complicated by various memory models and PAE. - */ - -#ifndef MAX_PHYSMEM_BITS -#ifdef CONFIG_HIGHMEM64G -#define MAX_PHYSMEM_BITS 36 -#else /* !CONFIG_HIGHMEM64G */ -/* - * If this definition of MAX_PHYSMEM_BITS is used, OBJ_INDEX_BITS will just - * be PAGE_SHIFT - */ -#define MAX_PHYSMEM_BITS BITS_PER_LONG -#endif -#endif -#define _PFN_BITS (MAX_PHYSMEM_BITS - PAGE_SHIFT) -#define OBJ_INDEX_BITS (BITS_PER_LONG - _PFN_BITS) -#define OBJ_INDEX_MASK ((_AC(1, UL) << OBJ_INDEX_BITS) - 1) - -#define MAX(a, b) ((a) >= (b) ? (a) : (b)) -/* ZS_MIN_ALLOC_SIZE must be multiple of ZS_ALIGN */ -#define ZS_MIN_ALLOC_SIZE \ - MAX(32, (ZS_MAX_PAGES_PER_ZSPAGE << PAGE_SHIFT >> OBJ_INDEX_BITS)) -#define ZS_MAX_ALLOC_SIZE PAGE_SIZE - -/* - * On systems with 4K page size, this gives 254 size classes! There is a - * trader-off here: - * - Large number of size classes is potentially wasteful as free page are - * spread across these classes - * - Small number of size classes causes large internal fragmentation - * - Probably its better to use specific size classes (empirically - * determined). NOTE: all those class sizes must be set as multiple of - * ZS_ALIGN to make sure link_free itself never has to span 2 pages. - * - * ZS_MIN_ALLOC_SIZE and ZS_SIZE_CLASS_DELTA must be multiple of ZS_ALIGN - * (reason above) - */ -#define ZS_SIZE_CLASS_DELTA 16 -#define ZS_SIZE_CLASSES ((ZS_MAX_ALLOC_SIZE - ZS_MIN_ALLOC_SIZE) / \ - ZS_SIZE_CLASS_DELTA + 1) - -/* - * We do not maintain any list for completely empty or full pages - */ -enum fullness_group { - ZS_ALMOST_FULL, - ZS_ALMOST_EMPTY, - _ZS_NR_FULLNESS_GROUPS, - - ZS_EMPTY, - ZS_FULL -}; - -/* - * We assign a page to ZS_ALMOST_EMPTY fullness group when: - * n <= N / f, where - * n = number of allocated objects - * N = total number of objects zspage can store - * f = 1/fullness_threshold_frac - * - * Similarly, we assign zspage to: - * ZS_ALMOST_FULL when n > N / f - * ZS_EMPTY when n == 0 - * ZS_FULL when n == N - * - * (see: fix_fullness_group()) - */ -static const int fullness_threshold_frac = 4; - -struct size_class { - /* - * Size of objects stored in this class. Must be multiple - * of ZS_ALIGN. - */ - int size; - unsigned int index; - - /* Number of PAGE_SIZE sized pages to combine to form a 'zspage' */ - int pages_per_zspage; - - spinlock_t lock; - - /* stats */ - u64 pages_allocated; - - struct page *fullness_list[_ZS_NR_FULLNESS_GROUPS]; -}; - -/* - * Placed within free objects to form a singly linked list. - * For every zspage, first_page->freelist gives head of this list. - * - * This must be power of 2 and less than or equal to ZS_ALIGN - */ -struct link_free { - /* Handle of next free chunk (encodes ) */ - void *next; -}; - -struct zs_pool { - struct size_class size_class[ZS_SIZE_CLASSES]; - - gfp_t flags; /* allocation flags used when growing pool */ - const char *name; -}; - -#endif -- cgit v0.10.2 From 8e3829c61b489933e58f671ac111a2f1980563d4 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 7 Aug 2012 08:55:00 +0100 Subject: staging:iio:adis16220: Use kobj_to_dev instead of open-coding it Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c index 575f1af..c31e1ec 100644 --- a/drivers/staging/iio/accel/adis16220_core.c +++ b/drivers/staging/iio/accel/adis16220_core.c @@ -372,8 +372,7 @@ static ssize_t adis16220_accel_bin_read(struct file *filp, struct kobject *kobj, loff_t off, size_t count) { - struct device *dev = container_of(kobj, struct device, kobj); - struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(kobj_to_dev(kobj)); return adis16220_capture_buffer_read(indio_dev, buf, off, count, @@ -394,8 +393,7 @@ static ssize_t adis16220_adc1_bin_read(struct file *filp, struct kobject *kobj, char *buf, loff_t off, size_t count) { - struct device *dev = container_of(kobj, struct device, kobj); - struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(kobj_to_dev(kobj)); return adis16220_capture_buffer_read(indio_dev, buf, off, count, @@ -416,8 +414,7 @@ static ssize_t adis16220_adc2_bin_read(struct file *filp, struct kobject *kobj, char *buf, loff_t off, size_t count) { - struct device *dev = container_of(kobj, struct device, kobj); - struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(kobj_to_dev(kobj)); return adis16220_capture_buffer_read(indio_dev, buf, off, count, -- cgit v0.10.2 From f4e4b9558bc696cc89de460e754d3fecb50b13cb Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 9 Aug 2012 08:51:00 +0100 Subject: staging:iio: Constify static iio_chan_spec arrays The per driver iio_chan_spec arrays are usually shared between multiple device instances. So a single device instance may not modify the iio_chan_spec array since this would also affect the other device instances. To make this restriction explicit mark the per driver iio_chan_spec arrays as const. Conversion was done automatically using the following coccinelle semantic patch: // @disable optional_qualifier@ identifier channels; @@ static +const struct iio_chan_spec channels[] = ...; // Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/accel/adis16201_core.c b/drivers/staging/iio/accel/adis16201_core.c index 204106b..ec2332f 100644 --- a/drivers/staging/iio/accel/adis16201_core.c +++ b/drivers/staging/iio/accel/adis16201_core.c @@ -390,7 +390,7 @@ static int adis16201_write_raw(struct iio_dev *indio_dev, return -EINVAL; } -static struct iio_chan_spec adis16201_channels[] = { +static const struct iio_chan_spec adis16201_channels[] = { { .type = IIO_VOLTAGE, .indexed = 1, diff --git a/drivers/staging/iio/accel/adis16203_core.c b/drivers/staging/iio/accel/adis16203_core.c index 22085e9..34b76c5 100644 --- a/drivers/staging/iio/accel/adis16203_core.c +++ b/drivers/staging/iio/accel/adis16203_core.c @@ -355,7 +355,7 @@ static int adis16203_read_raw(struct iio_dev *indio_dev, } } -static struct iio_chan_spec adis16203_channels[] = { +static const struct iio_chan_spec adis16203_channels[] = { { .type = IIO_VOLTAGE, .indexed = 1, diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c index 5f2e5f1..02fb101 100644 --- a/drivers/staging/iio/accel/adis16204_core.c +++ b/drivers/staging/iio/accel/adis16204_core.c @@ -397,7 +397,7 @@ static int adis16204_write_raw(struct iio_dev *indio_dev, return -EINVAL; } -static struct iio_chan_spec adis16204_channels[] = { +static const struct iio_chan_spec adis16204_channels[] = { { .type = IIO_VOLTAGE, .indexed = 1, /* Note was not previously indexed */ diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c index 4945705..4fa2229 100644 --- a/drivers/staging/iio/accel/adis16209_core.c +++ b/drivers/staging/iio/accel/adis16209_core.c @@ -390,7 +390,7 @@ static int adis16209_read_raw(struct iio_dev *indio_dev, return -EINVAL; } -static struct iio_chan_spec adis16209_channels[] = { +static const struct iio_chan_spec adis16209_channels[] = { { .type = IIO_VOLTAGE, .indexed = 1, diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c index b30b787..dafc0d8 100644 --- a/drivers/staging/iio/accel/adis16240_core.c +++ b/drivers/staging/iio/accel/adis16240_core.c @@ -448,7 +448,7 @@ static int adis16240_write_raw(struct iio_dev *indio_dev, return -EINVAL; } -static struct iio_chan_spec adis16240_channels[] = { +static const struct iio_chan_spec adis16240_channels[] = { { .type = IIO_VOLTAGE, .indexed = 1, diff --git a/drivers/staging/iio/accel/kxsd9.c b/drivers/staging/iio/accel/kxsd9.c index 8cf7cd9..713469f 100644 --- a/drivers/staging/iio/accel/kxsd9.c +++ b/drivers/staging/iio/accel/kxsd9.c @@ -186,7 +186,7 @@ error_ret: .address = KXSD9_REG_##axis, \ } -static struct iio_chan_spec kxsd9_channels[] = { +static const struct iio_chan_spec kxsd9_channels[] = { KXSD9_ACCEL_CHAN(X), KXSD9_ACCEL_CHAN(Y), KXSD9_ACCEL_CHAN(Z), { .type = IIO_VOLTAGE, diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c index 9d26348..0c2b4ba 100644 --- a/drivers/staging/iio/accel/lis3l02dq_core.c +++ b/drivers/staging/iio/accel/lis3l02dq_core.c @@ -538,7 +538,7 @@ static irqreturn_t lis3l02dq_event_handler(int irq, void *private) .event_mask = LIS3L02DQ_EVENT_MASK, \ } -static struct iio_chan_spec lis3l02dq_channels[] = { +static const struct iio_chan_spec lis3l02dq_channels[] = { LIS3L02DQ_CHAN(0, IIO_MOD_X), LIS3L02DQ_CHAN(1, IIO_MOD_Y), LIS3L02DQ_CHAN(2, IIO_MOD_Z), diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c index c218d71..cc040e1 100644 --- a/drivers/staging/iio/accel/sca3000_core.c +++ b/drivers/staging/iio/accel/sca3000_core.c @@ -450,7 +450,7 @@ static IIO_DEVICE_ATTR(revision, S_IRUGO, sca3000_show_rev, NULL, 0); .event_mask = SCA3000_EVENT_MASK, \ } -static struct iio_chan_spec sca3000_channels[] = { +static const struct iio_chan_spec sca3000_channels[] = { SCA3000_CHAN(0, IIO_MOD_X), SCA3000_CHAN(1, IIO_MOD_Y), SCA3000_CHAN(2, IIO_MOD_Z), diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index 22c3923..e381d4b 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c @@ -967,7 +967,7 @@ static const struct iio_info ad7195_info = { .scan_index = _si, \ .scan_type = IIO_ST('s', 24, 32, 0)} -static struct iio_chan_spec ad7192_channels[] = { +static const struct iio_chan_spec ad7192_channels[] = { AD7192_CHAN_DIFF(1, 2, NULL, AD7192_CH_AIN1P_AIN2M, 0), AD7192_CHAN_DIFF(3, 4, NULL, AD7192_CH_AIN3P_AIN4M, 1), AD7192_CHAN_TEMP(0, AD7192_CH_TEMP, 2), diff --git a/drivers/staging/iio/adc/ad7298_core.c b/drivers/staging/iio/adc/ad7298_core.c index 6141f4a..4c75114 100644 --- a/drivers/staging/iio/adc/ad7298_core.c +++ b/drivers/staging/iio/adc/ad7298_core.c @@ -38,7 +38,7 @@ }, \ } -static struct iio_chan_spec ad7298_channels[] = { +static const struct iio_chan_spec ad7298_channels[] = { { .type = IIO_TEMP, .indexed = 1, diff --git a/drivers/staging/iio/adc/ad7606.h b/drivers/staging/iio/adc/ad7606.h index 10f5989..9221a74 100644 --- a/drivers/staging/iio/adc/ad7606.h +++ b/drivers/staging/iio/adc/ad7606.h @@ -51,7 +51,7 @@ struct ad7606_platform_data { struct ad7606_chip_info { const char *name; u16 int_vref_mv; - struct iio_chan_spec *channels; + const struct iio_chan_spec *channels; unsigned num_channels; }; diff --git a/drivers/staging/iio/adc/ad7606_core.c b/drivers/staging/iio/adc/ad7606_core.c index ccb97fe..bae61cb 100644 --- a/drivers/staging/iio/adc/ad7606_core.c +++ b/drivers/staging/iio/adc/ad7606_core.c @@ -241,7 +241,7 @@ static const struct attribute_group ad7606_attribute_group_range = { .scan_type = IIO_ST('s', 16, 16, 0), \ } -static struct iio_chan_spec ad7606_8_channels[] = { +static const struct iio_chan_spec ad7606_8_channels[] = { AD7606_CHANNEL(0), AD7606_CHANNEL(1), AD7606_CHANNEL(2), @@ -253,7 +253,7 @@ static struct iio_chan_spec ad7606_8_channels[] = { IIO_CHAN_SOFT_TIMESTAMP(8), }; -static struct iio_chan_spec ad7606_6_channels[] = { +static const struct iio_chan_spec ad7606_6_channels[] = { AD7606_CHANNEL(0), AD7606_CHANNEL(1), AD7606_CHANNEL(2), @@ -263,7 +263,7 @@ static struct iio_chan_spec ad7606_6_channels[] = { IIO_CHAN_SOFT_TIMESTAMP(6), }; -static struct iio_chan_spec ad7606_4_channels[] = { +static const struct iio_chan_spec ad7606_4_channels[] = { AD7606_CHANNEL(0), AD7606_CHANNEL(1), AD7606_CHANNEL(2), diff --git a/drivers/staging/iio/adc/lpc32xx_adc.c b/drivers/staging/iio/adc/lpc32xx_adc.c index 348d051..7e9bd00 100644 --- a/drivers/staging/iio/adc/lpc32xx_adc.c +++ b/drivers/staging/iio/adc/lpc32xx_adc.c @@ -108,7 +108,7 @@ static const struct iio_info lpc32xx_adc_iio_info = { .scan_index = _index, \ } -static struct iio_chan_spec lpc32xx_adc_iio_channels[] = { +static const struct iio_chan_spec lpc32xx_adc_iio_channels[] = { LPC32XX_ADC_CHANNEL(0), LPC32XX_ADC_CHANNEL(1), LPC32XX_ADC_CHANNEL(2), diff --git a/drivers/staging/iio/adc/max1363.h b/drivers/staging/iio/adc/max1363.h index 2cd0112..c746918 100644 --- a/drivers/staging/iio/adc/max1363.h +++ b/drivers/staging/iio/adc/max1363.h @@ -100,7 +100,7 @@ enum max1363_modes { */ struct max1363_chip_info { const struct iio_info *info; - struct iio_chan_spec *channels; + const struct iio_chan_spec *channels; int num_channels; const enum max1363_modes *mode_list; enum max1363_modes default_mode; diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c index 6799ce2..816bb2c 100644 --- a/drivers/staging/iio/adc/max1363_core.c +++ b/drivers/staging/iio/adc/max1363_core.c @@ -335,12 +335,12 @@ static const enum max1363_modes max1363_mode_list[] = { IIO_CHAN_SOFT_TIMESTAMP(8) \ } -static struct iio_chan_spec max1036_channels[] = MAX1363_4X_CHANS(8, 0); -static struct iio_chan_spec max1136_channels[] = MAX1363_4X_CHANS(10, 0); -static struct iio_chan_spec max1236_channels[] = MAX1363_4X_CHANS(12, 0); -static struct iio_chan_spec max1361_channels[] = +static const struct iio_chan_spec max1036_channels[] = MAX1363_4X_CHANS(8, 0); +static const struct iio_chan_spec max1136_channels[] = MAX1363_4X_CHANS(10, 0); +static const struct iio_chan_spec max1236_channels[] = MAX1363_4X_CHANS(12, 0); +static const struct iio_chan_spec max1361_channels[] = MAX1363_4X_CHANS(10, MAX1363_EV_M); -static struct iio_chan_spec max1363_channels[] = +static const struct iio_chan_spec max1363_channels[] = MAX1363_4X_CHANS(12, MAX1363_EV_M); /* Applies to max1236, max1237 */ @@ -392,9 +392,9 @@ static const enum max1363_modes max1238_mode_list[] = { MAX1363_CHAN_B(11, 10, d11m10, 23, bits, 0), \ IIO_CHAN_SOFT_TIMESTAMP(24) \ } -static struct iio_chan_spec max1038_channels[] = MAX1363_12X_CHANS(8); -static struct iio_chan_spec max1138_channels[] = MAX1363_12X_CHANS(10); -static struct iio_chan_spec max1238_channels[] = MAX1363_12X_CHANS(12); +static const struct iio_chan_spec max1038_channels[] = MAX1363_12X_CHANS(8); +static const struct iio_chan_spec max1138_channels[] = MAX1363_12X_CHANS(10); +static const struct iio_chan_spec max1238_channels[] = MAX1363_12X_CHANS(12); static const enum max1363_modes max11607_mode_list[] = { _s0, _s1, _s2, _s3, @@ -433,9 +433,9 @@ static const enum max1363_modes max11608_mode_list[] = { MAX1363_CHAN_B(7, 6, d7m6, 15, bits, 0), \ IIO_CHAN_SOFT_TIMESTAMP(16) \ } -static struct iio_chan_spec max11602_channels[] = MAX1363_8X_CHANS(8); -static struct iio_chan_spec max11608_channels[] = MAX1363_8X_CHANS(10); -static struct iio_chan_spec max11614_channels[] = MAX1363_8X_CHANS(12); +static const struct iio_chan_spec max11602_channels[] = MAX1363_8X_CHANS(8); +static const struct iio_chan_spec max11608_channels[] = MAX1363_8X_CHANS(10); +static const struct iio_chan_spec max11614_channels[] = MAX1363_8X_CHANS(12); static const enum max1363_modes max11644_mode_list[] = { _s0, _s1, s0to1, d0m1, d1m0, @@ -449,8 +449,8 @@ static const enum max1363_modes max11644_mode_list[] = { IIO_CHAN_SOFT_TIMESTAMP(4) \ } -static struct iio_chan_spec max11646_channels[] = MAX1363_2X_CHANS(10); -static struct iio_chan_spec max11644_channels[] = MAX1363_2X_CHANS(12); +static const struct iio_chan_spec max11646_channels[] = MAX1363_2X_CHANS(10); +static const struct iio_chan_spec max11644_channels[] = MAX1363_2X_CHANS(12); enum { max1361, max1362, diff --git a/drivers/staging/iio/adc/spear_adc.c b/drivers/staging/iio/adc/spear_adc.c index 64d630e..675c427 100644 --- a/drivers/staging/iio/adc/spear_adc.c +++ b/drivers/staging/iio/adc/spear_adc.c @@ -189,7 +189,7 @@ static int spear_read_raw(struct iio_dev *indio_dev, }, \ } -static struct iio_chan_spec spear_adc_iio_channels[] = { +static const struct iio_chan_spec spear_adc_iio_channels[] = { SPEAR_ADC_CHAN(0), SPEAR_ADC_CHAN(1), SPEAR_ADC_CHAN(2), diff --git a/drivers/staging/iio/iio_simple_dummy.c b/drivers/staging/iio/iio_simple_dummy.c index 155a49a..22eea83 100644 --- a/drivers/staging/iio/iio_simple_dummy.c +++ b/drivers/staging/iio/iio_simple_dummy.c @@ -63,7 +63,7 @@ static const struct iio_dummy_accel_calibscale dummy_scales[] = { * This array of structures tells the IIO core about what the device * actually provides for a given channel. */ -static struct iio_chan_spec iio_dummy_channels[] = { +static const struct iio_chan_spec iio_dummy_channels[] = { /* indexed ADC channel in_voltage0_raw etc */ { .type = IIO_VOLTAGE, diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c index a8e51bc..e239ea9 100644 --- a/drivers/staging/iio/impedance-analyzer/ad5933.c +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c @@ -108,7 +108,7 @@ static struct ad5933_platform_data ad5933_default_pdata = { .vref_mv = 3300, }; -static struct iio_chan_spec ad5933_channels[] = { +static const struct iio_chan_spec ad5933_channels[] = { { .type = IIO_TEMP, .indexed = 1, diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c index 1f4c177..4ce9e3d 100644 --- a/drivers/staging/iio/imu/adis16400_core.c +++ b/drivers/staging/iio/imu/adis16400_core.c @@ -610,7 +610,7 @@ static int adis16400_read_raw(struct iio_dev *indio_dev, } } -static struct iio_chan_spec adis16400_channels[] = { +static const struct iio_chan_spec adis16400_channels[] = { { .type = IIO_VOLTAGE, .indexed = 1, @@ -740,7 +740,7 @@ static struct iio_chan_spec adis16400_channels[] = { IIO_CHAN_SOFT_TIMESTAMP(12) }; -static struct iio_chan_spec adis16350_channels[] = { +static const struct iio_chan_spec adis16350_channels[] = { { .type = IIO_VOLTAGE, .indexed = 1, @@ -865,7 +865,7 @@ static struct iio_chan_spec adis16350_channels[] = { IIO_CHAN_SOFT_TIMESTAMP(11) }; -static struct iio_chan_spec adis16300_channels[] = { +static const struct iio_chan_spec adis16300_channels[] = { { .type = IIO_VOLTAGE, .indexed = 1, diff --git a/drivers/staging/iio/meter/ade7758.h b/drivers/staging/iio/meter/ade7758.h index ec202b4..1e11ad5 100644 --- a/drivers/staging/iio/meter/ade7758.h +++ b/drivers/staging/iio/meter/ade7758.h @@ -122,7 +122,7 @@ struct ade7758_state { u8 *tx; u8 *rx; struct mutex buf_lock; - struct iio_chan_spec *ade7758_ring_channels; + const struct iio_chan_spec *ade7758_ring_channels; struct spi_transfer ring_xfer[4]; struct spi_message ring_msg; /* diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c index 7014a00..6d3725a 100644 --- a/drivers/staging/iio/meter/ade7758_core.c +++ b/drivers/staging/iio/meter/ade7758_core.c @@ -661,7 +661,7 @@ static const struct attribute_group ade7758_attribute_group = { .attrs = ade7758_attributes, }; -static struct iio_chan_spec ade7758_channels[] = { +static const struct iio_chan_spec ade7758_channels[] = { { .type = IIO_VOLTAGE, .indexed = 1, diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c index f313859..4ba4d05 100644 --- a/drivers/staging/iio/resolver/ad2s1210.c +++ b/drivers/staging/iio/resolver/ad2s1210.c @@ -575,7 +575,7 @@ static IIO_DEVICE_ATTR(lot_low_thrd, S_IRUGO | S_IWUSR, AD2S1210_REG_LOT_LOW_THRD); -static struct iio_chan_spec ad2s1210_channels[] = { +static const struct iio_chan_spec ad2s1210_channels[] = { { .type = IIO_ANGL, .indexed = 1, -- cgit v0.10.2 From d16f6dbddbd7a2ac40e090da1e6bb7dd9b5a1dcb Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sat, 21 Jul 2012 09:54:00 +0100 Subject: staging/iio: use module_platform_driver macro the code which under _init and _exit does only the platform_driver_register and platform_driver_unregister, and nothing else, so its better to use the module_platform_driver macro rather duplicating its implementation Signed-off-by: Devendra Naga Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/iio_hwmon.c b/drivers/staging/iio/iio_hwmon.c index 27d27ec..4bb017a 100644 --- a/drivers/staging/iio/iio_hwmon.c +++ b/drivers/staging/iio/iio_hwmon.c @@ -215,17 +215,7 @@ static struct platform_driver __refdata iio_hwmon_driver = { .remove = __devexit_p(iio_hwmon_remove), }; -static int iio_inkern_init(void) -{ - return platform_driver_register(&iio_hwmon_driver); -} -module_init(iio_inkern_init); - -static void iio_inkern_exit(void) -{ - platform_driver_unregister(&iio_hwmon_driver); -} -module_exit(iio_inkern_exit); +module_platform_driver(iio_hwmon_driver); MODULE_AUTHOR("Jonathan Cameron "); MODULE_DESCRIPTION("IIO to hwmon driver"); -- cgit v0.10.2 From 95605332997211f377af55d05209c3ef2b86bed1 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 13 Aug 2012 10:28:22 -0700 Subject: staging "vme" Fix typos. Signed-off-by: Justin P. Mattock Acked-by: Martyn Welch Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c index e25645e..0170788 100644 --- a/drivers/staging/vme/devices/vme_user.c +++ b/drivers/staging/vme/devices/vme_user.c @@ -64,13 +64,13 @@ static unsigned int bus_num; * * However the VME driver at http://www.vmelinux.org/ is rather old and doesn't * even support the tsi148 chipset (which has 8 master and 8 slave windows). - * We'll run with this or now as far as possible, however it probably makes + * We'll run with this for now as far as possible, however it probably makes * sense to get rid of the old mappings and just do everything dynamically. * * So for now, we'll restrict the driver to providing 4 masters and 4 slaves as * defined above and try to support at least some of the interface from - * http://www.vmelinux.org/ as an alternative drive can be written providing a - * saner interface later. + * http://www.vmelinux.org/ as an alternative the driver can be written + * providing a saner interface later. * * The vmelinux.org driver never supported slave images, the devices reserved * for slaves were repurposed to support all 8 master images on the UniverseII! @@ -242,7 +242,7 @@ static ssize_t resource_to_user(int minor, char __user *buf, size_t count, } /* - * We are going ot alloc a page during init per window for small transfers. + * We are going to alloc a page during init per window for small transfers. * Small transfers will go user space -> buffer -> VME. Larger (more than a * page) transfers will lock the user space buffer into memory and then * transfer the data directly from the user space buffers out to VME. -- cgit v0.10.2 From 2f123cbcf0ddaf526bd681081a1f2fe8c30ef59a Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 14 Aug 2012 10:04:45 +0300 Subject: Staging: xgifb: fix bitwise vs logical bug This is a static checker fix and not something I can test. The intent of the code here is to set some bit flags. For a logical OR the ">> 1" shift wouldn't make a difference. So it should be using a bitwise OR. Signed-off-by: Dan Carpenter Reviewed-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 80dba6a..fdb7d1a 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -1269,7 +1269,7 @@ static unsigned char GetXG27FPBits(struct vb_device_info *pVBInfo) if (temp <= 2) temp &= 0x03; else - temp = ((temp & 0x04) >> 1) || ((~temp) & 0x01); + temp = ((temp & 0x04) >> 1) | ((~temp) & 0x01); xgifb_reg_set(pVBInfo->P3d4, 0x4A, CR4A); -- cgit v0.10.2 From d99ff52ef1da75053de9e42a620930f74615f8ea Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Tue, 14 Aug 2012 16:31:27 +0100 Subject: staging: comedi: amplc_dio200: abbreviate IS_ENABLED() The IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_ISA) and IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_PCI) macro calls are a bit long-winded. Define a couple of macros DO_ISA and DO_PCI as abbreviations for them. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 6c81e377..0905e40 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -215,6 +215,9 @@ order they appear in the channel list. #define DIO200_DRIVER_NAME "amplc_dio200" +#define DO_ISA IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_ISA) +#define DO_PCI IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_PCI) + /* PCI IDs */ #define PCI_VENDOR_ID_AMPLICON 0x14dc #define PCI_DEVICE_ID_AMPLICON_PCI272 0x000a @@ -272,12 +275,12 @@ enum dio200_model { }; enum dio200_layout { -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_ISA) +#if DO_ISA pc212_layout, pc214_layout, #endif pc215_layout, -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_ISA) +#if DO_ISA pc218_layout, #endif pc272_layout @@ -292,7 +295,7 @@ struct dio200_board { }; static const struct dio200_board dio200_boards[] = { -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_ISA) +#if DO_ISA { .name = "pc212e", .bustype = isa_bustype, @@ -324,7 +327,7 @@ static const struct dio200_board dio200_boards[] = { .layout = pc272_layout, }, #endif -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_PCI) +#if DO_PCI { .name = "pci215", .devid = PCI_DEVICE_ID_AMPLICON_PCI215, @@ -367,7 +370,7 @@ struct dio200_layout_struct { }; static const struct dio200_layout_struct dio200_layouts[] = { -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_ISA) +#if DO_ISA [pc212_layout] = { .n_subdevs = 6, .sdtype = {sd_8255, sd_8254, sd_8254, sd_8254, @@ -396,7 +399,7 @@ static const struct dio200_layout_struct dio200_layouts[] = { .has_int_sce = 1, .has_clk_gat_sce = 1, }, -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_ISA) +#if DO_ISA [pc218_layout] = { .n_subdevs = 7, .sdtype = {sd_8254, sd_8254, sd_8255, sd_8254, @@ -1228,12 +1231,10 @@ static void dio200_report_attach(struct comedi_device *dev, unsigned int irq) char tmpbuf[60]; int tmplen; - if (IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_ISA) && - thisboard->bustype == isa_bustype) + if (DO_ISA && thisboard->bustype == isa_bustype) tmplen = scnprintf(tmpbuf, sizeof(tmpbuf), "(base %#lx) ", dev->iobase); - else if (IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_PCI) && - thisboard->bustype == pci_bustype) + else if (DO_PCI && thisboard->bustype == pci_bustype) tmplen = scnprintf(tmpbuf, sizeof(tmpbuf), "(pci %s) ", pci_name(pcidev)); else @@ -1361,8 +1362,7 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) } /* Process options and reserve resources according to bus type. */ - if (IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_ISA) && - thisboard->bustype == isa_bustype) { + if (DO_ISA && thisboard->bustype == isa_bustype) { unsigned long iobase; unsigned int irq; @@ -1372,8 +1372,7 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret < 0) return ret; return dio200_common_attach(dev, iobase, irq, 0); - } else if (IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_PCI) && - thisboard->bustype == pci_bustype) { + } else if (DO_PCI && thisboard->bustype == pci_bustype) { struct pci_dev *pci_dev; pci_dev = dio200_find_pci_dev(dev, it); @@ -1397,7 +1396,7 @@ static int __devinit dio200_attach_pci(struct comedi_device *dev, { int ret; - if (!IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_PCI)) + if (!DO_PCI) return -EINVAL; dev_info(dev->class_dev, DIO200_DRIVER_NAME ": attach pci %s\n", @@ -1470,7 +1469,7 @@ static struct comedi_driver amplc_dio200_driver = { .num_names = ARRAY_SIZE(dio200_boards), }; -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_PCI) +#if DO_PCI static DEFINE_PCI_DEVICE_TABLE(dio200_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI215) }, { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI272) }, -- cgit v0.10.2 From b7518888afc14e3d1e988837fef4471cd2b3c820 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Tue, 14 Aug 2012 16:31:29 +0100 Subject: staging: comedi: amplc_dio200: check bus type in detach routine When detaching the device in dio200_detach() mirror the bus type checks performed by dio200_attach(). The existing tests are safe but rely on dev->iobase being 0 when comedi_to_pci_dev(dev) is NULL. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 0905e40..7a61831 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -1417,7 +1417,6 @@ static int __devinit dio200_attach_pci(struct comedi_device *dev, static void dio200_detach(struct comedi_device *dev) { const struct dio200_board *thisboard = comedi_board(dev); - struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct dio200_layout_struct *layout; unsigned n; @@ -1442,13 +1441,16 @@ static void dio200_detach(struct comedi_device *dev) } } } - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - pci_dev_put(pcidev); - } else { + if (IS_ISA_BOARD(thisboard)) { if (dev->iobase) release_region(dev->iobase, DIO200_IO_SIZE); + } else if (IS_PCI_BOARD(thisboard)) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + if (pcidev) { + if (dev->iobase) + comedi_pci_disable(pcidev); + pci_dev_put(pcidev); + } } } -- cgit v0.10.2 From 858c8ada41c5ff9700f23c6b41adb9586f2983b8 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Tue, 14 Aug 2012 16:31:28 +0100 Subject: staging: comedi: amplc_dio200: add helper macros to check bus type Add helper macro IS_ISA_BOARD(board) to check if the driver supports ISA boards and this is an ISA board, and IS_PCI_BOARD(board) to check if the driver supports PCI boards and this is a PCI board. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 7a61831..f31d798 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -294,6 +294,9 @@ struct dio200_board { enum dio200_layout layout; }; +#define IS_ISA_BOARD(board) (DO_ISA && (board)->bustype == isa_bustype) +#define IS_PCI_BOARD(board) (DO_PCI && (board)->bustype == pci_bustype) + static const struct dio200_board dio200_boards[] = { #if DO_ISA { @@ -1231,10 +1234,10 @@ static void dio200_report_attach(struct comedi_device *dev, unsigned int irq) char tmpbuf[60]; int tmplen; - if (DO_ISA && thisboard->bustype == isa_bustype) + if (IS_ISA_BOARD(thisboard)) tmplen = scnprintf(tmpbuf, sizeof(tmpbuf), "(base %#lx) ", dev->iobase); - else if (DO_PCI && thisboard->bustype == pci_bustype) + else if (IS_PCI_BOARD(thisboard)) tmplen = scnprintf(tmpbuf, sizeof(tmpbuf), "(pci %s) ", pci_name(pcidev)); else @@ -1362,7 +1365,7 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) } /* Process options and reserve resources according to bus type. */ - if (DO_ISA && thisboard->bustype == isa_bustype) { + if (IS_ISA_BOARD(thisboard)) { unsigned long iobase; unsigned int irq; @@ -1372,7 +1375,7 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret < 0) return ret; return dio200_common_attach(dev, iobase, irq, 0); - } else if (DO_PCI && thisboard->bustype == pci_bustype) { + } else if (IS_PCI_BOARD(thisboard)) { struct pci_dev *pci_dev; pci_dev = dio200_find_pci_dev(dev, it); -- cgit v0.10.2 From 9291975d6647794710553630c2613b5658c81d3f Mon Sep 17 00:00:00 2001 From: Johannes Thumshirn Date: Tue, 14 Aug 2012 20:22:48 +0200 Subject: staging: line6: variax.c: Eliminated remaining strict_stroul()s Eliminated remaining calls to strict_stroul() and replaced them with strict_kstrtou8(). Signed-off-by: Johannes Thumshirn Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/line6/variax.c b/drivers/staging/line6/variax.c index bb99ee4..f97416b 100644 --- a/drivers/staging/line6/variax.c +++ b/drivers/staging/line6/variax.c @@ -353,10 +353,10 @@ static ssize_t variax_set_model(struct device *dev, { struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev)); - unsigned long value; + u8 value; int ret; - ret = strict_strtoul(buf, 10, &value); + ret = kstrtou8(buf, 10, &value); if (ret) return ret; @@ -387,10 +387,10 @@ static ssize_t variax_set_active(struct device *dev, { struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev)); - unsigned long value; + u8 value; int ret; - ret = strict_strtoul(buf, 10, &value); + ret = kstrtou8(buf, 10, &value); if (ret) return ret; -- cgit v0.10.2 From 69af59970bec925d182ca5ebd80e643fdd90b1cc Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Aug 2012 13:45:53 -0700 Subject: staging: comedi: adl_pci7x3x: fix pointer-to-int-cast warning This driver uses the void *private variable in the comedi_subdevice to pass the offset needed to read/write the appropriate register to get/set the channels for the subdevice. The adl_pci7x3x_do_insn_bits() and adl_pci7x3x_di_insn_bits() functions were retrieving this offset by casting the s->private value as an unsigned int. On 64-bit builds this results in a warning: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] Fix these warnings by casting the void * to an unsigned long. Signed-off-by: H Hartley Sweeten Reported-by: Greg Kroah-Hartman Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci7x3x.c b/drivers/staging/comedi/drivers/adl_pci7x3x.c index 990670a..41963fb 100644 --- a/drivers/staging/comedi/drivers/adl_pci7x3x.c +++ b/drivers/staging/comedi/drivers/adl_pci7x3x.c @@ -121,7 +121,7 @@ static int adl_pci7x3x_do_insn_bits(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - unsigned int reg = (unsigned int)s->private; + unsigned long reg = (unsigned long)s->private; unsigned int mask = data[0]; unsigned int bits = data[1]; @@ -147,7 +147,7 @@ static int adl_pci7x3x_di_insn_bits(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - unsigned int reg = (unsigned int)s->private; + unsigned long reg = (unsigned long)s->private; data[1] = inl(dev->iobase + reg); -- cgit v0.10.2 From 3c810c613a9d61eb70735cfb85fe5db6e0331bae Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Wed, 15 Aug 2012 15:18:01 -0500 Subject: staging: drm/omap: add rotation properties Use tiled buffers for rotated/reflected scanout, with CRTC and plane properties as the interface for userspace to configure rotation. Signed-off-by: Rob Clark Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/omapdrm/omap_crtc.c b/drivers/staging/omapdrm/omap_crtc.c index 62e0022..98a10bc 100644 --- a/drivers/staging/omapdrm/omap_crtc.c +++ b/drivers/staging/omapdrm/omap_crtc.c @@ -191,10 +191,18 @@ static int omap_crtc_page_flip_locked(struct drm_crtc *crtc, return 0; } +static int omap_crtc_set_property(struct drm_crtc *crtc, + struct drm_property *property, uint64_t val) +{ + struct omap_crtc *omap_crtc = to_omap_crtc(crtc); + return omap_plane_set_property(omap_crtc->plane, property, val); +} + static const struct drm_crtc_funcs omap_crtc_funcs = { .set_config = drm_crtc_helper_set_config, .destroy = omap_crtc_destroy, .page_flip = omap_crtc_page_flip_locked, + .set_property = omap_crtc_set_property, }; static const struct drm_crtc_helper_funcs omap_crtc_helper_funcs = { @@ -231,6 +239,8 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev, drm_crtc_init(dev, crtc, &omap_crtc_funcs); drm_crtc_helper_add(crtc, &omap_crtc_helper_funcs); + omap_plane_install_properties(omap_crtc->plane, &crtc->base); + return crtc; fail: diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c b/drivers/staging/omapdrm/omap_dmm_tiler.c index ec7a5c8..3ae3955 100644 --- a/drivers/staging/omapdrm/omap_dmm_tiler.c +++ b/drivers/staging/omapdrm/omap_dmm_tiler.c @@ -404,8 +404,26 @@ int tiler_release(struct tiler_block *block) * Utils */ -/* calculate the tiler space address of a pixel in a view orientation */ -static u32 tiler_get_address(u32 orient, enum tiler_fmt fmt, u32 x, u32 y) +/* calculate the tiler space address of a pixel in a view orientation... + * below description copied from the display subsystem section of TRM: + * + * When the TILER is addressed, the bits: + * [28:27] = 0x0 for 8-bit tiled + * 0x1 for 16-bit tiled + * 0x2 for 32-bit tiled + * 0x3 for page mode + * [31:29] = 0x0 for 0-degree view + * 0x1 for 180-degree view + mirroring + * 0x2 for 0-degree view + mirroring + * 0x3 for 180-degree view + * 0x4 for 270-degree view + mirroring + * 0x5 for 270-degree view + * 0x6 for 90-degree view + * 0x7 for 90-degree view + mirroring + * Otherwise the bits indicated the corresponding bit address to access + * the SDRAM. + */ +static u32 tiler_get_address(enum tiler_fmt fmt, u32 orient, u32 x, u32 y) { u32 x_bits, y_bits, tmp, x_mask, y_mask, alignment; @@ -417,8 +435,11 @@ static u32 tiler_get_address(u32 orient, enum tiler_fmt fmt, u32 x, u32 y) x_mask = MASK(x_bits); y_mask = MASK(y_bits); - if (x < 0 || x > x_mask || y < 0 || y > y_mask) + if (x < 0 || x > x_mask || y < 0 || y > y_mask) { + DBG("invalid coords: %u < 0 || %u > %u || %u < 0 || %u > %u", + x, x, x_mask, y, y, y_mask); return 0; + } /* account for mirroring */ if (orient & MASK_X_INVERT) @@ -439,11 +460,22 @@ dma_addr_t tiler_ssptr(struct tiler_block *block) { BUG_ON(!validfmt(block->fmt)); - return TILVIEW_8BIT + tiler_get_address(0, block->fmt, + return TILVIEW_8BIT + tiler_get_address(block->fmt, 0, block->area.p0.x * geom[block->fmt].slot_w, block->area.p0.y * geom[block->fmt].slot_h); } +dma_addr_t tiler_tsptr(struct tiler_block *block, uint32_t orient, + uint32_t x, uint32_t y) +{ + struct tcm_pt *p = &block->area.p0; + BUG_ON(!validfmt(block->fmt)); + + return tiler_get_address(block->fmt, orient, + (p->x * geom[block->fmt].slot_w) + x, + (p->y * geom[block->fmt].slot_h) + y); +} + void tiler_align(enum tiler_fmt fmt, uint16_t *w, uint16_t *h) { BUG_ON(!validfmt(fmt)); @@ -451,11 +483,14 @@ void tiler_align(enum tiler_fmt fmt, uint16_t *w, uint16_t *h) *h = round_up(*h, geom[fmt].slot_h); } -uint32_t tiler_stride(enum tiler_fmt fmt) +uint32_t tiler_stride(enum tiler_fmt fmt, uint32_t orient) { BUG_ON(!validfmt(fmt)); - return 1 << (CONT_WIDTH_BITS + geom[fmt].y_shft); + if (orient & MASK_XY_FLIP) + return 1 << (CONT_HEIGHT_BITS + geom[fmt].x_shft); + else + return 1 << (CONT_WIDTH_BITS + geom[fmt].y_shft); } size_t tiler_size(enum tiler_fmt fmt, uint16_t w, uint16_t h) diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.h b/drivers/staging/omapdrm/omap_dmm_tiler.h index 7b1052a..740911d 100644 --- a/drivers/staging/omapdrm/omap_dmm_tiler.h +++ b/drivers/staging/omapdrm/omap_dmm_tiler.h @@ -54,7 +54,18 @@ struct tiler_block { #define TILER_WIDTH (1 << (CONT_WIDTH_BITS - SLOT_WIDTH_BITS)) #define TILER_HEIGHT (1 << (CONT_HEIGHT_BITS - SLOT_HEIGHT_BITS)) -/* tiler space addressing bitfields */ +/* +Table 15-11. Coding and Description of TILER Orientations +S Y X Description Alternate description +0 0 0 0-degree view Natural view +0 0 1 0-degree view with vertical mirror 180-degree view with horizontal mirror +0 1 0 0-degree view with horizontal mirror 180-degree view with vertical mirror +0 1 1 180-degree view +1 0 0 90-degree view with vertical mirror 270-degree view with horizontal mirror +1 0 1 270-degree view +1 1 0 90-degree view +1 1 1 90-degree view with horizontal mirror 270-degree view with vertical mirror + */ #define MASK_XY_FLIP (1 << 31) #define MASK_Y_INVERT (1 << 30) #define MASK_X_INVERT (1 << 29) @@ -90,7 +101,9 @@ int tiler_release(struct tiler_block *block); /* utilities */ dma_addr_t tiler_ssptr(struct tiler_block *block); -uint32_t tiler_stride(enum tiler_fmt fmt); +dma_addr_t tiler_tsptr(struct tiler_block *block, uint32_t orient, + uint32_t x, uint32_t y); +uint32_t tiler_stride(enum tiler_fmt fmt, uint32_t orient); size_t tiler_size(enum tiler_fmt fmt, uint16_t w, uint16_t h); size_t tiler_vsize(enum tiler_fmt fmt, uint16_t w, uint16_t h); void tiler_align(enum tiler_fmt fmt, uint16_t *w, uint16_t *h); diff --git a/drivers/staging/omapdrm/omap_drv.c b/drivers/staging/omapdrm/omap_drv.c index 44149ee..b8e79eb 100644 --- a/drivers/staging/omapdrm/omap_drv.c +++ b/drivers/staging/omapdrm/omap_drv.c @@ -649,6 +649,8 @@ static int dev_firstopen(struct drm_device *dev) */ static void dev_lastclose(struct drm_device *dev) { + int i; + /* we don't support vga-switcheroo.. so just make sure the fbdev * mode is active */ @@ -657,6 +659,21 @@ static void dev_lastclose(struct drm_device *dev) DBG("lastclose: dev=%p", dev); + /* need to restore default rotation state.. not sure if there is + * a cleaner way to restore properties to default state? Maybe + * a flag that properties should automatically be restored to + * default state on lastclose? + */ + for (i = 0; i < priv->num_crtcs; i++) { + drm_object_property_set_value(&priv->crtcs[i]->base, + priv->rotation_prop, 0); + } + + for (i = 0; i < priv->num_planes; i++) { + drm_object_property_set_value(&priv->planes[i]->base, + priv->rotation_prop, 0); + } + ret = drm_fb_helper_restore_fbdev_mode(priv->fbdev); if (ret) DBG("failed to restore crtc mode"); diff --git a/drivers/staging/omapdrm/omap_drv.h b/drivers/staging/omapdrm/omap_drv.h index 2092a91..b103d28 100644 --- a/drivers/staging/omapdrm/omap_drv.h +++ b/drivers/staging/omapdrm/omap_drv.h @@ -59,6 +59,26 @@ struct omap_drm_private { struct list_head obj_list; bool has_dmm; + + /* properties: */ + struct drm_property *rotation_prop; +}; + +/* this should probably be in drm-core to standardize amongst drivers */ +#define DRM_ROTATE_0 0 +#define DRM_ROTATE_90 1 +#define DRM_ROTATE_180 2 +#define DRM_ROTATE_270 3 +#define DRM_REFLECT_X 4 +#define DRM_REFLECT_Y 5 + +/* parameters which describe (unrotated) coordinates of scanout within a fb: */ +struct omap_drm_window { + uint32_t rotation; + int32_t crtc_x, crtc_y; /* signed because can be offscreen */ + uint32_t crtc_w, crtc_h; + uint32_t src_x, src_y; + uint32_t src_w, src_h; }; #ifdef CONFIG_DEBUG_FS @@ -87,6 +107,10 @@ int omap_plane_mode_set(struct drm_plane *plane, uint32_t src_w, uint32_t src_h); void omap_plane_on_endwin(struct drm_plane *plane, void (*fxn)(void *), void *arg); +void omap_plane_install_properties(struct drm_plane *plane, + struct drm_mode_object *obj); +int omap_plane_set_property(struct drm_plane *plane, + struct drm_property *property, uint64_t val); struct drm_encoder *omap_encoder_init(struct drm_device *dev, struct omap_overlay_manager *mgr); @@ -114,8 +138,8 @@ struct drm_gem_object *omap_framebuffer_bo(struct drm_framebuffer *fb, int p); int omap_framebuffer_replace(struct drm_framebuffer *a, struct drm_framebuffer *b, void *arg, void (*unpin)(void *arg, struct drm_gem_object *bo)); -void omap_framebuffer_update_scanout(struct drm_framebuffer *fb, int x, int y, - struct omap_overlay_info *info); +void omap_framebuffer_update_scanout(struct drm_framebuffer *fb, + struct omap_drm_window *win, struct omap_overlay_info *info); struct drm_connector *omap_framebuffer_get_next_connector( struct drm_framebuffer *fb, struct drm_connector *from); void omap_framebuffer_flush(struct drm_framebuffer *fb, @@ -157,8 +181,12 @@ int omap_gem_get_pages(struct drm_gem_object *obj, struct page ***pages, bool remap); int omap_gem_put_pages(struct drm_gem_object *obj); uint32_t omap_gem_flags(struct drm_gem_object *obj); +int omap_gem_rotated_paddr(struct drm_gem_object *obj, uint32_t orient, + int x, int y, dma_addr_t *paddr); uint64_t omap_gem_mmap_offset(struct drm_gem_object *obj); size_t omap_gem_mmap_size(struct drm_gem_object *obj); +int omap_gem_tiled_size(struct drm_gem_object *obj, uint16_t *w, uint16_t *h); +int omap_gem_tiled_stride(struct drm_gem_object *obj, uint32_t orient); struct dma_buf * omap_gem_prime_export(struct drm_device *dev, struct drm_gem_object *obj, int flags); diff --git a/drivers/staging/omapdrm/omap_fb.c b/drivers/staging/omapdrm/omap_fb.c index 74260f0..446801d 100644 --- a/drivers/staging/omapdrm/omap_fb.c +++ b/drivers/staging/omapdrm/omap_fb.c @@ -18,6 +18,7 @@ */ #include "omap_drv.h" +#include "omap_dmm_tiler.h" #include "drm_crtc.h" #include "drm_crtc_helper.h" @@ -137,30 +138,100 @@ static const struct drm_framebuffer_funcs omap_framebuffer_funcs = { .dirty = omap_framebuffer_dirty, }; +static uint32_t get_linear_addr(struct plane *plane, + const struct format *format, int n, int x, int y) +{ + uint32_t offset; + + offset = plane->offset + + (x * format->planes[n].stride_bpp) + + (y * plane->pitch / format->planes[n].sub_y); + + return plane->paddr + offset; +} + /* update ovl info for scanout, handles cases of multi-planar fb's, etc. */ -void omap_framebuffer_update_scanout(struct drm_framebuffer *fb, int x, int y, - struct omap_overlay_info *info) +void omap_framebuffer_update_scanout(struct drm_framebuffer *fb, + struct omap_drm_window *win, struct omap_overlay_info *info) { struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb); const struct format *format = omap_fb->format; struct plane *plane = &omap_fb->planes[0]; - unsigned int offset; + uint32_t x, y, orient = 0; + + info->color_mode = format->dss_format; + + info->pos_x = win->crtc_x; + info->pos_y = win->crtc_y; + info->out_width = win->crtc_w; + info->out_height = win->crtc_h; + info->width = win->src_w; + info->height = win->src_h; + + x = win->src_x; + y = win->src_y; + + if (omap_gem_flags(plane->bo) & OMAP_BO_TILED) { + uint32_t w = win->src_w; + uint32_t h = win->src_h; + + switch (win->rotation & 0xf) { + default: + dev_err(fb->dev->dev, "invalid rotation: %02x", + (uint32_t)win->rotation); + /* fallthru to default to no rotation */ + case 0: + case BIT(DRM_ROTATE_0): + orient = 0; + break; + case BIT(DRM_ROTATE_90): + orient = MASK_XY_FLIP | MASK_X_INVERT; + break; + case BIT(DRM_ROTATE_180): + orient = MASK_X_INVERT | MASK_Y_INVERT; + break; + case BIT(DRM_ROTATE_270): + orient = MASK_XY_FLIP | MASK_Y_INVERT; + break; + } - offset = plane->offset + - (x * format->planes[0].stride_bpp) + - (y * plane->pitch / format->planes[0].sub_y); + if (win->rotation & BIT(DRM_REFLECT_X)) + orient ^= MASK_X_INVERT; + + if (win->rotation & BIT(DRM_REFLECT_Y)) + orient ^= MASK_Y_INVERT; + + /* adjust x,y offset for flip/invert: */ + if (orient & MASK_XY_FLIP) + swap(w, h); + if (orient & MASK_Y_INVERT) + y += h - 1; + if (orient & MASK_X_INVERT) + x += w - 1; - info->color_mode = format->dss_format; - info->paddr = plane->paddr + offset; - info->screen_width = plane->pitch / format->planes[0].stride_bpp; + omap_gem_rotated_paddr(plane->bo, orient, x, y, &info->paddr); + info->rotation_type = OMAP_DSS_ROT_TILER; + info->screen_width = omap_gem_tiled_stride(plane->bo, orient); + } else { + info->paddr = get_linear_addr(plane, format, 0, x, y); + info->rotation_type = OMAP_DSS_ROT_DMA; + info->screen_width = plane->pitch; + } + + /* convert to pixels: */ + info->screen_width /= format->planes[0].stride_bpp; if (format->dss_format == OMAP_DSS_COLOR_NV12) { plane = &omap_fb->planes[1]; - offset = plane->offset + - (x * format->planes[1].stride_bpp) + - (y * plane->pitch / format->planes[1].sub_y); - info->p_uv_addr = plane->paddr + offset; + + if (info->rotation_type == OMAP_DSS_ROT_TILER) { + WARN_ON(!(omap_gem_flags(plane->bo) & OMAP_BO_TILED)); + omap_gem_rotated_paddr(plane->bo, orient, + x/2, y/2, &info->p_uv_addr); + } else { + info->p_uv_addr = get_linear_addr(plane, format, 1, x, y); + } } else { info->p_uv_addr = 0; } @@ -377,7 +448,7 @@ struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev, size = pitch * mode_cmd->height / format->planes[i].sub_y; - if (size > (bos[i]->size - mode_cmd->offsets[i])) { + if (size > (omap_gem_mmap_size(bos[i]) - mode_cmd->offsets[i])) { dev_err(dev->dev, "provided buffer object is too small! %d < %d\n", bos[i]->size - mode_cmd->offsets[i], size); ret = -EINVAL; diff --git a/drivers/staging/omapdrm/omap_gem.c b/drivers/staging/omapdrm/omap_gem.c index 3a0d035..74082aa 100644 --- a/drivers/staging/omapdrm/omap_gem.c +++ b/drivers/staging/omapdrm/omap_gem.c @@ -339,6 +339,17 @@ size_t omap_gem_mmap_size(struct drm_gem_object *obj) return size; } +/* get tiled size, returns -EINVAL if not tiled buffer */ +int omap_gem_tiled_size(struct drm_gem_object *obj, uint16_t *w, uint16_t *h) +{ + struct omap_gem_object *omap_obj = to_omap_bo(obj); + if (omap_obj->flags & OMAP_BO_TILED) { + *w = omap_obj->width; + *h = omap_obj->height; + return 0; + } + return -EINVAL; +} /* Normal handling for the case of faulting in non-tiled buffers */ static int fault_1d(struct drm_gem_object *obj, @@ -832,6 +843,36 @@ fail: return ret; } +/* Get rotated scanout address (only valid if already pinned), at the + * specified orientation and x,y offset from top-left corner of buffer + * (only valid for tiled 2d buffers) + */ +int omap_gem_rotated_paddr(struct drm_gem_object *obj, uint32_t orient, + int x, int y, dma_addr_t *paddr) +{ + struct omap_gem_object *omap_obj = to_omap_bo(obj); + int ret = -EINVAL; + + mutex_lock(&obj->dev->struct_mutex); + if ((omap_obj->paddr_cnt > 0) && omap_obj->block && + (omap_obj->flags & OMAP_BO_TILED)) { + *paddr = tiler_tsptr(omap_obj->block, orient, x, y); + ret = 0; + } + mutex_unlock(&obj->dev->struct_mutex); + return ret; +} + +/* Get tiler stride for the buffer (only valid for 2d tiled buffers) */ +int omap_gem_tiled_stride(struct drm_gem_object *obj, uint32_t orient) +{ + struct omap_gem_object *omap_obj = to_omap_bo(obj); + int ret = -EINVAL; + if (omap_obj->flags & OMAP_BO_TILED) + ret = tiler_stride(gem2fmt(omap_obj->flags), orient); + return ret; +} + /* acquire pages when needed (for example, for DMA where physically * contiguous buffer is not required */ @@ -1402,7 +1443,7 @@ void omap_gem_init(struct drm_device *dev) */ usergart[i].height = h; usergart[i].height_shift = ilog2(h); - usergart[i].stride_pfn = tiler_stride(fmts[i]) >> PAGE_SHIFT; + usergart[i].stride_pfn = tiler_stride(fmts[i], 0) >> PAGE_SHIFT; usergart[i].slot_shift = ilog2((PAGE_SIZE / h) >> i); for (j = 0; j < NUM_USERGART_ENTRIES; j++) { struct usergart_entry *entry = &usergart[i].entry[j]; diff --git a/drivers/staging/omapdrm/omap_plane.c b/drivers/staging/omapdrm/omap_plane.c index 7997be7..6931d06 100644 --- a/drivers/staging/omapdrm/omap_plane.c +++ b/drivers/staging/omapdrm/omap_plane.c @@ -20,6 +20,7 @@ #include #include "omap_drv.h" +#include "omap_dmm_tiler.h" /* some hackery because omapdss has an 'enum omap_plane' (which would be * better named omap_plane_id).. and compiler seems unhappy about having @@ -43,10 +44,9 @@ struct omap_plane { struct omap_overlay *ovl; struct omap_overlay_info info; - /* Source values, converted to integers because we don't support - * fractional positions: - */ - unsigned int src_x, src_y; + /* position/orientation of scanout within the fb: */ + struct omap_drm_window win; + /* last fb that we pinned: */ struct drm_framebuffer *pinned_fb; @@ -289,6 +289,7 @@ static void update_scanout(struct drm_plane *plane) { struct omap_plane *omap_plane = to_omap_plane(plane); struct omap_overlay_info *info = &omap_plane->info; + struct omap_drm_window *win = &omap_plane->win; int ret; ret = update_pin(plane, plane->fb); @@ -299,11 +300,10 @@ static void update_scanout(struct drm_plane *plane) return; } - omap_framebuffer_update_scanout(plane->fb, - omap_plane->src_x, omap_plane->src_y, info); + omap_framebuffer_update_scanout(plane->fb, win, info); DBG("%s: %d,%d: %08x %08x (%d)", omap_plane->ovl->name, - omap_plane->src_x, omap_plane->src_y, + win->src_x, win->src_y, (u32)info->paddr, (u32)info->p_uv_addr, info->screen_width); } @@ -316,21 +316,18 @@ int omap_plane_mode_set(struct drm_plane *plane, uint32_t src_w, uint32_t src_h) { struct omap_plane *omap_plane = to_omap_plane(plane); + struct omap_drm_window *win = &omap_plane->win; + + win->crtc_x = crtc_x; + win->crtc_y = crtc_y; + win->crtc_w = crtc_w; + win->crtc_h = crtc_h; /* src values are in Q16 fixed point, convert to integer: */ - src_x = src_x >> 16; - src_y = src_y >> 16; - src_w = src_w >> 16; - src_h = src_h >> 16; - - omap_plane->info.pos_x = crtc_x; - omap_plane->info.pos_y = crtc_y; - omap_plane->info.out_width = crtc_w; - omap_plane->info.out_height = crtc_h; - omap_plane->info.width = src_w; - omap_plane->info.height = src_h; - omap_plane->src_x = src_x; - omap_plane->src_y = src_y; + win->src_x = src_x >> 16; + win->src_y = src_y >> 16; + win->src_w = src_w >> 16; + win->src_h = src_h >> 16; /* note: this is done after this fxn returns.. but if we need * to do a commit/update_scanout, etc before this returns we @@ -359,6 +356,8 @@ static int omap_plane_update(struct drm_plane *plane, static int omap_plane_disable(struct drm_plane *plane) { + struct omap_plane *omap_plane = to_omap_plane(plane); + omap_plane->win.rotation = BIT(DRM_ROTATE_0); return omap_plane_dpms(plane, DRM_MODE_DPMS_OFF); } @@ -409,10 +408,60 @@ void omap_plane_on_endwin(struct drm_plane *plane, install_irq(plane); } +/* helper to install properties which are common to planes and crtcs */ +void omap_plane_install_properties(struct drm_plane *plane, + struct drm_mode_object *obj) +{ + struct drm_device *dev = plane->dev; + struct omap_drm_private *priv = dev->dev_private; + struct drm_property *prop; + + prop = priv->rotation_prop; + if (!prop) { + const struct drm_prop_enum_list props[] = { + { DRM_ROTATE_0, "rotate-0" }, + { DRM_ROTATE_90, "rotate-90" }, + { DRM_ROTATE_180, "rotate-180" }, + { DRM_ROTATE_270, "rotate-270" }, + { DRM_REFLECT_X, "reflect-x" }, + { DRM_REFLECT_Y, "reflect-y" }, + }; + prop = drm_property_create_bitmask(dev, 0, "rotation", + props, ARRAY_SIZE(props)); + if (prop == NULL) + return; + priv->rotation_prop = prop; + } + drm_object_attach_property(obj, prop, 0); +} + +int omap_plane_set_property(struct drm_plane *plane, + struct drm_property *property, uint64_t val) +{ + struct omap_plane *omap_plane = to_omap_plane(plane); + struct omap_drm_private *priv = plane->dev->dev_private; + int ret = -EINVAL; + + if (property == priv->rotation_prop) { + struct omap_overlay *ovl = omap_plane->ovl; + + DBG("%s: rotation: %02x", ovl->name, (uint32_t)val); + omap_plane->win.rotation = val; + + if (ovl->is_enabled(ovl)) + ret = omap_plane_dpms(plane, DRM_MODE_DPMS_ON); + else + ret = 0; + } + + return ret; +} + static const struct drm_plane_funcs omap_plane_funcs = { .update_plane = omap_plane_update, .disable_plane = omap_plane_disable, .destroy = omap_plane_destroy, + .set_property = omap_plane_set_property, }; /* initialize plane */ @@ -455,6 +504,8 @@ struct drm_plane *omap_plane_init(struct drm_device *dev, drm_plane_init(dev, plane, possible_crtcs, &omap_plane_funcs, omap_plane->formats, omap_plane->nformats, priv); + omap_plane_install_properties(plane, &plane->base); + /* get our starting configuration, set defaults for parameters * we don't currently use, etc: */ @@ -463,7 +514,6 @@ struct drm_plane *omap_plane_init(struct drm_device *dev, omap_plane->info.rotation = OMAP_DSS_ROT_0; omap_plane->info.global_alpha = 0xff; omap_plane->info.mirror = 0; - omap_plane->info.mirror = 0; /* Set defaults depending on whether we are a CRTC or overlay * layer. -- cgit v0.10.2 From 8451b5adae5ca9b5f022cfdd029b7a5b5283f2ce Mon Sep 17 00:00:00 2001 From: Andre Renaud Date: Wed, 15 Aug 2012 15:18:02 -0500 Subject: staging: omapdrm: Expose the OMAP Z-Order property through DRM Added support for zorder changes through DRM plane properties Signed-off-by: Andre Renaud Signed-off-by: Rob Clark Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/omapdrm/omap_drv.h b/drivers/staging/omapdrm/omap_drv.h index b103d28..9dc72d1 100644 --- a/drivers/staging/omapdrm/omap_drv.h +++ b/drivers/staging/omapdrm/omap_drv.h @@ -62,6 +62,7 @@ struct omap_drm_private { /* properties: */ struct drm_property *rotation_prop; + struct drm_property *zorder_prop; }; /* this should probably be in drm-core to standardize amongst drivers */ diff --git a/drivers/staging/omapdrm/omap_plane.c b/drivers/staging/omapdrm/omap_plane.c index 6931d06..4bde639 100644 --- a/drivers/staging/omapdrm/omap_plane.c +++ b/drivers/staging/omapdrm/omap_plane.c @@ -433,6 +433,15 @@ void omap_plane_install_properties(struct drm_plane *plane, priv->rotation_prop = prop; } drm_object_attach_property(obj, prop, 0); + + prop = priv->zorder_prop; + if (!prop) { + prop = drm_property_create_range(dev, 0, "zorder", 0, 3); + if (prop == NULL) + return; + priv->zorder_prop = prop; + } + drm_object_attach_property(obj, prop, 0); } int omap_plane_set_property(struct drm_plane *plane, @@ -452,6 +461,16 @@ int omap_plane_set_property(struct drm_plane *plane, ret = omap_plane_dpms(plane, DRM_MODE_DPMS_ON); else ret = 0; + } else if (property == priv->zorder_prop) { + struct omap_overlay *ovl = omap_plane->ovl; + + DBG("%s: zorder: %d", ovl->name, (uint32_t)val); + omap_plane->info.zorder = val; + + if (ovl->is_enabled(ovl)) + ret = omap_plane_dpms(plane, DRM_MODE_DPMS_ON); + else + ret = 0; } return ret; -- cgit v0.10.2 From af0677c14e990e64bd6571be691e0bebd82a5dc0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Aug 2012 18:23:24 -0700 Subject: staging: comedi: dnya_pci10xx: remove thisboard and devpriv macros These macros rely on local variables having a specific name. Replace them with local variables where used. Use the comedi_board() helper to get the thisboard pointer. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index 064be9a..7884a94 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -104,9 +104,6 @@ struct dyna_pci10xx_private { unsigned long BADR3; }; -#define thisboard ((const struct boardtype *)dev->board_ptr) -#define devpriv ((struct dyna_pci10xx_private *)dev->private) - /******************************************************************************/ /************************** READ WRITE FUNCTIONS ******************************/ /******************************************************************************/ @@ -116,6 +113,8 @@ static int dyna_pci10xx_insn_read_ai(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + const struct boardtype *thisboard = comedi_board(dev); + struct dyna_pci10xx_private *devpriv = dev->private; int n, counter; u16 d = 0; unsigned int chan, range; @@ -159,6 +158,8 @@ static int dyna_pci10xx_insn_write_ao(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + const struct boardtype *thisboard = comedi_board(dev); + struct dyna_pci10xx_private *devpriv = dev->private; int n; unsigned int chan, range; @@ -181,6 +182,7 @@ static int dyna_pci10xx_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct dyna_pci10xx_private *devpriv = dev->private; u16 d = 0; mutex_lock(&devpriv->mutex); @@ -200,6 +202,8 @@ static int dyna_pci10xx_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct dyna_pci10xx_private *devpriv = dev->private; + /* The insn data is a mask in data[0] and the new data * in data[1], each channel cooresponding to a bit. * s->state contains the previous write data @@ -257,20 +261,22 @@ static struct pci_dev *dyna_pci10xx_find_pci_dev(struct comedi_device *dev, static int dyna_pci10xx_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct boardtype *thisboard; + struct dyna_pci10xx_private *devpriv; struct pci_dev *pcidev; struct comedi_subdevice *s; int ret; - if (alloc_private(dev, sizeof(struct dyna_pci10xx_private)) < 0) { - printk(KERN_ERR "comedi: dyna_pci10xx: " - "failed to allocate memory!\n"); - return -ENOMEM; - } + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; + devpriv = dev->private; pcidev = dyna_pci10xx_find_pci_dev(dev, it); if (!pcidev) return -EIO; comedi_set_hw_dev(dev, &pcidev->dev); + thisboard = comedi_board(dev); dev->board_name = thisboard->name; dev->irq = 0; @@ -342,6 +348,7 @@ static int dyna_pci10xx_attach(struct comedi_device *dev, static void dyna_pci10xx_detach(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct dyna_pci10xx_private *devpriv = dev->private; if (devpriv) mutex_destroy(&devpriv->mutex); -- cgit v0.10.2 From 690e839fc4915a372f2338b148c36d8949822253 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Aug 2012 18:23:49 -0700 Subject: staging: comedi: dnya_pci10xx: use attach_pci callback Convert this PCI driver to use the comedi PCI auto config attach mechanism by adding an attach_pci callback function. Since the driver does not require any external configuration options, disable the legacy attach by making the attach simply return -ENOSYS. This removes the need to walk the pci bus to find the pci_dev and the need for the pci_dev_put() in the detach. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index 7884a94..15048aa 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -227,73 +227,49 @@ static int dyna_pci10xx_do_insn_bits(struct comedi_device *dev, return insn->n; } -static struct pci_dev *dyna_pci10xx_find_pci_dev(struct comedi_device *dev, - struct comedi_devconfig *it) +static const void *dyna_pci10xx_find_boardinfo(struct comedi_device *dev, + struct pci_dev *pcidev) { - struct pci_dev *pcidev = NULL; - int bus = it->options[0]; - int slot = it->options[1]; + const struct boardtype *thisboard; int i; - for_each_pci_dev(pcidev) { - if (bus || slot) { - if (bus != pcidev->bus->number || - slot != PCI_SLOT(pcidev->devfn)) - continue; - } - if (pcidev->vendor != PCI_VENDOR_ID_DYNALOG) - continue; - - for (i = 0; i < ARRAY_SIZE(boardtypes); ++i) { - if (pcidev->device != boardtypes[i].device_id) - continue; - - dev->board_ptr = &boardtypes[i]; - return pcidev; - } + for (i = 0; i < ARRAY_SIZE(boardtypes); ++i) { + thisboard = &boardtypes[i]; + if (pcidev->device != thisboard->device_id) + return thisboard; } - dev_err(dev->class_dev, - "No supported board found! (req. bus %d, slot %d)\n", - bus, slot); return NULL; } -static int dyna_pci10xx_attach(struct comedi_device *dev, - struct comedi_devconfig *it) +static int dyna_pci10xx_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) { const struct boardtype *thisboard; struct dyna_pci10xx_private *devpriv; - struct pci_dev *pcidev; struct comedi_subdevice *s; int ret; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; - - pcidev = dyna_pci10xx_find_pci_dev(dev, it); - if (!pcidev) - return -EIO; comedi_set_hw_dev(dev, &pcidev->dev); - thisboard = comedi_board(dev); + thisboard = dyna_pci10xx_find_boardinfo(dev, pcidev); + if (!thisboard) + return -ENODEV; + dev->board_ptr = thisboard; dev->board_name = thisboard->name; - dev->irq = 0; - - if (comedi_pci_enable(pcidev, DRV_NAME)) { - printk(KERN_ERR "comedi: dyna_pci10xx: " - "failed to enable PCI device and request regions!"); - return -EIO; - } - - mutex_init(&devpriv->mutex); - printk(KERN_INFO "comedi: dyna_pci10xx: device found!\n"); + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; + devpriv = dev->private; + ret = comedi_pci_enable(pcidev, dev->board_name); + if (ret) + return ret; dev->iobase = pci_resource_start(pcidev, 2); devpriv->BADR3 = pci_resource_start(pcidev, 3); + mutex_init(&devpriv->mutex); + ret = comedi_alloc_subdevices(dev, 4); if (ret) return ret; @@ -339,10 +315,19 @@ static int dyna_pci10xx_attach(struct comedi_device *dev, s->state = 0; s->insn_bits = dyna_pci10xx_do_insn_bits; - printk(KERN_INFO "comedi: dyna_pci10xx: %s - device setup completed!\n", - thisboard->name); + dev_info(dev->class_dev, "%s: %s attached\n", + dev->driver->driver_name, dev->board_name); + + return 0; +} + +static int dyna_pci10xx_attach(struct comedi_device *dev, + struct comedi_devconfig *it) +{ + dev_warn(dev->class_dev, + "This driver does not support attach using comedi_config\n"); - return 1; + return -ENOSYS; } static void dyna_pci10xx_detach(struct comedi_device *dev) @@ -355,7 +340,6 @@ static void dyna_pci10xx_detach(struct comedi_device *dev) if (pcidev) { if (dev->iobase) comedi_pci_disable(pcidev); - pci_dev_put(pcidev); } } @@ -363,10 +347,8 @@ static struct comedi_driver dyna_pci10xx_driver = { .driver_name = "dyna_pci10xx", .module = THIS_MODULE, .attach = dyna_pci10xx_attach, + .attach_pci = dyna_pci10xx_attach_pci, .detach = dyna_pci10xx_detach, - .board_name = &boardtypes[0].name, - .offset = sizeof(struct boardtype), - .num_names = ARRAY_SIZE(boardtypes), }; static int __devinit dyna_pci10xx_pci_probe(struct pci_dev *dev, -- cgit v0.10.2 From f2eacff1369c46c7c4dab595a460dd9ec40e51db Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Aug 2012 18:24:19 -0700 Subject: staging: comedi: dnya_pci10xx: cleanup the analog output range The analog output channels on this board only support a single range, 0-10V unipolar. This range is available as an exported symbol from the comedi core and "range_unipolar10". Use that instead of duplicating the range in this driver and remove the information from the boardinfo. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index 15048aa..abfbb12 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -54,13 +54,6 @@ static const struct comedi_lrange range_pci1050_ai = { 3, { static const char range_codes_pci1050_ai[] = { 0x00, 0x10, 0x30 }; -static const struct comedi_lrange range_pci1050_ao = { 1, { - UNI_RANGE(10) - } -}; - -static const char range_codes_pci1050_ao[] = { 0x00 }; - struct boardtype { const char *name; int device_id; @@ -74,8 +67,6 @@ struct boardtype { int do_bits; const struct comedi_lrange *range_ai; const char *range_codes_ai; - const struct comedi_lrange *range_ao; - const char *range_codes_ao; }; static const struct boardtype boardtypes[] = { @@ -92,8 +83,6 @@ static const struct boardtype boardtypes[] = { .do_bits = 16, .range_ai = &range_pci1050_ai, .range_codes_ai = range_codes_pci1050_ai, - .range_ao = &range_pci1050_ao, - .range_codes_ao = range_codes_pci1050_ao, }, /* dummy entry corresponding to driver name */ {.name = DRV_NAME}, @@ -290,7 +279,7 @@ static int dyna_pci10xx_attach_pci(struct comedi_device *dev, s->subdev_flags = SDF_WRITABLE; s->n_chan = thisboard->ao_chans; s->maxdata = 0x0FFF; - s->range_table = thisboard->range_ao; + s->range_table = &range_unipolar10; s->len_chanlist = 16; s->insn_write = dyna_pci10xx_insn_write_ao; -- cgit v0.10.2 From 4884f724c3f78eac7ea814fbd71545b45577a1be Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Aug 2012 18:24:47 -0700 Subject: staging: comedi: dnya_pci10xx: remove unused fields in the boardinfo The *_bits information in the boardinfo is not used by the driver. Remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index abfbb12..80bfae5 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -58,13 +58,9 @@ struct boardtype { const char *name; int device_id; int ai_chans; - int ai_bits; int ao_chans; - int ao_bits; int di_chans; - int di_bits; int do_chans; - int do_bits; const struct comedi_lrange *range_ai; const char *range_codes_ai; }; @@ -74,13 +70,9 @@ static const struct boardtype boardtypes[] = { .name = "dyna_pci1050", .device_id = 0x1050, .ai_chans = 16, - .ai_bits = 12, .ao_chans = 16, - .ao_bits = 12, .di_chans = 16, - .di_bits = 16, .do_chans = 16, - .do_bits = 16, .range_ai = &range_pci1050_ai, .range_codes_ai = range_codes_pci1050_ai, }, -- cgit v0.10.2 From 8fda437d8924d2f9c864d805862b43ff36020c5b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Aug 2012 18:25:09 -0700 Subject: staging: comedi: dnya_pci10xx: move boardinfo values into subdevice setup There is only one "boardtype" actually supported by this driver. The second entry in the boardinfo is a dummy entry that would result in an unusable device. Remove the boardinfo fields and just use the open coded values in the subdevice setup. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index 80bfae5..a23969e 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -57,24 +57,12 @@ static const char range_codes_pci1050_ai[] = { 0x00, 0x10, 0x30 }; struct boardtype { const char *name; int device_id; - int ai_chans; - int ao_chans; - int di_chans; - int do_chans; - const struct comedi_lrange *range_ai; - const char *range_codes_ai; }; static const struct boardtype boardtypes[] = { { .name = "dyna_pci1050", .device_id = 0x1050, - .ai_chans = 16, - .ao_chans = 16, - .di_chans = 16, - .do_chans = 16, - .range_ai = &range_pci1050_ai, - .range_codes_ai = range_codes_pci1050_ai, }, /* dummy entry corresponding to driver name */ {.name = DRV_NAME}, @@ -94,7 +82,6 @@ static int dyna_pci10xx_insn_read_ai(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - const struct boardtype *thisboard = comedi_board(dev); struct dyna_pci10xx_private *devpriv = dev->private; int n, counter; u16 d = 0; @@ -102,7 +89,7 @@ static int dyna_pci10xx_insn_read_ai(struct comedi_device *dev, /* get the channel number and range */ chan = CR_CHAN(insn->chanspec); - range = thisboard->range_codes_ai[CR_RANGE((insn->chanspec))]; + range = range_codes_pci1050_ai[CR_RANGE((insn->chanspec))]; mutex_lock(&devpriv->mutex); /* convert n samples */ @@ -139,13 +126,12 @@ static int dyna_pci10xx_insn_write_ao(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - const struct boardtype *thisboard = comedi_board(dev); struct dyna_pci10xx_private *devpriv = dev->private; int n; unsigned int chan, range; chan = CR_CHAN(insn->chanspec); - range = thisboard->range_codes_ai[CR_RANGE((insn->chanspec))]; + range = range_codes_pci1050_ai[CR_RANGE((insn->chanspec))]; mutex_lock(&devpriv->mutex); for (n = 0; n < insn->n; n++) { @@ -259,9 +245,9 @@ static int dyna_pci10xx_attach_pci(struct comedi_device *dev, s = dev->subdevices + 0; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; - s->n_chan = thisboard->ai_chans; + s->n_chan = 16; s->maxdata = 0x0FFF; - s->range_table = thisboard->range_ai; + s->range_table = &range_pci1050_ai; s->len_chanlist = 16; s->insn_read = dyna_pci10xx_insn_read_ai; @@ -269,7 +255,7 @@ static int dyna_pci10xx_attach_pci(struct comedi_device *dev, s = dev->subdevices + 1; s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; - s->n_chan = thisboard->ao_chans; + s->n_chan = 16; s->maxdata = 0x0FFF; s->range_table = &range_unipolar10; s->len_chanlist = 16; @@ -279,20 +265,20 @@ static int dyna_pci10xx_attach_pci(struct comedi_device *dev, s = dev->subdevices + 2; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE | SDF_GROUND; - s->n_chan = thisboard->di_chans; + s->n_chan = 16; s->maxdata = 1; s->range_table = &range_digital; - s->len_chanlist = thisboard->di_chans; + s->len_chanlist = 16; s->insn_bits = dyna_pci10xx_di_insn_bits; /* digital output */ s = dev->subdevices + 3; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE | SDF_GROUND; - s->n_chan = thisboard->do_chans; + s->n_chan = 16; s->maxdata = 1; s->range_table = &range_digital; - s->len_chanlist = thisboard->do_chans; + s->len_chanlist = 16; s->state = 0; s->insn_bits = dyna_pci10xx_do_insn_bits; -- cgit v0.10.2 From a38936fe819a59c88957ef4bda6a33c0a537938a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Aug 2012 18:25:36 -0700 Subject: staging: comedi: dnya_pci10xx: remove unneeded boardinfo code The boardinfo code is not needed by this driver. Only one board type is supported. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index a23969e..56fb35b 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -54,20 +54,6 @@ static const struct comedi_lrange range_pci1050_ai = { 3, { static const char range_codes_pci1050_ai[] = { 0x00, 0x10, 0x30 }; -struct boardtype { - const char *name; - int device_id; -}; - -static const struct boardtype boardtypes[] = { - { - .name = "dyna_pci1050", - .device_id = 0x1050, - }, - /* dummy entry corresponding to driver name */ - {.name = DRV_NAME}, -}; - struct dyna_pci10xx_private { struct mutex mutex; unsigned long BADR3; @@ -194,35 +180,16 @@ static int dyna_pci10xx_do_insn_bits(struct comedi_device *dev, return insn->n; } -static const void *dyna_pci10xx_find_boardinfo(struct comedi_device *dev, - struct pci_dev *pcidev) -{ - const struct boardtype *thisboard; - int i; - - for (i = 0; i < ARRAY_SIZE(boardtypes); ++i) { - thisboard = &boardtypes[i]; - if (pcidev->device != thisboard->device_id) - return thisboard; - } - return NULL; -} - static int dyna_pci10xx_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) { - const struct boardtype *thisboard; struct dyna_pci10xx_private *devpriv; struct comedi_subdevice *s; int ret; comedi_set_hw_dev(dev, &pcidev->dev); - thisboard = dyna_pci10xx_find_boardinfo(dev, pcidev); - if (!thisboard) - return -ENODEV; - dev->board_ptr = thisboard; - dev->board_name = thisboard->name; + dev->board_name = dev->driver->driver_name; ret = alloc_private(dev, sizeof(*devpriv)); if (ret) @@ -282,8 +249,7 @@ static int dyna_pci10xx_attach_pci(struct comedi_device *dev, s->state = 0; s->insn_bits = dyna_pci10xx_do_insn_bits; - dev_info(dev->class_dev, "%s: %s attached\n", - dev->driver->driver_name, dev->board_name); + dev_info(dev->class_dev, "%s attached\n", dev->board_name); return 0; } -- cgit v0.10.2 From 3131de834e8ff8f6f1581d838a51cf30e8d22b61 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Aug 2012 18:25:59 -0700 Subject: staging: comedi: dnya_pci10xx: remove unused DRV_NAME This define is not used in the driver. Remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index 56fb35b..e852808 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -41,7 +41,6 @@ #include #define PCI_VENDOR_ID_DYNALOG 0x10b5 -#define DRV_NAME "dyna_pci10xx" #define READ_TIMEOUT 50 -- cgit v0.10.2 From 8c3714d60c0b681179000e3e1b5aae15d99e6218 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 15 Aug 2012 15:02:45 +0100 Subject: staging: comedi: make attach handler optional Some low-level Comedi drivers no longer support manual configuration of devices with the COMEDI_DEVCONFIG ioctl (used by the comedi_config program). For those drivers, the 'attach_pci' or 'attach_usb' handler will be set in the struct comedi_driver to configure devices automatically (via comedi_pci_auto_config() or comedi_usb_auto_config()). Their 'attach' handlers are redundant but the the comedi core module currently requires it to be set. Make the 'attach' handler optional and issue a warning if something wants to call it. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index c0fdb00..c8adc5e 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -186,6 +186,14 @@ int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it) } return -EIO; } + if (driv->attach == NULL) { + /* driver does not support manual configuration */ + dev_warn(dev->class_dev, + "driver '%s' does not support attach using comedi_config\n", + driv->driver_name); + module_put(driv->module); + return -ENOSYS; + } /* initialize dev->driver here so * comedi_error() can be called from attach */ dev->driver = driv; @@ -885,13 +893,18 @@ static int comedi_auto_config_wrapper(struct comedi_device *dev, void *context) dev->board_ptr = comedi_recognize(driv, it->board_name); if (dev->board_ptr == NULL) { printk(KERN_WARNING - "comedi: auto config failed to find board entry" - " '%s' for driver '%s'\n", it->board_name, - driv->driver_name); + "comedi: auto config failed to find board entry '%s' for driver '%s'\n", + it->board_name, driv->driver_name); comedi_report_boards(driv); return -EINVAL; } } + if (!driv->attach) { + printk(KERN_WARNING + "comedi: BUG! driver '%s' using old-style auto config but has no attach handler\n", + driv->driver_name); + return -EINVAL; + } return driv->attach(dev, it); } -- cgit v0.10.2 From c2dea97429788d920bf51d33cba6c4cf72617726 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 15 Aug 2012 15:31:41 +0100 Subject: staging: comedi: amplc_dio200: replace macros with inline functions Replace the IS_ISA_BOARD() and IS_PCI_BOARD() functionlike macros with inline functions is_isa_board() and is_pci_board(). Also call is_pci_board() in dio200_find_pci_board() instead of an explicit comparison operator. Reported-by: Dan Carpenter Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index f31d798..9c8fbf1 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -294,9 +294,6 @@ struct dio200_board { enum dio200_layout layout; }; -#define IS_ISA_BOARD(board) (DO_ISA && (board)->bustype == isa_bustype) -#define IS_PCI_BOARD(board) (DO_PCI && (board)->bustype == pci_bustype) - static const struct dio200_board dio200_boards[] = { #if DO_ISA { @@ -455,6 +452,16 @@ struct dio200_subdev_intr { int continuous; }; +static inline bool is_pci_board(const struct dio200_board *board) +{ + return DO_PCI && board->bustype == pci_bustype; +} + +static inline bool is_isa_board(const struct dio200_board *board) +{ + return DO_ISA && board->bustype == isa_bustype; +} + /* * This function looks for a board matching the supplied PCI device. */ @@ -464,7 +471,7 @@ dio200_find_pci_board(struct pci_dev *pci_dev) unsigned int i; for (i = 0; i < ARRAY_SIZE(dio200_boards); i++) - if (dio200_boards[i].bustype == pci_bustype && + if (is_pci_board(&dio200_boards[i]) && pci_dev->device == dio200_boards[i].devid) return &dio200_boards[i]; return NULL; @@ -1234,10 +1241,10 @@ static void dio200_report_attach(struct comedi_device *dev, unsigned int irq) char tmpbuf[60]; int tmplen; - if (IS_ISA_BOARD(thisboard)) + if (is_isa_board(thisboard)) tmplen = scnprintf(tmpbuf, sizeof(tmpbuf), "(base %#lx) ", dev->iobase); - else if (IS_PCI_BOARD(thisboard)) + else if (is_pci_board(thisboard)) tmplen = scnprintf(tmpbuf, sizeof(tmpbuf), "(pci %s) ", pci_name(pcidev)); else @@ -1365,7 +1372,7 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) } /* Process options and reserve resources according to bus type. */ - if (IS_ISA_BOARD(thisboard)) { + if (is_isa_board(thisboard)) { unsigned long iobase; unsigned int irq; @@ -1375,7 +1382,7 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret < 0) return ret; return dio200_common_attach(dev, iobase, irq, 0); - } else if (IS_PCI_BOARD(thisboard)) { + } else if (is_pci_board(thisboard)) { struct pci_dev *pci_dev; pci_dev = dio200_find_pci_dev(dev, it); @@ -1444,10 +1451,10 @@ static void dio200_detach(struct comedi_device *dev) } } } - if (IS_ISA_BOARD(thisboard)) { + if (is_isa_board(thisboard)) { if (dev->iobase) release_region(dev->iobase, DIO200_IO_SIZE); - } else if (IS_PCI_BOARD(thisboard)) { + } else if (is_pci_board(thisboard)) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); if (pcidev) { if (dev->iobase) -- cgit v0.10.2 From 9c8adb8ff5b7a9530d6e0e338bda7cf952512325 Mon Sep 17 00:00:00 2001 From: Jonathan Brett Date: Wed, 15 Aug 2012 20:47:32 +0100 Subject: staging: asus_oled: Change printk calls to dev_xxx - Use dev_err whenever a struct device * is present - None of the printk calls had levels set, but looked like they should probably be dev_err Signed-off-by: Jonathan Brett Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/asus_oled/asus_oled.c b/drivers/staging/asus_oled/asus_oled.c index f63c1d3..9a8843f 100644 --- a/drivers/staging/asus_oled/asus_oled.c +++ b/drivers/staging/asus_oled/asus_oled.c @@ -42,8 +42,6 @@ #define ASUS_OLED_NAME "asus-oled" #define ASUS_OLED_UNDERSCORE_NAME "asus_oled" -#define ASUS_OLED_ERROR "Asus OLED Display Error: " - #define ASUS_OLED_STATIC 's' #define ASUS_OLED_ROLL 'r' #define ASUS_OLED_FLASH 'f' @@ -383,13 +381,13 @@ static int append_values(struct asus_oled_dev *odev, uint8_t val, size_t count) default: i = 0; - printk(ASUS_OLED_ERROR "Unknown OLED Pack Mode: %d!\n", + dev_err(odev->dev, "Unknown OLED Pack Mode: %d!\n", odev->pack_mode); break; } if (i >= odev->buf_size) { - printk(ASUS_OLED_ERROR "Buffer overflow! Report a bug:" + dev_err(odev->dev, "Buffer overflow! Report a bug:" "offs: %d >= %d i: %d (x: %d y: %d)\n", (int) odev->buf_offs, (int) odev->buf_size, (int) i, (int) x, (int) y); @@ -435,7 +433,7 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, odev->buf = kmalloc(odev->buf_size, GFP_KERNEL); if (odev->buf == NULL) { odev->buf_size = 0; - printk(ASUS_OLED_ERROR "Out of memory!\n"); + dev_err(odev->dev, "Out of memory!\n"); return -ENOMEM; } @@ -473,7 +471,7 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, odev->pic_mode = buf[1]; break; default: - printk(ASUS_OLED_ERROR "Wrong picture mode: '%c'.\n", + dev_err(odev->dev, "Wrong picture mode: '%c'.\n", buf[1]); return -EIO; break; @@ -533,7 +531,7 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, if (odev->buf == NULL) { odev->buf_size = 0; - printk(ASUS_OLED_ERROR "Out of memory!\n"); + dev_err(odev->dev, "Out of memory!\n"); return -ENOMEM; } @@ -593,15 +591,15 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, return count; error_width: - printk(ASUS_OLED_ERROR "Wrong picture width specified.\n"); + dev_err(odev->dev, "Wrong picture width specified.\n"); return -EIO; error_height: - printk(ASUS_OLED_ERROR "Wrong picture height specified.\n"); + dev_err(odev->dev, "Wrong picture height specified.\n"); return -EIO; error_header: - printk(ASUS_OLED_ERROR "Wrong picture header.\n"); + dev_err(odev->dev, "Wrong picture header.\n"); return -EIO; } -- cgit v0.10.2 From bef41c3cd34a5db26cb845296d76c998eed8d667 Mon Sep 17 00:00:00 2001 From: Jonathan Brett Date: Wed, 15 Aug 2012 20:47:33 +0100 Subject: staging: asus_oled add MODULE_VERSION Moved version string from MODULE_DESCRIPTION to MODULE_VERSION Signed-off-by: Jonathan Brett Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/asus_oled/asus_oled.c b/drivers/staging/asus_oled/asus_oled.c index 9a8843f..42a5e7a 100644 --- a/drivers/staging/asus_oled/asus_oled.c +++ b/drivers/staging/asus_oled/asus_oled.c @@ -55,8 +55,9 @@ #define USB_DEVICE_ID_ASUS_LCM2 0x175b MODULE_AUTHOR("Jakub Schmidtke, sjakub@gmail.com"); -MODULE_DESCRIPTION("Asus OLED Driver v" ASUS_OLED_VERSION); +MODULE_DESCRIPTION("Asus OLED Driver"); MODULE_LICENSE("GPL"); +MODULE_VERSION(ASUS_OLED_VERSION); static struct class *oled_class; static int oled_num; -- cgit v0.10.2 From c660e6b594911ac8ab23fd98e114542cd47fe796 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Wed, 15 Aug 2012 14:56:01 +0545 Subject: staging: serqt_usb2: remove unneeded return in qt_unthrottle this return is at the end of the void function qt_unthrottle, which is not needed, and also remove the new line below this. Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c index 8a362f7..170762c 100644 --- a/drivers/staging/serqt_usb2/serqt_usb2.c +++ b/drivers/staging/serqt_usb2/serqt_usb2.c @@ -1499,8 +1499,6 @@ static void qt_unthrottle(struct tty_struct *tty) } } mutex_unlock(&qt_port->lock); - return; - } static int qt_calc_num_ports(struct usb_serial *serial) -- cgit v0.10.2 From 68e071d890a5551cf08521c7d75e07b9bef00a8a Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Wed, 15 Aug 2012 14:56:02 +0545 Subject: staging: serqt_usb2: remove unneeded return in qt_throttle this return is in the end of the qt_throttle function, so this return not needed Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c index 170762c..135eb38 100644 --- a/drivers/staging/serqt_usb2/serqt_usb2.c +++ b/drivers/staging/serqt_usb2/serqt_usb2.c @@ -1458,7 +1458,6 @@ static void qt_throttle(struct tty_struct *tty) qt_port->RxHolding = 1; mutex_unlock(&qt_port->lock); - return; } static void qt_unthrottle(struct tty_struct *tty) -- cgit v0.10.2 From 7b11eb3eaaf049586bc44e2512c5d0cd64eb79df Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Wed, 15 Aug 2012 14:56:03 +0545 Subject: staging: serqt_usb2: remove retval initialisation in qt_tiocmget and qt_tiocmset in qt_tiocmset, the retval gets assigned if we have a valid serial pointer in the critical section (between mutex_lock and _unlock) of the code, no need to initialise this variable. the same retval assignment follows in the qt_tiocmget function also, so remove the initialisation here too. Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c index 135eb38..5a5ea48 100644 --- a/drivers/staging/serqt_usb2/serqt_usb2.c +++ b/drivers/staging/serqt_usb2/serqt_usb2.c @@ -1412,7 +1412,7 @@ static int qt_tiocmget(struct tty_struct *tty) struct usb_serial_port *port = tty->driver_data; struct usb_serial *serial = get_usb_serial(port, __func__); struct quatech_port *qt_port = qt_get_port_private(port); - int retval = -ENODEV; + int retval; if (!serial) return -ENODEV; @@ -1430,7 +1430,7 @@ static int qt_tiocmset(struct tty_struct *tty, struct usb_serial_port *port = tty->driver_data; struct usb_serial *serial = get_usb_serial(port, __func__); struct quatech_port *qt_port = qt_get_port_private(port); - int retval = -ENODEV; + int retval; if (!serial) return -ENODEV; -- cgit v0.10.2 From 8cf78422eaeb29828fb6b897550c6090696fc40d Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Wed, 15 Aug 2012 14:56:04 +0545 Subject: staging: serqt_usb2: remove return in ProcessLineStatus and ProcessModemStatus These are void functions and they dont need return at the end of the function Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c index 5a5ea48..1b26023 100644 --- a/drivers/staging/serqt_usb2/serqt_usb2.c +++ b/drivers/staging/serqt_usb2/serqt_usb2.c @@ -247,7 +247,6 @@ static void ProcessLineStatus(struct quatech_port *qt_port, qt_port->shadowLSR = line_status & (SERIAL_LSR_OE | SERIAL_LSR_PE | SERIAL_LSR_FE | SERIAL_LSR_BI); - return; } static void ProcessModemStatus(struct quatech_port *qt_port, @@ -256,7 +255,6 @@ static void ProcessModemStatus(struct quatech_port *qt_port, qt_port->shadowMSR = modem_status; wake_up_interruptible(&qt_port->wait); - return; } static void ProcessRxChar(struct tty_struct *tty, struct usb_serial_port *port, -- cgit v0.10.2 From 5432e3f3e9f2d2644115b9c881c1e9dad0e1f8fc Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 15 Aug 2012 17:30:26 -0700 Subject: staging: comedi: contec_pci_dio: remove thisboard macro This macro relies on a local variable of a specific name. Remove the macro and use the comedi_board() helper to get the thisboard pointer. Move the 'dev->board_name = thisboard->name;' in contec_attach(). The contec_find_pci_dev() function modifies the dev->board_ptr. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c index 944cfee..71b7266 100644 --- a/drivers/staging/comedi/drivers/contec_pci_dio.c +++ b/drivers/staging/comedi/drivers/contec_pci_dio.c @@ -55,12 +55,11 @@ static const struct contec_board contec_boards[] = { #define PCI_DEVICE_ID_PIO1616L 0x8172 -#define thisboard ((const struct contec_board *)dev->board_ptr) - static int contec_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + const struct contec_board *thisboard = comedi_board(dev); dev_dbg(dev->class_dev, "contec_do_insn_bits called\n"); dev_dbg(dev->class_dev, "data: %d %d\n", data[0], data[1]); @@ -79,6 +78,7 @@ static int contec_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + const struct contec_board *thisboard = comedi_board(dev); dev_dbg(dev->class_dev, "contec_di_insn_bits called\n"); dev_dbg(dev->class_dev, "data: %d %d\n", data[0], data[1]); @@ -116,14 +116,13 @@ static struct pci_dev *contec_find_pci_dev(struct comedi_device *dev, static int contec_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct contec_board *thisboard; struct pci_dev *pcidev; struct comedi_subdevice *s; int ret; printk("comedi%d: contec: ", dev->minor); - dev->board_name = thisboard->name; - ret = comedi_alloc_subdevices(dev, 2); if (ret) return ret; @@ -132,6 +131,8 @@ static int contec_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (!pcidev) return -EIO; comedi_set_hw_dev(dev, &pcidev->dev); + thisboard = comedi_board(dev); + dev->board_name = thisboard->name; if (comedi_pci_enable(pcidev, "contec_pci_dio")) { printk("error enabling PCI device and request regions!\n"); -- cgit v0.10.2 From f7f57effa46c29984640bbcc60a8b3e9761da8f2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 15 Aug 2012 17:30:50 -0700 Subject: staging: comedi: contec_pci_dio: remove function trace messages The dev_dbg function trace messages in the contec_do_insn_bits and contec_di_insn_bits functions are just noise. Remove them. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c index 71b7266..387dd42 100644 --- a/drivers/staging/comedi/drivers/contec_pci_dio.c +++ b/drivers/staging/comedi/drivers/contec_pci_dio.c @@ -61,14 +61,10 @@ static int contec_do_insn_bits(struct comedi_device *dev, { const struct contec_board *thisboard = comedi_board(dev); - dev_dbg(dev->class_dev, "contec_do_insn_bits called\n"); - dev_dbg(dev->class_dev, "data: %d %d\n", data[0], data[1]); - if (data[0]) { s->state &= ~data[0]; s->state |= data[0] & data[1]; - dev_dbg(dev->class_dev, "out: %d on %lx\n", s->state, - dev->iobase + thisboard->out_offs); + outw(s->state, dev->iobase + thisboard->out_offs); } return insn->n; @@ -80,9 +76,6 @@ static int contec_di_insn_bits(struct comedi_device *dev, { const struct contec_board *thisboard = comedi_board(dev); - dev_dbg(dev->class_dev, "contec_di_insn_bits called\n"); - dev_dbg(dev->class_dev, "data: %d %d\n", data[0], data[1]); - data[1] = inw(dev->iobase + thisboard->in_offs); return insn->n; -- cgit v0.10.2 From 8bba4439fb784d9f1aa74c1e13a42cd21f989ffc Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 15 Aug 2012 17:31:12 -0700 Subject: staging: comedi: contec_pci_dio: remove unused fields in the boardinfo The model, in_ports, out_ports, and out_boffs information in the boardinfo is not used by the driver. Remove them. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c index 387dd42..24427ca 100644 --- a/drivers/staging/comedi/drivers/contec_pci_dio.c +++ b/drivers/staging/comedi/drivers/contec_pci_dio.c @@ -42,15 +42,11 @@ enum contec_model { struct contec_board { const char *name; - int model; - int in_ports; - int out_ports; int in_offs; int out_offs; - int out_boffs; }; static const struct contec_board contec_boards[] = { - {"PIO1616L", PIO1616L, 16, 16, 0, 2, 10}, + {"PIO1616L", 0, 2 }, }; #define PCI_DEVICE_ID_PIO1616L 0x8172 -- cgit v0.10.2 From 86d466b86e0c04b2f0f6ae41f0de75082865912d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 15 Aug 2012 17:31:39 -0700 Subject: staging: comedi: contec_pci_dio: define register map for board Only one board type is supported by this driver. Instead of passing the register offsets for the digital in/out ports in the boardinfo, define the register map and use that to access the ports. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c index 24427ca..698d05b 100644 --- a/drivers/staging/comedi/drivers/contec_pci_dio.c +++ b/drivers/staging/comedi/drivers/contec_pci_dio.c @@ -42,26 +42,28 @@ enum contec_model { struct contec_board { const char *name; - int in_offs; - int out_offs; }; static const struct contec_board contec_boards[] = { - {"PIO1616L", 0, 2 }, + {"PIO1616L", }, }; #define PCI_DEVICE_ID_PIO1616L 0x8172 +/* + * Register map + */ +#define PIO1616L_DI_REG 0x00 +#define PIO1616L_DO_REG 0x02 + static int contec_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - const struct contec_board *thisboard = comedi_board(dev); - if (data[0]) { s->state &= ~data[0]; s->state |= data[0] & data[1]; - outw(s->state, dev->iobase + thisboard->out_offs); + outw(s->state, dev->iobase + PIO1616L_DO_REG); } return insn->n; } @@ -70,9 +72,7 @@ static int contec_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - const struct contec_board *thisboard = comedi_board(dev); - - data[1] = inw(dev->iobase + thisboard->in_offs); + data[1] = inw(dev->iobase + PIO1616L_DI_REG); return insn->n; } -- cgit v0.10.2 From 3256837311344ef7efa41c717a280f95207e5140 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 15 Aug 2012 17:31:59 -0700 Subject: staging: comedi: contec_pci_dio: remove unneeded boardinfo code The boardinfo code is not needed by this driver. Only one board type is supported. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c index 698d05b..4b47fa0 100644 --- a/drivers/staging/comedi/drivers/contec_pci_dio.c +++ b/drivers/staging/comedi/drivers/contec_pci_dio.c @@ -36,17 +36,6 @@ Configuration Options: #include "../comedidev.h" -enum contec_model { - PIO1616L = 0, -}; - -struct contec_board { - const char *name; -}; -static const struct contec_board contec_boards[] = { - {"PIO1616L", }, -}; - #define PCI_DEVICE_ID_PIO1616L 0x8172 /* @@ -94,7 +83,6 @@ static struct pci_dev *contec_find_pci_dev(struct comedi_device *dev, pcidev->device != PCI_DEVICE_ID_PIO1616L) continue; - dev->board_ptr = contec_boards + 0; return pcidev; } dev_err(dev->class_dev, @@ -105,7 +93,6 @@ static struct pci_dev *contec_find_pci_dev(struct comedi_device *dev, static int contec_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - const struct contec_board *thisboard; struct pci_dev *pcidev; struct comedi_subdevice *s; int ret; @@ -120,8 +107,7 @@ static int contec_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (!pcidev) return -EIO; comedi_set_hw_dev(dev, &pcidev->dev); - thisboard = comedi_board(dev); - dev->board_name = thisboard->name; + dev->board_name = dev->driver->driver_name; if (comedi_pci_enable(pcidev, "contec_pci_dio")) { printk("error enabling PCI device and request regions!\n"); @@ -182,8 +168,7 @@ static void __devexit contec_pci_dio_pci_remove(struct pci_dev *dev) } static DEFINE_PCI_DEVICE_TABLE(contec_pci_dio_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_CONTEC, PCI_DEVICE_ID_PIO1616L), - .driver_data = PIO1616L }, + { PCI_DEVICE(PCI_VENDOR_ID_CONTEC, PCI_DEVICE_ID_PIO1616L) }, { 0 } }; MODULE_DEVICE_TABLE(pci, contec_pci_dio_pci_table); -- cgit v0.10.2 From 8d02b3aa670547f307b50058b2ca1c1fab2518ed Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 15 Aug 2012 17:32:29 -0700 Subject: staging: comedi: contec_pci_dio: use attach_pci callback Convert this PCI driver to use the comedi PCI auto config attach mechanism by adding an attach_pci callback function. Since the driver does not require any external configuration options, disable the legacy attach by making the attach simply return -ENOSYS. This removes the need to walk to pci bus to find the pci_dev and the need for the pci_dev_put in the detach. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c index 4b47fa0..b7b60d3 100644 --- a/drivers/staging/comedi/drivers/contec_pci_dio.c +++ b/drivers/staging/comedi/drivers/contec_pci_dio.c @@ -27,11 +27,7 @@ Author: Stefano Rivoir Updated: Wed, 27 Jun 2007 13:00:06 +0100 Status: works -Configuration Options: - [0] - PCI bus of device (optional) - [1] - PCI slot of device (optional) - If bus/slot is not specified, the first supported - PCI device found will be used. +Configuration Options: not applicable, uses comedi PCI auto config */ #include "../comedidev.h" @@ -66,76 +62,53 @@ static int contec_di_insn_bits(struct comedi_device *dev, return insn->n; } -static struct pci_dev *contec_find_pci_dev(struct comedi_device *dev, - struct comedi_devconfig *it) +static int contec_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) { - struct pci_dev *pcidev = NULL; - int bus = it->options[0]; - int slot = it->options[1]; - - for_each_pci_dev(pcidev) { - if (bus || slot) { - if (bus != pcidev->bus->number || - slot != PCI_SLOT(pcidev->devfn)) - continue; - } - if (pcidev->vendor != PCI_VENDOR_ID_CONTEC || - pcidev->device != PCI_DEVICE_ID_PIO1616L) - continue; - - return pcidev; - } - dev_err(dev->class_dev, - "No supported board found! (req. bus %d, slot %d)\n", - bus, slot); - return NULL; -} - -static int contec_attach(struct comedi_device *dev, struct comedi_devconfig *it) -{ - struct pci_dev *pcidev; struct comedi_subdevice *s; int ret; - printk("comedi%d: contec: ", dev->minor); - - ret = comedi_alloc_subdevices(dev, 2); - if (ret) - return ret; - - pcidev = contec_find_pci_dev(dev, it); - if (!pcidev) - return -EIO; comedi_set_hw_dev(dev, &pcidev->dev); + dev->board_name = dev->driver->driver_name; - if (comedi_pci_enable(pcidev, "contec_pci_dio")) { - printk("error enabling PCI device and request regions!\n"); - return -EIO; - } + ret = comedi_pci_enable(pcidev, dev->board_name); + if (ret) + return ret; dev->iobase = pci_resource_start(pcidev, 0); - printk(" base addr %lx ", dev->iobase); - s = dev->subdevices + 0; + ret = comedi_alloc_subdevices(dev, 2); + if (ret) + return ret; - s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE; - s->n_chan = 16; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = contec_di_insn_bits; + s = dev->subdevices + 0; + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE; + s->n_chan = 16; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = contec_di_insn_bits; s = dev->subdevices + 1; - s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITABLE; - s->n_chan = 16; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = contec_do_insn_bits; + s->type = COMEDI_SUBD_DO; + s->subdev_flags = SDF_WRITABLE; + s->n_chan = 16; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = contec_do_insn_bits; + + dev_info(dev->class_dev, "%s attached\n", dev->board_name); - printk("attached\n"); + return 0; +} + +static int contec_attach(struct comedi_device *dev, + struct comedi_devconfig *it) +{ + dev_warn(dev->class_dev, + "This driver does not support attach using comedi_config\n"); - return 1; + return -ENOSYS; } static void contec_detach(struct comedi_device *dev) @@ -145,7 +118,6 @@ static void contec_detach(struct comedi_device *dev) if (pcidev) { if (dev->iobase) comedi_pci_disable(pcidev); - pci_dev_put(pcidev); } } @@ -153,6 +125,7 @@ static struct comedi_driver contec_pci_dio_driver = { .driver_name = "contec_pci_dio", .module = THIS_MODULE, .attach = contec_attach, + .attach_pci = contec_attach_pci, .detach = contec_detach, }; -- cgit v0.10.2 From 00d7a906cdd05b76b059102cacf98cfb853fa109 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 15 Aug 2012 17:32:53 -0700 Subject: staging: comedi: contec_pci_dio: cleanup contec_do_insn_bits Create local variables for the mask and bits values passed in the data pointer to make this function a bit clearer. Return the state of the output bits (s->state) in data[1] since this is what comedilib is expecting. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c index b7b60d3..12ad9fa 100644 --- a/drivers/staging/comedi/drivers/contec_pci_dio.c +++ b/drivers/staging/comedi/drivers/contec_pci_dio.c @@ -44,12 +44,18 @@ static int contec_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (data[0]) { - s->state &= ~data[0]; - s->state |= data[0] & data[1]; + unsigned int mask = data[0]; + unsigned int bits = data[1]; + + if (mask) { + s->state &= ~mask; + s->state |= (bits & mask); outw(s->state, dev->iobase + PIO1616L_DO_REG); } + + data[1] = s->state; + return insn->n; } -- cgit v0.10.2 From d26769446f5389fa5dd5b8745ddc12d4371fc267 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 16 Aug 2012 11:14:18 +0100 Subject: staging: comedi: amplc_pc263: add helper functions to check bus type Add inline helper function is_isa_board(board) to check if the driver supports ISA boards and this is an ISA board, and is_pci_board(board) to check if the driver supports PCI boards and this is a PCI board. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index 40ec1ff..a389aea 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -93,6 +93,20 @@ static const struct pc263_board pc263_boards[] = { #endif }; +/* test if ISA supported and this is an ISA board */ +static inline bool is_isa_board(const struct pc263_board *board) +{ + return IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_ISA) + && board->bustype == isa_bustype; +} + +/* test if PCI supported and this is a PCI board */ +static inline bool is_pci_board(const struct pc263_board *board) +{ + return IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_PCI) + && board->bustype == pci_bustype; +} + /* * This function looks for a board matching the supplied PCI device. */ @@ -101,7 +115,7 @@ static const struct pc263_board *pc263_find_pci_board(struct pci_dev *pci_dev) unsigned int i; for (i = 0; i < ARRAY_SIZE(pc263_boards); i++) - if (pc263_boards[i].bustype == pci_bustype && + if (is_pci_board(&pc263_boards[i]) && pci_dev->device == pc263_boards[i].devid) return &pc263_boards[i]; return NULL; @@ -187,11 +201,9 @@ static void pc263_report_attach(struct comedi_device *dev) struct pci_dev *pcidev = comedi_to_pci_dev(dev); char tmpbuf[40]; - if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_ISA) && - thisboard->bustype == isa_bustype) + if (is_isa_board(thisboard)) snprintf(tmpbuf, sizeof(tmpbuf), "(base %#lx) ", dev->iobase); - else if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_PCI) && - thisboard->bustype == pci_bustype) + else if (is_pci_board(thisboard)) snprintf(tmpbuf, sizeof(tmpbuf), "(pci %s) ", pci_name(pcidev)); else @@ -259,15 +271,13 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev_info(dev->class_dev, PC263_DRIVER_NAME ": attach\n"); /* Process options and reserve resources according to bus type. */ - if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_ISA) && - thisboard->bustype == isa_bustype) { + if (is_isa_board(thisboard)) { unsigned long iobase = it->options[0]; ret = pc263_request_region(dev, iobase, PC263_IO_SIZE); if (ret < 0) return ret; return pc263_common_attach(dev, iobase); - } else if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_PCI) && - thisboard->bustype == pci_bustype) { + } else if (is_pci_board(thisboard)) { struct pci_dev *pci_dev; pci_dev = pc263_find_pci_dev(dev, it); -- cgit v0.10.2 From 6c292278288f9b29f994fe54cbe11cc30d021218 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 16 Aug 2012 11:14:19 +0100 Subject: staging: comedi: amplc_pc263: check bus type in detach routine When detaching the device in pc263_detach() mirror the bus type checks performed by pc263_attach(). The existing tests are safe but rely on dev->iobase being 0 when comedi_to_pci_dev(dev) is NULL. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index a389aea..7aa8280 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -313,15 +313,18 @@ static int __devinit pc263_attach_pci(struct comedi_device *dev, static void pc263_detach(struct comedi_device *dev) { - struct pci_dev *pcidev = comedi_to_pci_dev(dev); + const struct pc263_board *thisboard = comedi_board(dev); - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - pci_dev_put(pcidev); - } else { + if (is_isa_board(thisboard)) { if (dev->iobase) release_region(dev->iobase, PC263_IO_SIZE); + } else if (is_pci_board(thisboard)) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + if (pcidev) { + if (dev->iobase) + comedi_pci_disable(pcidev); + pci_dev_put(pcidev); + } } } -- cgit v0.10.2 From 87f8b20dce1fda9cf7c57f669415fe6918b19fa7 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 16 Aug 2012 11:14:20 +0100 Subject: staging: comedi: amplc_pc263: abbreviate IS_ENABLED() The IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_ISA) and IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_PCI) macro calls are a bit long-winded. Define a couple of macros DO_ISA and DO_PCI as abbreviations for them. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index 7aa8280..148c9d3 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -48,6 +48,9 @@ The state of the outputs can be read. #define PC263_DRIVER_NAME "amplc_pc263" +#define DO_ISA IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_ISA) +#define DO_PCI IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_PCI) + /* PCI263 PCI configuration register information */ #define PCI_VENDOR_ID_AMPLICON 0x14dc #define PCI_DEVICE_ID_AMPLICON_PCI263 0x000c @@ -70,14 +73,14 @@ struct pc263_board { enum pc263_model model; }; static const struct pc263_board pc263_boards[] = { -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_ISA) +#if DO_ISA { .name = "pc263", .bustype = isa_bustype, .model = pc263_model, }, #endif -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_PCI) +#if DO_PCI { .name = "pci263", .devid = PCI_DEVICE_ID_AMPLICON_PCI263, @@ -96,15 +99,13 @@ static const struct pc263_board pc263_boards[] = { /* test if ISA supported and this is an ISA board */ static inline bool is_isa_board(const struct pc263_board *board) { - return IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_ISA) - && board->bustype == isa_bustype; + return DO_ISA && board->bustype == isa_bustype; } /* test if PCI supported and this is a PCI board */ static inline bool is_pci_board(const struct pc263_board *board) { - return IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_PCI) - && board->bustype == pci_bustype; + return DO_PCI && board->bustype == pci_bustype; } /* @@ -298,7 +299,7 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) static int __devinit pc263_attach_pci(struct comedi_device *dev, struct pci_dev *pci_dev) { - if (!IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_PCI)) + if (!DO_PCI) return -EINVAL; dev_info(dev->class_dev, PC263_DRIVER_NAME ": attach pci %s\n", @@ -345,7 +346,7 @@ static struct comedi_driver amplc_pc263_driver = { .num_names = ARRAY_SIZE(pc263_boards), }; -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_PCI) +#if DO_PCI static DEFINE_PCI_DEVICE_TABLE(pc263_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI263) }, {0} -- cgit v0.10.2 From 409861ff73c1bde35993da3d2b976ec8b9c107ea Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 16 Aug 2012 12:24:08 +0100 Subject: staging: comedi: amplc_pc236: add helper functions to check bus type Add inline helper function is_isa_board(board) to check if the driver supports ISA boards and this is an ISA board, and is_pci_board(board) to check if the driver supports PCI boards and this is a PCI board. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index aabba98..5a81cf3 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -135,6 +135,20 @@ struct pc236_private { int enable_irq; }; +/* test if ISA supported and this is an ISA board */ +static inline bool is_isa_board(const struct pc236_board *board) +{ + return IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) + && board->bustype == isa_bustype; +} + +/* test if PCI supported and this is a PCI board */ +static inline bool is_pci_board(const struct pc236_board *board) +{ + return IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) + && board->bustype == pci_bustype; +} + /* * This function looks for a board matching the supplied PCI device. */ @@ -143,7 +157,7 @@ static const struct pc236_board *pc236_find_pci_board(struct pci_dev *pci_dev) unsigned int i; for (i = 0; i < ARRAY_SIZE(pc236_boards); i++) - if (pc236_boards[i].bustype == pci_bustype && + if (is_pci_board(&pc236_boards[i]) && pci_dev->device == pc236_boards[i].devid) return &pc236_boards[i]; return NULL; @@ -414,15 +428,13 @@ static void pc236_report_attach(struct comedi_device *dev, unsigned int irq) char tmpbuf[60]; int tmplen; - if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) && - thisboard->bustype == isa_bustype) + if (is_isa_board(thisboard)) tmplen = scnprintf(tmpbuf, sizeof(tmpbuf), "(base %#lx) ", dev->iobase); - else if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) && - thisboard->bustype == pci_bustype) { + else if (is_pci_board(thisboard)) tmplen = scnprintf(tmpbuf, sizeof(tmpbuf), "(pci %s) ", pci_name(pcidev)); - } else + else tmplen = 0; if (irq) tmplen += scnprintf(&tmpbuf[tmplen], sizeof(tmpbuf) - tmplen, @@ -517,16 +529,14 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) return ret; } /* Process options according to bus type. */ - if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) && - thisboard->bustype == isa_bustype) { + if (is_isa_board(thisboard)) { unsigned long iobase = it->options[0]; unsigned int irq = it->options[1]; ret = pc236_request_region(dev, iobase, PC236_IO_SIZE); if (ret < 0) return ret; return pc236_common_attach(dev, iobase, irq, 0); - } else if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) && - thisboard->bustype == pci_bustype) { + } else if (is_pci_board(thisboard)) { struct pci_dev *pci_dev; pci_dev = pc236_find_pci_dev(dev, it); -- cgit v0.10.2 From 02918c0066b1c990a4e60c0dd4702eb9639b760b Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 16 Aug 2012 12:24:09 +0100 Subject: staging: comedi: amplc_pc236: check bus type in detach routine When detaching the device in pc236_detach() mirror the bus type checks performed by pc236_attach(). The existing tests are safe but rely on dev->iobase being 0 when comedi_to_pci_dev(dev) is NULL. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index 5a81cf3..330fa3a 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -580,8 +580,8 @@ static int __devinit pc236_attach_pci(struct comedi_device *dev, static void pc236_detach(struct comedi_device *dev) { + const struct pc236_board *thisboard = comedi_board(dev); struct pc236_private *devpriv = dev->private; - struct pci_dev *pcidev = comedi_to_pci_dev(dev); if (devpriv) pc236_intr_disable(dev); @@ -589,13 +589,16 @@ static void pc236_detach(struct comedi_device *dev) free_irq(dev->irq, dev); if (dev->subdevices) subdev_8255_cleanup(dev, dev->subdevices + 0); - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - pci_dev_put(pcidev); - } else { + if (is_isa_board(thisboard)) { if (dev->iobase) release_region(dev->iobase, PC236_IO_SIZE); + } else if (is_pci_board(thisboard)) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + if (pcidev) { + if (dev->iobase) + comedi_pci_disable(pcidev); + pci_dev_put(pcidev); + } } } -- cgit v0.10.2 From 15bad7b518043aa00d6220effabaf8c262a5af64 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 16 Aug 2012 12:24:10 +0100 Subject: staging: comedi: amplc_pc236: check bus type before accessing LCR The PCI-local bridge LCR registers are (assumed to be) present and used iff the board is a PCI board (a PCI236). Currently the code tests if devpriv->lcr_iobase is valid before accessing the registers. Instead, check if the board is a PCI board and assume devpriv->lcr_iobase is valid if so. (Currently, no validity check is performed as the PCI vendor and device ID ought to suffice, but simple checks could be added when attaching the device.) Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index 330fa3a..88aa179 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -228,12 +228,13 @@ static int pc236_request_region(struct comedi_device *dev, unsigned long from, */ static void pc236_intr_disable(struct comedi_device *dev) { + const struct pc236_board *thisboard = comedi_board(dev); struct pc236_private *devpriv = dev->private; unsigned long flags; spin_lock_irqsave(&dev->spinlock, flags); devpriv->enable_irq = 0; - if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) && devpriv->lcr_iobase) + if (is_pci_board(thisboard)) outl(PCI236_INTR_DISABLE, devpriv->lcr_iobase + PLX9052_INTCSR); spin_unlock_irqrestore(&dev->spinlock, flags); } @@ -245,12 +246,13 @@ static void pc236_intr_disable(struct comedi_device *dev) */ static void pc236_intr_enable(struct comedi_device *dev) { + const struct pc236_board *thisboard = comedi_board(dev); struct pc236_private *devpriv = dev->private; unsigned long flags; spin_lock_irqsave(&dev->spinlock, flags); devpriv->enable_irq = 1; - if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) && devpriv->lcr_iobase) + if (is_pci_board(thisboard)) outl(PCI236_INTR_ENABLE, devpriv->lcr_iobase + PLX9052_INTCSR); spin_unlock_irqrestore(&dev->spinlock, flags); } @@ -264,6 +266,7 @@ static void pc236_intr_enable(struct comedi_device *dev) */ static int pc236_intr_check(struct comedi_device *dev) { + const struct pc236_board *thisboard = comedi_board(dev); struct pc236_private *devpriv = dev->private; int retval = 0; unsigned long flags; @@ -271,8 +274,7 @@ static int pc236_intr_check(struct comedi_device *dev) spin_lock_irqsave(&dev->spinlock, flags); if (devpriv->enable_irq) { retval = 1; - if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) && - devpriv->lcr_iobase) { + if (is_pci_board(thisboard)) { if ((inl(devpriv->lcr_iobase + PLX9052_INTCSR) & PLX9052_INTCSR_LI1STAT_MASK) == PLX9052_INTCSR_LI1STAT_INACTIVE) { -- cgit v0.10.2 From 00255d194321a4800de6bd87fc5b30972d5ecbb3 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 16 Aug 2012 12:24:11 +0100 Subject: staging: comedi: amplc_pc236: abbreviate IS_ENABLED() The IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) and IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) macro calls are a bit long-winded. Define a couple of macros DO_ISA and DO_PCI as abbreviations for them. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index 88aa179..c644385 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -61,6 +61,9 @@ unused. #define PC236_DRIVER_NAME "amplc_pc236" +#define DO_ISA IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) +#define DO_PCI IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) + /* PCI236 PCI configuration register information */ #define PCI_VENDOR_ID_AMPLICON 0x14dc #define PCI_DEVICE_ID_AMPLICON_PCI236 0x0009 @@ -103,14 +106,14 @@ struct pc236_board { enum pc236_model model; }; static const struct pc236_board pc236_boards[] = { -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) +#if DO_ISA { .name = "pc36at", .bustype = isa_bustype, .model = pc36at_model, }, #endif -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) +#if DO_PCI { .name = "pci236", .devid = PCI_DEVICE_ID_AMPLICON_PCI236, @@ -138,15 +141,13 @@ struct pc236_private { /* test if ISA supported and this is an ISA board */ static inline bool is_isa_board(const struct pc236_board *board) { - return IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) - && board->bustype == isa_bustype; + return DO_ISA && board->bustype == isa_bustype; } /* test if PCI supported and this is a PCI board */ static inline bool is_pci_board(const struct pc236_board *board) { - return IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) - && board->bustype == pci_bustype; + return DO_PCI && board->bustype == pci_bustype; } /* @@ -562,7 +563,7 @@ static int __devinit pc236_attach_pci(struct comedi_device *dev, { int ret; - if (!IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI)) + if (!DO_PCI) return -EINVAL; dev_info(dev->class_dev, PC236_DRIVER_NAME ": attach pci %s\n", @@ -621,7 +622,7 @@ static struct comedi_driver amplc_pc236_driver = { .num_names = ARRAY_SIZE(pc236_boards), }; -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) +#if DO_PCI static DEFINE_PCI_DEVICE_TABLE(pc236_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI236) }, {0} -- cgit v0.10.2 From 4f870fe6269bbc7cca2a70c50a4cc6f811fe21c5 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 16 Aug 2012 14:38:05 +0100 Subject: staging: comedi: replace printk calls in comedi core Replace the printk() calls in the comedi core module with something more suitable, such as dev_...() or pr_...(). Remove the ones that report a failure to increment a module count (try_module_get() failure). Change the printk() call in the DPRINTK() macro to pr_debug(). TODO: Most of the DPRINTK() calls need to be replaced with something else. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index e821264..7a76f9c 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -882,14 +882,12 @@ static int check_insn_config_length(struct comedi_insn *insn, /* by default we allow the insn since we don't have checks for * all possible cases yet */ default: - printk(KERN_WARNING - "comedi: no check for data length of config insn id " - "%i is implemented.\n" - " Add a check to %s in %s.\n" - " Assuming n=%i is correct.\n", data[0], __func__, - __FILE__, insn->n); + pr_warn("comedi: No check for data length of config insn id %i is implemented.\n", + data[0]); + pr_warn("comedi: Add a check to %s in %s.\n", + __func__, __FILE__); + pr_warn("comedi: Assuming n=%i is correct.\n", insn->n); return 0; - break; } return -EINVAL; } @@ -2034,8 +2032,8 @@ void do_become_nonbusy(struct comedi_device *dev, struct comedi_subdevice *s) comedi_reset_async_buf(async); async->inttrig = NULL; } else { - printk(KERN_ERR - "BUG: (?) do_become_nonbusy called with async=0\n"); + dev_err(dev->class_dev, + "BUG: (?) do_become_nonbusy called with async=NULL\n"); } s->busy = NULL; @@ -2211,14 +2209,12 @@ static int __init comedi_init(void) int i; int retval; - printk(KERN_INFO "comedi: version " COMEDI_RELEASE - " - http://www.comedi.org\n"); + pr_info("comedi: version " COMEDI_RELEASE " - http://www.comedi.org\n"); if (comedi_num_legacy_minors < 0 || comedi_num_legacy_minors > COMEDI_NUM_BOARD_MINORS) { - printk(KERN_ERR "comedi: error: invalid value for module " - "parameter \"comedi_num_legacy_minors\". Valid values " - "are 0 through %i.\n", COMEDI_NUM_BOARD_MINORS); + pr_err("comedi: error: invalid value for module parameter \"comedi_num_legacy_minors\". Valid values are 0 through %i.\n", + COMEDI_NUM_BOARD_MINORS); return -EINVAL; } @@ -2247,7 +2243,7 @@ static int __init comedi_init(void) } comedi_class = class_create(THIS_MODULE, "comedi"); if (IS_ERR(comedi_class)) { - printk(KERN_ERR "comedi: failed to create class"); + pr_err("comedi: failed to create class\n"); cdev_del(&comedi_cdev); unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0), COMEDI_NUM_MINORS); @@ -2295,8 +2291,7 @@ module_exit(comedi_cleanup); void comedi_error(const struct comedi_device *dev, const char *s) { - printk(KERN_ERR "comedi%d: %s: %s\n", dev->minor, - dev->driver->driver_name, s); + dev_err(dev->class_dev, "%s: %s\n", dev->driver->driver_name, s); } EXPORT_SYMBOL(comedi_error); @@ -2420,9 +2415,7 @@ int comedi_alloc_board_minor(struct device *hardware_device) comedi_device_cleanup(info->device); kfree(info->device); kfree(info); - printk(KERN_ERR - "comedi: error: " - "ran out of minor numbers for board device files.\n"); + pr_err("comedi: error: ran out of minor numbers for board device files.\n"); return -EBUSY; } info->device->minor = i; @@ -2499,9 +2492,7 @@ int comedi_alloc_subdevice_minor(struct comedi_device *dev, spin_unlock(&comedi_file_info_table_lock); if (i == COMEDI_NUM_MINORS) { kfree(info); - printk(KERN_ERR - "comedi: error: " - "ran out of minor numbers for board device files.\n"); + pr_err("comedi: error: ran out of minor numbers for board device files.\n"); return -EBUSY; } s->minor = i; diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index f713783..cb67a5c 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -46,7 +46,7 @@ #define DPRINTK(format, args...) do { \ if (comedi_debug) \ - printk(KERN_DEBUG "comedi: " format , ## args); \ + pr_debug("comedi: " format, ## args); \ } while (0) #define COMEDI_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c)) diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index c8adc5e..c9f5c1f 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -119,8 +119,8 @@ static void __comedi_device_detach(struct comedi_device *dev) if (dev->driver) dev->driver->detach(dev); else - printk(KERN_WARNING - "BUG: dev->driver=NULL in comedi_device_detach()\n"); + dev_warn(dev->class_dev, + "BUG: dev->driver=NULL in comedi_device_detach()\n"); cleanup_device(dev); } @@ -142,8 +142,7 @@ static int comedi_device_postconfig(struct comedi_device *dev) return ret; } if (!dev->board_name) { - printk(KERN_WARNING "BUG: dev->board_name=<%p>\n", - dev->board_name); + dev_warn(dev->class_dev, "BUG: dev->board_name=NULL\n"); dev->board_name = "BUG"; } smp_wmb(); @@ -161,7 +160,6 @@ int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it) for (driv = comedi_drivers; driv; driv = driv->next) { if (!try_module_get(driv->module)) { - printk(KERN_INFO "comedi: failed to increment module count, skipping\n"); continue; } if (driv->num_names) { @@ -177,8 +175,6 @@ int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* report valid board names before returning error */ for (driv = comedi_drivers; driv; driv = driv->next) { if (!try_module_get(driv->module)) { - printk(KERN_INFO - "comedi: failed to increment module count\n"); continue; } comedi_report_boards(driv); @@ -233,8 +229,9 @@ int comedi_driver_unregister(struct comedi_driver *driver) mutex_lock(&dev->mutex); if (dev->attached && dev->driver == driver) { if (dev->use_count) - printk(KERN_WARNING "BUG! detaching device with use_count=%d\n", - dev->use_count); + dev_warn(dev->class_dev, + "BUG! detaching device with use_count=%d\n", + dev->use_count); comedi_device_detach(dev); } mutex_unlock(&dev->mutex); @@ -281,8 +278,8 @@ static int postconfig(struct comedi_device *dev) async = kzalloc(sizeof(struct comedi_async), GFP_KERNEL); if (async == NULL) { - printk(KERN_INFO - "failed to allocate async struct\n"); + dev_warn(dev->class_dev, + "failed to allocate async struct\n"); return -ENOMEM; } init_waitqueue_head(&async->wait_head); @@ -298,7 +295,8 @@ static int postconfig(struct comedi_device *dev) async->prealloc_buf = NULL; async->prealloc_bufsz = 0; if (comedi_buf_alloc(dev, s, buf_size) < 0) { - printk(KERN_INFO "Buffer allocation failed\n"); + dev_warn(dev->class_dev, + "Buffer allocation failed\n"); return -ENOMEM; } if (s->buf_change) { @@ -378,17 +376,17 @@ static void comedi_report_boards(struct comedi_driver *driv) unsigned int i; const char *const *name_ptr; - printk(KERN_INFO "comedi: valid board names for %s driver are:\n", - driv->driver_name); + pr_info("comedi: valid board names for %s driver are:\n", + driv->driver_name); name_ptr = driv->board_name; for (i = 0; i < driv->num_names; i++) { - printk(KERN_INFO " %s\n", *name_ptr); + pr_info(" %s\n", *name_ptr); name_ptr = (const char **)((char *)name_ptr + driv->offset); } if (driv->num_names == 0) - printk(KERN_INFO " %s\n", driv->driver_name); + pr_info(" %s\n", driv->driver_name); } static int poll_invalid(struct comedi_device *dev, struct comedi_subdevice *s) @@ -592,9 +590,9 @@ static unsigned int comedi_buf_munge(struct comedi_async *async, block_size = num_bytes - count; if (block_size < 0) { - printk(KERN_WARNING - "%s: %s: bug! block_size is negative\n", - __FILE__, __func__); + dev_warn(s->device->class_dev, + "%s: %s: bug! block_size is negative\n", + __FILE__, __func__); break; } if ((int)(async->munge_ptr + block_size - @@ -675,7 +673,8 @@ unsigned comedi_buf_write_free(struct comedi_async *async, unsigned int nbytes) { if ((int)(async->buf_write_count + nbytes - async->buf_write_alloc_count) > 0) { - printk(KERN_INFO "comedi: attempted to write-free more bytes than have been write-allocated.\n"); + dev_info(async->subdevice->device->class_dev, + "attempted to write-free more bytes than have been write-allocated.\n"); nbytes = async->buf_write_alloc_count - async->buf_write_count; } async->buf_write_count += nbytes; @@ -711,8 +710,8 @@ unsigned comedi_buf_read_free(struct comedi_async *async, unsigned int nbytes) smp_mb(); if ((int)(async->buf_read_count + nbytes - async->buf_read_alloc_count) > 0) { - printk(KERN_INFO - "comedi: attempted to read-free more bytes than have been read-allocated.\n"); + dev_info(async->subdevice->device->class_dev, + "attempted to read-free more bytes than have been read-allocated.\n"); nbytes = async->buf_read_alloc_count - async->buf_read_count; } async->buf_read_count += nbytes; @@ -861,10 +860,9 @@ comedi_auto_config_helper(struct device *hardware_device, mutex_lock(&comedi_dev->mutex); if (comedi_dev->attached) ret = -EBUSY; - else if (!try_module_get(driver->module)) { - printk(KERN_INFO "comedi: failed to increment module count\n"); + else if (!try_module_get(driver->module)) ret = -EIO; - } else { + else { /* set comedi_dev->driver here for attach wrapper */ comedi_dev->driver = driver; ret = (*attach_wrapper)(comedi_dev, context); @@ -892,17 +890,17 @@ static int comedi_auto_config_wrapper(struct comedi_device *dev, void *context) * has already been copied to it->board_name */ dev->board_ptr = comedi_recognize(driv, it->board_name); if (dev->board_ptr == NULL) { - printk(KERN_WARNING - "comedi: auto config failed to find board entry '%s' for driver '%s'\n", - it->board_name, driv->driver_name); + dev_warn(dev->class_dev, + "auto config failed to find board entry '%s' for driver '%s'\n", + it->board_name, driv->driver_name); comedi_report_boards(driv); return -EINVAL; } } if (!driv->attach) { - printk(KERN_WARNING - "comedi: BUG! driver '%s' using old-style auto config but has no attach handler\n", - driv->driver_name); + dev_warn(dev->class_dev, + "BUG! driver '%s' using old-style auto config but has no attach handler\n", + driv->driver_name); return -EINVAL; } return driv->attach(dev, it); diff --git a/drivers/staging/comedi/range.c b/drivers/staging/comedi/range.c index 41f9523..5a6b6df 100644 --- a/drivers/staging/comedi/range.c +++ b/drivers/staging/comedi/range.c @@ -131,6 +131,7 @@ static int aref_invalid(struct comedi_subdevice *s, unsigned int chanspec) int comedi_check_chanlist(struct comedi_subdevice *s, int n, unsigned int *chanlist) { + struct comedi_device *dev = s->device; int i; int chan; @@ -139,10 +140,10 @@ int comedi_check_chanlist(struct comedi_subdevice *s, int n, if (CR_CHAN(chanlist[i]) >= s->n_chan || CR_RANGE(chanlist[i]) >= s->range_table->length || aref_invalid(s, chanlist[i])) { - printk(KERN_ERR "bad chanlist[%d]=0x%08x " - "in_chan=%d range length=%d\n", i, - chanlist[i], s->n_chan, - s->range_table->length); + dev_warn(dev->class_dev, + "bad chanlist[%d]=0x%08x in_chan=%d range length=%d\n", + i, chanlist[i], s->n_chan, + s->range_table->length); return -EINVAL; } } else if (s->range_table_list) { @@ -152,13 +153,14 @@ int comedi_check_chanlist(struct comedi_subdevice *s, int n, CR_RANGE(chanlist[i]) >= s->range_table_list[chan]->length || aref_invalid(s, chanlist[i])) { - printk(KERN_ERR "bad chanlist[%d]=0x%08x\n", - i, chanlist[i]); + dev_warn(dev->class_dev, + "bad chanlist[%d]=0x%08x\n", + i, chanlist[i]); return -EINVAL; } } } else { - printk(KERN_ERR "comedi: (bug) no range type list!\n"); + dev_err(dev->class_dev, "(bug) no range type list!\n"); return -EINVAL; } return 0; -- cgit v0.10.2 From c4f9e64456ae3ed6f6c8df07cc903a292c755991 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Thu, 16 Aug 2012 21:50:03 +0530 Subject: staging:csr: remove usage of CsrSnprintf and use scnprintf MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change tries to achieve the removal of the csr driver defined snprintf and uses the kernel defined snprintf. After this change i got following build warnings, which are solved in this patch warnings generated: drivers/staging/csr/io.c:929:13: warning: format ‘%lu’ expects type ‘long unsigned int’, but argument 4 has type ‘u32’ drivers/staging/csr/io.c:929:13: warning: format ‘%lu’ expects type ‘long unsigned int’, but argument 5 has type ‘u32’ drivers/staging/csr/csr_wifi_hip_udi.c: In function ‘unifi_print_status’: drivers/staging/csr/csr_wifi_hip_udi.c:78:27: warning: format ‘%lu’ expects type ‘long unsigned int’, but argument 4 has type ‘u32’ drivers/staging/csr/csr_wifi_hip_udi.c:151:27: warning: format ‘%u’ expects type ‘unsigned int’, but argument 5 has type ‘long int’ drivers/staging/csr/csr_wifi_hip_udi.c:257:27: warning: format ‘%lu’ expects type ‘long unsigned int’, but argument 4 has type ‘u32’ drivers/staging/csr/csr_wifi_hip_udi.c:257:27: warning: format ‘%lu’ expects type ‘long unsigned int’, but argument 5 has type ‘u32’ drivers/staging/csr/csr_wifi_hip_udi.c:261:27: warning: format ‘%lu’ expects type ‘long unsigned int’, but argument 4 has type ‘u32’ Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/csr/Makefile b/drivers/staging/csr/Makefile index afda44b..ab626ed 100644 --- a/drivers/staging/csr/Makefile +++ b/drivers/staging/csr/Makefile @@ -25,7 +25,6 @@ csr_wifi-y := bh.o \ unifi_event.o \ unifi_pdu_processing.o \ unifi_sme.o \ - csr_formatted_io.o \ csr_wifi_hip_card_sdio.o \ csr_wifi_hip_card_sdio_intr.o \ csr_wifi_hip_card_sdio_mem.o \ diff --git a/drivers/staging/csr/csr_formatted_io.c b/drivers/staging/csr/csr_formatted_io.c deleted file mode 100644 index 7213cc8..0000000 --- a/drivers/staging/csr/csr_formatted_io.c +++ /dev/null @@ -1,27 +0,0 @@ -/***************************************************************************** - - (c) Cambridge Silicon Radio Limited 2010 - All rights reserved and confidential information of CSR - - Refer to LICENSE.txt included with this source for details - on the license terms. - -*****************************************************************************/ -#include -#include "csr_formatted_io.h" - -s32 CsrSnprintf(char *dest, size_t n, const char *fmt, ...) -{ - s32 r; - va_list args; - va_start(args, fmt); - r = vsnprintf(dest, n, fmt, args); - va_end(args); - - if (dest && (n > 0)) - { - dest[n - 1] = '\0'; - } - - return r; -} diff --git a/drivers/staging/csr/csr_formatted_io.h b/drivers/staging/csr/csr_formatted_io.h deleted file mode 100644 index 2e238cb..0000000 --- a/drivers/staging/csr/csr_formatted_io.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef CSR_FORMATTED_IO_H__ -#define CSR_FORMATTED_IO_H__ -/***************************************************************************** - - (c) Cambridge Silicon Radio Limited 2010 - All rights reserved and confidential information of CSR - - Refer to LICENSE.txt included with this source for details - on the license terms. - -*****************************************************************************/ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -s32 CsrSnprintf(char *dest, size_t n, const char *fmt, ...); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/drivers/staging/csr/csr_wifi_hip_card_sdio.c b/drivers/staging/csr/csr_wifi_hip_card_sdio.c index 44ab00c..cf148a0 100644 --- a/drivers/staging/csr/csr_wifi_hip_card_sdio.c +++ b/drivers/staging/csr/csr_wifi_hip_card_sdio.c @@ -1612,13 +1612,13 @@ static CsrResult card_allocate_memory_resources(card_t *card) /* Reset any state carried forward from a previous life */ card->fh_command_queue.q_rd_ptr = 0; card->fh_command_queue.q_wr_ptr = 0; - (void)CsrSnprintf(card->fh_command_queue.name, UNIFI_QUEUE_NAME_MAX_LENGTH, + (void)scnprintf(card->fh_command_queue.name, UNIFI_QUEUE_NAME_MAX_LENGTH, "fh_cmd_q"); for (i = 0; i < UNIFI_NO_OF_TX_QS; i++) { card->fh_traffic_queue[i].q_rd_ptr = 0; card->fh_traffic_queue[i].q_wr_ptr = 0; - (void)CsrSnprintf(card->fh_traffic_queue[i].name, + (void)scnprintf(card->fh_traffic_queue[i].name, UNIFI_QUEUE_NAME_MAX_LENGTH, "fh_data_q%d", i); } #ifndef CSR_WIFI_HIP_TA_DISABLE @@ -1826,13 +1826,13 @@ static void card_init_soft_queues(card_t *card) /* Reset any state carried forward from a previous life */ card->fh_command_queue.q_rd_ptr = 0; card->fh_command_queue.q_wr_ptr = 0; - (void)CsrSnprintf(card->fh_command_queue.name, UNIFI_QUEUE_NAME_MAX_LENGTH, + (void)scnprintf(card->fh_command_queue.name, UNIFI_QUEUE_NAME_MAX_LENGTH, "fh_cmd_q"); for (i = 0; i < UNIFI_NO_OF_TX_QS; i++) { card->fh_traffic_queue[i].q_rd_ptr = 0; card->fh_traffic_queue[i].q_wr_ptr = 0; - (void)CsrSnprintf(card->fh_traffic_queue[i].name, + (void)scnprintf(card->fh_traffic_queue[i].name, UNIFI_QUEUE_NAME_MAX_LENGTH, "fh_data_q%d", i); } #ifndef CSR_WIFI_HIP_TA_DISABLE diff --git a/drivers/staging/csr/csr_wifi_hip_udi.c b/drivers/staging/csr/csr_wifi_hip_udi.c index 07cfd36..31a27cc 100644 --- a/drivers/staging/csr/csr_wifi_hip_udi.c +++ b/drivers/staging/csr/csr_wifi_hip_udi.c @@ -64,104 +64,104 @@ s32 unifi_print_status(card_t *card, char *str, s32 *remain) } i = n = 0; - written = CsrSnprintf(p, remaining, "Chip ID %u\n", + written = scnprintf(p, remaining, "Chip ID %u\n", (u16)card->chip_id); UNIFI_SNPRINTF_RET(p, remaining, written); - written = CsrSnprintf(p, remaining, "Chip Version %04X\n", + written = scnprintf(p, remaining, "Chip Version %04X\n", card->chip_version); UNIFI_SNPRINTF_RET(p, remaining, written); - written = CsrSnprintf(p, remaining, "HIP v%u.%u\n", + written = scnprintf(p, remaining, "HIP v%u.%u\n", (card->config_data.version >> 8) & 0xFF, card->config_data.version & 0xFF); UNIFI_SNPRINTF_RET(p, remaining, written); - written = CsrSnprintf(p, remaining, "Build %lu: %s\n", + written = scnprintf(p, remaining, "Build %u: %s\n", card->build_id, card->build_id_string); UNIFI_SNPRINTF_RET(p, remaining, written); cfg = &card->config_data; - written = CsrSnprintf(p, remaining, "sdio ctrl offset %u\n", + written = scnprintf(p, remaining, "sdio ctrl offset %u\n", cfg->sdio_ctrl_offset); UNIFI_SNPRINTF_RET(p, remaining, written); - written = CsrSnprintf(p, remaining, "fromhost sigbuf handle %u\n", + written = scnprintf(p, remaining, "fromhost sigbuf handle %u\n", cfg->fromhost_sigbuf_handle); UNIFI_SNPRINTF_RET(p, remaining, written); - written = CsrSnprintf(p, remaining, "tohost_sigbuf_handle %u\n", + written = scnprintf(p, remaining, "tohost_sigbuf_handle %u\n", cfg->tohost_sigbuf_handle); UNIFI_SNPRINTF_RET(p, remaining, written); - written = CsrSnprintf(p, remaining, "num_fromhost_sig_frags %u\n", + written = scnprintf(p, remaining, "num_fromhost_sig_frags %u\n", cfg->num_fromhost_sig_frags); UNIFI_SNPRINTF_RET(p, remaining, written); - written = CsrSnprintf(p, remaining, "num_tohost_sig_frags %u\n", + written = scnprintf(p, remaining, "num_tohost_sig_frags %u\n", cfg->num_tohost_sig_frags); UNIFI_SNPRINTF_RET(p, remaining, written); - written = CsrSnprintf(p, remaining, "num_fromhost_data_slots %u\n", + written = scnprintf(p, remaining, "num_fromhost_data_slots %u\n", cfg->num_fromhost_data_slots); UNIFI_SNPRINTF_RET(p, remaining, written); - written = CsrSnprintf(p, remaining, "num_tohost_data_slots %u\n", + written = scnprintf(p, remaining, "num_tohost_data_slots %u\n", cfg->num_tohost_data_slots); UNIFI_SNPRINTF_RET(p, remaining, written); - written = CsrSnprintf(p, remaining, "data_slot_size %u\n", + written = scnprintf(p, remaining, "data_slot_size %u\n", cfg->data_slot_size); UNIFI_SNPRINTF_RET(p, remaining, written); /* Added by protocol version 0x0001 */ - written = CsrSnprintf(p, remaining, "overlay_size %u\n", + written = scnprintf(p, remaining, "overlay_size %u\n", (u16)cfg->overlay_size); UNIFI_SNPRINTF_RET(p, remaining, written); /* Added by protocol version 0x0300 */ - written = CsrSnprintf(p, remaining, "data_slot_round %u\n", + written = scnprintf(p, remaining, "data_slot_round %u\n", cfg->data_slot_round); UNIFI_SNPRINTF_RET(p, remaining, written); - written = CsrSnprintf(p, remaining, "sig_frag_size %u\n", + written = scnprintf(p, remaining, "sig_frag_size %u\n", cfg->sig_frag_size); UNIFI_SNPRINTF_RET(p, remaining, written); /* Added by protocol version 0x0300 */ - written = CsrSnprintf(p, remaining, "tohost_sig_pad %u\n", + written = scnprintf(p, remaining, "tohost_sig_pad %u\n", cfg->tohost_signal_padding); UNIFI_SNPRINTF_RET(p, remaining, written); - written = CsrSnprintf(p, remaining, "\nInternal state:\n"); + written = scnprintf(p, remaining, "\nInternal state:\n"); UNIFI_SNPRINTF_RET(p, remaining, written); - written = CsrSnprintf(p, remaining, "Last PHY PANIC: %04x:%04x\n", + written = scnprintf(p, remaining, "Last PHY PANIC: %04x:%04x\n", card->last_phy_panic_code, card->last_phy_panic_arg); UNIFI_SNPRINTF_RET(p, remaining, written); - written = CsrSnprintf(p, remaining, "Last MAC PANIC: %04x:%04x\n", + written = scnprintf(p, remaining, "Last MAC PANIC: %04x:%04x\n", card->last_mac_panic_code, card->last_mac_panic_arg); UNIFI_SNPRINTF_RET(p, remaining, written); - written = CsrSnprintf(p, remaining, "fhsr: %u\n", + written = scnprintf(p, remaining, "fhsr: %u\n", (u16)card->from_host_signals_r); UNIFI_SNPRINTF_RET(p, remaining, written); - written = CsrSnprintf(p, remaining, "fhsw: %u\n", + written = scnprintf(p, remaining, "fhsw: %u\n", (u16)card->from_host_signals_w); UNIFI_SNPRINTF_RET(p, remaining, written); - written = CsrSnprintf(p, remaining, "thsr: %u\n", + written = scnprintf(p, remaining, "thsr: %u\n", (u16)card->to_host_signals_r); UNIFI_SNPRINTF_RET(p, remaining, written); - written = CsrSnprintf(p, remaining, "thsw: %u\n", + written = scnprintf(p, remaining, "thsw: %u\n", (u16)card->to_host_signals_w); UNIFI_SNPRINTF_RET(p, remaining, written); - written = CsrSnprintf(p, remaining, - "fh buffer contains: %u signals, %u bytes\n", + written = scnprintf(p, remaining, + "fh buffer contains: %d signals, %ld bytes\n", card->fh_buffer.count, card->fh_buffer.ptr - card->fh_buffer.buf); UNIFI_SNPRINTF_RET(p, remaining, written); - written = CsrSnprintf(p, remaining, "paused: "); + written = scnprintf(p, remaining, "paused: "); UNIFI_SNPRINTF_RET(p, remaining, written); for (i = 0; i < sizeof(card->tx_q_paused_flag) / sizeof(card->tx_q_paused_flag[0]); i++) { - written = CsrSnprintf(p, remaining, card->tx_q_paused_flag[i]?"1" : "0"); + written = scnprintf(p, remaining, card->tx_q_paused_flag[i]?"1" : "0"); UNIFI_SNPRINTF_RET(p, remaining, written); } - written = CsrSnprintf(p, remaining, "\n"); + written = scnprintf(p, remaining, "\n"); UNIFI_SNPRINTF_RET(p, remaining, written); - written = CsrSnprintf(p, remaining, + written = scnprintf(p, remaining, "fh command q: %u waiting, %u free of %u:\n", CSR_WIFI_HIP_Q_SLOTS_USED(&card->fh_command_queue), CSR_WIFI_HIP_Q_SLOTS_FREE(&card->fh_command_queue), @@ -169,7 +169,7 @@ s32 unifi_print_status(card_t *card, char *str, s32 *remain) UNIFI_SNPRINTF_RET(p, remaining, written); for (i = 0; i < UNIFI_NO_OF_TX_QS; i++) { - written = CsrSnprintf(p, remaining, + written = scnprintf(p, remaining, "fh traffic q[%u]: %u waiting, %u free of %u:\n", i, CSR_WIFI_HIP_Q_SLOTS_USED(&card->fh_traffic_queue[i]), @@ -178,58 +178,58 @@ s32 unifi_print_status(card_t *card, char *str, s32 *remain) UNIFI_SNPRINTF_RET(p, remaining, written); } - written = CsrSnprintf(p, remaining, "fh data slots free: %u\n", + written = scnprintf(p, remaining, "fh data slots free: %u\n", card->from_host_data?CardGetFreeFromHostDataSlots(card) : 0); UNIFI_SNPRINTF_RET(p, remaining, written); - written = CsrSnprintf(p, remaining, "From host data slots:"); + written = scnprintf(p, remaining, "From host data slots:"); UNIFI_SNPRINTF_RET(p, remaining, written); n = card->config_data.num_fromhost_data_slots; for (i = 0; i < n && card->from_host_data; i++) { - written = CsrSnprintf(p, remaining, " %u", + written = scnprintf(p, remaining, " %u", (u16)card->from_host_data[i].bd.data_length); UNIFI_SNPRINTF_RET(p, remaining, written); } - written = CsrSnprintf(p, remaining, "\n"); + written = scnprintf(p, remaining, "\n"); UNIFI_SNPRINTF_RET(p, remaining, written); - written = CsrSnprintf(p, remaining, "To host data slots:"); + written = scnprintf(p, remaining, "To host data slots:"); UNIFI_SNPRINTF_RET(p, remaining, written); n = card->config_data.num_tohost_data_slots; for (i = 0; i < n && card->to_host_data; i++) { - written = CsrSnprintf(p, remaining, " %u", + written = scnprintf(p, remaining, " %u", (u16)card->to_host_data[i].data_length); UNIFI_SNPRINTF_RET(p, remaining, written); } - written = CsrSnprintf(p, remaining, "\n"); + written = scnprintf(p, remaining, "\n"); UNIFI_SNPRINTF_RET(p, remaining, written); #ifdef CSR_UNSAFE_SDIO_ACCESS - written = CsrSnprintf(p, remaining, "Host State: %s\n", states[card->host_state]); + written = scnprintf(p, remaining, "Host State: %s\n", states[card->host_state]); UNIFI_SNPRINTF_RET(p, remaining, written); r = unifi_check_io_status(card, &iostate); if (iostate == 1) { - written = CsrSnprintf(p, remaining, "I/O Check: F1 disabled\n"); + written = scnprintf(p, remaining, "I/O Check: F1 disabled\n"); UNIFI_SNPRINTF_RET(p, remaining, written); } else { if (iostate == 1) { - written = CsrSnprintf(p, remaining, "I/O Check: pending interrupt\n"); + written = scnprintf(p, remaining, "I/O Check: pending interrupt\n"); UNIFI_SNPRINTF_RET(p, remaining, written); } - written = CsrSnprintf(p, remaining, "BH reason interrupt = %d\n", + written = scnprintf(p, remaining, "BH reason interrupt = %d\n", card->bh_reason_unifi); UNIFI_SNPRINTF_RET(p, remaining, written); - written = CsrSnprintf(p, remaining, "BH reason host = %d\n", + written = scnprintf(p, remaining, "BH reason host = %d\n", card->bh_reason_host); UNIFI_SNPRINTF_RET(p, remaining, written); @@ -238,26 +238,26 @@ s32 unifi_print_status(card_t *card, char *str, s32 *remain) r = unifi_read_8_or_16(card, card->sdio_ctrl_addr + 2, &b); if ((r == CSR_RESULT_SUCCESS) && (!(b & 0x80))) { - written = CsrSnprintf(p, remaining, "fhsr: %u (driver thinks is %u)\n", + written = scnprintf(p, remaining, "fhsr: %u (driver thinks is %u)\n", b, card->from_host_signals_r); UNIFI_SNPRINTF_RET(p, remaining, written); break; } } iostate = unifi_read_shared_count(card, card->sdio_ctrl_addr + 4); - written = CsrSnprintf(p, remaining, "thsw: %u (driver thinks is %u)\n", + written = scnprintf(p, remaining, "thsw: %u (driver thinks is %u)\n", iostate, card->to_host_signals_w); UNIFI_SNPRINTF_RET(p, remaining, written); } #endif - written = CsrSnprintf(p, remaining, "\nStats:\n"); + written = scnprintf(p, remaining, "\nStats:\n"); UNIFI_SNPRINTF_RET(p, remaining, written); - written = CsrSnprintf(p, remaining, "Total SDIO bytes: R=%lu W=%lu\n", + written = scnprintf(p, remaining, "Total SDIO bytes: R=%u W=%u\n", card->sdio_bytes_read, card->sdio_bytes_written); UNIFI_SNPRINTF_RET(p, remaining, written); - written = CsrSnprintf(p, remaining, "Interrupts generated on card: %lu\n", + written = scnprintf(p, remaining, "Interrupts generated on card: %u\n", card->unifi_interrupt_seq); UNIFI_SNPRINTF_RET(p, remaining, written); diff --git a/drivers/staging/csr/csr_wifi_hip_unifi.h b/drivers/staging/csr/csr_wifi_hip_unifi.h index dc3c60b..2923e2ef 100644 --- a/drivers/staging/csr/csr_wifi_hip_unifi.h +++ b/drivers/staging/csr/csr_wifi_hip_unifi.h @@ -98,7 +98,6 @@ extern "C" { #include "csr_framework_ext.h" /* from the synergy porting folder */ #include "csr_sdio.h" /* from the synergy porting folder */ #include "csr_macro.h" /* from the synergy porting folder */ -#include "csr_formatted_io.h" /* from the synergy gsp folder */ #include "csr_wifi_result.h" /* Utility MACROS. Note that UNIFI_MAC_ADDRESS_CMP returns TRUE on success */ diff --git a/drivers/staging/csr/io.c b/drivers/staging/csr/io.c index deaff25..4774dc8 100644 --- a/drivers/staging/csr/io.c +++ b/drivers/staging/csr/io.c @@ -347,7 +347,7 @@ register_unifi_sdio(CsrSdioFunction *sdio_dev, int bus_id, struct device *dev) /* * We use the slot number as unifi device index. */ - snprintf(priv->proc_entry_name, 64, "driver/unifi%d", priv->instance); + scnprintf(priv->proc_entry_name, 64, "driver/unifi%d", priv->instance); /* * The following complex casting is in place in order to eliminate 64-bit compilation warning * "cast to/from pointer from/to integer of different size" @@ -904,54 +904,54 @@ uf_read_proc(char *page, char **start, off_t offset, int count, orig_p = p; - written = CsrSnprintf(p, remain, "UniFi SDIO Driver: %s %s %s\n", + written = scnprintf(p, remain, "UniFi SDIO Driver: %s %s %s\n", CSR_WIFI_VERSION, __DATE__, __TIME__); UNIFI_SNPRINTF_RET(p, remain, written); #ifdef CSR_SME_USERSPACE - written = CsrSnprintf(p, remain, "SME: CSR userspace "); + written = scnprintf(p, remain, "SME: CSR userspace "); UNIFI_SNPRINTF_RET(p, remain, written); #ifdef CSR_SUPPORT_WEXT - written = CsrSnprintf(p, remain, "with WEXT support\n"); + written = scnprintf(p, remain, "with WEXT support\n"); #else - written = CsrSnprintf(p, remain, "\n"); + written = scnprintf(p, remain, "\n"); #endif /* CSR_SUPPORT_WEXT */ UNIFI_SNPRINTF_RET(p, remain, written); #endif /* CSR_SME_USERSPACE */ #ifdef CSR_NATIVE_LINUX - written = CsrSnprintf(p, remain, "SME: native\n"); + written = scnprintf(p, remain, "SME: native\n"); UNIFI_SNPRINTF_RET(p, remain, written); #endif #ifdef CSR_SUPPORT_SME - written = CsrSnprintf(p, remain, - "Firmware (ROM) build:%lu, Patch:%lu\n", + written = scnprintf(p, remain, + "Firmware (ROM) build:%u, Patch:%u\n", priv->card_info.fw_build, priv->sme_versions.firmwarePatch); UNIFI_SNPRINTF_RET(p, remain, written); #endif p += unifi_print_status(priv->card, p, &remain); - written = CsrSnprintf(p, remain, "Last dbg str: %s\n", + written = scnprintf(p, remain, "Last dbg str: %s\n", priv->last_debug_string); UNIFI_SNPRINTF_RET(p, remain, written); - written = CsrSnprintf(p, remain, "Last dbg16:"); + written = scnprintf(p, remain, "Last dbg16:"); UNIFI_SNPRINTF_RET(p, remain, written); for (i = 0; i < 8; i++) { - written = CsrSnprintf(p, remain, " %04X", + written = scnprintf(p, remain, " %04X", priv->last_debug_word16[i]); UNIFI_SNPRINTF_RET(p, remain, written); } - written = CsrSnprintf(p, remain, "\n"); + written = scnprintf(p, remain, "\n"); UNIFI_SNPRINTF_RET(p, remain, written); - written = CsrSnprintf(p, remain, " "); + written = scnprintf(p, remain, " "); UNIFI_SNPRINTF_RET(p, remain, written); for (; i < 16; i++) { - written = CsrSnprintf(p, remain, " %04X", + written = scnprintf(p, remain, " %04X", priv->last_debug_word16[i]); UNIFI_SNPRINTF_RET(p, remain, written); } - written = CsrSnprintf(p, remain, "\n"); + written = scnprintf(p, remain, "\n"); UNIFI_SNPRINTF_RET(p, remain, written); *start = page; -- cgit v0.10.2 From 390d75c1287bf68c2e29226bf8eb10ae6a08c380 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 31 Jul 2012 14:09:00 +0100 Subject: drivers/iio/adc/at91_adc.c: use devm_ functions The various devm_ functions allocate memory that is released when a driver detaches. This patch uses these functions for data that is allocated in the probe function of a platform device and is only freed in the remove function. The call to platform_get_resource(pdev, IORESOURCE_MEM, 0) is moved coser to the call to devm_request_and_ioremap, which is th first use of the result of platform_get_resource. This does not use devm_request_irq to ensure that free_irq is executed before its idev argument is freed. Signed-off-by: Julia Lawall Reviewed-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index f61780a..98c96f9 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -545,13 +545,6 @@ static int __devinit at91_adc_probe(struct platform_device *pdev) goto error_free_device; } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "No resource defined\n"); - ret = -ENXIO; - goto error_ret; - } - platform_set_drvdata(pdev, idev); idev->dev.parent = &pdev->dev; @@ -566,18 +559,12 @@ static int __devinit at91_adc_probe(struct platform_device *pdev) goto error_free_device; } - if (!request_mem_region(res->start, resource_size(res), - "AT91 adc registers")) { - dev_err(&pdev->dev, "Resources are unavailable.\n"); - ret = -EBUSY; - goto error_free_device; - } + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - st->reg_base = ioremap(res->start, resource_size(res)); + st->reg_base = devm_request_and_ioremap(&pdev->dev, res); if (!st->reg_base) { - dev_err(&pdev->dev, "Failed to map registers.\n"); ret = -ENOMEM; - goto error_release_mem; + goto error_free_device; } /* @@ -592,10 +579,10 @@ static int __devinit at91_adc_probe(struct platform_device *pdev) idev); if (ret) { dev_err(&pdev->dev, "Failed to allocate IRQ.\n"); - goto error_unmap_reg; + goto error_free_device; } - st->clk = clk_get(&pdev->dev, "adc_clk"); + st->clk = devm_clk_get(&pdev->dev, "adc_clk"); if (IS_ERR(st->clk)) { dev_err(&pdev->dev, "Failed to get the clock.\n"); ret = PTR_ERR(st->clk); @@ -605,7 +592,7 @@ static int __devinit at91_adc_probe(struct platform_device *pdev) ret = clk_prepare(st->clk); if (ret) { dev_err(&pdev->dev, "Could not prepare the clock.\n"); - goto error_free_clk; + goto error_free_irq; } ret = clk_enable(st->clk); @@ -614,7 +601,7 @@ static int __devinit at91_adc_probe(struct platform_device *pdev) goto error_unprepare_clk; } - st->adc_clk = clk_get(&pdev->dev, "adc_op_clk"); + st->adc_clk = devm_clk_get(&pdev->dev, "adc_op_clk"); if (IS_ERR(st->adc_clk)) { dev_err(&pdev->dev, "Failed to get the ADC clock.\n"); ret = PTR_ERR(st->clk); @@ -624,7 +611,7 @@ static int __devinit at91_adc_probe(struct platform_device *pdev) ret = clk_prepare(st->adc_clk); if (ret) { dev_err(&pdev->dev, "Could not prepare the ADC clock.\n"); - goto error_free_adc_clk; + goto error_disable_clk; } ret = clk_enable(st->adc_clk); @@ -697,20 +684,12 @@ error_disable_adc_clk: clk_disable(st->adc_clk); error_unprepare_adc_clk: clk_unprepare(st->adc_clk); -error_free_adc_clk: - clk_put(st->adc_clk); error_disable_clk: clk_disable(st->clk); error_unprepare_clk: clk_unprepare(st->clk); -error_free_clk: - clk_put(st->clk); error_free_irq: free_irq(st->irq, idev); -error_unmap_reg: - iounmap(st->reg_base); -error_release_mem: - release_mem_region(res->start, resource_size(res)); error_free_device: iio_device_free(idev); error_ret: @@ -720,20 +699,15 @@ error_ret: static int __devexit at91_adc_remove(struct platform_device *pdev) { struct iio_dev *idev = platform_get_drvdata(pdev); - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); struct at91_adc_state *st = iio_priv(idev); iio_device_unregister(idev); at91_adc_trigger_remove(idev); at91_adc_buffer_remove(idev); clk_disable_unprepare(st->adc_clk); - clk_put(st->adc_clk); clk_disable(st->clk); clk_unprepare(st->clk); - clk_put(st->clk); free_irq(st->irq, idev); - iounmap(st->reg_base); - release_mem_region(res->start, resource_size(res)); iio_device_free(idev); return 0; -- cgit v0.10.2 From 6cffc1f814b25d59ca6f0cd75b64bb159801c0fa Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 12 Aug 2012 16:21:00 +0100 Subject: IIO: Add 4-byte unsigned reads into generic-buffer example Add unsigned 32bit-wide reads into the generic-buffer.c Signed-off-by: Marek Vasut Cc: Jonathan Cameron Cc: Juergen Beisert Cc: Lars-Peter Clausen Cc: Wolfgang Denk Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/Documentation/generic_buffer.c b/drivers/staging/iio/Documentation/generic_buffer.c index 827e92d..40d0eca 100644 --- a/drivers/staging/iio/Documentation/generic_buffer.c +++ b/drivers/staging/iio/Documentation/generic_buffer.c @@ -104,6 +104,16 @@ void process_scan(char *data, print2byte(*(uint16_t *)(data + channels[k].location), &channels[k]); break; + case 4: + if (!channels[k].is_signed) { + uint32_t val = *(uint32_t *) + (data + channels[k].location); + printf("%05f ", ((float)val + + channels[k].offset)* + channels[k].scale); + + } + break; case 8: if (channels[k].is_signed) { int64_t val = *(int64_t *) -- cgit v0.10.2 From bc2c90c974a0ed390327bbd94f49269e9f24e280 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 12 Aug 2012 16:21:00 +0100 Subject: IIO: Add basic MXS LRADC driver This driver is very basic. It supports userland trigger, buffer and raw access to channels. The support for delay channels is missing altogether. Signed-off-by: Marek Vasut Signed-off-by: Jonathan Cameron Cc: Jonathan Cameron Cc: Juergen Beisert Cc: Lars-Peter Clausen Cc: Shawn Guo Cc: Wolfgang Denk diff --git a/Documentation/devicetree/bindings/staging/iio/adc/mxs-lradc.txt b/Documentation/devicetree/bindings/staging/iio/adc/mxs-lradc.txt new file mode 100644 index 0000000..801d58c --- /dev/null +++ b/Documentation/devicetree/bindings/staging/iio/adc/mxs-lradc.txt @@ -0,0 +1,15 @@ +* Freescale i.MX28 LRADC device driver + +Required properties: +- compatible: Should be "fsl,imx28-lradc" +- reg: Address and length of the register set for the device +- interrupts: Should contain the LRADC interrupts + +Examples: + + lradc@80050000 { + compatible = "fsl,imx28-lradc"; + reg = <0x80050000 0x2000>; + interrupts = <10 14 15 16 17 18 19 + 20 21 22 23 24 25>; + }; diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index 67711b7..845fb6c 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -200,6 +200,18 @@ config LPC32XX_ADC activate only one via device tree selection. Provides direct access via sysfs. +config MXS_LRADC + tristate "Freescale i.MX28 LRADC" + depends on ARCH_MXS + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER + help + Say yes here to build support for i.MX28 LRADC convertor + built into these chips. + + To compile this driver as a module, choose M here: the + module will be called mxs-lradc. + config SPEAR_ADC tristate "ST SPEAr ADC" depends on PLAT_SPEAR diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile index 14e98b6..ecac9a0 100644 --- a/drivers/staging/iio/adc/Makefile +++ b/drivers/staging/iio/adc/Makefile @@ -38,4 +38,5 @@ obj-$(CONFIG_ADT7310) += adt7310.o obj-$(CONFIG_ADT7410) += adt7410.o obj-$(CONFIG_AD7280) += ad7280a.o obj-$(CONFIG_LPC32XX_ADC) += lpc32xx_adc.o +obj-$(CONFIG_MXS_LRADC) += mxs-lradc.o obj-$(CONFIG_SPEAR_ADC) += spear_adc.o diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c new file mode 100644 index 0000000..ae549e5 --- /dev/null +++ b/drivers/staging/iio/adc/mxs-lradc.c @@ -0,0 +1,590 @@ +/* + * Freescale i.MX28 LRADC driver + * + * Copyright (c) 2012 DENX Software Engineering, GmbH. + * Marek Vasut + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#define DRIVER_NAME "mxs-lradc" + +#define LRADC_MAX_DELAY_CHANS 4 +#define LRADC_MAX_MAPPED_CHANS 8 +#define LRADC_MAX_TOTAL_CHANS 16 + +#define LRADC_DELAY_TIMER_HZ 2000 + +/* + * Make this runtime configurable if necessary. Currently, if the buffered mode + * is enabled, the LRADC takes LRADC_DELAY_TIMER_LOOP samples of data before + * triggering IRQ. The sampling happens every (LRADC_DELAY_TIMER_PER / 2000) + * seconds. The result is that the samples arrive every 500mS. + */ +#define LRADC_DELAY_TIMER_PER 200 +#define LRADC_DELAY_TIMER_LOOP 5 + +static const char * const mxs_lradc_irq_name[] = { + "mxs-lradc-touchscreen", + "mxs-lradc-thresh0", + "mxs-lradc-thresh1", + "mxs-lradc-channel0", + "mxs-lradc-channel1", + "mxs-lradc-channel2", + "mxs-lradc-channel3", + "mxs-lradc-channel4", + "mxs-lradc-channel5", + "mxs-lradc-channel6", + "mxs-lradc-channel7", + "mxs-lradc-button0", + "mxs-lradc-button1", +}; + +struct mxs_lradc_chan { + uint8_t slot; + uint8_t flags; +}; + +struct mxs_lradc { + struct device *dev; + void __iomem *base; + int irq[13]; + + uint32_t *buffer; + struct iio_trigger *trig; + + struct mutex lock; + + uint8_t enable; + + struct completion completion; +}; + +#define LRADC_CTRL0 0x00 +#define LRADC_CTRL0_TOUCH_DETECT_ENABLE (1 << 23) +#define LRADC_CTRL0_TOUCH_SCREEN_TYPE (1 << 22) + +#define LRADC_CTRL1 0x10 +#define LRADC_CTRL1_LRADC_IRQ(n) (1 << (n)) +#define LRADC_CTRL1_LRADC_IRQ_MASK 0x1fff +#define LRADC_CTRL1_LRADC_IRQ_EN(n) (1 << ((n) + 16)) +#define LRADC_CTRL1_LRADC_IRQ_EN_MASK (0x1fff << 16) + +#define LRADC_CTRL2 0x20 +#define LRADC_CTRL2_TEMPSENSE_PWD (1 << 15) + +#define LRADC_CH(n) (0x50 + (0x10 * (n))) +#define LRADC_CH_ACCUMULATE (1 << 29) +#define LRADC_CH_NUM_SAMPLES_MASK (0x1f << 24) +#define LRADC_CH_NUM_SAMPLES_OFFSET 24 +#define LRADC_CH_VALUE_MASK 0x3ffff +#define LRADC_CH_VALUE_OFFSET 0 + +#define LRADC_DELAY(n) (0xd0 + (0x10 * (n))) +#define LRADC_DELAY_TRIGGER_LRADCS_MASK (0xff << 24) +#define LRADC_DELAY_TRIGGER_LRADCS_OFFSET 24 +#define LRADC_DELAY_KICK (1 << 20) +#define LRADC_DELAY_TRIGGER_DELAYS_MASK (0xf << 16) +#define LRADC_DELAY_TRIGGER_DELAYS_OFFSET 16 +#define LRADC_DELAY_LOOP_COUNT_MASK (0x1f << 11) +#define LRADC_DELAY_LOOP_COUNT_OFFSET 11 +#define LRADC_DELAY_DELAY_MASK 0x7ff +#define LRADC_DELAY_DELAY_OFFSET 0 + +#define LRADC_CTRL4 0x140 +#define LRADC_CTRL4_LRADCSELECT_MASK(n) (0xf << ((n) * 4)) +#define LRADC_CTRL4_LRADCSELECT_OFFSET(n) ((n) * 4) + +/* + * Raw I/O operations + */ +static int mxs_lradc_read_raw(struct iio_dev *iio_dev, + const struct iio_chan_spec *chan, + int *val, int *val2, long m) +{ + struct mxs_lradc *lradc = iio_priv(iio_dev); + int ret; + + if (m != IIO_CHAN_INFO_RAW) + return -EINVAL; + + /* Check for invalid channel */ + if (chan->channel > LRADC_MAX_TOTAL_CHANS) + return -EINVAL; + + /* + * See if there is no buffered operation in progess. If there is, simply + * bail out. This can be improved to support both buffered and raw IO at + * the same time, yet the code becomes horribly complicated. Therefore I + * applied KISS principle here. + */ + ret = mutex_trylock(&lradc->lock); + if (!ret) + return -EBUSY; + + INIT_COMPLETION(lradc->completion); + + /* + * No buffered operation in progress, map the channel and trigger it. + * Virtual channel 0 is always used here as the others are always not + * used if doing raw sampling. + */ + writel(LRADC_CTRL1_LRADC_IRQ_EN_MASK, + lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR); + writel(0xff, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR); + + writel(chan->channel, lradc->base + LRADC_CTRL4); + writel(0, lradc->base + LRADC_CH(0)); + + /* Enable the IRQ and start sampling the channel. */ + writel(LRADC_CTRL1_LRADC_IRQ_EN(0), + lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_SET); + writel(1 << 0, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET); + + /* Wait for completion on the channel, 1 second max. */ + ret = wait_for_completion_killable_timeout(&lradc->completion, HZ); + if (!ret) + ret = -ETIMEDOUT; + if (ret < 0) + goto err; + + /* Read the data. */ + *val = readl(lradc->base + LRADC_CH(0)) & LRADC_CH_VALUE_MASK; + ret = IIO_VAL_INT; + +err: + writel(LRADC_CTRL1_LRADC_IRQ_EN(0), + lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR); + + mutex_unlock(&lradc->lock); + + return ret; +} + +static const struct iio_info mxs_lradc_iio_info = { + .driver_module = THIS_MODULE, + .read_raw = mxs_lradc_read_raw, +}; + +/* + * IRQ Handling + */ +static irqreturn_t mxs_lradc_handle_irq(int irq, void *data) +{ + struct iio_dev *iio = data; + struct mxs_lradc *lradc = iio_priv(iio); + unsigned long reg = readl(lradc->base + LRADC_CTRL1); + + if (!(reg & LRADC_CTRL1_LRADC_IRQ_MASK)) + return IRQ_NONE; + + /* + * Touchscreen IRQ handling code shall probably have priority + * and therefore shall be placed here. + */ + + if (iio_buffer_enabled(iio)) + iio_trigger_poll(iio->trig, iio_get_time_ns()); + else if (reg & LRADC_CTRL1_LRADC_IRQ(0)) + complete(&lradc->completion); + + writel(reg & LRADC_CTRL1_LRADC_IRQ_MASK, + lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR); + + return IRQ_HANDLED; +} + +/* + * Trigger handling + */ +static irqreturn_t mxs_lradc_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *iio = pf->indio_dev; + struct mxs_lradc *lradc = iio_priv(iio); + struct iio_buffer *buffer = iio->buffer; + const uint32_t chan_value = LRADC_CH_ACCUMULATE | + ((LRADC_DELAY_TIMER_LOOP - 1) << LRADC_CH_NUM_SAMPLES_OFFSET); + int i, j = 0; + + for_each_set_bit(i, iio->active_scan_mask, iio->masklength) { + lradc->buffer[j] = readl(lradc->base + LRADC_CH(j)); + writel(chan_value, lradc->base + LRADC_CH(j)); + lradc->buffer[j] &= LRADC_CH_VALUE_MASK; + lradc->buffer[j] /= LRADC_DELAY_TIMER_LOOP; + j++; + } + + if (iio->scan_timestamp) { + s64 *timestamp = (s64 *)((u8 *)lradc->buffer + + ALIGN(j, sizeof(s64))); + *timestamp = pf->timestamp; + } + + iio_push_to_buffer(buffer, (u8 *)lradc->buffer, pf->timestamp); + + iio_trigger_notify_done(iio->trig); + + return IRQ_HANDLED; +} + +static int mxs_lradc_configure_trigger(struct iio_trigger *trig, bool state) +{ + struct iio_dev *iio = trig->private_data; + struct mxs_lradc *lradc = iio_priv(iio); + const uint32_t st = state ? STMP_OFFSET_REG_SET : STMP_OFFSET_REG_CLR; + + writel(LRADC_DELAY_KICK, lradc->base + LRADC_DELAY(0) + st); + + return 0; +} + +static const struct iio_trigger_ops mxs_lradc_trigger_ops = { + .owner = THIS_MODULE, + .set_trigger_state = &mxs_lradc_configure_trigger, +}; + +static int mxs_lradc_trigger_init(struct iio_dev *iio) +{ + int ret; + struct iio_trigger *trig; + + trig = iio_trigger_alloc("%s-dev%i", iio->name, iio->id); + if (trig == NULL) + return -ENOMEM; + + trig->dev.parent = iio->dev.parent; + trig->private_data = iio; + trig->ops = &mxs_lradc_trigger_ops; + + ret = iio_trigger_register(trig); + if (ret) { + iio_trigger_free(trig); + return ret; + } + + iio->trig = trig; + + return 0; +} + +static void mxs_lradc_trigger_remove(struct iio_dev *iio) +{ + iio_trigger_unregister(iio->trig); + iio_trigger_free(iio->trig); +} + +static int mxs_lradc_buffer_preenable(struct iio_dev *iio) +{ + struct mxs_lradc *lradc = iio_priv(iio); + struct iio_buffer *buffer = iio->buffer; + int ret = 0, chan, ofs = 0, enable = 0; + uint32_t ctrl4 = 0; + uint32_t ctrl1_irq = 0; + const uint32_t chan_value = LRADC_CH_ACCUMULATE | + ((LRADC_DELAY_TIMER_LOOP - 1) << LRADC_CH_NUM_SAMPLES_OFFSET); + const int len = bitmap_weight(buffer->scan_mask, LRADC_MAX_TOTAL_CHANS); + + if (!len) + return -EINVAL; + + /* + * Lock the driver so raw access can not be done during buffered + * operation. This simplifies the code a lot. + */ + ret = mutex_trylock(&lradc->lock); + if (!ret) + return -EBUSY; + + lradc->buffer = kmalloc(len * sizeof(*lradc->buffer), GFP_KERNEL); + if (!lradc->buffer) { + ret = -ENOMEM; + goto err_mem; + } + + ret = iio_sw_buffer_preenable(iio); + if (ret < 0) + goto err_buf; + + writel(LRADC_CTRL1_LRADC_IRQ_EN_MASK, + lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR); + writel(0xff, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR); + + for_each_set_bit(chan, buffer->scan_mask, LRADC_MAX_TOTAL_CHANS) { + ctrl4 |= chan << LRADC_CTRL4_LRADCSELECT_OFFSET(ofs); + ctrl1_irq |= LRADC_CTRL1_LRADC_IRQ_EN(ofs); + writel(chan_value, lradc->base + LRADC_CH(ofs)); + enable |= 1 << ofs; + ofs++; + }; + + writel(LRADC_DELAY_TRIGGER_LRADCS_MASK | LRADC_DELAY_KICK, + lradc->base + LRADC_DELAY(0) + STMP_OFFSET_REG_CLR); + + writel(ctrl4, lradc->base + LRADC_CTRL4); + writel(ctrl1_irq, lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_SET); + + writel(enable << LRADC_DELAY_TRIGGER_LRADCS_OFFSET, + lradc->base + LRADC_DELAY(0) + STMP_OFFSET_REG_SET); + + return 0; + +err_buf: + kfree(lradc->buffer); +err_mem: + mutex_unlock(&lradc->lock); + return ret; +} + +static int mxs_lradc_buffer_postdisable(struct iio_dev *iio) +{ + struct mxs_lradc *lradc = iio_priv(iio); + + writel(LRADC_DELAY_TRIGGER_LRADCS_MASK | LRADC_DELAY_KICK, + lradc->base + LRADC_DELAY(0) + STMP_OFFSET_REG_CLR); + + writel(0xff, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR); + writel(LRADC_CTRL1_LRADC_IRQ_EN_MASK, + lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR); + + kfree(lradc->buffer); + mutex_unlock(&lradc->lock); + + return 0; +} + +static bool mxs_lradc_validate_scan_mask(struct iio_dev *iio, + const unsigned long *mask) +{ + const int mw = bitmap_weight(mask, iio->masklength); + + return mw <= LRADC_MAX_MAPPED_CHANS; +} + +static const struct iio_buffer_setup_ops mxs_lradc_buffer_ops = { + .preenable = &mxs_lradc_buffer_preenable, + .postenable = &iio_triggered_buffer_postenable, + .predisable = &iio_triggered_buffer_predisable, + .postdisable = &mxs_lradc_buffer_postdisable, + .validate_scan_mask = &mxs_lradc_validate_scan_mask, +}; + +/* + * Driver initialization + */ + +#define MXS_ADC_CHAN(idx, chan_type) { \ + .type = (chan_type), \ + .indexed = 1, \ + .scan_index = (idx), \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, \ + .channel = (idx), \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 18, \ + .storagebits = 32, \ + }, \ +} + +static const struct iio_chan_spec mxs_lradc_chan_spec[] = { + MXS_ADC_CHAN(0, IIO_VOLTAGE), + MXS_ADC_CHAN(1, IIO_VOLTAGE), + MXS_ADC_CHAN(2, IIO_VOLTAGE), + MXS_ADC_CHAN(3, IIO_VOLTAGE), + MXS_ADC_CHAN(4, IIO_VOLTAGE), + MXS_ADC_CHAN(5, IIO_VOLTAGE), + MXS_ADC_CHAN(6, IIO_VOLTAGE), + MXS_ADC_CHAN(7, IIO_VOLTAGE), /* VBATT */ + MXS_ADC_CHAN(8, IIO_TEMP), /* Temp sense 0 */ + MXS_ADC_CHAN(9, IIO_TEMP), /* Temp sense 1 */ + MXS_ADC_CHAN(10, IIO_VOLTAGE), /* VDDIO */ + MXS_ADC_CHAN(11, IIO_VOLTAGE), /* VTH */ + MXS_ADC_CHAN(12, IIO_VOLTAGE), /* VDDA */ + MXS_ADC_CHAN(13, IIO_VOLTAGE), /* VDDD */ + MXS_ADC_CHAN(14, IIO_VOLTAGE), /* VBG */ + MXS_ADC_CHAN(15, IIO_VOLTAGE), /* VDD5V */ +}; + +static void mxs_lradc_hw_init(struct mxs_lradc *lradc) +{ + int i; + const uint32_t cfg = + (LRADC_DELAY_TIMER_PER << LRADC_DELAY_DELAY_OFFSET); + + stmp_reset_block(lradc->base); + + for (i = 0; i < LRADC_MAX_DELAY_CHANS; i++) + writel(cfg | (1 << (LRADC_DELAY_TRIGGER_DELAYS_OFFSET + i)), + lradc->base + LRADC_DELAY(i)); + + /* Start internal temperature sensing. */ + writel(0, lradc->base + LRADC_CTRL2); +} + +static void mxs_lradc_hw_stop(struct mxs_lradc *lradc) +{ + int i; + + writel(LRADC_CTRL1_LRADC_IRQ_EN_MASK, + lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR); + + for (i = 0; i < LRADC_MAX_DELAY_CHANS; i++) + writel(0, lradc->base + LRADC_DELAY(i)); +} + +static int __devinit mxs_lradc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct mxs_lradc *lradc; + struct iio_dev *iio; + struct resource *iores; + int ret = 0; + int i; + + /* Allocate the IIO device. */ + iio = iio_device_alloc(sizeof(*lradc)); + if (!iio) { + dev_err(dev, "Failed to allocate IIO device\n"); + return -ENOMEM; + } + + lradc = iio_priv(iio); + + /* Grab the memory area */ + iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); + lradc->dev = &pdev->dev; + lradc->base = devm_request_and_ioremap(dev, iores); + if (!lradc->base) { + ret = -EADDRNOTAVAIL; + goto err_addr; + } + + /* Grab all IRQ sources */ + for (i = 0; i < 13; i++) { + lradc->irq[i] = platform_get_irq(pdev, i); + if (lradc->irq[i] < 0) { + ret = -EINVAL; + goto err_addr; + } + + ret = devm_request_irq(dev, lradc->irq[i], + mxs_lradc_handle_irq, 0, + mxs_lradc_irq_name[i], iio); + if (ret) + goto err_addr; + } + + platform_set_drvdata(pdev, iio); + + init_completion(&lradc->completion); + mutex_init(&lradc->lock); + + iio->name = pdev->name; + iio->dev.parent = &pdev->dev; + iio->info = &mxs_lradc_iio_info; + iio->modes = INDIO_DIRECT_MODE; + iio->channels = mxs_lradc_chan_spec; + iio->num_channels = ARRAY_SIZE(mxs_lradc_chan_spec); + + ret = iio_triggered_buffer_setup(iio, &iio_pollfunc_store_time, + &mxs_lradc_trigger_handler, + &mxs_lradc_buffer_ops); + if (ret) + goto err_addr; + + ret = mxs_lradc_trigger_init(iio); + if (ret) + goto err_trig; + + /* Register IIO device. */ + ret = iio_device_register(iio); + if (ret) { + dev_err(dev, "Failed to register IIO device\n"); + goto err_dev; + } + + /* Configure the hardware. */ + mxs_lradc_hw_init(lradc); + + return 0; + +err_dev: + mxs_lradc_trigger_remove(iio); +err_trig: + iio_triggered_buffer_cleanup(iio); +err_addr: + iio_device_free(iio); + return ret; +} + +static int __devexit mxs_lradc_remove(struct platform_device *pdev) +{ + struct iio_dev *iio = platform_get_drvdata(pdev); + struct mxs_lradc *lradc = iio_priv(iio); + + mxs_lradc_hw_stop(lradc); + + iio_device_unregister(iio); + iio_triggered_buffer_cleanup(iio); + mxs_lradc_trigger_remove(iio); + iio_device_free(iio); + + return 0; +} + +static const struct of_device_id mxs_lradc_dt_ids[] = { + { .compatible = "fsl,imx28-lradc", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, mxs_lradc_dt_ids); + +static struct platform_driver mxs_lradc_driver = { + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = mxs_lradc_dt_ids, + }, + .probe = mxs_lradc_probe, + .remove = __devexit_p(mxs_lradc_remove), +}; + +module_platform_driver(mxs_lradc_driver); + +MODULE_AUTHOR("Marek Vasut "); +MODULE_DESCRIPTION("Freescale i.MX28 LRADC driver"); +MODULE_LICENSE("GPL v2"); -- cgit v0.10.2 From 424d56ec3ca0ea5a4cc4caad885d8e49a3cfafc8 Mon Sep 17 00:00:00 2001 From: Omar Ramirez Luna Date: Thu, 16 Aug 2012 18:33:26 -0500 Subject: staging: tidspbridge: fix uuid strings Commit 8cb05f4b54535cb91d7a5f9f8eb230bd4fa86e4e (staging: tidspbridge: eliminate uuid_uuid_to_string), not only broke compilation but also functionality for tidspbridge driver. So: - Replace remaining instances of uuid_uuid_to_string with snprintf to fix compilation. - Fix the format from %pU to %pUL. - Since these UUIDs are used in the firmware to reference section names, the firmware doesn't follow the standard uuid delimiter '-' it uses '_' instead. The driver can follow the standard convention however for dsp sections we must transform the uuid to what is expected by the firmware. E.g.: tidspbridge sees: 24BC8D90-BB45-11D4-B756-006008BDB66F firmware expects: .24BC8D90_BB45_11D4_B756_006008BDB66F Signed-off-by: Omar Ramirez Luna CC: Andy Shevchenko Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/tidspbridge/rmgr/dbdcd.c b/drivers/staging/tidspbridge/rmgr/dbdcd.c index e05670d..9d52c3c 100644 --- a/drivers/staging/tidspbridge/rmgr/dbdcd.c +++ b/drivers/staging/tidspbridge/rmgr/dbdcd.c @@ -346,11 +346,13 @@ int dcd_get_object_def(struct dcd_manager *hdcd_mgr, struct dcd_manager *dcd_mgr_obj = hdcd_mgr; /* ptr to DCD mgr */ struct cod_libraryobj *lib = NULL; int status = 0; + int len; u32 ul_addr = 0; /* Used by cod_get_section */ u32 ul_len = 0; /* Used by cod_get_section */ u32 dw_buf_size; /* Used by REG functions */ char sz_reg_key[DCD_MAXPATHLENGTH]; char *sz_uuid; /*[MAXUUIDLEN]; */ + char *tmp; struct dcd_key_elem *dcd_key = NULL; char sz_sect_name[MAXUUIDLEN + 2]; /* ".[UUID]\0" */ char *psz_coff_buf; @@ -395,7 +397,7 @@ int dcd_get_object_def(struct dcd_manager *hdcd_mgr, } /* Create UUID value to set in registry. */ - snprintf(sz_uuid, MAXUUIDLEN, "%pU", obj_uuid); + snprintf(sz_uuid, MAXUUIDLEN, "%pUL", obj_uuid); if ((strlen(sz_reg_key) + MAXUUIDLEN) < DCD_MAXPATHLENGTH) strncat(sz_reg_key, sz_uuid, MAXUUIDLEN); @@ -429,12 +431,27 @@ int dcd_get_object_def(struct dcd_manager *hdcd_mgr, } /* Ensure sz_uuid + 1 is not greater than sizeof sz_sect_name. */ + len = strlen(sz_uuid); + if (len + 1 > sizeof(sz_sect_name)) { + status = -EPERM; + goto func_end; + } /* Create section name based on node UUID. A period is * pre-pended to the UUID string to form the section name. * I.e. ".24BC8D90_BB45_11d4_B756_006008BDB66F" */ + + len -= 4; /* uuid has 4 delimiters '-' */ + tmp = sz_uuid; + strncpy(sz_sect_name, ".", 2); - strncat(sz_sect_name, sz_uuid, strlen(sz_uuid)); + do { + char *uuid = strsep(&tmp, "-"); + if (!uuid) + break; + len -= strlen(uuid); + strncat(sz_sect_name, uuid, strlen(uuid) + 1); + } while (len && strncat(sz_sect_name, "_", 2)); /* Get section information. */ status = cod_get_section(lib, sz_sect_name, &ul_addr, &ul_len); @@ -666,7 +683,7 @@ int dcd_get_library_name(struct dcd_manager *hdcd_mgr, status = -EPERM; } /* Create UUID value to find match in registry. */ - uuid_uuid_to_string(uuid_obj, sz_uuid, MAXUUIDLEN); + snprintf(sz_uuid, MAXUUIDLEN, "%pUL", uuid_obj); if ((strlen(sz_reg_key) + MAXUUIDLEN) < DCD_MAXPATHLENGTH) strncat(sz_reg_key, sz_uuid, MAXUUIDLEN); else @@ -706,7 +723,7 @@ int dcd_get_library_name(struct dcd_manager *hdcd_mgr, } else { status = -EPERM; } - uuid_uuid_to_string(uuid_obj, sz_uuid, MAXUUIDLEN); + snprintf(sz_uuid, MAXUUIDLEN, "%pUL", uuid_obj); if ((strlen(sz_reg_key) + MAXUUIDLEN) < DCD_MAXPATHLENGTH) strncat(sz_reg_key, sz_uuid, MAXUUIDLEN); else @@ -797,7 +814,7 @@ int dcd_register_object(struct dsp_uuid *uuid_obj, status = -EPERM; /* Create UUID value to set in registry. */ - uuid_uuid_to_string(uuid_obj, sz_uuid, MAXUUIDLEN); + snprintf(sz_uuid, MAXUUIDLEN, "%pUL", uuid_obj); if ((strlen(sz_reg_key) + MAXUUIDLEN) < DCD_MAXPATHLENGTH) strncat(sz_reg_key, sz_uuid, MAXUUIDLEN); else diff --git a/drivers/staging/tidspbridge/rmgr/node.c b/drivers/staging/tidspbridge/rmgr/node.c index f17c128..c2fc613 100644 --- a/drivers/staging/tidspbridge/rmgr/node.c +++ b/drivers/staging/tidspbridge/rmgr/node.c @@ -2714,8 +2714,7 @@ static int get_node_props(struct dcd_manager *hdcd_mgr, hnode->ntype = node_type = pndb_props->ntype; /* Create UUID value to set in registry. */ - uuid_uuid_to_string((struct dsp_uuid *)node_uuid, sz_uuid, - MAXUUIDLEN); + snprintf(sz_uuid, MAXUUIDLEN, "%pUL", node_uuid); dev_dbg(bridge, "(node) UUID: %s\n", sz_uuid); /* Fill in message args that come from NDB */ -- cgit v0.10.2 From 12a2dd66a259f2ae6bd26243f711383d710872b9 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 16 Aug 2012 19:41:45 -0700 Subject: staging: comedi: adl_pci6208: remove manual legacy attach This driver uses the 'attach_pci' callback to attach the pci device to the comedi subsystem. Since the 'attach' callback is now optional it can be removed from the driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c index 3abff556..99fbd94 100644 --- a/drivers/staging/comedi/drivers/adl_pci6208.c +++ b/drivers/staging/comedi/drivers/adl_pci6208.c @@ -248,15 +248,6 @@ static int pci6208_attach_pci(struct comedi_device *dev, return 0; } -static int pci6208_attach(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - dev_warn(dev->class_dev, - "This driver does not support attach using comedi_config\n"); - - return -ENOSYS; -} - static void pci6208_detach(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -270,7 +261,6 @@ static void pci6208_detach(struct comedi_device *dev) static struct comedi_driver adl_pci6208_driver = { .driver_name = "adl_pci6208", .module = THIS_MODULE, - .attach = pci6208_attach, .attach_pci = pci6208_attach_pci, .detach = pci6208_detach, }; -- cgit v0.10.2 From c1a54962537afe40351f390bbb0197c49f858b6d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 16 Aug 2012 19:42:09 -0700 Subject: staging: comedi: adl_pci7296: remove manual legacy attach This driver uses the 'attach_pci' callback to attach the pci device to the comedi subsystem. Since the 'attach' callback is now optional it can be removed from the driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci7296.c b/drivers/staging/comedi/drivers/adl_pci7296.c index 1b9ea54..67233be 100644 --- a/drivers/staging/comedi/drivers/adl_pci7296.c +++ b/drivers/staging/comedi/drivers/adl_pci7296.c @@ -133,15 +133,6 @@ static int adl_pci7296_attach_pci(struct comedi_device *dev, return 0; } -static int adl_pci7296_attach(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - dev_warn(dev->class_dev, - "This driver does not support attach using comedi_config\n"); - - return -ENOSYS; -} - static void adl_pci7296_detach(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -164,7 +155,6 @@ static void adl_pci7296_detach(struct comedi_device *dev) static struct comedi_driver adl_pci7296_driver = { .driver_name = "adl_pci7296", .module = THIS_MODULE, - .attach = adl_pci7296_attach, .attach_pci = adl_pci7296_attach_pci, .detach = adl_pci7296_detach, }; -- cgit v0.10.2 From 180d7fc8ab7ace9b911196d6eba2c1e47c3cbe85 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 16 Aug 2012 19:42:30 -0700 Subject: staging: comedi: adl_pci7x3x: remove manual legacy attach This driver uses the 'attach_pci' callback to attach the pci device to the comedi subsystem. Since the 'attach' callback is now optional it can be removed from the driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci7x3x.c b/drivers/staging/comedi/drivers/adl_pci7x3x.c index 41963fb..48b3baa 100644 --- a/drivers/staging/comedi/drivers/adl_pci7x3x.c +++ b/drivers/staging/comedi/drivers/adl_pci7x3x.c @@ -280,15 +280,6 @@ static int adl_pci7x3x_attach_pci(struct comedi_device *dev, return 0; } -static int adl_pci7x3x_attach(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - dev_warn(dev->class_dev, - "This driver does not support attach using comedi_config\n"); - - return -ENOSYS; -} - static void adl_pci7x3x_detach(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -302,7 +293,6 @@ static void adl_pci7x3x_detach(struct comedi_device *dev) static struct comedi_driver adl_pci7x3x_driver = { .driver_name = "adl_pci7x3x", .module = THIS_MODULE, - .attach = adl_pci7x3x_attach, .attach_pci = adl_pci7x3x_attach_pci, .detach = adl_pci7x3x_detach, }; -- cgit v0.10.2 From 6bfbd988d8abfd86e0cd93ae21ba1998378bddfa Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 16 Aug 2012 19:43:05 -0700 Subject: staging: comedi: adl_pci8164: use attach_pci callback Convert this PCI driver to use the comedi PCI auto config attach mechanism by adding an 'attach_pci' callback function. Since the driver does not require any external configuration options, and the legacy 'attach' callback is now optional, remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c index 247ef00..ac406cf 100644 --- a/drivers/staging/comedi/drivers/adl_pci8164.c +++ b/drivers/staging/comedi/drivers/adl_pci8164.c @@ -27,11 +27,7 @@ Author: Michel Lachaine Status: experimental Updated: Mon, 14 Apr 2008 15:10:32 +0100 -Configuration Options: - [0] - PCI bus of device (optional) - [1] - PCI slot of device (optional) - If bus/slot is not specified, the first supported - PCI device found will be used. +Configuration Options: not applicable, uses PCI auto config */ #include "../comedidev.h" @@ -216,59 +212,24 @@ static int adl_pci8164_insn_write_buf1(struct comedi_device *dev, return 2; } -static struct pci_dev *adl_pci8164_find_pci(struct comedi_device *dev, - struct comedi_devconfig *it) +static int adl_pci8164_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) { - struct pci_dev *pcidev = NULL; - int bus = it->options[0]; - int slot = it->options[1]; - - for_each_pci_dev(pcidev) { - if (pcidev->vendor != PCI_VENDOR_ID_ADLINK || - pcidev->device != PCI_DEVICE_ID_PCI8164) - continue; - if (bus || slot) { - /* requested particular bus/slot */ - if (pcidev->bus->number != bus || - PCI_SLOT(pcidev->devfn) != slot) - continue; - } - return pcidev; - } - printk(KERN_ERR - "comedi%d: no supported board found! (req. bus/slot : %d/%d)\n", - dev->minor, bus, slot); - return NULL; -} - -static int adl_pci8164_attach(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - struct pci_dev *pcidev; struct comedi_subdevice *s; int ret; - printk(KERN_INFO "comedi: attempt to attach...\n"); - printk(KERN_INFO "comedi%d: adl_pci8164\n", dev->minor); + comedi_set_hw_dev(dev, &pcidev->dev); - dev->board_name = "pci8164"; + dev->board_name = dev->driver->driver_name; - ret = comedi_alloc_subdevices(dev, 4); + ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) return ret; - - pcidev = adl_pci8164_find_pci(dev, it); - if (!pcidev) - return -EIO; - comedi_set_hw_dev(dev, &pcidev->dev); - - if (comedi_pci_enable(pcidev, "adl_pci8164") < 0) { - printk(KERN_ERR "comedi%d: Failed to enable " - "PCI device and request regions\n", dev->minor); - return -EIO; - } dev->iobase = pci_resource_start(pcidev, 2); - printk(KERN_DEBUG "comedi: base addr %4lx\n", dev->iobase); + + ret = comedi_alloc_subdevices(dev, 4); + if (ret) + return ret; s = dev->subdevices + 0; s->type = COMEDI_SUBD_PROC; @@ -310,7 +271,8 @@ static int adl_pci8164_attach(struct comedi_device *dev, s->insn_read = adl_pci8164_insn_read_buf1; s->insn_write = adl_pci8164_insn_write_buf1; - printk(KERN_INFO "comedi: attached\n"); + dev_info(dev->class_dev, "%s attached\n", dev->board_name); + return 0; } @@ -321,14 +283,13 @@ static void adl_pci8164_detach(struct comedi_device *dev) if (pcidev) { if (dev->iobase) comedi_pci_disable(pcidev); - pci_dev_put(pcidev); } } static struct comedi_driver adl_pci8164_driver = { .driver_name = "adl_pci8164", .module = THIS_MODULE, - .attach = adl_pci8164_attach, + .attach_pci = adl_pci8164_attach_pci, .detach = adl_pci8164_detach, }; -- cgit v0.10.2 From 3b96f250ba086109241261337751ade2833ac333 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 16 Aug 2012 19:43:29 -0700 Subject: staging: comedi: cb_pcidas: use attach_pci callback Convert this PCI driver to use the comedi PCI auto config attach mechanism by adding an 'attach_pci' callback function. Since the driver does not require any external configuration options, and the legacy 'attach' callback is now optional, remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index 2b6a637..4b6fb88 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -45,11 +45,7 @@ Status: The boards may be autocalibrated using the comedi_calibrate utility. -Configuration options: - [0] - PCI bus of device (optional) - [1] - PCI slot of device (optional) - If bus/slot is not specified, the first supported - PCI device found will be used. +Configuration options: not applicable, uses PCI auto config For commands, the scanned channels must be consecutive (i.e. 4-5-6-7, 2-3-4,...), and must all have the same @@ -1501,69 +1497,45 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d) return IRQ_HANDLED; } -static struct pci_dev *cb_pcidas_find_pci_device(struct comedi_device *dev, - struct comedi_devconfig *it) +static const void *cb_pcidas_find_boardinfo(struct comedi_device *dev, + struct pci_dev *pcidev) { const struct cb_pcidas_board *thisboard; - struct pci_dev *pcidev = NULL; - int bus = it->options[0]; - int slot = it->options[1]; int i; - for_each_pci_dev(pcidev) { - /* is it not a computer boards card? */ - if (pcidev->vendor != PCI_VENDOR_ID_CB) - continue; - /* loop through cards supported by this driver */ - for (i = 0; i < ARRAY_SIZE(cb_pcidas_boards); i++) { - thisboard = &cb_pcidas_boards[i]; - if (thisboard->device_id != pcidev->device) - continue; - /* was a particular bus/slot requested? */ - if (bus || slot) { - /* are we on the wrong bus/slot? */ - if (pcidev->bus->number != bus || - PCI_SLOT(pcidev->devfn) != slot) { - continue; - } - } - dev_dbg(dev->class_dev, - "Found %s on bus %i, slot %i\n", - thisboard->name, - pcidev->bus->number, PCI_SLOT(pcidev->devfn)); - dev->board_ptr = thisboard; - return pcidev; - } + for (i = 0; i < ARRAY_SIZE(cb_pcidas_boards); i++) { + thisboard = &cb_pcidas_boards[i]; + if (thisboard->device_id == pcidev->device) + return thisboard; } - dev_err(dev->class_dev, "No supported card found\n"); return NULL; } -static int cb_pcidas_attach(struct comedi_device *dev, - struct comedi_devconfig *it) +static int cb_pcidas_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) { const struct cb_pcidas_board *thisboard; struct cb_pcidas_private *devpriv; - struct pci_dev *pcidev; struct comedi_subdevice *s; int i; int ret; - if (alloc_private(dev, sizeof(struct cb_pcidas_private)) < 0) - return -ENOMEM; - devpriv = dev->private; - - pcidev = cb_pcidas_find_pci_device(dev, it); - if (!pcidev) - return -EIO; comedi_set_hw_dev(dev, &pcidev->dev); - thisboard = comedi_board(dev); - if (comedi_pci_enable(pcidev, dev->driver->driver_name)) { - dev_err(dev->class_dev, - "Failed to enable PCI device and request regions\n"); - return -EIO; - } + thisboard = cb_pcidas_find_boardinfo(dev, pcidev); + if (!thisboard) + return -ENODEV; + dev->board_ptr = thisboard; + dev->board_name = thisboard->name; + + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; + devpriv = dev->private; + + ret = comedi_pci_enable(pcidev, dev->board_name); + if (ret) + return ret; devpriv->s5933_config = pci_resource_start(pcidev, 0); devpriv->control_status = pci_resource_start(pcidev, 1); @@ -1584,8 +1556,6 @@ static int cb_pcidas_attach(struct comedi_device *dev, } dev->irq = pcidev->irq; - dev->board_name = thisboard->name; - ret = comedi_alloc_subdevices(dev, 7); if (ret) return ret; @@ -1698,7 +1668,10 @@ static int cb_pcidas_attach(struct comedi_device *dev, outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS, devpriv->s5933_config + AMCC_OP_REG_INTCSR); - return 1; + dev_info(dev->class_dev, "%s: %s attached\n", + dev->driver->driver_name, dev->board_name); + + return 0; } static void cb_pcidas_detach(struct comedi_device *dev) @@ -1719,14 +1692,13 @@ static void cb_pcidas_detach(struct comedi_device *dev) if (pcidev) { if (devpriv->s5933_config) comedi_pci_disable(pcidev); - pci_dev_put(pcidev); } } static struct comedi_driver cb_pcidas_driver = { .driver_name = "cb_pcidas", .module = THIS_MODULE, - .attach = cb_pcidas_attach, + .attach_pci = cb_pcidas_attach_pci, .detach = cb_pcidas_detach, }; -- cgit v0.10.2 From 39ffddbb6c6803590f6150eb889975727acb943c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 16 Aug 2012 19:43:55 -0700 Subject: staging: comedi: cb_pcidio: remove thisboard macro This macro relies on a local variable having a specific name. Remove it and use the comedi_board() helper to get the pointer. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcidio.c b/drivers/staging/comedi/drivers/cb_pcidio.c index e370d0d..c377beb 100644 --- a/drivers/staging/comedi/drivers/cb_pcidio.c +++ b/drivers/staging/comedi/drivers/cb_pcidio.c @@ -85,11 +85,6 @@ static const struct pcidio_board pcidio_boards[] = { }, }; -/* - * Useful for shorthand access to the particular board structure - */ -#define thisboard ((const struct pcidio_board *)dev->board_ptr) - static struct pci_dev *pcidio_find_pci_dev(struct comedi_device *dev, struct comedi_devconfig *it) { @@ -122,6 +117,7 @@ static struct pci_dev *pcidio_find_pci_dev(struct comedi_device *dev, static int pcidio_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct pcidio_board *thisboard; struct pci_dev *pcidev; int i; int ret; @@ -130,11 +126,7 @@ static int pcidio_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (!pcidev) return -EIO; comedi_set_hw_dev(dev, &pcidev->dev); - -/* - * Initialize dev->board_name. Note that we can use the "thisboard" - * macro now, since we just initialized it in the last line. - */ + thisboard = comedi_board(dev); dev->board_name = thisboard->name; if (comedi_pci_enable(pcidev, thisboard->name)) @@ -158,6 +150,7 @@ static int pcidio_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void pcidio_detach(struct comedi_device *dev) { + const struct pcidio_board *thisboard = comedi_board(dev); struct pci_dev *pcidev = comedi_to_pci_dev(dev); if (pcidev) { -- cgit v0.10.2 From 93ddbbbcb2fc719d94179f6f8dffbce5e58a8e8f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 16 Aug 2012 19:44:35 -0700 Subject: staging: comedi: cb_pcidio: use attach_pci callback Convert this PCI driver to use the comedi PCI auto config attach mechanism by adding an 'attach_pci' callback function. Since the driver does not require any external configuration options, and the legacy 'attach' callback is now optional, remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcidio.c b/drivers/staging/comedi/drivers/cb_pcidio.c index c377beb..52c6379 100644 --- a/drivers/staging/comedi/drivers/cb_pcidio.c +++ b/drivers/staging/comedi/drivers/cb_pcidio.c @@ -30,13 +30,7 @@ Status: experimental This driver has been modified from skel.c of comedi-0.7.70. -Configuration Options: - [0] - PCI bus of device (optional) - [1] - PCI slot of device (optional) - If bus/slot is not specified, the first available PCI device will - be used. - -Passing a zero for an option is the same as leaving it unspecified. +Configuration Options: not applicable, uses PCI auto config */ /*------------------------------ HEADER FILES ---------------------------------*/ @@ -85,90 +79,81 @@ static const struct pcidio_board pcidio_boards[] = { }, }; -static struct pci_dev *pcidio_find_pci_dev(struct comedi_device *dev, - struct comedi_devconfig *it) +static const void *pcidio_find_boardinfo(struct comedi_device *dev, + struct pci_dev *pcidev) { - struct pci_dev *pcidev = NULL; - int bus = it->options[0]; - int slot = it->options[1]; + const struct pcidio_board *board; int i; - for_each_pci_dev(pcidev) { - if (bus || slot) { - if (bus != pcidev->bus->number || - slot != PCI_SLOT(pcidev->devfn)) - continue; - } - if (pcidev->vendor != PCI_VENDOR_ID_CB) - continue; - for (i = 0; i < ARRAY_SIZE(pcidio_boards); i++) { - if (pcidio_boards[i].dev_id != pcidev->device) - continue; - - dev->board_ptr = pcidio_boards + i; - return pcidev; - } + for (i = 0; i < ARRAY_SIZE(pcidio_boards); i++) { + board = &pcidio_boards[i]; + if (board->dev_id == pcidev->device) + return board; } - dev_err(dev->class_dev, - "No supported board found! (req. bus %d, slot %d)\n", - bus, slot); return NULL; } -static int pcidio_attach(struct comedi_device *dev, struct comedi_devconfig *it) +static int pcidio_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) { - const struct pcidio_board *thisboard; - struct pci_dev *pcidev; + const struct pcidio_board *board; + struct comedi_subdevice *s; int i; int ret; - pcidev = pcidio_find_pci_dev(dev, it); - if (!pcidev) - return -EIO; comedi_set_hw_dev(dev, &pcidev->dev); - thisboard = comedi_board(dev); - dev->board_name = thisboard->name; - if (comedi_pci_enable(pcidev, thisboard->name)) - return -EIO; + board = pcidio_find_boardinfo(dev, pcidev); + if (!board) + return -ENODEV; + dev->board_ptr = board; + dev->board_name = board->name; - dev->iobase = pci_resource_start(pcidev, thisboard->dioregs_badrindex); + ret = comedi_pci_enable(pcidev, dev->board_name); + if (ret) + return ret; + dev->iobase = pci_resource_start(pcidev, board->dioregs_badrindex); - ret = comedi_alloc_subdevices(dev, thisboard->n_8255); + ret = comedi_alloc_subdevices(dev, board->n_8255); if (ret) return ret; - for (i = 0; i < thisboard->n_8255; i++) { - subdev_8255_init(dev, dev->subdevices + i, - NULL, dev->iobase + i * 4); - dev_dbg(dev->class_dev, "subdev %d: base = 0x%lx\n", i, - dev->iobase + i * 4); + for (i = 0; i < board->n_8255; i++) { + s = dev->subdevices + i; + ret = subdev_8255_init(dev, s, NULL, dev->iobase + i * 4); + if (ret) + return ret; } - return 1; + dev_info(dev->class_dev, "%s attached (%d digital i/o channels)\n", + dev->board_name, board->n_8255 * 24); + + return 0; } static void pcidio_detach(struct comedi_device *dev) { - const struct pcidio_board *thisboard = comedi_board(dev); + const struct pcidio_board *board = comedi_board(dev); struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct comedi_subdevice *s; + int i; + if (dev->subdevices) { + for (i = 0; i < board->n_8255; i++) { + s = dev->subdevices + i; + subdev_8255_cleanup(dev, s); + } + } if (pcidev) { if (dev->iobase) comedi_pci_disable(pcidev); - pci_dev_put(pcidev); - } - if (dev->subdevices) { - int i; - for (i = 0; i < thisboard->n_8255; i++) - subdev_8255_cleanup(dev, dev->subdevices + i); } } static struct comedi_driver cb_pcidio_driver = { .driver_name = "cb_pcidio", .module = THIS_MODULE, - .attach = pcidio_attach, + .attach_pci = pcidio_attach_pci, .detach = pcidio_detach, }; -- cgit v0.10.2 From c6ad306b948e78dddcc064a71c41382469d656a3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 16 Aug 2012 19:44:59 -0700 Subject: staging: comedi: cb_pcidda: remove thisboard and devpriv macros These macros rely on a local variable having a specific name. Remove them and use the comedi_board() helper to get the thisboard pointer. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index 12660a3..63f5d70 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -203,11 +203,6 @@ static const struct cb_pcidda_board cb_pcidda_boards[] = { }; /* - * Useful for shorthand access to the particular board structure - */ -#define thisboard ((const struct cb_pcidda_board *)dev->board_ptr) - -/* * this structure is for data unique to this hardware driver. If * several hardware drivers keep similar information in this structure, * feel free to suggest moving the variable to the struct comedi_device @@ -229,12 +224,6 @@ struct cb_pcidda_private { u16 eeprom_data[EEPROM_SIZE]; /* software copy of board's eeprom */ }; -/* - * most drivers define the following macro to make it easy to - * access the private structure. - */ -#define devpriv ((struct cb_pcidda_private *)dev->private) - /* static int cb_pcidda_ai_rinsn(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data); */ static int cb_pcidda_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, @@ -289,21 +278,23 @@ static struct pci_dev *cb_pcidda_find_pci_dev(struct comedi_device *dev, static int cb_pcidda_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct cb_pcidda_board *thisboard; + struct cb_pcidda_private *devpriv; struct pci_dev *pcidev; struct comedi_subdevice *s; int index; int ret; -/* - * Allocate the private structure area. - */ - if (alloc_private(dev, sizeof(struct cb_pcidda_private)) < 0) - return -ENOMEM; + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; + devpriv = dev->private; pcidev = cb_pcidda_find_pci_dev(dev, it); if (!pcidev) return -EIO; comedi_set_hw_dev(dev, &pcidev->dev); + thisboard = comedi_board(dev); /* * Enable PCI device and request regions. @@ -585,6 +576,7 @@ static int cb_pcidda_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct cb_pcidda_private *devpriv = dev->private; unsigned int command; unsigned int channel, range; @@ -634,6 +626,7 @@ static int cb_pcidda_ao_winsn(struct comedi_device *dev, /* lowlevel read from eeprom */ static unsigned int cb_pcidda_serial_in(struct comedi_device *dev) { + struct cb_pcidda_private *devpriv = dev->private; unsigned int value = 0; int i; const int value_width = 16; /* number of bits wide values are */ @@ -651,6 +644,7 @@ static unsigned int cb_pcidda_serial_in(struct comedi_device *dev) static void cb_pcidda_serial_out(struct comedi_device *dev, unsigned int value, unsigned int num_bits) { + struct cb_pcidda_private *devpriv = dev->private; int i; for (i = 1; i <= num_bits; i++) { @@ -667,6 +661,7 @@ static void cb_pcidda_serial_out(struct comedi_device *dev, unsigned int value, static unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev, unsigned int address) { + struct cb_pcidda_private *devpriv = dev->private; unsigned int i; unsigned int cal2_bits; unsigned int value; @@ -703,6 +698,7 @@ static void cb_pcidda_write_caldac(struct comedi_device *dev, unsigned int caldac, unsigned int channel, unsigned int value) { + struct cb_pcidda_private *devpriv = dev->private; unsigned int cal2_bits; unsigned int i; /* caldacs use 3 bit channel specification */ @@ -797,6 +793,7 @@ static unsigned int eeprom_fine_byte(unsigned int word) static void cb_pcidda_calibrate(struct comedi_device *dev, unsigned int channel, unsigned int range) { + struct cb_pcidda_private *devpriv = dev->private; unsigned int coarse_offset, fine_offset, coarse_gain, fine_gain; /* remember range so we can tell when we need to readjust calibration */ -- cgit v0.10.2 From 6d336a56d43c90c0c46273eb82cae022cac24af4 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 16 Aug 2012 19:45:30 -0700 Subject: staging: comedi: cb_pcidda: remove forward declarations Move a couple of the functions in order to remove the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index 63f5d70..8a66e1a 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -224,160 +224,6 @@ struct cb_pcidda_private { u16 eeprom_data[EEPROM_SIZE]; /* software copy of board's eeprom */ }; -/* static int cb_pcidda_ai_rinsn(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data); */ -static int cb_pcidda_ao_winsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* static int cb_pcidda_ai_cmd(struct comedi_device *dev, struct *comedi_subdevice *s);*/ -/* static int cb_pcidda_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd); */ -/* static int cb_pcidda_ns_to_timer(unsigned int *ns,int *round); */ - -static unsigned int cb_pcidda_serial_in(struct comedi_device *dev); -static void cb_pcidda_serial_out(struct comedi_device *dev, unsigned int value, - unsigned int num_bits); -static unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev, - unsigned int address); -static void cb_pcidda_calibrate(struct comedi_device *dev, unsigned int channel, - unsigned int range); - -static struct pci_dev *cb_pcidda_find_pci_dev(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - struct pci_dev *pcidev = NULL; - int bus = it->options[0]; - int slot = it->options[1]; - int i; - - for_each_pci_dev(pcidev) { - if (bus || slot) { - if (bus != pcidev->bus->number || - slot != PCI_SLOT(pcidev->devfn)) - continue; - } - if (pcidev->vendor != PCI_VENDOR_ID_CB) - continue; - - for (i = 0; i < ARRAY_SIZE(cb_pcidda_boards); i++) { - if (cb_pcidda_boards[i].device_id != pcidev->device) - continue; - dev->board_ptr = cb_pcidda_boards + i; - return pcidev; - } - } - dev_err(dev->class_dev, - "No supported board found! (req. bus %d, slot %d)\n", - bus, slot); - return NULL; -} - -/* - * Attach is called by the Comedi core to configure the driver - * for a particular board. - */ -static int cb_pcidda_attach(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - const struct cb_pcidda_board *thisboard; - struct cb_pcidda_private *devpriv; - struct pci_dev *pcidev; - struct comedi_subdevice *s; - int index; - int ret; - - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; - - pcidev = cb_pcidda_find_pci_dev(dev, it); - if (!pcidev) - return -EIO; - comedi_set_hw_dev(dev, &pcidev->dev); - thisboard = comedi_board(dev); - - /* - * Enable PCI device and request regions. - */ - if (comedi_pci_enable(pcidev, thisboard->name)) { - dev_err(dev->class_dev, - "cb_pcidda: failed to enable PCI device and request regions\n"); - return -EIO; - } - -/* - * Allocate the I/O ports. - */ - devpriv->digitalio = pci_resource_start(pcidev, DIGITALIO_BADRINDEX); - devpriv->dac = pci_resource_start(pcidev, DAC_BADRINDEX); - dev->iobase = devpriv->dac; - -/* - * Warn about the status of the driver. - */ - if (thisboard->status == 2) - printk - ("WARNING: DRIVER FOR THIS BOARD NOT CHECKED WITH MANUAL. " - "WORKS ASSUMING FULL COMPATIBILITY WITH PCI-DDA08/12. " - "PLEASE REPORT USAGE TO .\n"); - -/* - * Initialize dev->board_name. - */ - dev->board_name = thisboard->name; - - ret = comedi_alloc_subdevices(dev, 3); - if (ret) - return ret; - - s = dev->subdevices + 0; - /* analog output subdevice */ - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITABLE; - s->n_chan = thisboard->ao_chans; - s->maxdata = (1 << thisboard->ao_bits) - 1; - s->range_table = thisboard->ranges; - s->insn_write = cb_pcidda_ao_winsn; - - /* s->subdev_flags |= SDF_CMD_READ; */ - /* s->do_cmd = cb_pcidda_ai_cmd; */ - /* s->do_cmdtest = cb_pcidda_ai_cmdtest; */ - - /* two 8255 digital io subdevices */ - s = dev->subdevices + 1; - subdev_8255_init(dev, s, NULL, devpriv->digitalio); - s = dev->subdevices + 2; - subdev_8255_init(dev, s, NULL, devpriv->digitalio + PORT2A); - - dev_dbg(dev->class_dev, "eeprom:\n"); - for (index = 0; index < EEPROM_SIZE; index++) { - devpriv->eeprom_data[index] = cb_pcidda_read_eeprom(dev, index); - dev_dbg(dev->class_dev, "%i:0x%x\n", index, - devpriv->eeprom_data[index]); - } - - /* set calibrations dacs */ - for (index = 0; index < thisboard->ao_chans; index++) - cb_pcidda_calibrate(dev, index, devpriv->ao_range[index]); - - return 1; -} - -static void cb_pcidda_detach(struct comedi_device *dev) -{ - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - pci_dev_put(pcidev); - } - if (dev->subdevices) { - subdev_8255_cleanup(dev, dev->subdevices + 1); - subdev_8255_cleanup(dev, dev->subdevices + 2); - } -} - /* * I will program this later... ;-) */ @@ -572,57 +418,6 @@ static int cb_pcidda_ns_to_timer(unsigned int *ns, int round) } #endif -static int cb_pcidda_ao_winsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - struct cb_pcidda_private *devpriv = dev->private; - unsigned int command; - unsigned int channel, range; - - channel = CR_CHAN(insn->chanspec); - range = CR_RANGE(insn->chanspec); - - /* adjust calibration dacs if range has changed */ - if (range != devpriv->ao_range[channel]) - cb_pcidda_calibrate(dev, channel, range); - - /* output channel configuration */ - command = NOSU | ENABLEDAC; - - /* output channel range */ - switch (range) { - case 0: - command |= BIP | RANGE10V; - break; - case 1: - command |= BIP | RANGE5V; - break; - case 2: - command |= BIP | RANGE2V5; - break; - case 3: - command |= UNIP | RANGE10V; - break; - case 4: - command |= UNIP | RANGE5V; - break; - case 5: - command |= UNIP | RANGE2V5; - break; - } - - /* output channel specification */ - command |= channel << 2; - outw(command, devpriv->dac + DACONTROL); - - /* write data */ - outw(data[0], devpriv->dac + DADATA + channel * 2); - - /* return the number of samples read/written */ - return 1; -} - /* lowlevel read from eeprom */ static unsigned int cb_pcidda_serial_in(struct comedi_device *dev) { @@ -824,6 +619,190 @@ static void cb_pcidda_calibrate(struct comedi_device *dev, unsigned int channel, fine_gain_channel(channel), fine_gain); } +static int cb_pcidda_ao_winsn(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + struct cb_pcidda_private *devpriv = dev->private; + unsigned int command; + unsigned int channel, range; + + channel = CR_CHAN(insn->chanspec); + range = CR_RANGE(insn->chanspec); + + /* adjust calibration dacs if range has changed */ + if (range != devpriv->ao_range[channel]) + cb_pcidda_calibrate(dev, channel, range); + + /* output channel configuration */ + command = NOSU | ENABLEDAC; + + /* output channel range */ + switch (range) { + case 0: + command |= BIP | RANGE10V; + break; + case 1: + command |= BIP | RANGE5V; + break; + case 2: + command |= BIP | RANGE2V5; + break; + case 3: + command |= UNIP | RANGE10V; + break; + case 4: + command |= UNIP | RANGE5V; + break; + case 5: + command |= UNIP | RANGE2V5; + break; + } + + /* output channel specification */ + command |= channel << 2; + outw(command, devpriv->dac + DACONTROL); + + /* write data */ + outw(data[0], devpriv->dac + DADATA + channel * 2); + + /* return the number of samples read/written */ + return 1; +} + +static struct pci_dev *cb_pcidda_find_pci_dev(struct comedi_device *dev, + struct comedi_devconfig *it) +{ + struct pci_dev *pcidev = NULL; + int bus = it->options[0]; + int slot = it->options[1]; + int i; + + for_each_pci_dev(pcidev) { + if (bus || slot) { + if (bus != pcidev->bus->number || + slot != PCI_SLOT(pcidev->devfn)) + continue; + } + if (pcidev->vendor != PCI_VENDOR_ID_CB) + continue; + + for (i = 0; i < ARRAY_SIZE(cb_pcidda_boards); i++) { + if (cb_pcidda_boards[i].device_id != pcidev->device) + continue; + dev->board_ptr = cb_pcidda_boards + i; + return pcidev; + } + } + dev_err(dev->class_dev, + "No supported board found! (req. bus %d, slot %d)\n", + bus, slot); + return NULL; +} + +static int cb_pcidda_attach(struct comedi_device *dev, + struct comedi_devconfig *it) +{ + const struct cb_pcidda_board *thisboard; + struct cb_pcidda_private *devpriv; + struct pci_dev *pcidev; + struct comedi_subdevice *s; + int index; + int ret; + + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; + devpriv = dev->private; + + pcidev = cb_pcidda_find_pci_dev(dev, it); + if (!pcidev) + return -EIO; + comedi_set_hw_dev(dev, &pcidev->dev); + thisboard = comedi_board(dev); + + /* + * Enable PCI device and request regions. + */ + if (comedi_pci_enable(pcidev, thisboard->name)) { + dev_err(dev->class_dev, + "cb_pcidda: failed to enable PCI device and request regions\n"); + return -EIO; + } + +/* + * Allocate the I/O ports. + */ + devpriv->digitalio = pci_resource_start(pcidev, DIGITALIO_BADRINDEX); + devpriv->dac = pci_resource_start(pcidev, DAC_BADRINDEX); + dev->iobase = devpriv->dac; + +/* + * Warn about the status of the driver. + */ + if (thisboard->status == 2) + printk + ("WARNING: DRIVER FOR THIS BOARD NOT CHECKED WITH MANUAL. " + "WORKS ASSUMING FULL COMPATIBILITY WITH PCI-DDA08/12. " + "PLEASE REPORT USAGE TO .\n"); + +/* + * Initialize dev->board_name. + */ + dev->board_name = thisboard->name; + + ret = comedi_alloc_subdevices(dev, 3); + if (ret) + return ret; + + s = dev->subdevices + 0; + /* analog output subdevice */ + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITABLE; + s->n_chan = thisboard->ao_chans; + s->maxdata = (1 << thisboard->ao_bits) - 1; + s->range_table = thisboard->ranges; + s->insn_write = cb_pcidda_ao_winsn; + + /* s->subdev_flags |= SDF_CMD_READ; */ + /* s->do_cmd = cb_pcidda_ai_cmd; */ + /* s->do_cmdtest = cb_pcidda_ai_cmdtest; */ + + /* two 8255 digital io subdevices */ + s = dev->subdevices + 1; + subdev_8255_init(dev, s, NULL, devpriv->digitalio); + s = dev->subdevices + 2; + subdev_8255_init(dev, s, NULL, devpriv->digitalio + PORT2A); + + dev_dbg(dev->class_dev, "eeprom:\n"); + for (index = 0; index < EEPROM_SIZE; index++) { + devpriv->eeprom_data[index] = cb_pcidda_read_eeprom(dev, index); + dev_dbg(dev->class_dev, "%i:0x%x\n", index, + devpriv->eeprom_data[index]); + } + + /* set calibrations dacs */ + for (index = 0; index < thisboard->ao_chans; index++) + cb_pcidda_calibrate(dev, index, devpriv->ao_range[index]); + + return 1; +} + +static void cb_pcidda_detach(struct comedi_device *dev) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + + if (pcidev) { + if (dev->iobase) + comedi_pci_disable(pcidev); + pci_dev_put(pcidev); + } + if (dev->subdevices) { + subdev_8255_cleanup(dev, dev->subdevices + 1); + subdev_8255_cleanup(dev, dev->subdevices + 2); + } +} + static struct comedi_driver cb_pcidda_driver = { .driver_name = "cb_pcidda", .module = THIS_MODULE, -- cgit v0.10.2 From 2c0db01128e0d767c4071a5ad22376875bc5d545 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 16 Aug 2012 19:45:54 -0700 Subject: staging: comedi: cb_pcidda: use attach_pci callback Convert this PCI driver to use the comedi PCI auto config attach mechanism by adding an 'attach_pci' callback function. Since the driver does not require any external configuration options, and the legacy 'attach' callback is now optional, remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index 8a66e1a..c5944e3 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -56,14 +56,6 @@ Please report success/failure with other different cards to /* maximum number of ao channels for supported boards */ #define MAX_AO_CHANNELS 8 -/* PCI-DDA base addresses */ -#define DIGITALIO_BADRINDEX 2 - /* DIGITAL I/O is pci_dev->resource[2] */ -#define DIGITALIO_SIZE 8 - /* DIGITAL I/O uses 8 I/O port addresses */ -#define DAC_BADRINDEX 3 - /* DAC is pci_dev->resource[3] */ - /* Digital I/O registers */ #define PORT1A 0 /* PORT 1A DATA */ @@ -670,87 +662,56 @@ static int cb_pcidda_ao_winsn(struct comedi_device *dev, return 1; } -static struct pci_dev *cb_pcidda_find_pci_dev(struct comedi_device *dev, - struct comedi_devconfig *it) +static const void *cb_pcidda_find_boardinfo(struct comedi_device *dev, + struct pci_dev *pcidev) { - struct pci_dev *pcidev = NULL; - int bus = it->options[0]; - int slot = it->options[1]; + const struct cb_pcidda_board *thisboard; int i; - for_each_pci_dev(pcidev) { - if (bus || slot) { - if (bus != pcidev->bus->number || - slot != PCI_SLOT(pcidev->devfn)) - continue; - } - if (pcidev->vendor != PCI_VENDOR_ID_CB) - continue; - - for (i = 0; i < ARRAY_SIZE(cb_pcidda_boards); i++) { - if (cb_pcidda_boards[i].device_id != pcidev->device) - continue; - dev->board_ptr = cb_pcidda_boards + i; - return pcidev; - } + for (i = 0; i < ARRAY_SIZE(cb_pcidda_boards); i++) { + thisboard = &cb_pcidda_boards[i]; + if (thisboard->device_id != pcidev->device) + return thisboard; } - dev_err(dev->class_dev, - "No supported board found! (req. bus %d, slot %d)\n", - bus, slot); return NULL; } -static int cb_pcidda_attach(struct comedi_device *dev, - struct comedi_devconfig *it) +static int cb_pcidda_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) { const struct cb_pcidda_board *thisboard; struct cb_pcidda_private *devpriv; - struct pci_dev *pcidev; struct comedi_subdevice *s; int index; int ret; + comedi_set_hw_dev(dev, &pcidev->dev); + + thisboard = cb_pcidda_find_boardinfo(dev, pcidev); + if (!pcidev) + return -ENODEV; + dev->board_ptr = thisboard; + dev->board_name = thisboard->name; + ret = alloc_private(dev, sizeof(*devpriv)); if (ret) return ret; devpriv = dev->private; - pcidev = cb_pcidda_find_pci_dev(dev, it); - if (!pcidev) - return -EIO; - comedi_set_hw_dev(dev, &pcidev->dev); - thisboard = comedi_board(dev); - - /* - * Enable PCI device and request regions. - */ - if (comedi_pci_enable(pcidev, thisboard->name)) { - dev_err(dev->class_dev, - "cb_pcidda: failed to enable PCI device and request regions\n"); - return -EIO; - } + ret = comedi_pci_enable(pcidev, dev->board_name); + if (ret) + return ret; -/* - * Allocate the I/O ports. - */ - devpriv->digitalio = pci_resource_start(pcidev, DIGITALIO_BADRINDEX); - devpriv->dac = pci_resource_start(pcidev, DAC_BADRINDEX); + devpriv->digitalio = pci_resource_start(pcidev, 2); + devpriv->dac = pci_resource_start(pcidev, 3); dev->iobase = devpriv->dac; -/* - * Warn about the status of the driver. - */ if (thisboard->status == 2) printk ("WARNING: DRIVER FOR THIS BOARD NOT CHECKED WITH MANUAL. " "WORKS ASSUMING FULL COMPATIBILITY WITH PCI-DDA08/12. " "PLEASE REPORT USAGE TO .\n"); -/* - * Initialize dev->board_name. - */ - dev->board_name = thisboard->name; - ret = comedi_alloc_subdevices(dev, 3); if (ret) return ret; @@ -785,28 +746,29 @@ static int cb_pcidda_attach(struct comedi_device *dev, for (index = 0; index < thisboard->ao_chans; index++) cb_pcidda_calibrate(dev, index, devpriv->ao_range[index]); - return 1; + dev_info(dev->class_dev, "%s attached\n", dev->board_name); + + return 0; } static void cb_pcidda_detach(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - pci_dev_put(pcidev); - } if (dev->subdevices) { subdev_8255_cleanup(dev, dev->subdevices + 1); subdev_8255_cleanup(dev, dev->subdevices + 2); } + if (pcidev) { + if (dev->iobase) + comedi_pci_disable(pcidev); + } } static struct comedi_driver cb_pcidda_driver = { .driver_name = "cb_pcidda", .module = THIS_MODULE, - .attach = cb_pcidda_attach, + .attach_pci = cb_pcidda_attach_pci, .detach = cb_pcidda_detach, }; -- cgit v0.10.2 From 5f7cab0a9b0651e8cb125eb7ce2b1cb21f48b24f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 16 Aug 2012 19:46:20 -0700 Subject: staging: comedi: cb_pcimdas: remove thisboard and devpriv macros These macros rely on a local variable having a specific name. Remove them and use the comedi_board() helper to get the thisboard pointer. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index c632a89..124478d 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -119,11 +119,6 @@ static const struct cb_pcimdas_board cb_pcimdas_boards[] = { }; /* - * Useful for shorthand access to the particular board structure - */ -#define thisboard ((const struct cb_pcimdas_board *)dev->board_ptr) - -/* * this structure is for data unique to this hardware driver. If * several hardware drivers keep similar information in this structure, * feel free to suggest moving the variable to the struct comedi_device @@ -137,12 +132,6 @@ struct cb_pcimdas_private { unsigned int ao_readback[2]; }; -/* - * most drivers define the following macro to make it easy to - * access the private structure. - */ -#define devpriv ((struct cb_pcimdas_private *)dev->private) - static int cb_pcimdas_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); @@ -193,21 +182,23 @@ static struct pci_dev *cb_pcimdas_find_pci_dev(struct comedi_device *dev, static int cb_pcimdas_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct cb_pcimdas_board *thisboard; + struct cb_pcimdas_private *devpriv; struct pci_dev *pcidev; struct comedi_subdevice *s; unsigned long iobase_8255; int ret; -/* - * Allocate the private structure area. - */ - if (alloc_private(dev, sizeof(struct cb_pcimdas_private)) < 0) - return -ENOMEM; + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; + devpriv = dev->private; pcidev = cb_pcimdas_find_pci_dev(dev, it); if (!pcidev) return -EIO; comedi_set_hw_dev(dev, &pcidev->dev); + thisboard = comedi_board(dev); /* Warn about non-tested features */ switch (thisboard->device_id) { @@ -299,6 +290,8 @@ static int cb_pcimdas_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + const struct cb_pcimdas_board *thisboard = comedi_board(dev); + struct cb_pcimdas_private *devpriv = dev->private; int n, i; unsigned int d; unsigned int busy; @@ -368,6 +361,7 @@ static int cb_pcimdas_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct cb_pcimdas_private *devpriv = dev->private; int i; int chan = CR_CHAN(insn->chanspec); @@ -397,6 +391,7 @@ static int cb_pcimdas_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct cb_pcimdas_private *devpriv = dev->private; int i; int chan = CR_CHAN(insn->chanspec); -- cgit v0.10.2 From 2682b2dc46d30cad83c880645b57fbce46ab35fa Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 16 Aug 2012 19:46:40 -0700 Subject: staging: comedi: cb_pcimdas: remove forward declarations Move a couple of the functions in order to remove the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index 124478d..5a5f102 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -132,15 +132,124 @@ struct cb_pcimdas_private { unsigned int ao_readback[2]; }; +/* + * "instructions" read/write data in "one-shot" or "software-triggered" + * mode. + */ static int cb_pcimdas_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); + struct comedi_insn *insn, unsigned int *data) +{ + const struct cb_pcimdas_board *thisboard = comedi_board(dev); + struct cb_pcimdas_private *devpriv = dev->private; + int n, i; + unsigned int d; + unsigned int busy; + int chan = CR_CHAN(insn->chanspec); + unsigned short chanlims; + int maxchans; + + /* only support sw initiated reads from a single channel */ + + /* check channel number */ + if ((inb(devpriv->BADR3 + 2) & 0x20) == 0) /* differential mode */ + maxchans = thisboard->ai_diff_chans; + else + maxchans = thisboard->ai_se_chans; + + if (chan > (maxchans - 1)) + return -ETIMEDOUT; /* *** Wrong error code. Fixme. */ + + /* configure for sw initiated read */ + d = inb(devpriv->BADR3 + 5); + if ((d & 0x03) > 0) { /* only reset if needed. */ + d = d & 0xfd; + outb(d, devpriv->BADR3 + 5); + } + outb(0x01, devpriv->BADR3 + 6); /* set bursting off, conversions on */ + outb(0x00, devpriv->BADR3 + 7); /* set range to 10V. UP/BP is controlled by a switch on the board */ + + /* + * write channel limits to multiplexer, set Low (bits 0-3) and + * High (bits 4-7) channels to chan. + */ + chanlims = chan | (chan << 4); + outb(chanlims, devpriv->BADR3 + 0); + + /* convert n samples */ + for (n = 0; n < insn->n; n++) { + /* trigger conversion */ + outw(0, dev->iobase + 0); + +#define TIMEOUT 1000 /* typically takes 5 loops on a lightly loaded Pentium 100MHz, */ + /* this is likely to be 100 loops on a 2GHz machine, so set 1000 as the limit. */ + + /* wait for conversion to end */ + for (i = 0; i < TIMEOUT; i++) { + busy = inb(devpriv->BADR3 + 2) & 0x80; + if (!busy) + break; + } + if (i == TIMEOUT) { + printk("timeout\n"); + return -ETIMEDOUT; + } + /* read data */ + d = inw(dev->iobase + 0); + + /* mangle the data as necessary */ + /* d ^= 1<<(thisboard->ai_bits-1); // 16 bit data from ADC, so no mangle needed. */ + + data[n] = d; + } + + /* return the number of samples read/written */ + return n; +} + static int cb_pcimdas_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); + struct comedi_insn *insn, unsigned int *data) +{ + struct cb_pcimdas_private *devpriv = dev->private; + int i; + int chan = CR_CHAN(insn->chanspec); + + /* Writing a list of values to an AO channel is probably not + * very useful, but that's how the interface is defined. */ + for (i = 0; i < insn->n; i++) { + switch (chan) { + case 0: + outw(data[i] & 0x0FFF, dev->iobase + DAC0_OFFSET); + break; + case 1: + outw(data[i] & 0x0FFF, dev->iobase + DAC1_OFFSET); + break; + default: + return -1; + } + devpriv->ao_readback[chan] = data[i]; + } + + /* return the number of samples read/written */ + return i; +} + +/* AO subdevices should have a read insn as well as a write insn. + * Usually this means copying a value stored in devpriv. */ static int cb_pcimdas_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); + struct comedi_insn *insn, unsigned int *data) +{ + struct cb_pcimdas_private *devpriv = dev->private; + int i; + int chan = CR_CHAN(insn->chanspec); + + for (i = 0; i < insn->n; i++) + data[i] = devpriv->ao_readback[chan]; + + return i; +} static struct pci_dev *cb_pcimdas_find_pci_dev(struct comedi_device *dev, struct comedi_devconfig *it) @@ -173,12 +282,6 @@ static struct pci_dev *cb_pcimdas_find_pci_dev(struct comedi_device *dev, return NULL; } -/* - * Attach is called by the Comedi core to configure the driver - * for a particular board. If you specified a board_name array - * in the driver structure, dev->board_ptr contains that - * address. - */ static int cb_pcimdas_attach(struct comedi_device *dev, struct comedi_devconfig *it) { @@ -282,125 +385,6 @@ static void cb_pcimdas_detach(struct comedi_device *dev) } } -/* - * "instructions" read/write data in "one-shot" or "software-triggered" - * mode. - */ -static int cb_pcimdas_ai_rinsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - const struct cb_pcimdas_board *thisboard = comedi_board(dev); - struct cb_pcimdas_private *devpriv = dev->private; - int n, i; - unsigned int d; - unsigned int busy; - int chan = CR_CHAN(insn->chanspec); - unsigned short chanlims; - int maxchans; - - /* only support sw initiated reads from a single channel */ - - /* check channel number */ - if ((inb(devpriv->BADR3 + 2) & 0x20) == 0) /* differential mode */ - maxchans = thisboard->ai_diff_chans; - else - maxchans = thisboard->ai_se_chans; - - if (chan > (maxchans - 1)) - return -ETIMEDOUT; /* *** Wrong error code. Fixme. */ - - /* configure for sw initiated read */ - d = inb(devpriv->BADR3 + 5); - if ((d & 0x03) > 0) { /* only reset if needed. */ - d = d & 0xfd; - outb(d, devpriv->BADR3 + 5); - } - outb(0x01, devpriv->BADR3 + 6); /* set bursting off, conversions on */ - outb(0x00, devpriv->BADR3 + 7); /* set range to 10V. UP/BP is controlled by a switch on the board */ - - /* - * write channel limits to multiplexer, set Low (bits 0-3) and - * High (bits 4-7) channels to chan. - */ - chanlims = chan | (chan << 4); - outb(chanlims, devpriv->BADR3 + 0); - - /* convert n samples */ - for (n = 0; n < insn->n; n++) { - /* trigger conversion */ - outw(0, dev->iobase + 0); - -#define TIMEOUT 1000 /* typically takes 5 loops on a lightly loaded Pentium 100MHz, */ - /* this is likely to be 100 loops on a 2GHz machine, so set 1000 as the limit. */ - - /* wait for conversion to end */ - for (i = 0; i < TIMEOUT; i++) { - busy = inb(devpriv->BADR3 + 2) & 0x80; - if (!busy) - break; - } - if (i == TIMEOUT) { - printk("timeout\n"); - return -ETIMEDOUT; - } - /* read data */ - d = inw(dev->iobase + 0); - - /* mangle the data as necessary */ - /* d ^= 1<<(thisboard->ai_bits-1); // 16 bit data from ADC, so no mangle needed. */ - - data[n] = d; - } - - /* return the number of samples read/written */ - return n; -} - -static int cb_pcimdas_ao_winsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - struct cb_pcimdas_private *devpriv = dev->private; - int i; - int chan = CR_CHAN(insn->chanspec); - - /* Writing a list of values to an AO channel is probably not - * very useful, but that's how the interface is defined. */ - for (i = 0; i < insn->n; i++) { - switch (chan) { - case 0: - outw(data[i] & 0x0FFF, dev->iobase + DAC0_OFFSET); - break; - case 1: - outw(data[i] & 0x0FFF, dev->iobase + DAC1_OFFSET); - break; - default: - return -1; - } - devpriv->ao_readback[chan] = data[i]; - } - - /* return the number of samples read/written */ - return i; -} - -/* AO subdevices should have a read insn as well as a write insn. - * Usually this means copying a value stored in devpriv. */ -static int cb_pcimdas_ao_rinsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - struct cb_pcimdas_private *devpriv = dev->private; - int i; - int chan = CR_CHAN(insn->chanspec); - - for (i = 0; i < insn->n; i++) - data[i] = devpriv->ao_readback[chan]; - - return i; -} - static struct comedi_driver cb_pcimdas_driver = { .driver_name = "cb_pcimdas", .module = THIS_MODULE, -- cgit v0.10.2 From 2d069fbed1fa367e5e5f59b6723898b92b3b80ba Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 16 Aug 2012 19:47:05 -0700 Subject: staging: comedi: cb_pcimdas: use attach_pci callback Convert this PCI driver to use the comedi PCI auto config attach mechanism by adding an 'attach_pci' callback function. Since the driver does not require any external configuration options, and the legacy 'attach' callback is now optional, remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index 5a5f102..fa3fd88 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -251,58 +251,42 @@ static int cb_pcimdas_ao_rinsn(struct comedi_device *dev, return i; } -static struct pci_dev *cb_pcimdas_find_pci_dev(struct comedi_device *dev, - struct comedi_devconfig *it) +static const void *cb_pcimdas_find_boardinfo(struct comedi_device *dev, + struct pci_dev *pcidev) { - struct pci_dev *pcidev = NULL; - int bus = it->options[0]; - int slot = it->options[1]; + const struct cb_pcimdas_board *thisboard; int i; - for_each_pci_dev(pcidev) { - if (bus || slot) { - if (bus != pcidev->bus->number || - slot != PCI_SLOT(pcidev->devfn)) - continue; - } - if (pcidev->vendor != PCI_VENDOR_ID_COMPUTERBOARDS) - continue; - - for (i = 0; i < ARRAY_SIZE(cb_pcimdas_boards); i++) { - if (cb_pcimdas_boards[i].device_id != pcidev->device) - continue; - - dev->board_ptr = cb_pcimdas_boards + i; - return pcidev; - } + for (i = 0; i < ARRAY_SIZE(cb_pcimdas_boards); i++) { + thisboard = &cb_pcimdas_boards[i]; + if (thisboard->device_id == pcidev->device) + return thisboard; } - dev_err(dev->class_dev, - "No supported board found! (req. bus %d, slot %d)\n", - bus, slot); return NULL; } -static int cb_pcimdas_attach(struct comedi_device *dev, - struct comedi_devconfig *it) +static int cb_pcimdas_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) { const struct cb_pcimdas_board *thisboard; struct cb_pcimdas_private *devpriv; - struct pci_dev *pcidev; struct comedi_subdevice *s; unsigned long iobase_8255; int ret; + comedi_set_hw_dev(dev, &pcidev->dev); + + thisboard = cb_pcimdas_find_boardinfo(dev, pcidev); + if (!thisboard) + return -ENODEV; + dev->board_ptr = thisboard; + dev->board_name = thisboard->name; + ret = alloc_private(dev, sizeof(*devpriv)); if (ret) return ret; devpriv = dev->private; - pcidev = cb_pcimdas_find_pci_dev(dev, it); - if (!pcidev) - return -EIO; - comedi_set_hw_dev(dev, &pcidev->dev); - thisboard = comedi_board(dev); - /* Warn about non-tested features */ switch (thisboard->device_id) { case 0x56: @@ -313,11 +297,9 @@ static int cb_pcimdas_attach(struct comedi_device *dev, "PLEASE REPORT USAGE TO \n"); } - if (comedi_pci_enable(pcidev, "cb_pcimdas")) { - dev_err(dev->class_dev, - "Failed to enable PCI device and request regions\n"); - return -EIO; - } + ret = comedi_pci_enable(pcidev, dev->board_name); + if (ret) + return ret; dev->iobase = pci_resource_start(pcidev, 2); devpriv->BADR3 = pci_resource_start(pcidev, 3); @@ -332,9 +314,6 @@ static int cb_pcimdas_attach(struct comedi_device *dev, /* } */ /* dev->irq = pcidev->irq; */ - /* Initialize dev->board_name */ - dev->board_name = thisboard->name; - ret = comedi_alloc_subdevices(dev, 3); if (ret) return ret; @@ -369,7 +348,9 @@ static int cb_pcimdas_attach(struct comedi_device *dev, else s->type = COMEDI_SUBD_UNUSED; - return 1; + dev_info(dev->class_dev, "%s attached\n", dev->board_name); + + return 0; } static void cb_pcimdas_detach(struct comedi_device *dev) @@ -381,14 +362,13 @@ static void cb_pcimdas_detach(struct comedi_device *dev) if (pcidev) { if (dev->iobase) comedi_pci_disable(pcidev); - pci_dev_put(pcidev); } } static struct comedi_driver cb_pcimdas_driver = { .driver_name = "cb_pcimdas", .module = THIS_MODULE, - .attach = cb_pcimdas_attach, + .attach_pci = cb_pcimdas_attach_pci, .detach = cb_pcimdas_detach, }; -- cgit v0.10.2 From aeb0ca6e72740f562b6eff5fa59a88107a8af8c9 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 16 Aug 2012 19:47:26 -0700 Subject: staging: comedi: cb_pcimdda: remove REG_SZ and REGS_BARINDEX macros The REG_SZ macro isn't being use. Both macros use the 'thisboard' macro which relys on a local variable having a specific name. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index a801461..04a9d5b 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -135,9 +135,6 @@ static const struct board_struct boards[] = { */ #define thisboard ((const struct board_struct *)dev->board_ptr) -#define REG_SZ (thisboard->reg_sz) -#define REGS_BADRINDEX (thisboard->regs_badrindex) - /* * this structure is for data unique to this hardware driver. If * several hardware drivers keep similar information in this structure, @@ -406,7 +403,7 @@ static int probe(struct comedi_device *dev, const struct comedi_devconfig *it) } registers = pci_resource_start(devpriv->pci_dev, - REGS_BADRINDEX); + thisboard->regs_badrindex); devpriv->registers = registers; devpriv->dio_registers = devpriv->registers + thisboard->dio_offset; -- cgit v0.10.2 From 2a4b0ba517bb30f764b22efa47f3ce937318b04e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 16 Aug 2012 19:47:51 -0700 Subject: staging: comedi: cb_pcimdda: remove thisboard and devpriv macros These macros rely on a local variable having a specific name. Remove them and use the comedi_board() helper to get the thisboard pointer. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index 04a9d5b..04b9995 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -131,11 +131,6 @@ static const struct board_struct boards[] = { }; /* - * Useful for shorthand access to the particular board structure - */ -#define thisboard ((const struct board_struct *)dev->board_ptr) - -/* * this structure is for data unique to this hardware driver. If * several hardware drivers keep similar information in this structure, * feel free to suggest moving the variable to the struct comedi_device @@ -154,12 +149,6 @@ struct board_private_struct { }; -/* - * most drivers define the following macro to make it easy to - * access the private structure. - */ -#define devpriv ((struct board_private_struct *)dev->private) - static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); static int ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, @@ -203,17 +192,15 @@ static int probe(struct comedi_device *dev, const struct comedi_devconfig *it); */ static int attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct board_struct *thisboard; + struct board_private_struct *devpriv; struct comedi_subdevice *s; int err; -/* - * Allocate the private structure area. alloc_private() is a - * convenient macro defined in comedidev.h. - * if this function fails (returns negative) then the private area is - * kfree'd by comedi - */ - if (alloc_private(dev, sizeof(struct board_private_struct)) < 0) - return -ENOMEM; + err = alloc_private(dev, sizeof(*devpriv)); + if (err) + return err; + devpriv = dev->private; /* * If you can probe the device to determine what device in a series @@ -223,6 +210,7 @@ static int attach(struct comedi_device *dev, struct comedi_devconfig *it) err = probe(dev, it); if (err) return err; + thisboard = comedi_board(dev); /* Output some info */ printk("comedi%d: %s: ", dev->minor, thisboard->name); @@ -281,6 +269,8 @@ static int attach(struct comedi_device *dev, struct comedi_devconfig *it) static void detach(struct comedi_device *dev) { + struct board_private_struct *devpriv = dev->private; + if (devpriv) { if (dev->subdevices && devpriv->attached_to_8255) { subdev_8255_cleanup(dev, dev->subdevices + 2); @@ -297,6 +287,7 @@ static void detach(struct comedi_device *dev) static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct board_private_struct *devpriv = dev->private; int i; int chan = CR_CHAN(insn->chanspec); unsigned long offset = devpriv->registers + chan * 2; @@ -336,6 +327,7 @@ static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, static int ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct board_private_struct *devpriv = dev->private; int i; int chan = CR_CHAN(insn->chanspec); @@ -372,6 +364,8 @@ static int ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, */ static int probe(struct comedi_device *dev, const struct comedi_devconfig *it) { + const struct board_struct *thisboard; + struct board_private_struct *devpriv = dev->private; struct pci_dev *pcidev = NULL; int index; unsigned long registers; @@ -396,6 +390,7 @@ static int probe(struct comedi_device *dev, const struct comedi_devconfig *it) devpriv->pci_dev = pcidev; dev->board_ptr = boards + index; + thisboard = comedi_board(dev); if (comedi_pci_enable(pcidev, thisboard->name)) { printk ("cb_pcimdda: Failed to enable PCI device and request regions\n"); -- cgit v0.10.2 From fa090ab24bc8155ca8c4fbeafec0873da03f04bc Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 16 Aug 2012 19:48:14 -0700 Subject: staging: comedi: cb_pcimdda: remove forward declarations Move a couple of the functions in order to remove the need for the forward declarations. Also, remove the unnecessary comments. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index 04b9995..75e803a 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -149,141 +149,12 @@ struct board_private_struct { }; -static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/*--------------------------------------------------------------------------- - HELPER FUNCTION DECLARATIONS ------------------------------------------------------------------------------*/ - /* returns a maxdata value for a given n_bits */ static inline unsigned int figure_out_maxdata(int bits) { return ((unsigned int)1 << bits) - 1; } -/* - * Probes for a supported device. - * - * Prerequisite: private be allocated already inside dev - * - * If the device is found, it returns 0 and has the following side effects: - * - * o assigns a struct pci_dev * to dev->private->pci_dev - * o assigns a struct board * to dev->board_ptr - * o sets dev->private->registers - * o sets dev->private->dio_registers - * - * Otherwise, returns a -errno on error - */ -static int probe(struct comedi_device *dev, const struct comedi_devconfig *it); - -/*--------------------------------------------------------------------------- - FUNCTION DEFINITIONS ------------------------------------------------------------------------------*/ - -/* - * Attach is called by the Comedi core to configure the driver - * for a particular board. If you specified a board_name array - * in the driver structure, dev->board_ptr contains that - * address. - */ -static int attach(struct comedi_device *dev, struct comedi_devconfig *it) -{ - const struct board_struct *thisboard; - struct board_private_struct *devpriv; - struct comedi_subdevice *s; - int err; - - err = alloc_private(dev, sizeof(*devpriv)); - if (err) - return err; - devpriv = dev->private; - -/* - * If you can probe the device to determine what device in a series - * it is, this is the place to do it. Otherwise, dev->board_ptr - * should already be initialized. - */ - err = probe(dev, it); - if (err) - return err; - thisboard = comedi_board(dev); - -/* Output some info */ - printk("comedi%d: %s: ", dev->minor, thisboard->name); - -/* - * Initialize dev->board_name. Note that we can use the "thisboard" - * macro now, since we just initialized it in the last line. - */ - dev->board_name = thisboard->name; - - err = comedi_alloc_subdevices(dev, 2); - if (err) - return err; - - s = dev->subdevices + 0; - - /* analog output subdevice */ - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE; - s->n_chan = thisboard->ao_chans; - s->maxdata = figure_out_maxdata(thisboard->ao_bits); - /* this is hard-coded here */ - if (it->options[2]) - s->range_table = &range_bipolar10; - else - s->range_table = &range_bipolar5; - s->insn_write = &ao_winsn; - s->insn_read = &ao_rinsn; - - s = dev->subdevices + 1; - /* digital i/o subdevice */ - if (thisboard->dio_chans) { - switch (thisboard->dio_method) { - case DIO_8255: - /* - * this is a straight 8255, so register us with - * the 8255 driver - */ - subdev_8255_init(dev, s, NULL, devpriv->dio_registers); - devpriv->attached_to_8255 = 1; - break; - case DIO_INTERNAL: - default: - printk("DIO_INTERNAL not implemented yet!\n"); - return -ENXIO; - break; - } - } else { - s->type = COMEDI_SUBD_UNUSED; - } - - printk("attached\n"); - - return 1; -} - -static void detach(struct comedi_device *dev) -{ - struct board_private_struct *devpriv = dev->private; - - if (devpriv) { - if (dev->subdevices && devpriv->attached_to_8255) { - subdev_8255_cleanup(dev, dev->subdevices + 2); - devpriv->attached_to_8255 = 0; - } - if (devpriv->pci_dev) { - if (devpriv->registers) - comedi_pci_disable(devpriv->pci_dev); - pci_dev_put(devpriv->pci_dev); - } - } -} - static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { @@ -344,24 +215,6 @@ static int ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, return i; } -/*--------------------------------------------------------------------------- - HELPER FUNCTION DEFINITIONS ------------------------------------------------------------------------------*/ - -/* - * Probes for a supported device. - * - * Prerequisite: private be allocated already inside dev - * - * If the device is found, it returns 0 and has the following side effects: - * - * o assigns a struct pci_dev * to dev->private->pci_dev - * o assigns a struct board * to dev->board_ptr - * o sets dev->private->registers - * o sets dev->private->dio_registers - * - * Otherwise, returns a -errno on error - */ static int probe(struct comedi_device *dev, const struct comedi_devconfig *it) { const struct board_struct *thisboard; @@ -411,6 +264,100 @@ static int probe(struct comedi_device *dev, const struct comedi_devconfig *it) return -ENODEV; } +static int attach(struct comedi_device *dev, struct comedi_devconfig *it) +{ + const struct board_struct *thisboard; + struct board_private_struct *devpriv; + struct comedi_subdevice *s; + int err; + + err = alloc_private(dev, sizeof(*devpriv)); + if (err) + return err; + devpriv = dev->private; + +/* + * If you can probe the device to determine what device in a series + * it is, this is the place to do it. Otherwise, dev->board_ptr + * should already be initialized. + */ + err = probe(dev, it); + if (err) + return err; + thisboard = comedi_board(dev); + +/* Output some info */ + printk("comedi%d: %s: ", dev->minor, thisboard->name); + +/* + * Initialize dev->board_name. Note that we can use the "thisboard" + * macro now, since we just initialized it in the last line. + */ + dev->board_name = thisboard->name; + + err = comedi_alloc_subdevices(dev, 2); + if (err) + return err; + + s = dev->subdevices + 0; + + /* analog output subdevice */ + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITABLE | SDF_READABLE; + s->n_chan = thisboard->ao_chans; + s->maxdata = figure_out_maxdata(thisboard->ao_bits); + /* this is hard-coded here */ + if (it->options[2]) + s->range_table = &range_bipolar10; + else + s->range_table = &range_bipolar5; + s->insn_write = &ao_winsn; + s->insn_read = &ao_rinsn; + + s = dev->subdevices + 1; + /* digital i/o subdevice */ + if (thisboard->dio_chans) { + switch (thisboard->dio_method) { + case DIO_8255: + /* + * this is a straight 8255, so register us with + * the 8255 driver + */ + subdev_8255_init(dev, s, NULL, devpriv->dio_registers); + devpriv->attached_to_8255 = 1; + break; + case DIO_INTERNAL: + default: + printk("DIO_INTERNAL not implemented yet!\n"); + return -ENXIO; + break; + } + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + printk("attached\n"); + + return 1; +} + +static void detach(struct comedi_device *dev) +{ + struct board_private_struct *devpriv = dev->private; + + if (devpriv) { + if (dev->subdevices && devpriv->attached_to_8255) { + subdev_8255_cleanup(dev, dev->subdevices + 2); + devpriv->attached_to_8255 = 0; + } + if (devpriv->pci_dev) { + if (devpriv->registers) + comedi_pci_disable(devpriv->pci_dev); + pci_dev_put(devpriv->pci_dev); + } + } +} + static struct comedi_driver cb_pcimdda_driver = { .driver_name = "cb_pcimdda", .module = THIS_MODULE, -- cgit v0.10.2 From d1438d4158ed9650e8beffb4eac22e6ae62a0200 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 16 Aug 2012 19:48:35 -0700 Subject: staging: comedi: cb_pcimdda: add namespace to the driver The structs, static data, and functions in this driver have pretty generic names. Add namespace to everything to prevent any problems. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index 75e803a..edce275 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -96,7 +96,7 @@ Configuration Options: * This is straight from skel.c -- I did this in case this source file * will someday support more than 1 board... */ -struct board_struct { +struct cb_pcimdda_board { const char *name; unsigned short device_id; int ao_chans; @@ -116,7 +116,7 @@ enum DIO_METHODS { DIO_INTERNAL /* unimplemented */ }; -static const struct board_struct boards[] = { +static const struct cb_pcimdda_board cb_pcimdda_boards[] = { { .name = "cb_pcimdda06-16", .device_id = PCI_ID_PCIM_DDA06_16, @@ -136,7 +136,7 @@ static const struct board_struct boards[] = { * feel free to suggest moving the variable to the struct comedi_device * struct. */ -struct board_private_struct { +struct cb_pcimdda_private { unsigned long registers; /* set by probe */ unsigned long dio_registers; char attached_to_8255; /* boolean */ @@ -149,16 +149,12 @@ struct board_private_struct { }; -/* returns a maxdata value for a given n_bits */ -static inline unsigned int figure_out_maxdata(int bits) +static int cb_pcimdda_ao_winsn(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - return ((unsigned int)1 << bits) - 1; -} - -static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - struct board_private_struct *devpriv = dev->private; + struct cb_pcimdda_private *devpriv = dev->private; int i; int chan = CR_CHAN(insn->chanspec); unsigned long offset = devpriv->registers + chan * 2; @@ -172,7 +168,7 @@ static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, the channel voltage updated in the DAC, unless we're in simultaneous xfer mode (jumper on card) then a rinsn is necessary to actually update the DAC -- - see ao_rinsn() below... */ + see cb_pcimdda_ao_rinsn() below... */ outb((char)(data[i] >> 8 & 0x00ff), offset + 1); /* for testing only.. the actual rinsn SHOULD do an inw! @@ -195,10 +191,12 @@ static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, all AO channels update simultaneously. This is useful for some control applications, I would imagine. */ -static int ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int cb_pcimdda_ao_rinsn(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - struct board_private_struct *devpriv = dev->private; + struct cb_pcimdda_private *devpriv = dev->private; int i; int chan = CR_CHAN(insn->chanspec); @@ -215,10 +213,11 @@ static int ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, return i; } -static int probe(struct comedi_device *dev, const struct comedi_devconfig *it) +static int cb_pcimdda_probe(struct comedi_device *dev, + const struct comedi_devconfig *it) { - const struct board_struct *thisboard; - struct board_private_struct *devpriv = dev->private; + const struct cb_pcimdda_board *thisboard; + struct cb_pcimdda_private *devpriv = dev->private; struct pci_dev *pcidev = NULL; int index; unsigned long registers; @@ -228,8 +227,8 @@ static int probe(struct comedi_device *dev, const struct comedi_devconfig *it) if (pcidev->vendor != PCI_VENDOR_ID_COMPUTERBOARDS) continue; /* loop through cards supported by this driver */ - for (index = 0; index < ARRAY_SIZE(boards); index++) { - if (boards[index].device_id != pcidev->device) + for (index = 0; index < ARRAY_SIZE(cb_pcimdda_boards); index++) { + if (cb_pcimdda_boards[index].device_id != pcidev->device) continue; /* was a particular bus/slot requested? */ if (it->options[0] || it->options[1]) { @@ -242,7 +241,7 @@ static int probe(struct comedi_device *dev, const struct comedi_devconfig *it) /* found ! */ devpriv->pci_dev = pcidev; - dev->board_ptr = boards + index; + dev->board_ptr = cb_pcimdda_boards + index; thisboard = comedi_board(dev); if (comedi_pci_enable(pcidev, thisboard->name)) { printk @@ -264,10 +263,11 @@ static int probe(struct comedi_device *dev, const struct comedi_devconfig *it) return -ENODEV; } -static int attach(struct comedi_device *dev, struct comedi_devconfig *it) +static int cb_pcimdda_attach(struct comedi_device *dev, + struct comedi_devconfig *it) { - const struct board_struct *thisboard; - struct board_private_struct *devpriv; + const struct cb_pcimdda_board *thisboard; + struct cb_pcimdda_private *devpriv; struct comedi_subdevice *s; int err; @@ -281,7 +281,7 @@ static int attach(struct comedi_device *dev, struct comedi_devconfig *it) * it is, this is the place to do it. Otherwise, dev->board_ptr * should already be initialized. */ - err = probe(dev, it); + err = cb_pcimdda_probe(dev, it); if (err) return err; thisboard = comedi_board(dev); @@ -305,14 +305,14 @@ static int attach(struct comedi_device *dev, struct comedi_devconfig *it) s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE | SDF_READABLE; s->n_chan = thisboard->ao_chans; - s->maxdata = figure_out_maxdata(thisboard->ao_bits); + s->maxdata = (1 << thisboard->ao_bits) - 1; /* this is hard-coded here */ if (it->options[2]) s->range_table = &range_bipolar10; else s->range_table = &range_bipolar5; - s->insn_write = &ao_winsn; - s->insn_read = &ao_rinsn; + s->insn_write = &cb_pcimdda_ao_winsn; + s->insn_read = &cb_pcimdda_ao_rinsn; s = dev->subdevices + 1; /* digital i/o subdevice */ @@ -341,9 +341,9 @@ static int attach(struct comedi_device *dev, struct comedi_devconfig *it) return 1; } -static void detach(struct comedi_device *dev) +static void cb_pcimdda_detach(struct comedi_device *dev) { - struct board_private_struct *devpriv = dev->private; + struct cb_pcimdda_private *devpriv = dev->private; if (devpriv) { if (dev->subdevices && devpriv->attached_to_8255) { @@ -361,8 +361,8 @@ static void detach(struct comedi_device *dev) static struct comedi_driver cb_pcimdda_driver = { .driver_name = "cb_pcimdda", .module = THIS_MODULE, - .attach = attach, - .detach = detach, + .attach = cb_pcimdda_attach, + .detach = cb_pcimdda_detach, }; static int __devinit cb_pcimdda_pci_probe(struct pci_dev *dev, -- cgit v0.10.2 From b41bf58f3a088008d856b02faedfdf23167833a2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 16 Aug 2012 19:48:56 -0700 Subject: staging: comedi: cb_pcimdda: cleanup pci probe Make cb_pcimdda_probe() return the pointer to the found pci_dev and move the comedi_pci_enable() call into the 'attach' function. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index edce275..0c6d941 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -213,54 +213,30 @@ static int cb_pcimdda_ao_rinsn(struct comedi_device *dev, return i; } -static int cb_pcimdda_probe(struct comedi_device *dev, - const struct comedi_devconfig *it) +static struct pci_dev *cb_pcimdda_probe(struct comedi_device *dev, + struct comedi_devconfig *it) { - const struct cb_pcimdda_board *thisboard; - struct cb_pcimdda_private *devpriv = dev->private; struct pci_dev *pcidev = NULL; int index; - unsigned long registers; for_each_pci_dev(pcidev) { - /* is it not a computer boards card? */ if (pcidev->vendor != PCI_VENDOR_ID_COMPUTERBOARDS) continue; - /* loop through cards supported by this driver */ for (index = 0; index < ARRAY_SIZE(cb_pcimdda_boards); index++) { if (cb_pcimdda_boards[index].device_id != pcidev->device) continue; - /* was a particular bus/slot requested? */ if (it->options[0] || it->options[1]) { - /* are we on the wrong bus/slot? */ if (pcidev->bus->number != it->options[0] || PCI_SLOT(pcidev->devfn) != it->options[1]) { continue; } } - /* found ! */ - devpriv->pci_dev = pcidev; dev->board_ptr = cb_pcimdda_boards + index; - thisboard = comedi_board(dev); - if (comedi_pci_enable(pcidev, thisboard->name)) { - printk - ("cb_pcimdda: Failed to enable PCI device and request regions\n"); - return -EIO; - } - registers = - pci_resource_start(devpriv->pci_dev, - thisboard->regs_badrindex); - devpriv->registers = registers; - devpriv->dio_registers - = devpriv->registers + thisboard->dio_offset; - return 0; + return pcidev; } } - - printk("cb_pcimdda: No supported ComputerBoards/MeasurementComputing " - "card found at the requested position\n"); - return -ENODEV; + return NULL; } static int cb_pcimdda_attach(struct comedi_device *dev, @@ -268,6 +244,7 @@ static int cb_pcimdda_attach(struct comedi_device *dev, { const struct cb_pcimdda_board *thisboard; struct cb_pcimdda_private *devpriv; + struct pci_dev *pcidev; struct comedi_subdevice *s; int err; @@ -276,25 +253,20 @@ static int cb_pcimdda_attach(struct comedi_device *dev, return err; devpriv = dev->private; -/* - * If you can probe the device to determine what device in a series - * it is, this is the place to do it. Otherwise, dev->board_ptr - * should already be initialized. - */ - err = cb_pcimdda_probe(dev, it); - if (err) - return err; + pcidev = cb_pcimdda_probe(dev, it); + if (!pcidev) + return -EIO; + devpriv->pci_dev = pcidev; thisboard = comedi_board(dev); - -/* Output some info */ - printk("comedi%d: %s: ", dev->minor, thisboard->name); - -/* - * Initialize dev->board_name. Note that we can use the "thisboard" - * macro now, since we just initialized it in the last line. - */ dev->board_name = thisboard->name; + err = comedi_pci_enable(pcidev, dev->board_name); + if (err) + return err; + devpriv->registers = pci_resource_start(devpriv->pci_dev, + thisboard->regs_badrindex); + devpriv->dio_registers = devpriv->registers + thisboard->dio_offset; + err = comedi_alloc_subdevices(dev, 2); if (err) return err; @@ -336,7 +308,7 @@ static int cb_pcimdda_attach(struct comedi_device *dev, s->type = COMEDI_SUBD_UNUSED; } - printk("attached\n"); + dev_info(dev->class_dev, "%s attached\n", dev->board_name); return 1; } -- cgit v0.10.2 From a9ce3eefa55038d1a80b388cf885ea52f8f84433 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 16 Aug 2012 19:49:15 -0700 Subject: staging: comedi: cb_pcimdda: use dev->iobase Use dev->iobase for the pci i/o address instead of carrying it in the private data. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index 0c6d941..dc53f7e 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -137,7 +137,6 @@ static const struct cb_pcimdda_board cb_pcimdda_boards[] = { * struct. */ struct cb_pcimdda_private { - unsigned long registers; /* set by probe */ unsigned long dio_registers; char attached_to_8255; /* boolean */ /* would be useful for a PCI device */ @@ -157,7 +156,7 @@ static int cb_pcimdda_ao_winsn(struct comedi_device *dev, struct cb_pcimdda_private *devpriv = dev->private; int i; int chan = CR_CHAN(insn->chanspec); - unsigned long offset = devpriv->registers + chan * 2; + unsigned long offset = dev->iobase + chan * 2; /* Writing a list of values to an AO channel is probably not * very useful, but that's how the interface is defined. */ @@ -201,7 +200,7 @@ static int cb_pcimdda_ao_rinsn(struct comedi_device *dev, int chan = CR_CHAN(insn->chanspec); for (i = 0; i < insn->n; i++) { - inw(devpriv->registers + chan * 2); + inw(dev->iobase + chan * 2); /* * should I set data[i] to the result of the actual read * on the register or the cached unsigned int in @@ -263,9 +262,9 @@ static int cb_pcimdda_attach(struct comedi_device *dev, err = comedi_pci_enable(pcidev, dev->board_name); if (err) return err; - devpriv->registers = pci_resource_start(devpriv->pci_dev, + dev->iobase = pci_resource_start(devpriv->pci_dev, thisboard->regs_badrindex); - devpriv->dio_registers = devpriv->registers + thisboard->dio_offset; + devpriv->dio_registers = dev->iobase + thisboard->dio_offset; err = comedi_alloc_subdevices(dev, 2); if (err) @@ -323,7 +322,7 @@ static void cb_pcimdda_detach(struct comedi_device *dev) devpriv->attached_to_8255 = 0; } if (devpriv->pci_dev) { - if (devpriv->registers) + if (dev->iobase) comedi_pci_disable(devpriv->pci_dev); pci_dev_put(devpriv->pci_dev); } -- cgit v0.10.2 From 8b00a2f801866bd89a70f082cd0f322c7019d476 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 16 Aug 2012 19:49:38 -0700 Subject: staging: comedi: cb_pcimdda: store the pci_dev in the comedi_device Use the hw_dev pointer in the comed_device struct to hold the pci_dev instead of carrying it in the private data. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index dc53f7e..4127aa7 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -139,8 +139,6 @@ static const struct cb_pcimdda_board cb_pcimdda_boards[] = { struct cb_pcimdda_private { unsigned long dio_registers; char attached_to_8255; /* boolean */ - /* would be useful for a PCI device */ - struct pci_dev *pci_dev; #define MAX_AO_READBACK_CHANNELS 6 /* Used for AO readback */ @@ -255,15 +253,14 @@ static int cb_pcimdda_attach(struct comedi_device *dev, pcidev = cb_pcimdda_probe(dev, it); if (!pcidev) return -EIO; - devpriv->pci_dev = pcidev; + comedi_set_hw_dev(dev, &pcidev->dev); thisboard = comedi_board(dev); dev->board_name = thisboard->name; err = comedi_pci_enable(pcidev, dev->board_name); if (err) return err; - dev->iobase = pci_resource_start(devpriv->pci_dev, - thisboard->regs_badrindex); + dev->iobase = pci_resource_start(pcidev, thisboard->regs_badrindex); devpriv->dio_registers = dev->iobase + thisboard->dio_offset; err = comedi_alloc_subdevices(dev, 2); @@ -314,6 +311,7 @@ static int cb_pcimdda_attach(struct comedi_device *dev, static void cb_pcimdda_detach(struct comedi_device *dev) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct cb_pcimdda_private *devpriv = dev->private; if (devpriv) { @@ -321,11 +319,11 @@ static void cb_pcimdda_detach(struct comedi_device *dev) subdev_8255_cleanup(dev, dev->subdevices + 2); devpriv->attached_to_8255 = 0; } - if (devpriv->pci_dev) { - if (dev->iobase) - comedi_pci_disable(devpriv->pci_dev); - pci_dev_put(devpriv->pci_dev); - } + } + if (pcidev) { + if (dev->iobase) + comedi_pci_disable(pcidev); + pci_dev_put(pcidev); } } -- cgit v0.10.2 From ce774eab13606610df53301897e9c003476d7c6c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 16 Aug 2012 19:50:01 -0700 Subject: staging: comedi: cb_pcimdda: cleanup the 8255 subdevice init The dio_registers variable in the private data is only used to pass the base address to the 8255 subdevice. Remove the variable from the private data and pass the value directly to the subdev_8255_init() function. Make sure to check the return from subdev_8255_init(). That function can fail. For aesthetic reasons, rename the local variable 'err' to 'ret'. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index 4127aa7..b4d1f8b 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -137,7 +137,6 @@ static const struct cb_pcimdda_board cb_pcimdda_boards[] = { * struct. */ struct cb_pcimdda_private { - unsigned long dio_registers; char attached_to_8255; /* boolean */ #define MAX_AO_READBACK_CHANNELS 6 @@ -243,11 +242,11 @@ static int cb_pcimdda_attach(struct comedi_device *dev, struct cb_pcimdda_private *devpriv; struct pci_dev *pcidev; struct comedi_subdevice *s; - int err; + int ret; - err = alloc_private(dev, sizeof(*devpriv)); - if (err) - return err; + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; devpriv = dev->private; pcidev = cb_pcimdda_probe(dev, it); @@ -257,15 +256,14 @@ static int cb_pcimdda_attach(struct comedi_device *dev, thisboard = comedi_board(dev); dev->board_name = thisboard->name; - err = comedi_pci_enable(pcidev, dev->board_name); - if (err) - return err; + ret = comedi_pci_enable(pcidev, dev->board_name); + if (ret) + return ret; dev->iobase = pci_resource_start(pcidev, thisboard->regs_badrindex); - devpriv->dio_registers = dev->iobase + thisboard->dio_offset; - err = comedi_alloc_subdevices(dev, 2); - if (err) - return err; + ret = comedi_alloc_subdevices(dev, 2); + if (ret) + return ret; s = dev->subdevices + 0; @@ -287,11 +285,10 @@ static int cb_pcimdda_attach(struct comedi_device *dev, if (thisboard->dio_chans) { switch (thisboard->dio_method) { case DIO_8255: - /* - * this is a straight 8255, so register us with - * the 8255 driver - */ - subdev_8255_init(dev, s, NULL, devpriv->dio_registers); + ret = subdev_8255_init(dev, s, NULL, + dev->iobase + thisboard->dio_offset); + if (ret) + return ret; devpriv->attached_to_8255 = 1; break; case DIO_INTERNAL: -- cgit v0.10.2 From e070c6a949c4b7f0ebe73a08ff4df422b0d95216 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 16 Aug 2012 19:50:19 -0700 Subject: staging: comedi: cb_pcimdda: remove the DIO_METHODS The digital i/o on this card is handled by an 8255 compatible device. There are not other options. Remove the DIO_METHODS enum as well as the dio_method variable in the boardinfo and the code dealing with it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index b4d1f8b..f658cff 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -102,7 +102,6 @@ struct cb_pcimdda_board { int ao_chans; int ao_bits; int dio_chans; - int dio_method; /* how many bytes into the BADR are the DIO ports */ int dio_offset; int regs_badrindex; /* IO Region for the control, analog output, @@ -110,12 +109,6 @@ struct cb_pcimdda_board { int reg_sz; /* number of bytes of registers in io region */ }; -enum DIO_METHODS { - DIO_NONE = 0, - DIO_8255, - DIO_INTERNAL /* unimplemented */ -}; - static const struct cb_pcimdda_board cb_pcimdda_boards[] = { { .name = "cb_pcimdda06-16", @@ -123,7 +116,6 @@ static const struct cb_pcimdda_board cb_pcimdda_boards[] = { .ao_chans = 6, .ao_bits = 16, .dio_chans = 24, - .dio_method = DIO_8255, .dio_offset = 12, .regs_badrindex = 3, .reg_sz = 16, @@ -283,20 +275,11 @@ static int cb_pcimdda_attach(struct comedi_device *dev, s = dev->subdevices + 1; /* digital i/o subdevice */ if (thisboard->dio_chans) { - switch (thisboard->dio_method) { - case DIO_8255: - ret = subdev_8255_init(dev, s, NULL, - dev->iobase + thisboard->dio_offset); - if (ret) - return ret; - devpriv->attached_to_8255 = 1; - break; - case DIO_INTERNAL: - default: - printk("DIO_INTERNAL not implemented yet!\n"); - return -ENXIO; - break; - } + ret = subdev_8255_init(dev, s, NULL, + dev->iobase + thisboard->dio_offset); + if (ret) + return ret; + devpriv->attached_to_8255 = 1; } else { s->type = COMEDI_SUBD_UNUSED; } -- cgit v0.10.2 From 4d928b176a7e9c59a54a3d48fa16f9421dea0ad8 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 16 Aug 2012 19:50:42 -0700 Subject: staging: comedi: cb_pcimdda: remove dio_chans from the private data The cards supported by this driver always have 8255 compatible device. Remove the dio_chans variable from the private data and always initialize the 8255 subdevice. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index f658cff..bf98af4 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -101,7 +101,6 @@ struct cb_pcimdda_board { unsigned short device_id; int ao_chans; int ao_bits; - int dio_chans; /* how many bytes into the BADR are the DIO ports */ int dio_offset; int regs_badrindex; /* IO Region for the control, analog output, @@ -115,7 +114,6 @@ static const struct cb_pcimdda_board cb_pcimdda_boards[] = { .device_id = PCI_ID_PCIM_DDA06_16, .ao_chans = 6, .ao_bits = 16, - .dio_chans = 24, .dio_offset = 12, .regs_badrindex = 3, .reg_sz = 16, @@ -274,15 +272,11 @@ static int cb_pcimdda_attach(struct comedi_device *dev, s = dev->subdevices + 1; /* digital i/o subdevice */ - if (thisboard->dio_chans) { - ret = subdev_8255_init(dev, s, NULL, - dev->iobase + thisboard->dio_offset); - if (ret) - return ret; - devpriv->attached_to_8255 = 1; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + ret = subdev_8255_init(dev, s, NULL, + dev->iobase + thisboard->dio_offset); + if (ret) + return ret; + devpriv->attached_to_8255 = 1; dev_info(dev->class_dev, "%s attached\n", dev->board_name); -- cgit v0.10.2 From d9e33afb40e011d45fb9e47ecab305f5dc436028 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 16 Aug 2012 19:51:05 -0700 Subject: staging: comedi: cb_pcimdda: define the register map Add defines for the register map of the card. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index bf98af4..765f92c 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -93,6 +93,12 @@ Configuration Options: #define PCI_ID_PCIM_DDA06_16 0x0053 /* + * Register map, 8-bit access only + */ +#define PCIMDDA_DA_CHAN(x) (0x00 + (x) * 2) +#define PCIMDDA_8255_BASE_REG 0x0c + +/* * This is straight from skel.c -- I did this in case this source file * will someday support more than 1 board... */ -- cgit v0.10.2 From 08c3c4077857a7c56b76d1b5b9d50ae3f8190424 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 16 Aug 2012 19:51:27 -0700 Subject: staging: comedi: cb_pcimdda: remove dio_offset from the boardinfo The 8255 device is located at a fixed offset from the base address of the card. There is not need to carry this offset in the boardinfo. Remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index 765f92c..ecad85b 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -107,8 +107,6 @@ struct cb_pcimdda_board { unsigned short device_id; int ao_chans; int ao_bits; - /* how many bytes into the BADR are the DIO ports */ - int dio_offset; int regs_badrindex; /* IO Region for the control, analog output, and DIO registers */ int reg_sz; /* number of bytes of registers in io region */ @@ -120,7 +118,6 @@ static const struct cb_pcimdda_board cb_pcimdda_boards[] = { .device_id = PCI_ID_PCIM_DDA06_16, .ao_chans = 6, .ao_bits = 16, - .dio_offset = 12, .regs_badrindex = 3, .reg_sz = 16, } @@ -279,7 +276,7 @@ static int cb_pcimdda_attach(struct comedi_device *dev, s = dev->subdevices + 1; /* digital i/o subdevice */ ret = subdev_8255_init(dev, s, NULL, - dev->iobase + thisboard->dio_offset); + dev->iobase + PCIMDDA_8255_BASE_REG); if (ret) return ret; devpriv->attached_to_8255 = 1; -- cgit v0.10.2 From c8dd8e934087cc0ecf7033786ee00cff4ebcba4f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 16 Aug 2012 19:51:58 -0700 Subject: staging: comedi: cb_pcimdda: remove regs_badrindex and reg_sz from boardinfo The base address of the card is always found in pci resource 3. There is no need to carry this information in the boardinfo. The reg_sz is not used in the driver. Remove them. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index ecad85b..0e34603 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -107,9 +107,6 @@ struct cb_pcimdda_board { unsigned short device_id; int ao_chans; int ao_bits; - int regs_badrindex; /* IO Region for the control, analog output, - and DIO registers */ - int reg_sz; /* number of bytes of registers in io region */ }; static const struct cb_pcimdda_board cb_pcimdda_boards[] = { @@ -118,8 +115,6 @@ static const struct cb_pcimdda_board cb_pcimdda_boards[] = { .device_id = PCI_ID_PCIM_DDA06_16, .ao_chans = 6, .ao_bits = 16, - .regs_badrindex = 3, - .reg_sz = 16, } }; @@ -252,7 +247,7 @@ static int cb_pcimdda_attach(struct comedi_device *dev, ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) return ret; - dev->iobase = pci_resource_start(pcidev, thisboard->regs_badrindex); + dev->iobase = pci_resource_start(pcidev, 3); ret = comedi_alloc_subdevices(dev, 2); if (ret) -- cgit v0.10.2 From accff3509e947a4c1f7c88aec7e41d14f6c6f51e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 16 Aug 2012 19:52:30 -0700 Subject: staging: comedi: cb_pcimdda: remove ao_chans and ao_bits from boardinfo This board always has 6, 16-bit analog outputs. There is no need to carry this information in the boardinfo. Remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index 0e34603..82fb5f6 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -105,16 +105,12 @@ Configuration Options: struct cb_pcimdda_board { const char *name; unsigned short device_id; - int ao_chans; - int ao_bits; }; static const struct cb_pcimdda_board cb_pcimdda_boards[] = { { .name = "cb_pcimdda06-16", .device_id = PCI_ID_PCIM_DDA06_16, - .ao_chans = 6, - .ao_bits = 16, } }; @@ -258,8 +254,8 @@ static int cb_pcimdda_attach(struct comedi_device *dev, /* analog output subdevice */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE | SDF_READABLE; - s->n_chan = thisboard->ao_chans; - s->maxdata = (1 << thisboard->ao_bits) - 1; + s->n_chan = 6; + s->maxdata = 0xffff; /* this is hard-coded here */ if (it->options[2]) s->range_table = &range_bipolar10; -- cgit v0.10.2 From 86476d9f7cdffbe51396a1c0597d621a670d337d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 16 Aug 2012 19:52:52 -0700 Subject: staging: comedi: cb_pcimdda: remove boardinfo The boardinfo struct and associated code is no longer needed by this driver. Remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index 82fb5f6..e9f0a68 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -99,22 +99,6 @@ Configuration Options: #define PCIMDDA_8255_BASE_REG 0x0c /* - * This is straight from skel.c -- I did this in case this source file - * will someday support more than 1 board... - */ -struct cb_pcimdda_board { - const char *name; - unsigned short device_id; -}; - -static const struct cb_pcimdda_board cb_pcimdda_boards[] = { - { - .name = "cb_pcimdda06-16", - .device_id = PCI_ID_PCIM_DDA06_16, - } -}; - -/* * this structure is for data unique to this hardware driver. If * several hardware drivers keep similar information in this structure, * feel free to suggest moving the variable to the struct comedi_device @@ -197,24 +181,20 @@ static struct pci_dev *cb_pcimdda_probe(struct comedi_device *dev, struct comedi_devconfig *it) { struct pci_dev *pcidev = NULL; - int index; for_each_pci_dev(pcidev) { if (pcidev->vendor != PCI_VENDOR_ID_COMPUTERBOARDS) continue; - for (index = 0; index < ARRAY_SIZE(cb_pcimdda_boards); index++) { - if (cb_pcimdda_boards[index].device_id != pcidev->device) + if (pcidev->device != PCI_ID_PCIM_DDA06_16) + continue; + if (it->options[0] || it->options[1]) { + if (pcidev->bus->number != it->options[0] || + PCI_SLOT(pcidev->devfn) != it->options[1]) { continue; - if (it->options[0] || it->options[1]) { - if (pcidev->bus->number != it->options[0] || - PCI_SLOT(pcidev->devfn) != it->options[1]) { - continue; - } } - - dev->board_ptr = cb_pcimdda_boards + index; - return pcidev; } + + return pcidev; } return NULL; } @@ -222,7 +202,6 @@ static struct pci_dev *cb_pcimdda_probe(struct comedi_device *dev, static int cb_pcimdda_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - const struct cb_pcimdda_board *thisboard; struct cb_pcimdda_private *devpriv; struct pci_dev *pcidev; struct comedi_subdevice *s; @@ -237,8 +216,7 @@ static int cb_pcimdda_attach(struct comedi_device *dev, if (!pcidev) return -EIO; comedi_set_hw_dev(dev, &pcidev->dev); - thisboard = comedi_board(dev); - dev->board_name = thisboard->name; + dev->board_name = dev->driver->driver_name; ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) -- cgit v0.10.2 From 8496fc47e311b2ceeccb224d215baae86172d092 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 16 Aug 2012 19:53:20 -0700 Subject: staging: comedi: cb_pcimdda: remove attached_to_8255 from private data The attached_to_8255 variable in the private data is used as a flag to indicate that the 8255 subdevice has been initialized. The call to subdev_8255_cleanup only requires that the dev->subdevices pointer is valid. Change the test in the detach function and remove the attached_to_8255 variable. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index e9f0a68..b10831d 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -105,8 +105,6 @@ Configuration Options: * struct. */ struct cb_pcimdda_private { - char attached_to_8255; /* boolean */ - #define MAX_AO_READBACK_CHANNELS 6 /* Used for AO readback */ unsigned int ao_readback[MAX_AO_READBACK_CHANNELS]; @@ -248,7 +246,6 @@ static int cb_pcimdda_attach(struct comedi_device *dev, dev->iobase + PCIMDDA_8255_BASE_REG); if (ret) return ret; - devpriv->attached_to_8255 = 1; dev_info(dev->class_dev, "%s attached\n", dev->board_name); @@ -258,14 +255,9 @@ static int cb_pcimdda_attach(struct comedi_device *dev, static void cb_pcimdda_detach(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - struct cb_pcimdda_private *devpriv = dev->private; - if (devpriv) { - if (dev->subdevices && devpriv->attached_to_8255) { - subdev_8255_cleanup(dev, dev->subdevices + 2); - devpriv->attached_to_8255 = 0; - } - } + if (dev->subdevices) + subdev_8255_cleanup(dev, dev->subdevices + 2); if (pcidev) { if (dev->iobase) comedi_pci_disable(pcidev); -- cgit v0.10.2 From c7ac601e1d744da6b213531eac140982c6821b6f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 16 Aug 2012 19:53:45 -0700 Subject: staging: comedi: cb_pcimdda: fix bug in call to subdev_8255_cleanup The attach function only allocated 2 subdevices, an analog output sundevice (index 0) and the 8255 dio subdevice (index 1). The detach function is passing the wrong subdevice (index 2) to the subdev_8255_cleanup function which will result in a bug when it tries to do the kfree(s->private). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index b10831d..99a6160 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -257,7 +257,7 @@ static void cb_pcimdda_detach(struct comedi_device *dev) struct pci_dev *pcidev = comedi_to_pci_dev(dev); if (dev->subdevices) - subdev_8255_cleanup(dev, dev->subdevices + 2); + subdev_8255_cleanup(dev, dev->subdevices + 1); if (pcidev) { if (dev->iobase) comedi_pci_disable(pcidev); -- cgit v0.10.2 From b9616b18c1dbbc3bfad9c1801fb96f41c26449e2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 16 Aug 2012 19:54:05 -0700 Subject: staging: comedi: cb_pcimdda: minor cleanup of the private data Remove the cut-and-paste comment from the skel driver and for aesthetic reasons, move the #define out of the struct. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index 99a6160..a5e055f 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -98,17 +98,10 @@ Configuration Options: #define PCIMDDA_DA_CHAN(x) (0x00 + (x) * 2) #define PCIMDDA_8255_BASE_REG 0x0c -/* - * this structure is for data unique to this hardware driver. If - * several hardware drivers keep similar information in this structure, - * feel free to suggest moving the variable to the struct comedi_device - * struct. - */ +#define MAX_AO_READBACK_CHANNELS 6 + struct cb_pcimdda_private { -#define MAX_AO_READBACK_CHANNELS 6 - /* Used for AO readback */ unsigned int ao_readback[MAX_AO_READBACK_CHANNELS]; - }; static int cb_pcimdda_ao_winsn(struct comedi_device *dev, -- cgit v0.10.2 From aee815b53bca1cfa092ecd742fc59512b8030336 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 16 Aug 2012 19:54:32 -0700 Subject: staging: comedi: cb_pcimdda: cleanup the analog out read/write Use the register map define to work out the i/o address. Cleanup the comments about the simultaneous transfer mode for the analog outputs. Change the return to 'insn->n', the comedi core expects the return to be the number of data elements used. Technically the 'i' value is correct but 'insn->n' just makes it clearer. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index a5e055f..350c807 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -110,62 +110,51 @@ static int cb_pcimdda_ao_winsn(struct comedi_device *dev, unsigned int *data) { struct cb_pcimdda_private *devpriv = dev->private; + unsigned int chan = CR_CHAN(insn->chanspec); + unsigned long offset = dev->iobase + PCIMDDA_DA_CHAN(chan); + unsigned int val = 0; int i; - int chan = CR_CHAN(insn->chanspec); - unsigned long offset = dev->iobase + chan * 2; - /* Writing a list of values to an AO channel is probably not - * very useful, but that's how the interface is defined. */ for (i = 0; i < insn->n; i++) { - /* first, load the low byte */ - outb((char)(data[i] & 0x00ff), offset); - /* next, write the high byte -- only after this is written is - the channel voltage updated in the DAC, unless - we're in simultaneous xfer mode (jumper on card) - then a rinsn is necessary to actually update the DAC -- - see cb_pcimdda_ao_rinsn() below... */ - outb((char)(data[i] >> 8 & 0x00ff), offset + 1); - - /* for testing only.. the actual rinsn SHOULD do an inw! - (see the stuff about simultaneous XFER mode on this board) */ - devpriv->ao_readback[chan] = data[i]; + val = data[i]; + + /* + * Write the LSB then MSB. + * + * If the simultaneous xfer mode is selected by the + * jumper on the card, a read instruction is needed + * in order to initiate the simultaneous transfer. + * Otherwise, the DAC will be updated when the MSB + * is written. + */ + outb(val & 0x00ff, offset); + outb((val >> 8) & 0x00ff, offset + 1); } - /* return the number of samples read/written */ - return i; -} + /* Cache the last value for readback */ + devpriv->ao_readback[chan] = val; -/* AO subdevices should have a read insn as well as a write insn. + return insn->n; +} - Usually this means copying a value stored in devpriv->ao_readback. - However, since this board has this jumper setting called "Simultaneous - Xfer mode" (off by default), we will support it. Simultaneaous xfer - mode is accomplished by loading ALL the values you want for AO in all the - channels, then READing off one of the AO registers to initiate the - instantaneous simultaneous update of all DAC outputs, which makes - all AO channels update simultaneously. This is useful for some control - applications, I would imagine. -*/ static int cb_pcimdda_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { struct cb_pcimdda_private *devpriv = dev->private; - int i; int chan = CR_CHAN(insn->chanspec); + unsigned long offset = dev->iobase + PCIMDDA_DA_CHAN(chan); + int i; for (i = 0; i < insn->n; i++) { - inw(dev->iobase + chan * 2); - /* - * should I set data[i] to the result of the actual read - * on the register or the cached unsigned int in - * devpriv->ao_readback[]? - */ + /* Initiate the simultaneous transfer */ + inw(offset); + data[i] = devpriv->ao_readback[chan]; } - return i; + return insn->n; } static struct pci_dev *cb_pcimdda_probe(struct comedi_device *dev, -- cgit v0.10.2 From 22f2f541d06a874d8a5b228fca0186e333a1e351 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 16 Aug 2012 19:55:01 -0700 Subject: staging: comedi: cb_pcimdda: use attach_pci callback Convert this PCI driver to use the comedi PCI auto config attach mechanism by adding an 'attach_pci' callback function. This driver does use an external configuration option to determine the analog output range which is controlled by a jumper on the board. In order to remove the legacy 'attach' callback, an assumption is made that the jumper is in the factory setting position for +/-5V outputs. This does not effect the operation of the board just the range info that is returned to the user. A sysfs method will be investigated to allow the user to change the range. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index 350c807..ea96514 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -57,12 +57,7 @@ output modes on the board: then issue one comedi_data_read() on any channel on the AO subdevice to initiate the simultaneous XFER. -Configuration Options: - [0] PCI bus (optional) - [1] PCI slot (optional) - [2] analog output range jumper setting - 0 == +/- 5 V - 1 == +/- 10 V +Configuration Options: not applicable, uses PCI auto config */ /* @@ -157,47 +152,21 @@ static int cb_pcimdda_ao_rinsn(struct comedi_device *dev, return insn->n; } -static struct pci_dev *cb_pcimdda_probe(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - struct pci_dev *pcidev = NULL; - - for_each_pci_dev(pcidev) { - if (pcidev->vendor != PCI_VENDOR_ID_COMPUTERBOARDS) - continue; - if (pcidev->device != PCI_ID_PCIM_DDA06_16) - continue; - if (it->options[0] || it->options[1]) { - if (pcidev->bus->number != it->options[0] || - PCI_SLOT(pcidev->devfn) != it->options[1]) { - continue; - } - } - - return pcidev; - } - return NULL; -} - -static int cb_pcimdda_attach(struct comedi_device *dev, - struct comedi_devconfig *it) +static int cb_pcimdda_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) { struct cb_pcimdda_private *devpriv; - struct pci_dev *pcidev; struct comedi_subdevice *s; int ret; + comedi_set_hw_dev(dev, &pcidev->dev); + dev->board_name = dev->driver->driver_name; + ret = alloc_private(dev, sizeof(*devpriv)); if (ret) return ret; devpriv = dev->private; - pcidev = cb_pcimdda_probe(dev, it); - if (!pcidev) - return -EIO; - comedi_set_hw_dev(dev, &pcidev->dev); - dev->board_name = dev->driver->driver_name; - ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) return ret; @@ -208,19 +177,14 @@ static int cb_pcimdda_attach(struct comedi_device *dev, return ret; s = dev->subdevices + 0; - /* analog output subdevice */ - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE; - s->n_chan = 6; - s->maxdata = 0xffff; - /* this is hard-coded here */ - if (it->options[2]) - s->range_table = &range_bipolar10; - else - s->range_table = &range_bipolar5; - s->insn_write = &cb_pcimdda_ao_winsn; - s->insn_read = &cb_pcimdda_ao_rinsn; + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITABLE | SDF_READABLE; + s->n_chan = 6; + s->maxdata = 0xffff; + s->range_table = &range_bipolar5; + s->insn_write = cb_pcimdda_ao_winsn; + s->insn_read = cb_pcimdda_ao_rinsn; s = dev->subdevices + 1; /* digital i/o subdevice */ @@ -243,14 +207,13 @@ static void cb_pcimdda_detach(struct comedi_device *dev) if (pcidev) { if (dev->iobase) comedi_pci_disable(pcidev); - pci_dev_put(pcidev); } } static struct comedi_driver cb_pcimdda_driver = { .driver_name = "cb_pcimdda", .module = THIS_MODULE, - .attach = cb_pcimdda_attach, + .attach_pci = cb_pcimdda_attach_pci, .detach = cb_pcimdda_detach, }; -- cgit v0.10.2 From c3b52d465916acd02803e83e58d9440ec365ab72 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 16 Aug 2012 19:55:19 -0700 Subject: staging: comedi: dyna_pci10xx: remove manual legacy attach This driver uses the 'attach_pci' callback to attach the pci device to the comedi subsystem. Since the 'attach' callback is now optional it can be removed from the driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index e852808..9d55aa9 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -253,15 +253,6 @@ static int dyna_pci10xx_attach_pci(struct comedi_device *dev, return 0; } -static int dyna_pci10xx_attach(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - dev_warn(dev->class_dev, - "This driver does not support attach using comedi_config\n"); - - return -ENOSYS; -} - static void dyna_pci10xx_detach(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -278,7 +269,6 @@ static void dyna_pci10xx_detach(struct comedi_device *dev) static struct comedi_driver dyna_pci10xx_driver = { .driver_name = "dyna_pci10xx", .module = THIS_MODULE, - .attach = dyna_pci10xx_attach, .attach_pci = dyna_pci10xx_attach_pci, .detach = dyna_pci10xx_detach, }; -- cgit v0.10.2 From 5afbfa638d52ac844459bca55170f354b109b4dc Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 16 Aug 2012 19:55:43 -0700 Subject: staging: comedi: ke_counter: use attach_pci callback Convert this PCI driver to use the comedi PCI auto config attach mechanism by adding an 'attach_pci' callback function. Since the driver does not require any external configuration options, and the legacy 'attach' callback is now optional, remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c index d4e9292..a24e932 100644 --- a/drivers/staging/comedi/drivers/ke_counter.c +++ b/drivers/staging/comedi/drivers/ke_counter.c @@ -28,11 +28,7 @@ Author: Michael Hillmann Updated: Mon, 14 Apr 2008 15:42:42 +0100 Status: tested -Configuration Options: - [0] - PCI bus of device (optional) - [1] - PCI slot of device (optional) - If bus/slot is not specified, the first supported - PCI device found will be used. +Configuration Options: not applicable, uses PCI auto config This driver is a simple driver to read the counter values from Kolter Electronic PCI Counter Card. @@ -111,72 +107,43 @@ static int cnt_rinsn(struct comedi_device *dev, return 1; } -static struct pci_dev *cnt_find_pci_dev(struct comedi_device *dev, - struct comedi_devconfig *it) +static const void *cnt_find_boardinfo(struct comedi_device *dev, + struct pci_dev *pcidev) { const struct cnt_board_struct *board; - struct pci_dev *pcidev = NULL; - int bus = it->options[0]; - int slot = it->options[1]; int i; - /* Probe the device to determine what device in the series it is. */ - for_each_pci_dev(pcidev) { - if (bus || slot) { - if (pcidev->bus->number != bus || - PCI_SLOT(pcidev->devfn) != slot) - continue; - } - if (pcidev->vendor != PCI_VENDOR_ID_KOLTER) - continue; - - for (i = 0; i < ARRAY_SIZE(cnt_boards); i++) { - board = &cnt_boards[i]; - if (board->device_id != pcidev->device) - continue; - - dev->board_ptr = board; - return pcidev; - } + for (i = 0; i < ARRAY_SIZE(cnt_boards); i++) { + board = &cnt_boards[i]; + if (board->device_id == pcidev->device) + return board; } - dev_err(dev->class_dev, - "No supported board found! (req. bus %d, slot %d)\n", - bus, slot); return NULL; } -static int cnt_attach(struct comedi_device *dev, struct comedi_devconfig *it) +static int cnt_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) { const struct cnt_board_struct *board; - struct pci_dev *pcidev; struct comedi_subdevice *subdevice; - unsigned long io_base; - int error; + int ret; - pcidev = cnt_find_pci_dev(dev, it); - if (!pcidev) - return -EIO; comedi_set_hw_dev(dev, &pcidev->dev); - board = comedi_board(dev); + board = cnt_find_boardinfo(dev, pcidev); + if (!board) + return -ENODEV; + dev->board_ptr = board; dev->board_name = board->name; - /* enable PCI device and request regions */ - error = comedi_pci_enable(pcidev, CNT_DRIVER_NAME); - if (error < 0) { - printk(KERN_WARNING "comedi%d: " - "failed to enable PCI device and request regions!\n", - dev->minor); - return error; - } - - /* read register base address [PCI_BASE_ADDRESS #0] */ - io_base = pci_resource_start(pcidev, 0); - dev->iobase = io_base; + ret = comedi_pci_enable(pcidev, dev->board_name); + if (ret) + return ret; + dev->iobase = pci_resource_start(pcidev, 0); - error = comedi_alloc_subdevices(dev, 1); - if (error) - return error; + ret = comedi_alloc_subdevices(dev, 1); + if (ret) + return ret; subdevice = dev->subdevices + 0; dev->read_subdev = subdevice; @@ -196,8 +163,9 @@ static int cnt_attach(struct comedi_device *dev, struct comedi_devconfig *it) outb(0, dev->iobase + 0x20); outb(0, dev->iobase + 0x40); - printk(KERN_INFO "comedi%d: " CNT_DRIVER_NAME " attached.\n", - dev->minor); + dev_info(dev->class_dev, "%s: %s attached\n", + dev->driver->driver_name, dev->board_name); + return 0; } @@ -208,14 +176,13 @@ static void cnt_detach(struct comedi_device *dev) if (pcidev) { if (dev->iobase) comedi_pci_disable(pcidev); - pci_dev_put(pcidev); } } static struct comedi_driver ke_counter_driver = { .driver_name = "ke_counter", .module = THIS_MODULE, - .attach = cnt_attach, + .attach_pci = cnt_attach_pci, .detach = cnt_detach, }; -- cgit v0.10.2 From 93efc55b42536273d8ca5cccb5261cfe5e1471bb Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Thu, 16 Aug 2012 22:22:36 -0400 Subject: staging: usbip: export usbip_debug_flag as a usbip-core module parameter. Now usbip_common.c's pr_fmt is the only thing setup by CONFIG_USBIP_DEBUG that you can't subsequently alter using this parameter. Signed-off-by: W. Trevor King Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/staging/usbip/usbip_common.c index 70f23026..8919842 100644 --- a/drivers/staging/usbip/usbip_common.c +++ b/drivers/staging/usbip/usbip_common.c @@ -22,7 +22,9 @@ #include #include #include +#include #include +#include #include #include "usbip_common.h" @@ -36,6 +38,8 @@ unsigned long usbip_debug_flag = 0xffffffff; unsigned long usbip_debug_flag; #endif EXPORT_SYMBOL_GPL(usbip_debug_flag); +module_param(usbip_debug_flag, ulong, S_IRUGO|S_IWUSR); +MODULE_PARM_DESC(usbip_debug_flag, "debug flags (defined in usbip_common.h)"); /* FIXME */ struct device_attribute dev_attr_usbip_debug; -- cgit v0.10.2 From ce591f76c79da49389091a2f62597c88b8a29374 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Fri, 17 Aug 2012 06:47:05 -0400 Subject: staging: usbip: userspace: allow `configure --with-tcp-wrappers` When `--with-tcp-wrappers` is passed to `configure`, the previous code always reset LIBS to $saved_LIBS, regardless of whether libwrap was found or not. The current code makes the `--with-tcp-wrappers` case look more like the default case, and it only resets LIBS if libwrap was not found. Signed-off-by: W. Trevor King Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/usbip/userspace/configure.ac b/drivers/staging/usbip/userspace/configure.ac index bf5cf49..43e641e 100644 --- a/drivers/staging/usbip/userspace/configure.ac +++ b/drivers/staging/usbip/userspace/configure.ac @@ -56,11 +56,11 @@ AC_ARG_WITH([tcp-wrappers], [AS_HELP_STRING([--with-tcp-wrappers], [use the libwrap (TCP wrappers) library])], dnl [ACTION-IF-GIVEN] - [saved_LIBS="$LIBS" - if test "$withval" = "yes"; then + [if test "$withval" = "yes"; then AC_MSG_RESULT([yes]) AC_MSG_CHECKING([for hosts_access in -lwrap]) - LIBS="-lwrap $LIBS" + saved_LIBS="$LIBS" + LIBS="-lwrap $saved_LIBS" AC_TRY_LINK( [int hosts_access(); int allow_severity, deny_severity;], [hosts_access()], @@ -69,9 +69,9 @@ AC_ARG_WITH([tcp-wrappers], [use tcp wrapper]) wrap_LIB="-lwrap"], [AC_MSG_RESULT([not found]); exit 1]) else - AC_MSG_RESULT([no]) - fi - LIBS="$saved_LIBS"], + AC_MSG_RESULT([no]); + LIBS="$saved_LIBS" + fi], dnl [ACTION-IF-NOT-GIVEN] [AC_MSG_RESULT([(default)]) AC_MSG_CHECKING([for hosts_access in -lwrap]) -- cgit v0.10.2 From 4faf3a8d1838b86e7b66441da9a088f347e1c56b Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Fri, 17 Aug 2012 06:49:37 -0400 Subject: staging: usbip: userspace: update man pages for v1.0.0 This brings them back up to date after: commit e9837bbb3e694eef4c55c934ebf1f8a0399b142c Author: matt mooney Date: Thu May 26 06:17:11 2011 -0700 staging: usbip: userspace tools v1.0.0 I couldn't find a current equivalent for client:# usbip --port Perhaps that functionality has been deprecated due to better logging. It seems like libsrc/usbip_common.h's usbip_status_string is no longer used. Signed-off-by: W. Trevor King Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/usbip/userspace/doc/usbip.8 b/drivers/staging/usbip/userspace/doc/usbip.8 index 1653bb2..6e0d745 100644 --- a/drivers/staging/usbip/userspace/doc/usbip.8 +++ b/drivers/staging/usbip/userspace/doc/usbip.8 @@ -3,69 +3,87 @@ usbip \- manage USB/IP devices .SH SYNOPSIS .B usbip -[\fIoptions\fR] +[\foptions\R] <\fIcommand\fR> <\fIargs\fR> .SH DESCRIPTION -Devices exported by USB/IP servers can be listed, attached and -detached using this program. +On a USB/IP server, devices can be listed, bound, and unbound using +this program. On a USB/IP client, devices exported by USB/IP servers +can be listed, attached and detached. .SH OPTIONS .HP -\fB\-a\fR, \fB\-\-attach\fR +\fB\-\-debug\fR .IP -Attach a remote USB device. +Print debugging information. +.PP + +.HP +\fB\-\-log\fR +.IP +Log to syslog. +.PP + +.SH COMMANDS +.HP +\fBversion\fR +.IP +Show version and exit. .PP .HP -\fB\-x\fR, \fB\-\-attachall\fR +\fBhelp\fR [\fIcommand\fR] .IP -Attach all remote USB devices on the specific host. +Print the program help message, or help on a specific command, and +then exit. .PP .HP -\fB\-d\fR, \fB\-\-detach\fR +\fBattach\fR \-\-host=<\fIhost\fR> \-\-busid=<\fIbus_id\fR> +.IP +Attach a remote USB device. +.PP + +.HP +\fBdetach\fR \-\-port=<\fIport\fR> .IP Detach an imported USB device. .PP .HP -\fB\-l\fR, \fB\-\-list\fR +\fBbind\fR \-\-busid=<\fIbusid\fR> .IP -List exported USB devices. +Make a device exportable. .PP .HP -\fB\-p\fR, \fB\-\-port\fR +\fBunbind\fR \-\-busid=<\fIbusid\fR> .IP -List virtual USB port status. +Stop exporting a device so it can be used by a local driver. .PP .HP -\fB\-D\fR, \fB\-\-debug\fR +\fBlist\fR \-\-remote=<\fIhost\fR> .IP -Print debugging information. +List USB devices exported by a remote host. .PP .HP -\fB\-v\fR, \fB\-\-version\fR +\fBlist\fR \-\-local .IP -Show version. +List local USB devices. .PP + .SH EXAMPLES - client:# usbip --list server + client:# usbip list --remote=server - List exportable usb devices on the server. - client:# usbip --attach server 1-2 + client:# usbip attach --host=server --busid=1-2 - Connect the remote USB device. - client:# usbip --port - - Show virtual port status. - - client:# usbip --detach 0 + client:# usbip detach --port=0 - Detach the usb device. .SH "SEE ALSO" -\fBusbipd\fP\fB(8)\fB\fP, -\fBusbip_attach_driver\fP\fB(8)\fB\fP +\fBusbipd\fP\fB(8)\fB\fP diff --git a/drivers/staging/usbip/userspace/doc/usbip_bind_driver.8 b/drivers/staging/usbip/userspace/doc/usbip_bind_driver.8 deleted file mode 100644 index d43bbd6..0000000 --- a/drivers/staging/usbip/userspace/doc/usbip_bind_driver.8 +++ /dev/null @@ -1,42 +0,0 @@ -.TH USBIP_BIND_DRIVER "8" "February 2009" "usbip" "System Administration Utilities" -.SH NAME -usbip_bind_driver \- change driver binding for USB/IP - -.SH SYNOPSIS -.B usbip_bind_driver -[\fIoptions\fR] - -.SH DESCRIPTION -Driver bindings for USB devices can be changed using -this program. It is used to export and unexport USB -devices over USB/IP. - -.SH OPTIONS -.TP -\fB\-u\fR, \fB\-\-usbip\fR -Make a device exportable -.TP -\fB\-o\fR, \fB\-\-other\fR -Use a device by a local driver -.TP -\fB\-l\fR, \fB\-\-list\fR -Print usb devices and their drivers -.TP -\fB\-L\fR, \fB\-\-list2\fR -Print usb devices and their drivers in parseable mode - -.SH EXAMPLES - - server:# usbip_bind_driver --list - - List driver assignments for usb devices. - - server:# usbip_bind_driver --usbip 1-2 - - Bind usbip-host.ko to the device of busid 1-2. - - A usb device 1-2 is now exportable to other hosts! - - server:# usbip_bind_driver --other 1-2 - - Shutdown exporting and use the device locally. - -.SH "SEE ALSO" -\fBusbip\fP\fB(8)\fB\fP, -\fBusbipd\fP\fB(8)\fB\fP diff --git a/drivers/staging/usbip/userspace/doc/usbipd.8 b/drivers/staging/usbip/userspace/doc/usbipd.8 index 006559f..d896936 100644 --- a/drivers/staging/usbip/userspace/doc/usbipd.8 +++ b/drivers/staging/usbip/userspace/doc/usbipd.8 @@ -10,7 +10,7 @@ usbipd \- USB/IP server daemon provides USB/IP clients access to exported USB devices. Devices have to explicitly be exported using -.B usbip_bind_driver +.B usbip bind before usbipd makes them available to other hosts. The daemon accepts connections from USB/IP clients @@ -29,6 +29,11 @@ Run as a daemon process. Print debugging information. .PP +\fB\-h\fR, \fB\-\-help\fR +.IP +Print the program help message and exit. +.PP + .HP \fB\-v\fR, \fB\-\-version\fR .IP @@ -48,15 +53,14 @@ USB/IP client can connect and use exported devices. server:# usbipd -D - Start usbip daemon. - server:# usbip_bind_driver --list + server:# usbip list --local - List driver assignments for usb devices. - server:# usbip_bind_driver --usbip 1-2 + server:# usbip bind --busid=1-2 - Bind usbip-host.ko to the device of busid 1-2. - A usb device 1-2 is now exportable to other hosts! - - Use 'usbip_bind_driver --other 1-2' when you want to shutdown exporting and use the device locally. + - Use 'usbip unbind --busid=1-2' when you want to shutdown exporting and use the device locally. .SH "SEE ALSO" -\fBusbip\fP\fB(8)\fB\fP, -\fBusbip_attach_driver\fP\fB(8)\fB\fP +\fBusbip\fP\fB(8)\fB\fP -- cgit v0.10.2 From ac9bbd085f5d22a2f01a03cb79abe740412bdae1 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 17 Aug 2012 14:37:21 +0900 Subject: staging/olpc_dcon: fix checkpatch warnings The below checkpatch warnings was fixed, - WARNING: Prefer pr_debug(... to printk(KERN_DEBUG, ... - WARNING: Prefer pr_warn(... to printk(KERN_WARNING, ... - WARNING: Prefer pr_info(... to printk(KERN_INFO, ... - WARNING: Prefer pr_err(... to printk(KERN_ERR, ... And added pr_fmt. Signed-off-by: Toshiaki Yamane Acked-by: Andres Salomon Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index 2c4bd74..d49c32a 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c @@ -11,6 +11,7 @@ * License as published by the Free Software Foundation. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include #include @@ -72,18 +73,16 @@ static int dcon_hw_init(struct dcon_priv *dcon, int is_init) ver = dcon_read(dcon, DCON_REG_ID); if ((ver >> 8) != 0xDC) { - printk(KERN_ERR "olpc-dcon: DCON ID not 0xDCxx: 0x%04x instead.\n", - ver); + pr_err("DCON ID not 0xDCxx: 0x%04x instead.\n", ver); rc = -ENXIO; goto err; } if (is_init) { - printk(KERN_INFO "olpc-dcon: Discovered DCON version %x\n", - ver & 0xFF); + pr_info("Discovered DCON version %x\n", ver & 0xFF); rc = pdata->init(dcon); if (rc != 0) { - printk(KERN_ERR "olpc-dcon: Unable to init.\n"); + pr_err("Unable to init.\n"); goto err; } } @@ -137,8 +136,7 @@ power_up: x = 1; x = olpc_ec_cmd(0x26, (unsigned char *)&x, 1, NULL, 0); if (x) { - printk(KERN_WARNING "olpc-dcon: unable to force dcon to power up: %d!\n", - x); + pr_warn("unable to force dcon to power up: %d!\n", x); return x; } msleep(10); /* we'll be conservative */ @@ -151,7 +149,7 @@ power_up: x = dcon_read(dcon, DCON_REG_ID); } if (x < 0) { - printk(KERN_ERR "olpc-dcon: unable to stabilize dcon's smbus, reasserting power and praying.\n"); + pr_err("unable to stabilize dcon's smbus, reasserting power and praying.\n"); BUG_ON(olpc_board_at_least(olpc_board(0xc2))); x = 0; olpc_ec_cmd(0x26, (unsigned char *)&x, 1, NULL, 0); @@ -222,8 +220,7 @@ static void dcon_sleep(struct dcon_priv *dcon, bool sleep) x = 0; x = olpc_ec_cmd(0x26, (unsigned char *)&x, 1, NULL, 0); if (x) - printk(KERN_WARNING "olpc-dcon: unable to force dcon to power down: %d!\n", - x); + pr_warn("unable to force dcon to power down: %d!\n", x); else dcon->asleep = sleep; } else { @@ -232,8 +229,7 @@ static void dcon_sleep(struct dcon_priv *dcon, bool sleep) dcon->disp_mode |= MODE_BL_ENABLE; x = dcon_bus_stabilize(dcon, 1); if (x) - printk(KERN_WARNING "olpc-dcon: unable to reinit dcon hardware: %d!\n", - x); + pr_warn("unable to reinit dcon hardware: %d!\n", x); else dcon->asleep = sleep; @@ -304,12 +300,11 @@ static void dcon_source_switch(struct work_struct *work) switch (source) { case DCON_SOURCE_CPU: - printk(KERN_INFO "dcon_source_switch to CPU\n"); + pr_info("dcon_source_switch to CPU\n"); /* Enable the scanline interrupt bit */ if (dcon_write(dcon, DCON_REG_MODE, dcon->disp_mode | MODE_SCAN_INT)) - printk(KERN_ERR - "olpc-dcon: couldn't enable scanline interrupt!\n"); + pr_err("couldn't enable scanline interrupt!\n"); else { /* Wait up to one second for the scanline interrupt */ wait_event_timeout(dcon_wait_queue, @@ -317,11 +312,11 @@ static void dcon_source_switch(struct work_struct *work) } if (!dcon->switched) - printk(KERN_ERR "olpc-dcon: Timeout entering CPU mode; expect a screen glitch.\n"); + pr_err("Timeout entering CPU mode; expect a screen glitch.\n"); /* Turn off the scanline interrupt */ if (dcon_write(dcon, DCON_REG_MODE, dcon->disp_mode)) - printk(KERN_ERR "olpc-dcon: couldn't disable scanline interrupt!\n"); + pr_err("couldn't disable scanline interrupt!\n"); /* * Ideally we'd like to disable interrupts here so that the @@ -332,7 +327,7 @@ static void dcon_source_switch(struct work_struct *work) * For now, we just hope.. */ if (!dcon_blank_fb(dcon, false)) { - printk(KERN_ERR "olpc-dcon: Failed to enter CPU mode\n"); + pr_err("Failed to enter CPU mode\n"); dcon->pending_src = DCON_SOURCE_DCON; return; } @@ -341,14 +336,14 @@ static void dcon_source_switch(struct work_struct *work) pdata->set_dconload(1); getnstimeofday(&dcon->load_time); - printk(KERN_INFO "olpc-dcon: The CPU has control\n"); + pr_info("The CPU has control\n"); break; case DCON_SOURCE_DCON: { int t; struct timespec delta_t; - printk(KERN_INFO "dcon_source_switch to DCON\n"); + pr_info("dcon_source_switch to DCON\n"); add_wait_queue(&dcon_wait_queue, &wait); set_current_state(TASK_UNINTERRUPTIBLE); @@ -362,7 +357,7 @@ static void dcon_source_switch(struct work_struct *work) set_current_state(TASK_RUNNING); if (!dcon->switched) { - printk(KERN_ERR "olpc-dcon: Timeout entering DCON mode; expect a screen glitch.\n"); + pr_err("Timeout entering DCON mode; expect a screen glitch.\n"); } else { /* sometimes the DCON doesn't follow its own rules, * and doesn't wait for two vsync pulses before @@ -378,7 +373,7 @@ static void dcon_source_switch(struct work_struct *work) delta_t = timespec_sub(dcon->irq_time, dcon->load_time); if (dcon->switched && delta_t.tv_sec == 0 && delta_t.tv_nsec < NSEC_PER_MSEC * 20) { - printk(KERN_ERR "olpc-dcon: missed loading, retrying\n"); + pr_err("missed loading, retrying\n"); pdata->set_dconload(1); mdelay(41); pdata->set_dconload(0); @@ -388,7 +383,7 @@ static void dcon_source_switch(struct work_struct *work) } dcon_blank_fb(dcon, true); - printk(KERN_INFO "olpc-dcon: The DCON has control\n"); + pr_info("The DCON has control\n"); break; } default: @@ -476,7 +471,7 @@ static ssize_t dcon_freeze_store(struct device *dev, if (ret) return ret; - printk(KERN_INFO "dcon_freeze_store: %lu\n", output); + pr_info("dcon_freeze_store: %lu\n", output); switch (output) { case 0: @@ -650,7 +645,7 @@ static int dcon_probe(struct i2c_client *client, const struct i2c_device_id *id) dcon_device = platform_device_alloc("dcon", -1); if (dcon_device == NULL) { - printk(KERN_ERR "dcon: Unable to create the DCON device\n"); + pr_err("Unable to create the DCON device\n"); rc = -ENOMEM; goto eirq; } @@ -658,7 +653,7 @@ static int dcon_probe(struct i2c_client *client, const struct i2c_device_id *id) platform_set_drvdata(dcon_device, dcon); if (rc) { - printk(KERN_ERR "dcon: Unable to add the DCON device\n"); + pr_err("Unable to add the DCON device\n"); goto edev; } @@ -762,7 +757,7 @@ irqreturn_t dcon_interrupt(int irq, void *id) switch (status & 3) { case 3: - printk(KERN_DEBUG "olpc-dcon: DCONLOAD_MISSED interrupt\n"); + pr_debug("DCONLOAD_MISSED interrupt\n"); break; case 2: /* switch to DCON mode */ @@ -784,9 +779,9 @@ irqreturn_t dcon_interrupt(int irq, void *id) dcon->switched = true; getnstimeofday(&dcon->irq_time); wake_up(&dcon_wait_queue); - printk(KERN_DEBUG "olpc-dcon: switching w/ status 0/0\n"); + pr_debug("switching w/ status 0/0\n"); } else { - printk(KERN_DEBUG "olpc-dcon: scanline interrupt w/CPU\n"); + pr_debug("scanline interrupt w/CPU\n"); } } diff --git a/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c b/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c index c87fdfa..77e8eb5 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c +++ b/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c @@ -10,6 +10,9 @@ * modify it under the terms of version 2 of the GNU General Public * License as published by the Free Software Foundation. */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -22,23 +25,23 @@ static int dcon_init_xo_1(struct dcon_priv *dcon) unsigned char lob; if (gpio_request(OLPC_GPIO_DCON_STAT0, "OLPC-DCON")) { - printk(KERN_ERR "olpc-dcon: failed to request STAT0 GPIO\n"); + pr_err("failed to request STAT0 GPIO\n"); return -EIO; } if (gpio_request(OLPC_GPIO_DCON_STAT1, "OLPC-DCON")) { - printk(KERN_ERR "olpc-dcon: failed to request STAT1 GPIO\n"); + pr_err("failed to request STAT1 GPIO\n"); goto err_gp_stat1; } if (gpio_request(OLPC_GPIO_DCON_IRQ, "OLPC-DCON")) { - printk(KERN_ERR "olpc-dcon: failed to request IRQ GPIO\n"); + pr_err("failed to request IRQ GPIO\n"); goto err_gp_irq; } if (gpio_request(OLPC_GPIO_DCON_LOAD, "OLPC-DCON")) { - printk(KERN_ERR "olpc-dcon: failed to request LOAD GPIO\n"); + pr_err("failed to request LOAD GPIO\n"); goto err_gp_load; } if (gpio_request(OLPC_GPIO_DCON_BLANK, "OLPC-DCON")) { - printk(KERN_ERR "olpc-dcon: failed to request BLANK GPIO\n"); + pr_err("failed to request BLANK GPIO\n"); goto err_gp_blank; } @@ -83,7 +86,7 @@ static int dcon_init_xo_1(struct dcon_priv *dcon) /* Register the interrupt handler */ if (request_irq(DCON_IRQ, &dcon_interrupt, 0, "DCON", dcon)) { - printk(KERN_ERR "olpc-dcon: failed to request DCON's irq\n"); + pr_err("failed to request DCON's irq\n"); goto err_req_irq; } diff --git a/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c b/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c index 69415ee..352dd3d 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c +++ b/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c @@ -6,6 +6,8 @@ * License as published by the Free Software Foundation. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -66,7 +68,7 @@ static int dcon_init_xo_1_5(struct dcon_priv *dcon) pdev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855, NULL); if (!pdev) { - printk(KERN_ERR "cannot find VX855 PCI ID\n"); + pr_err("cannot find VX855 PCI ID\n"); return 1; } @@ -104,7 +106,7 @@ static int dcon_init_xo_1_5(struct dcon_priv *dcon) /* we're sharing the IRQ with ACPI */ irq = acpi_gbl_FADT.sci_interrupt; if (request_irq(irq, &dcon_interrupt, IRQF_SHARED, "DCON", dcon)) { - printk(KERN_ERR PREFIX "DCON (IRQ%d) allocation failed\n", irq); + pr_err("DCON (IRQ%d) allocation failed\n", irq); return 1; } -- cgit v0.10.2 From ae0c514cce96fa8eb68f1fdb1563eba1ff61056f Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Sat, 18 Aug 2012 01:07:16 +0900 Subject: staging: bcm: Fix typo in drivers/bcm Correct spelling typo in drivers/bcm Signed-off-by: Masanari Iida Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/PHSModule.c b/drivers/staging/bcm/PHSModule.c index 4795742..6dc0bbc 100644 --- a/drivers/staging/bcm/PHSModule.c +++ b/drivers/staging/bcm/PHSModule.c @@ -66,7 +66,7 @@ Input parameters: IN struct bcm_mini_adapter *Adapter - Miniport Adapte BOOLEAN bHeaderSuppressionEnabled - indicates if header suprression is enabled for SF. Return: STATUS_SUCCESS - If the send was successful. - Other - If an error occured. + Other - If an error occurred. */ int PHSTransmit(struct bcm_mini_adapter *Adapter, @@ -346,7 +346,7 @@ int phs_init(PPHS_DEVICE_EXTENSION pPhsdeviceExtension, struct bcm_mini_adapter - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\n phs_init Successfull"); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\n phs_init Successful"); return STATUS_SUCCESS; } diff --git a/drivers/staging/bcm/cntrl_SignalingInterface.h b/drivers/staging/bcm/cntrl_SignalingInterface.h index 7619e4b..41d732d 100644 --- a/drivers/staging/bcm/cntrl_SignalingInterface.h +++ b/drivers/staging/bcm/cntrl_SignalingInterface.h @@ -223,7 +223,7 @@ typedef struct _stServiceFlowParamSI{ /** 8bit Indicates whether or not MBS service is requested for this Serivce Flow*/ B_UINT8 u8MBSService; - /** 8bit QOS Parameter Set specifies proper application of QoS paramters to Provisioned, Admitted and Active sets*/ + /** 8bit QOS Parameter Set specifies proper application of QoS parameters to Provisioned, Admitted and Active sets*/ B_UINT8 u8QosParamSet; /** 8bit Traffic Priority Of the Service Flow */ diff --git a/drivers/staging/bcm/nvm.c b/drivers/staging/bcm/nvm.c index b179dba..ed592e0 100644 --- a/drivers/staging/bcm/nvm.c +++ b/drivers/staging/bcm/nvm.c @@ -3932,7 +3932,7 @@ int validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, PFLASH2X_READWRIT BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2_PART3); } - /* since this uiSectEndoffset is the size of iso Image. hence for calculating the vitual endoffset + /* since this uiSectEndoffset is the size of iso Image. hence for calculating the virtual endoffset * it should be added in startoffset. so that check done in last of this function can be valued. */ uiSectEndOffset = uiSectStartOffset + uiSectEndOffset; diff --git a/drivers/staging/bcm/target_params.h b/drivers/staging/bcm/target_params.h index 1487638..ad7ec00 100644 --- a/drivers/staging/bcm/target_params.h +++ b/drivers/staging/bcm/target_params.h @@ -32,7 +32,7 @@ typedef struct _TARGET_PARAMS B_UINT32 m_u32PowerSavingModesEnable; //bit 1: 1 Idlemode enable; bit2: 1 Sleepmode Enable /* PowerSaving Mode Options: bit 0 = 1: CPE mode - to keep pcmcia if alive; - bit 1 = 1: CINR reporing in Idlemode Msg + bit 1 = 1: CINR reporting in Idlemode Msg bit 2 = 1: Default PSC Enable in sleepmode*/ B_UINT32 m_u32PowerSavingModeOptions; -- cgit v0.10.2 From efde99cd281a3f0d3562bb2fa7e7ef60ad32fe8d Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Fri, 17 Aug 2012 16:39:36 +0530 Subject: Staging: android: binder: Make task_get_unused_fd_flags function static MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Silence the following warning: drivers/staging/android/binder.c:368:5: warning: symbol 'task_get_unused_fd_flags' was not declared. Should it be static? Cc: Arve Hjønnevåg Signed-off-by: Sachin Kamat Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c index 574e992..668bec7 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c @@ -365,7 +365,7 @@ binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer); /* * copied from get_unused_fd_flags */ -int task_get_unused_fd_flags(struct binder_proc *proc, int flags) +static int task_get_unused_fd_flags(struct binder_proc *proc, int flags) { struct files_struct *files = proc->files; int fd, error; -- cgit v0.10.2 From bf2023614201b36f929cce0d9fbb3cc856ea7c1a Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Fri, 17 Aug 2012 16:39:37 +0530 Subject: Staging: android: binder: Remove an inconsequential conditional macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removes an inconsequential conditional macro. Cc: Arve Hjønnevåg Signed-off-by: Sachin Kamat Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c index 668bec7..a807129 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c @@ -415,13 +415,13 @@ repeat: else __clear_close_on_exec(fd, fdt); files->next_fd = fd + 1; -#if 1 + /* Sanity check */ if (fdt->fd[fd] != NULL) { pr_warn("get_unused_fd: slot %d not NULL!\n", fd); fdt->fd[fd] = NULL; } -#endif + error = fd; out: -- cgit v0.10.2 From d602a064f9818819d6c99d99f101bc6b1ae1540d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 17 Aug 2012 09:34:52 -0700 Subject: staging: comedi: contec_pci: remove manual legacy attach This driver uses the 'attach_pci' callback to attach the pci device to the comedi subsystem. Since the 'attach' callback is now optional it can be removed from the driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c index 12ad9fa..def3e7d 100644 --- a/drivers/staging/comedi/drivers/contec_pci_dio.c +++ b/drivers/staging/comedi/drivers/contec_pci_dio.c @@ -108,15 +108,6 @@ static int contec_attach_pci(struct comedi_device *dev, return 0; } -static int contec_attach(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - dev_warn(dev->class_dev, - "This driver does not support attach using comedi_config\n"); - - return -ENOSYS; -} - static void contec_detach(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -130,7 +121,6 @@ static void contec_detach(struct comedi_device *dev) static struct comedi_driver contec_pci_dio_driver = { .driver_name = "contec_pci_dio", .module = THIS_MODULE, - .attach = contec_attach, .attach_pci = contec_attach_pci, .detach = contec_detach, }; -- cgit v0.10.2 From c8c194d5c21fc157c2329436e541bf8f33a2ee25 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 10 Aug 2012 17:36:00 +0100 Subject: staging:iio:ad7793: Remove unused platform_data from device state struct The platform data for the device is only used from within the drivers probe callback, so there is no need to keep it around in the devices state struct. While we are at it mark the platform data struct as const. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c index 112e2b7..5c2fcd7 100644 --- a/drivers/staging/iio/adc/ad7793.c +++ b/drivers/staging/iio/adc/ad7793.c @@ -44,7 +44,6 @@ struct ad7793_state { struct iio_trigger *trig; const struct ad7793_chip_info *chip_info; struct regulator *reg; - struct ad7793_platform_data *pdata; wait_queue_head_t wq_data_avail; bool done; bool irq_dis; @@ -253,7 +252,8 @@ out: return ret; } -static int ad7793_setup(struct ad7793_state *st) +static int ad7793_setup(struct ad7793_state *st, + const struct ad7793_platform_data *pdata) { int i, ret = -1; unsigned long long scale_uv; @@ -277,9 +277,9 @@ static int ad7793_setup(struct ad7793_state *st) goto out; } - st->mode = (st->pdata->mode & ~AD7793_MODE_SEL(-1)) | + st->mode = (pdata->mode & ~AD7793_MODE_SEL(-1)) | AD7793_MODE_SEL(AD7793_MODE_IDLE); - st->conf = st->pdata->conf & ~AD7793_CONF_CHAN(-1); + st->conf = pdata->conf & ~AD7793_CONF_CHAN(-1); ret = ad7793_write_reg(st, AD7793_REG_MODE, sizeof(st->mode), st->mode); if (ret) @@ -290,7 +290,7 @@ static int ad7793_setup(struct ad7793_state *st) goto out; ret = ad7793_write_reg(st, AD7793_REG_IO, - sizeof(st->pdata->io), st->pdata->io); + sizeof(pdata->io), pdata->io); if (ret) goto out; @@ -882,7 +882,7 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { static int __devinit ad7793_probe(struct spi_device *spi) { - struct ad7793_platform_data *pdata = spi->dev.platform_data; + const struct ad7793_platform_data *pdata = spi->dev.platform_data; struct ad7793_state *st; struct iio_dev *indio_dev; int ret, voltage_uv = 0; @@ -915,8 +915,6 @@ static int __devinit ad7793_probe(struct spi_device *spi) st->chip_info = &ad7793_chip_info_tbl[spi_get_device_id(spi)->driver_data]; - st->pdata = pdata; - if (pdata && pdata->vref_mv) st->int_vref_mv = pdata->vref_mv; else if (voltage_uv) @@ -944,7 +942,7 @@ static int __devinit ad7793_probe(struct spi_device *spi) if (ret) goto error_unreg_ring; - ret = ad7793_setup(st); + ret = ad7793_setup(st, pdata); if (ret) goto error_remove_trigger; -- cgit v0.10.2 From 49f8812e4d15970341f0ed320e78951cc16b596d Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 10 Aug 2012 17:36:00 +0100 Subject: staging:iio:ad7192: Remove unused platform_data from device state struct The platform data for the device is only used from within the drivers probe callback, so there is no need to keep it around in the devices state struct. While we are at it mark the platform data struct as const. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index 405d9a8..cdb4fc4 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c @@ -136,7 +136,6 @@ struct ad7192_state { struct spi_device *spi; struct iio_trigger *trig; struct regulator *reg; - struct ad7192_platform_data *pdata; wait_queue_head_t wq_data_avail; bool done; bool irq_dis; @@ -347,10 +346,10 @@ out: return ret; } -static int ad7192_setup(struct ad7192_state *st) +static int ad7192_setup(struct ad7192_state *st, + const struct ad7192_platform_data *pdata) { struct iio_dev *indio_dev = spi_get_drvdata(st->spi); - struct ad7192_platform_data *pdata = st->pdata; unsigned long long scale_uv; int i, ret, id; u8 ones[6]; @@ -985,7 +984,7 @@ static const struct iio_chan_spec ad7192_channels[] = { static int __devinit ad7192_probe(struct spi_device *spi) { - struct ad7192_platform_data *pdata = spi->dev.platform_data; + const struct ad7192_platform_data *pdata = spi->dev.platform_data; struct ad7192_state *st; struct iio_dev *indio_dev; int ret , voltage_uv = 0; @@ -1015,8 +1014,6 @@ static int __devinit ad7192_probe(struct spi_device *spi) voltage_uv = regulator_get_voltage(st->reg); } - st->pdata = pdata; - if (pdata && pdata->vref_mv) st->int_vref_mv = pdata->vref_mv; else if (voltage_uv) @@ -1047,7 +1044,7 @@ static int __devinit ad7192_probe(struct spi_device *spi) if (ret) goto error_ring_cleanup; - ret = ad7192_setup(st); + ret = ad7192_setup(st, pdata); if (ret) goto error_remove_trigger; -- cgit v0.10.2 From 2d66f389ccf2c3ffea93c0270ef34186e4995333 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 10 Aug 2012 17:36:00 +0100 Subject: iio: Introduce iio_device_{set,get}_drvdata() Introduce two new helper functions to attach a arbitrary pointer to a IIO device. This is useful to get access to external non-global data from within a IIO device callbacks where only the IIO device is available. Internally these functions use dev_{set,get}_drvdata() on the struct device embedded in the IIO device. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index be82936..b18e74e 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -516,6 +516,31 @@ static inline struct iio_dev *iio_device_get(struct iio_dev *indio_dev) return indio_dev ? dev_to_iio_dev(get_device(&indio_dev->dev)) : NULL; } + +/** + * iio_device_set_drvdata() - Set device driver data + * @indio_dev: IIO device structure + * @data: Driver specific data + * + * Allows to attach an arbitrary pointer to an IIO device, which can later be + * retrieved by iio_device_get_drvdata(). + */ +static inline void iio_device_set_drvdata(struct iio_dev *indio_dev, void *data) +{ + dev_set_drvdata(&indio_dev->dev, data); +} + +/** + * iio_device_get_drvdata() - Get device driver data + * @indio_dev: IIO device structure + * + * Returns the data previously set with iio_device_set_drvdata() + */ +static inline void *iio_device_get_drvdata(struct iio_dev *indio_dev) +{ + return dev_get_drvdata(&indio_dev->dev); +} + /* Can we make this smaller? */ #define IIO_ALIGN L1_CACHE_BYTES /** -- cgit v0.10.2 From af3008485ea0372fb9ce1f69f3768617d39eb4e6 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 10 Aug 2012 17:36:00 +0100 Subject: iio:adc: Add common code for ADI Sigma Delta devices Most devices from the Analog Devices Sigma Delta family use a similar scheme for communication with the device. This includes register access, as well as trigger handling. But each device sub-family has different features and different register layouts (some even have no registers at all) and thus it is impractical to try to support all of the devices by the same driver. This patch adds a common base library for Sigma Delta converter devices. It will be used by individual drivers. This code is mostly based on the three existing Sigma Delta drivers the AD7192, AD7780 and AD7793, but has been improved for more robustness and flexibility. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 8a78b4f..a2c5071 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -3,6 +3,11 @@ # menu "Analog to digital converters" +config AD_SIGMA_DELTA + tristate + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER + config AD7266 tristate "Analog Devices AD7265/AD7266 ADC driver" depends on SPI_MASTER diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index 52eec25..5989356 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -2,5 +2,6 @@ # Makefile for IIO ADC drivers # +obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o obj-$(CONFIG_AD7266) += ad7266.o obj-$(CONFIG_AT91_ADC) += at91_adc.o diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c new file mode 100644 index 0000000..ae847c5 --- /dev/null +++ b/drivers/iio/adc/ad_sigma_delta.c @@ -0,0 +1,558 @@ +/* + * Support code for Analog Devices Sigma-Delta ADCs + * + * Copyright 2012 Analog Devices Inc. + * Author: Lars-Peter Clausen + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + + +#define AD_SD_COMM_CHAN_MASK 0x3 + +#define AD_SD_REG_COMM 0x00 +#define AD_SD_REG_DATA 0x03 + +/** + * ad_sd_set_comm() - Set communications register + * + * @sigma_delta: The sigma delta device + * @comm: New value for the communications register + */ +void ad_sd_set_comm(struct ad_sigma_delta *sigma_delta, uint8_t comm) +{ + /* Some variants use the lower two bits of the communications register + * to select the channel */ + sigma_delta->comm = comm & AD_SD_COMM_CHAN_MASK; +} +EXPORT_SYMBOL_GPL(ad_sd_set_comm); + +/** + * ad_sd_write_reg() - Write a register + * + * @sigma_delta: The sigma delta device + * @reg: Address of the register + * @size: Size of the register (0-3) + * @val: Value to write to the register + * + * Returns 0 on success, an error code otherwise. + **/ +int ad_sd_write_reg(struct ad_sigma_delta *sigma_delta, unsigned int reg, + unsigned int size, unsigned int val) +{ + uint8_t *data = sigma_delta->data; + struct spi_transfer t = { + .tx_buf = data, + .len = size + 1, + .cs_change = sigma_delta->bus_locked, + }; + struct spi_message m; + int ret; + + data[0] = (reg << sigma_delta->info->addr_shift) | sigma_delta->comm; + + switch (size) { + case 3: + data[1] = val >> 16; + data[2] = val >> 8; + data[3] = val; + break; + case 2: + put_unaligned_be16(val, &data[1]); + break; + case 1: + data[1] = val; + break; + case 0: + break; + default: + return -EINVAL; + } + + spi_message_init(&m); + spi_message_add_tail(&t, &m); + + if (sigma_delta->bus_locked) + ret = spi_sync_locked(sigma_delta->spi, &m); + else + ret = spi_sync(sigma_delta->spi, &m); + + return ret; +} +EXPORT_SYMBOL_GPL(ad_sd_write_reg); + +static int ad_sd_read_reg_raw(struct ad_sigma_delta *sigma_delta, + unsigned int reg, unsigned int size, uint8_t *val) +{ + uint8_t *data = sigma_delta->data; + int ret; + struct spi_transfer t[] = { + { + .tx_buf = data, + .len = 1, + }, { + .rx_buf = val, + .len = size, + .cs_change = sigma_delta->bus_locked, + }, + }; + struct spi_message m; + + spi_message_init(&m); + + if (sigma_delta->info->has_registers) { + data[0] = reg << sigma_delta->info->addr_shift; + data[0] |= sigma_delta->info->read_mask; + spi_message_add_tail(&t[0], &m); + } + spi_message_add_tail(&t[1], &m); + + if (sigma_delta->bus_locked) + ret = spi_sync_locked(sigma_delta->spi, &m); + else + ret = spi_sync(sigma_delta->spi, &m); + + return ret; +} + +/** + * ad_sd_read_reg() - Read a register + * + * @sigma_delta: The sigma delta device + * @reg: Address of the register + * @size: Size of the register (1-4) + * @val: Read value + * + * Returns 0 on success, an error code otherwise. + **/ +int ad_sd_read_reg(struct ad_sigma_delta *sigma_delta, + unsigned int reg, unsigned int size, unsigned int *val) +{ + int ret; + + ret = ad_sd_read_reg_raw(sigma_delta, reg, size, sigma_delta->data); + if (ret < 0) + goto out; + + switch (size) { + case 4: + *val = get_unaligned_be32(sigma_delta->data); + break; + case 3: + *val = (sigma_delta->data[0] << 16) | + (sigma_delta->data[1] << 8) | + sigma_delta->data[2]; + break; + case 2: + *val = get_unaligned_be16(sigma_delta->data); + break; + case 1: + *val = sigma_delta->data[0]; + break; + default: + ret = -EINVAL; + break; + } + +out: + return ret; +} +EXPORT_SYMBOL_GPL(ad_sd_read_reg); + +static int ad_sd_calibrate(struct ad_sigma_delta *sigma_delta, + unsigned int mode, unsigned int channel) +{ + int ret; + + ret = ad_sigma_delta_set_channel(sigma_delta, channel); + if (ret) + return ret; + + spi_bus_lock(sigma_delta->spi->master); + sigma_delta->bus_locked = true; + INIT_COMPLETION(sigma_delta->completion); + + ret = ad_sigma_delta_set_mode(sigma_delta, mode); + if (ret < 0) + goto out; + + sigma_delta->irq_dis = false; + enable_irq(sigma_delta->spi->irq); + ret = wait_for_completion_timeout(&sigma_delta->completion, 2*HZ); + if (ret == 0) { + sigma_delta->irq_dis = true; + disable_irq_nosync(sigma_delta->spi->irq); + ret = -EIO; + } else { + ret = 0; + } +out: + sigma_delta->bus_locked = false; + spi_bus_unlock(sigma_delta->spi->master); + ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE); + + return ret; +} + +/** + * ad_sd_calibrate_all() - Performs channel calibration + * @sigma_delta: The sigma delta device + * @cb: Array of channels and calibration type to perform + * @n: Number of items in cb + * + * Returns 0 on success, an error code otherwise. + **/ +int ad_sd_calibrate_all(struct ad_sigma_delta *sigma_delta, + const struct ad_sd_calib_data *cb, unsigned int n) +{ + unsigned int i; + int ret; + + for (i = 0; i < n; i++) { + ret = ad_sd_calibrate(sigma_delta, cb[i].mode, cb[i].channel); + if (ret) + return ret; + } + + return 0; +} +EXPORT_SYMBOL_GPL(ad_sd_calibrate_all); + +/** + * ad_sigma_delta_single_conversion() - Performs a single data conversion + * @indio_dev: The IIO device + * @chan: The conversion is done for this channel + * @val: Pointer to the location where to store the read value + * + * Returns: 0 on success, an error value otherwise. + */ +int ad_sigma_delta_single_conversion(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, int *val) +{ + struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev); + unsigned int sample, raw_sample; + int ret = 0; + + if (iio_buffer_enabled(indio_dev)) + return -EBUSY; + + mutex_lock(&indio_dev->mlock); + ad_sigma_delta_set_channel(sigma_delta, chan->address); + + spi_bus_lock(sigma_delta->spi->master); + sigma_delta->bus_locked = true; + INIT_COMPLETION(sigma_delta->completion); + + ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_SINGLE); + + sigma_delta->irq_dis = false; + enable_irq(sigma_delta->spi->irq); + ret = wait_for_completion_interruptible_timeout( + &sigma_delta->completion, HZ); + + sigma_delta->bus_locked = false; + spi_bus_unlock(sigma_delta->spi->master); + + if (ret == 0) + ret = -EIO; + if (ret < 0) + goto out; + + ret = ad_sd_read_reg(sigma_delta, AD_SD_REG_DATA, + DIV_ROUND_UP(chan->scan_type.realbits + chan->scan_type.shift, 8), + &raw_sample); + +out: + if (!sigma_delta->irq_dis) { + disable_irq_nosync(sigma_delta->spi->irq); + sigma_delta->irq_dis = true; + } + + ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE); + mutex_unlock(&indio_dev->mlock); + + if (ret) + return ret; + + sample = raw_sample >> chan->scan_type.shift; + sample &= (1 << chan->scan_type.realbits) - 1; + *val = sample; + + ret = ad_sigma_delta_postprocess_sample(sigma_delta, raw_sample); + if (ret) + return ret; + + return IIO_VAL_INT; +} +EXPORT_SYMBOL_GPL(ad_sigma_delta_single_conversion); + +static int ad_sd_buffer_postenable(struct iio_dev *indio_dev) +{ + struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev); + unsigned int channel; + int ret; + + ret = iio_triggered_buffer_postenable(indio_dev); + if (ret < 0) + return ret; + + channel = find_first_bit(indio_dev->active_scan_mask, + indio_dev->masklength); + ret = ad_sigma_delta_set_channel(sigma_delta, + indio_dev->channels[channel].address); + if (ret) + goto err_predisable; + + spi_bus_lock(sigma_delta->spi->master); + sigma_delta->bus_locked = true; + ret = ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_CONTINUOUS); + if (ret) + goto err_unlock; + + sigma_delta->irq_dis = false; + enable_irq(sigma_delta->spi->irq); + + return 0; + +err_unlock: + spi_bus_unlock(sigma_delta->spi->master); +err_predisable: + + return ret; +} + +static int ad_sd_buffer_postdisable(struct iio_dev *indio_dev) +{ + struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev); + + INIT_COMPLETION(sigma_delta->completion); + wait_for_completion_timeout(&sigma_delta->completion, HZ); + + if (!sigma_delta->irq_dis) { + disable_irq_nosync(sigma_delta->spi->irq); + sigma_delta->irq_dis = true; + } + + ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE); + + sigma_delta->bus_locked = false; + return spi_bus_unlock(sigma_delta->spi->master); +} + +static irqreturn_t ad_sd_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev); + unsigned int reg_size; + uint8_t data[16]; + int ret; + + memset(data, 0x00, 16); + + /* Guaranteed to be aligned with 8 byte boundary */ + if (indio_dev->scan_timestamp) + ((s64 *)data)[1] = pf->timestamp; + + reg_size = indio_dev->channels[0].scan_type.realbits + + indio_dev->channels[0].scan_type.shift; + reg_size = DIV_ROUND_UP(reg_size, 8); + + switch (reg_size) { + case 4: + case 2: + case 1: + ret = ad_sd_read_reg_raw(sigma_delta, AD_SD_REG_DATA, + reg_size, &data[0]); + break; + case 3: + /* We store 24 bit samples in a 32 bit word. Keep the upper + * byte set to zero. */ + ret = ad_sd_read_reg_raw(sigma_delta, AD_SD_REG_DATA, + reg_size, &data[1]); + break; + } + + iio_push_to_buffer(indio_dev->buffer, (uint8_t *)data, pf->timestamp); + + iio_trigger_notify_done(indio_dev->trig); + sigma_delta->irq_dis = false; + enable_irq(sigma_delta->spi->irq); + + return IRQ_HANDLED; +} + +static const struct iio_buffer_setup_ops ad_sd_buffer_setup_ops = { + .preenable = &iio_sw_buffer_preenable, + .postenable = &ad_sd_buffer_postenable, + .predisable = &iio_triggered_buffer_predisable, + .postdisable = &ad_sd_buffer_postdisable, + .validate_scan_mask = &iio_validate_scan_mask_onehot, +}; + +static irqreturn_t ad_sd_data_rdy_trig_poll(int irq, void *private) +{ + struct ad_sigma_delta *sigma_delta = private; + + complete(&sigma_delta->completion); + disable_irq_nosync(irq); + sigma_delta->irq_dis = true; + iio_trigger_poll(sigma_delta->trig, iio_get_time_ns()); + + return IRQ_HANDLED; +} + +/** + * ad_sd_validate_trigger() - validate_trigger callback for ad_sigma_delta devices + * @indio_dev: The IIO device + * @trig: The new trigger + * + * Returns: 0 if the 'trig' matches the trigger registered by the ad_sigma_delta + * device, -EINVAL otherwise. + */ +int ad_sd_validate_trigger(struct iio_dev *indio_dev, struct iio_trigger *trig) +{ + struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev); + + if (sigma_delta->trig != trig) + return -EINVAL; + + return 0; +} +EXPORT_SYMBOL_GPL(ad_sd_validate_trigger); + +static const struct iio_trigger_ops ad_sd_trigger_ops = { + .owner = THIS_MODULE, +}; + +static int ad_sd_probe_trigger(struct iio_dev *indio_dev) +{ + struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev); + int ret; + + sigma_delta->trig = iio_trigger_alloc("%s-dev%d", indio_dev->name, + indio_dev->id); + if (sigma_delta->trig == NULL) { + ret = -ENOMEM; + goto error_ret; + } + sigma_delta->trig->ops = &ad_sd_trigger_ops; + init_completion(&sigma_delta->completion); + + ret = request_irq(sigma_delta->spi->irq, + ad_sd_data_rdy_trig_poll, + IRQF_TRIGGER_LOW, + indio_dev->name, + sigma_delta); + if (ret) + goto error_free_trig; + + if (!sigma_delta->irq_dis) { + sigma_delta->irq_dis = true; + disable_irq_nosync(sigma_delta->spi->irq); + } + sigma_delta->trig->dev.parent = &sigma_delta->spi->dev; + sigma_delta->trig->private_data = sigma_delta; + + ret = iio_trigger_register(sigma_delta->trig); + if (ret) + goto error_free_irq; + + /* select default trigger */ + indio_dev->trig = sigma_delta->trig; + + return 0; + +error_free_irq: + free_irq(sigma_delta->spi->irq, sigma_delta); +error_free_trig: + iio_trigger_free(sigma_delta->trig); +error_ret: + return ret; +} + +static void ad_sd_remove_trigger(struct iio_dev *indio_dev) +{ + struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev); + + iio_trigger_unregister(sigma_delta->trig); + free_irq(sigma_delta->spi->irq, sigma_delta); + iio_trigger_free(sigma_delta->trig); +} + +/** + * ad_sd_setup_buffer_and_trigger() - + * @indio_dev: The IIO device + */ +int ad_sd_setup_buffer_and_trigger(struct iio_dev *indio_dev) +{ + int ret; + + ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, + &ad_sd_trigger_handler, &ad_sd_buffer_setup_ops); + if (ret) + return ret; + + ret = ad_sd_probe_trigger(indio_dev); + if (ret) { + iio_triggered_buffer_cleanup(indio_dev); + return ret; + } + + return 0; +} +EXPORT_SYMBOL_GPL(ad_sd_setup_buffer_and_trigger); + +/** + * ad_sd_cleanup_buffer_and_trigger() - + * @indio_dev: The IIO device + */ +void ad_sd_cleanup_buffer_and_trigger(struct iio_dev *indio_dev) +{ + ad_sd_remove_trigger(indio_dev); + iio_triggered_buffer_cleanup(indio_dev); +} +EXPORT_SYMBOL_GPL(ad_sd_cleanup_buffer_and_trigger); + +/** + * ad_sd_init() - Initializes a ad_sigma_delta struct + * @sigma_delta: The ad_sigma_delta device + * @indio_dev: The IIO device which the Sigma Delta device is used for + * @spi: The SPI device for the ad_sigma_delta device + * @info: Device specific callbacks and options + * + * This function needs to be called before any other operations are performed on + * the ad_sigma_delta struct. + */ +int ad_sd_init(struct ad_sigma_delta *sigma_delta, struct iio_dev *indio_dev, + struct spi_device *spi, const struct ad_sigma_delta_info *info) +{ + sigma_delta->spi = spi; + sigma_delta->info = info; + iio_device_set_drvdata(indio_dev, sigma_delta); + + return 0; +} +EXPORT_SYMBOL_GPL(ad_sd_init); + +MODULE_AUTHOR("Lars-Peter Clausen "); +MODULE_DESCRIPTION("Analog Devices Sigma-Delta ADCs"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/iio/adc/ad_sigma_delta.h b/include/linux/iio/adc/ad_sigma_delta.h new file mode 100644 index 0000000..2e4eab9 --- /dev/null +++ b/include/linux/iio/adc/ad_sigma_delta.h @@ -0,0 +1,173 @@ +/* + * Support code for Analog Devices Sigma-Delta ADCs + * + * Copyright 2012 Analog Devices Inc. + * Author: Lars-Peter Clausen + * + * Licensed under the GPL-2. + */ +#ifndef __AD_SIGMA_DELTA_H__ +#define __AD_SIGMA_DELTA_H__ + +enum ad_sigma_delta_mode { + AD_SD_MODE_CONTINUOUS = 0, + AD_SD_MODE_SINGLE = 1, + AD_SD_MODE_IDLE = 2, + AD_SD_MODE_POWERDOWN = 3, +}; + +/** + * struct ad_sigma_delta_calib_data - Calibration data for Sigma Delta devices + * @mode: Calibration mode. + * @channel: Calibration channel. + */ +struct ad_sd_calib_data { + unsigned int mode; + unsigned int channel; +}; + +struct ad_sigma_delta; +struct iio_dev; + +/** + * struct ad_sigma_delta_info - Sigma Delta driver specific callbacks and options + * @set_channel: Will be called to select the current channel, may be NULL. + * @set_mode: Will be called to select the current mode, may be NULL. + * @postprocess_sample: Is called for each sampled data word, can be used to + * modify or drop the sample data, it, may be NULL. + * @has_registers: true if the device has writable and readable registers, false + * if there is just one read-only sample data shift register. + * @addr_shift: Shift of the register address in the communications register. + * @read_mask: Mask for the communications register having the read bit set. + */ +struct ad_sigma_delta_info { + int (*set_channel)(struct ad_sigma_delta *, unsigned int channel); + int (*set_mode)(struct ad_sigma_delta *, enum ad_sigma_delta_mode mode); + int (*postprocess_sample)(struct ad_sigma_delta *, unsigned int raw_sample); + bool has_registers; + unsigned int addr_shift; + unsigned int read_mask; +}; + +/** + * struct ad_sigma_delta - Sigma Delta device struct + * @spi: The spi device associated with the Sigma Delta device. + * @trig: The IIO trigger associated with the Sigma Delta device. + * + * Most of the fields are private to the sigma delta library code and should not + * be accessed by individual drivers. + */ +struct ad_sigma_delta { + struct spi_device *spi; + struct iio_trigger *trig; + +/* private: */ + struct completion completion; + bool irq_dis; + + bool bus_locked; + + uint8_t comm; + + const struct ad_sigma_delta_info *info; + + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + */ + uint8_t data[4] ____cacheline_aligned; +}; + +static inline int ad_sigma_delta_set_channel(struct ad_sigma_delta *sd, + unsigned int channel) +{ + if (sd->info->set_channel) + return sd->info->set_channel(sd, channel); + + return 0; +} + +static inline int ad_sigma_delta_set_mode(struct ad_sigma_delta *sd, + unsigned int mode) +{ + if (sd->info->set_mode) + return sd->info->set_mode(sd, mode); + + return 0; +} + +static inline int ad_sigma_delta_postprocess_sample(struct ad_sigma_delta *sd, + unsigned int raw_sample) +{ + if (sd->info->postprocess_sample) + return sd->info->postprocess_sample(sd, raw_sample); + + return 0; +} + +void ad_sd_set_comm(struct ad_sigma_delta *sigma_delta, uint8_t comm); +int ad_sd_write_reg(struct ad_sigma_delta *sigma_delta, unsigned int reg, + unsigned int size, unsigned int val); +int ad_sd_read_reg(struct ad_sigma_delta *sigma_delta, unsigned int reg, + unsigned int size, unsigned int *val); + +int ad_sigma_delta_single_conversion(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, int *val); +int ad_sd_calibrate_all(struct ad_sigma_delta *sigma_delta, + const struct ad_sd_calib_data *cd, unsigned int n); +int ad_sd_init(struct ad_sigma_delta *sigma_delta, struct iio_dev *indio_dev, + struct spi_device *spi, const struct ad_sigma_delta_info *info); + +int ad_sd_setup_buffer_and_trigger(struct iio_dev *indio_dev); +void ad_sd_cleanup_buffer_and_trigger(struct iio_dev *indio_dev); + +int ad_sd_validate_trigger(struct iio_dev *indio_dev, struct iio_trigger *trig); + +#define __AD_SD_CHANNEL(_si, _channel1, _channel2, _address, _bits, \ + _storagebits, _shift, _extend_name, _type) \ + { \ + .type = (_type), \ + .differential = (_channel2 == -1 ? 0 : 1), \ + .indexed = 1, \ + .channel = (_channel1), \ + .channel2 = (_channel2), \ + .address = (_address), \ + .extend_name = (_extend_name), \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT | \ + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, \ + .scan_index = (_si), \ + .scan_type = { \ + .sign = 'u', \ + .realbits = (_bits), \ + .storagebits = (_storagebits), \ + .shift = (_shift), \ + .endianness = IIO_BE, \ + }, \ + } + +#define AD_SD_DIFF_CHANNEL(_si, _channel1, _channel2, _address, _bits, \ + _storagebits, _shift) \ + __AD_SD_CHANNEL(_si, _channel1, _channel2, _address, _bits, \ + _storagebits, _shift, NULL, IIO_VOLTAGE) + +#define AD_SD_SHORTED_CHANNEL(_si, _channel, _address, _bits, \ + _storagebits, _shift) \ + __AD_SD_CHANNEL(_si, _channel, _channel, _address, _bits, \ + _storagebits, _shift, "shorted", IIO_VOLTAGE) + +#define AD_SD_CHANNEL(_si, _channel, _address, _bits, \ + _storagebits, _shift) \ + __AD_SD_CHANNEL(_si, _channel, -1, _address, _bits, \ + _storagebits, _shift, NULL, IIO_VOLTAGE) + +#define AD_SD_TEMP_CHANNEL(_si, _address, _bits, _storagebits, _shift) \ + __AD_SD_CHANNEL(_si, 0, -1, _address, _bits, \ + _storagebits, _shift, NULL, IIO_TEMP) + +#define AD_SD_SUPPLY_CHANNEL(_si, _channel, _address, _bits, _storagebits, \ + _shift) \ + __AD_SD_CHANNEL(_si, _channel, -1, _address, _bits, \ + _storagebits, _shift, "supply", IIO_VOLTAGE) + +#endif -- cgit v0.10.2 From 32e0e7e08c32fbd61ddfb7e80ba96c13085f3d39 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 10 Aug 2012 17:36:00 +0100 Subject: staging:iio:ad7780: Use common Sigma Delta library Convert the ad7780 driver to make use of the new common code for devices from the Analog Devices Sigma Delta family. As a bonus the ad7780 driver gains support for buffered mode. Although this is a bit tricky. The ad7780 reports in the lower 4 unused bits of the data word the internal gain used. The driver will update the scale attribute value depending on the gain accordingly, but obviously this will only work if the gain does not change while sampling. This is not perfect, but since we store the raw value in the buffer an application which is aware of this can extract the gain factor from the buffer as well an apply it accordingly. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index 845fb6c..d0eb27b 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -99,6 +99,7 @@ config AD7780 tristate "Analog Devices AD7780 AD7781 ADC driver" depends on SPI depends on GPIOLIB + select AD_SIGMA_DELTA help Say yes here to build support for Analog Devices AD7780 and AD7781 SPI analog to digital converters (ADC). diff --git a/drivers/staging/iio/adc/ad7780.c b/drivers/staging/iio/adc/ad7780.c index 19ee49c..853f8b1 100644 --- a/drivers/staging/iio/adc/ad7780.c +++ b/drivers/staging/iio/adc/ad7780.c @@ -20,6 +20,7 @@ #include #include +#include #include "ad7780.h" @@ -37,20 +38,13 @@ struct ad7780_chip_info { }; struct ad7780_state { - struct spi_device *spi; const struct ad7780_chip_info *chip_info; struct regulator *reg; - struct ad7780_platform_data *pdata; - wait_queue_head_t wq_data_avail; - bool done; + int powerdown_gpio; + unsigned int gain; u16 int_vref_mv; - struct spi_transfer xfer; - struct spi_message msg; - /* - * DMA (thus cache coherency maintenance) requires the - * transfer buffers to live in their own cache lines. - */ - unsigned int data ____cacheline_aligned; + + struct ad_sigma_delta sd; }; enum ad7780_supported_device_ids { @@ -58,28 +52,30 @@ enum ad7780_supported_device_ids { ID_AD7781, }; -static int ad7780_read(struct ad7780_state *st, int *val) +static struct ad7780_state *ad_sigma_delta_to_ad7780(struct ad_sigma_delta *sd) { - int ret; - - spi_bus_lock(st->spi->master); - - enable_irq(st->spi->irq); - st->done = false; - gpio_set_value(st->pdata->gpio_pdrst, 1); + return container_of(sd, struct ad7780_state, sd); +} - ret = wait_event_interruptible(st->wq_data_avail, st->done); - disable_irq_nosync(st->spi->irq); - if (ret) - goto out; +static int ad7780_set_mode(struct ad_sigma_delta *sigma_delta, + enum ad_sigma_delta_mode mode) +{ + struct ad7780_state *st = ad_sigma_delta_to_ad7780(sigma_delta); + unsigned val; + + switch (mode) { + case AD_SD_MODE_SINGLE: + case AD_SD_MODE_CONTINUOUS: + val = 1; + break; + default: + val = 0; + break; + } - ret = spi_sync_locked(st->spi, &st->msg); - *val = be32_to_cpu(st->data); -out: - gpio_set_value(st->pdata->gpio_pdrst, 0); - spi_bus_unlock(st->spi->master); + gpio_set_value(st->powerdown_gpio, val); - return ret; + return 0; } static int ad7780_read_raw(struct iio_dev *indio_dev, @@ -89,89 +85,57 @@ static int ad7780_read_raw(struct iio_dev *indio_dev, long m) { struct ad7780_state *st = iio_priv(indio_dev); - struct iio_chan_spec channel = st->chip_info->channel; - int ret, smpl = 0; unsigned long scale_uv; switch (m) { case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); - ret = ad7780_read(st, &smpl); - mutex_unlock(&indio_dev->mlock); - - if (ret < 0) - return ret; - - if ((smpl & AD7780_ERR) || - !((smpl & AD7780_PAT0) && !(smpl & AD7780_PAT1))) - return -EIO; - - *val = (smpl >> channel.scan_type.shift) & - ((1 << (channel.scan_type.realbits)) - 1); - *val -= (1 << (channel.scan_type.realbits - 1)); - - if (!(smpl & AD7780_GAIN)) - *val *= 128; - - return IIO_VAL_INT; + return ad_sigma_delta_single_conversion(indio_dev, chan, val); case IIO_CHAN_INFO_SCALE: - scale_uv = (st->int_vref_mv * 100000) - >> (channel.scan_type.realbits - 1); + scale_uv = (st->int_vref_mv * 100000 * st->gain) + >> (chan->scan_type.realbits - 1); *val = scale_uv / 100000; *val2 = (scale_uv % 100000) * 10; return IIO_VAL_INT_PLUS_MICRO; + case IIO_CHAN_INFO_OFFSET: + *val -= (1 << (chan->scan_type.realbits - 1)); + return IIO_VAL_INT; } + return -EINVAL; } +static int ad7780_postprocess_sample(struct ad_sigma_delta *sigma_delta, + unsigned int raw_sample) +{ + struct ad7780_state *st = ad_sigma_delta_to_ad7780(sigma_delta); + + if ((raw_sample & AD7780_ERR) || + !((raw_sample & AD7780_PAT0) && !(raw_sample & AD7780_PAT1))) + return -EIO; + + if (raw_sample & AD7780_GAIN) + st->gain = 1; + else + st->gain = 128; + + return 0; +} + +static const struct ad_sigma_delta_info ad7780_sigma_delta_info = { + .set_mode = ad7780_set_mode, + .postprocess_sample = ad7780_postprocess_sample, + .has_registers = false, +}; + static const struct ad7780_chip_info ad7780_chip_info_tbl[] = { [ID_AD7780] = { - .channel = { - .type = IIO_VOLTAGE, - .indexed = 1, - .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_OFFSET_SHARED_BIT, - .scan_type = { - .sign = 'u', - .realbits = 24, - .storagebits = 32, - .shift = 8, - }, - }, + .channel = AD_SD_CHANNEL(1, 0, 0, 24, 32, 8), }, [ID_AD7781] = { - .channel = { - .type = IIO_VOLTAGE, - .indexed = 1, - .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_OFFSET_SHARED_BIT, - .scan_type = { - .sign = 'u', - .realbits = 20, - .storagebits = 32, - .shift = 12, - }, - }, + .channel = AD_SD_CHANNEL(1, 0, 0, 20, 32, 12), }, }; -/** - * Interrupt handler - */ -static irqreturn_t ad7780_interrupt(int irq, void *dev_id) -{ - struct ad7780_state *st = dev_id; - - st->done = true; - wake_up_interruptible(&st->wq_data_avail); - - return IRQ_HANDLED; -}; - static const struct iio_info ad7780_info = { .read_raw = &ad7780_read_raw, .driver_module = THIS_MODULE, @@ -194,6 +158,9 @@ static int __devinit ad7780_probe(struct spi_device *spi) return -ENOMEM; st = iio_priv(indio_dev); + st->gain = 1; + + ad_sd_init(&st->sd, indio_dev, spi, &ad7780_sigma_delta_info); st->reg = regulator_get(&spi->dev, "vcc"); if (!IS_ERR(st->reg)) { @@ -207,7 +174,7 @@ static int __devinit ad7780_probe(struct spi_device *spi) st->chip_info = &ad7780_chip_info_tbl[spi_get_device_id(spi)->driver_data]; - st->pdata = pdata; + st->powerdown_gpio = pdata->gpio_pdrst; if (pdata && pdata->vref_mv) st->int_vref_mv = pdata->vref_mv; @@ -217,7 +184,6 @@ static int __devinit ad7780_probe(struct spi_device *spi) dev_warn(&spi->dev, "reference voltage unspecified\n"); spi_set_drvdata(spi, indio_dev); - st->spi = spi; indio_dev->dev.parent = &spi->dev; indio_dev->name = spi_get_device_id(spi)->name; @@ -226,40 +192,27 @@ static int __devinit ad7780_probe(struct spi_device *spi) indio_dev->num_channels = 1; indio_dev->info = &ad7780_info; - init_waitqueue_head(&st->wq_data_avail); - - /* Setup default message */ - - st->xfer.rx_buf = &st->data; - st->xfer.len = st->chip_info->channel.scan_type.storagebits / 8; - - spi_message_init(&st->msg); - spi_message_add_tail(&st->xfer, &st->msg); - - ret = gpio_request_one(st->pdata->gpio_pdrst, GPIOF_OUT_INIT_LOW, + ret = gpio_request_one(pdata->gpio_pdrst, GPIOF_OUT_INIT_LOW, "AD7780 /PDRST"); if (ret) { dev_err(&spi->dev, "failed to request GPIO PDRST\n"); goto error_disable_reg; } - ret = request_irq(spi->irq, ad7780_interrupt, - IRQF_TRIGGER_FALLING, spi_get_device_id(spi)->name, st); + ret = ad_sd_setup_buffer_and_trigger(indio_dev); if (ret) goto error_free_gpio; - disable_irq(spi->irq); - ret = iio_device_register(indio_dev); if (ret) - goto error_free_irq; + goto error_cleanup_buffer_and_trigger; return 0; -error_free_irq: - free_irq(spi->irq, st); +error_cleanup_buffer_and_trigger: + ad_sd_cleanup_buffer_and_trigger(indio_dev); error_free_gpio: - gpio_free(st->pdata->gpio_pdrst); + gpio_free(pdata->gpio_pdrst); error_disable_reg: if (!IS_ERR(st->reg)) regulator_disable(st->reg); @@ -278,8 +231,9 @@ static int ad7780_remove(struct spi_device *spi) struct ad7780_state *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); - free_irq(spi->irq, st); - gpio_free(st->pdata->gpio_pdrst); + ad_sd_cleanup_buffer_and_trigger(indio_dev); + + gpio_free(st->powerdown_gpio); if (!IS_ERR(st->reg)) { regulator_disable(st->reg); regulator_put(st->reg); -- cgit v0.10.2 From 1abec6ac69fe5aea1013c1e8f764d9e71a8e64c4 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 10 Aug 2012 17:36:00 +0100 Subject: staging:iio:ad7793: Use common Sigma Delta library Convert the ad7793 driver to make use of the new common code for devices from the Analog Devices Sigma Delta family. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index d0eb27b..f7d7e44 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -111,8 +111,7 @@ config AD7780 config AD7793 tristate "Analog Devices AD7792 AD7793 ADC driver" depends on SPI - select IIO_BUFFER - select IIO_TRIGGERED_BUFFER + select AD_SIGMA_DELTA help Say yes here to build support for Analog Devices AD7792 and AD7793 SPI analog to digital converters (ADC). diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c index 5c2fcd7..9033595 100644 --- a/drivers/staging/iio/adc/ad7793.c +++ b/drivers/staging/iio/adc/ad7793.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "ad7793.h" @@ -36,27 +37,19 @@ */ struct ad7793_chip_info { - struct iio_chan_spec channel[7]; + struct iio_chan_spec channel[7]; }; struct ad7793_state { - struct spi_device *spi; - struct iio_trigger *trig; const struct ad7793_chip_info *chip_info; struct regulator *reg; - wait_queue_head_t wq_data_avail; - bool done; - bool irq_dis; u16 int_vref_mv; u16 mode; u16 conf; u32 scale_avail[8][2]; - /* - * DMA (thus cache coherency maintenance) requires the - * transfer buffers to live in their own cache lines. - */ - u8 data[4] ____cacheline_aligned; + struct ad_sigma_delta sd; + }; enum ad7793_supported_device_ids { @@ -64,169 +57,41 @@ enum ad7793_supported_device_ids { ID_AD7793, }; -static int __ad7793_write_reg(struct ad7793_state *st, bool locked, - bool cs_change, unsigned char reg, - unsigned size, unsigned val) +static struct ad7793_state *ad_sigma_delta_to_ad7793(struct ad_sigma_delta *sd) { - u8 *data = st->data; - struct spi_transfer t = { - .tx_buf = data, - .len = size + 1, - .cs_change = cs_change, - }; - struct spi_message m; - - data[0] = AD7793_COMM_WRITE | AD7793_COMM_ADDR(reg); - - switch (size) { - case 3: - data[1] = val >> 16; - data[2] = val >> 8; - data[3] = val; - break; - case 2: - data[1] = val >> 8; - data[2] = val; - break; - case 1: - data[1] = val; - break; - default: - return -EINVAL; - } - - spi_message_init(&m); - spi_message_add_tail(&t, &m); - - if (locked) - return spi_sync_locked(st->spi, &m); - else - return spi_sync(st->spi, &m); + return container_of(sd, struct ad7793_state, sd); } -static int ad7793_write_reg(struct ad7793_state *st, - unsigned reg, unsigned size, unsigned val) +static int ad7793_set_channel(struct ad_sigma_delta *sd, unsigned int channel) { - return __ad7793_write_reg(st, false, false, reg, size, val); -} + struct ad7793_state *st = ad_sigma_delta_to_ad7793(sd); -static int __ad7793_read_reg(struct ad7793_state *st, bool locked, - bool cs_change, unsigned char reg, - int *val, unsigned size) -{ - u8 *data = st->data; - int ret; - struct spi_transfer t[] = { - { - .tx_buf = data, - .len = 1, - }, { - .rx_buf = data, - .len = size, - .cs_change = cs_change, - }, - }; - struct spi_message m; - - data[0] = AD7793_COMM_READ | AD7793_COMM_ADDR(reg); - - spi_message_init(&m); - spi_message_add_tail(&t[0], &m); - spi_message_add_tail(&t[1], &m); - - if (locked) - ret = spi_sync_locked(st->spi, &m); - else - ret = spi_sync(st->spi, &m); + st->conf &= ~AD7793_CONF_CHAN_MASK; + st->conf |= AD7793_CONF_CHAN(channel); - if (ret < 0) - return ret; - - switch (size) { - case 3: - *val = data[0] << 16 | data[1] << 8 | data[2]; - break; - case 2: - *val = data[0] << 8 | data[1]; - break; - case 1: - *val = data[0]; - break; - default: - return -EINVAL; - } - - return 0; + return ad_sd_write_reg(&st->sd, AD7793_REG_CONF, 2, st->conf); } -static int ad7793_read_reg(struct ad7793_state *st, - unsigned reg, int *val, unsigned size) +static int ad7793_set_mode(struct ad_sigma_delta *sd, + enum ad_sigma_delta_mode mode) { - return __ad7793_read_reg(st, 0, 0, reg, val, size); -} - -static int ad7793_read(struct ad7793_state *st, unsigned ch, - unsigned len, int *val) -{ - int ret; - st->conf = (st->conf & ~AD7793_CONF_CHAN(-1)) | AD7793_CONF_CHAN(ch); - st->mode = (st->mode & ~AD7793_MODE_SEL(-1)) | - AD7793_MODE_SEL(AD7793_MODE_SINGLE); + struct ad7793_state *st = ad_sigma_delta_to_ad7793(sd); - ad7793_write_reg(st, AD7793_REG_CONF, sizeof(st->conf), st->conf); + st->mode &= ~AD7793_MODE_SEL_MASK; + st->mode |= AD7793_MODE_SEL(mode); - spi_bus_lock(st->spi->master); - st->done = false; - - ret = __ad7793_write_reg(st, 1, 1, AD7793_REG_MODE, - sizeof(st->mode), st->mode); - if (ret < 0) - goto out; - - st->irq_dis = false; - enable_irq(st->spi->irq); - wait_event_interruptible(st->wq_data_avail, st->done); - - ret = __ad7793_read_reg(st, 1, 0, AD7793_REG_DATA, val, len); -out: - spi_bus_unlock(st->spi->master); - - return ret; + return ad_sd_write_reg(&st->sd, AD7793_REG_MODE, 2, st->mode); } -static int ad7793_calibrate(struct ad7793_state *st, unsigned mode, unsigned ch) -{ - int ret; - - st->conf = (st->conf & ~AD7793_CONF_CHAN(-1)) | AD7793_CONF_CHAN(ch); - st->mode = (st->mode & ~AD7793_MODE_SEL(-1)) | AD7793_MODE_SEL(mode); - - ad7793_write_reg(st, AD7793_REG_CONF, sizeof(st->conf), st->conf); - - spi_bus_lock(st->spi->master); - st->done = false; - - ret = __ad7793_write_reg(st, 1, 1, AD7793_REG_MODE, - sizeof(st->mode), st->mode); - if (ret < 0) - goto out; - - st->irq_dis = false; - enable_irq(st->spi->irq); - wait_event_interruptible(st->wq_data_avail, st->done); - - st->mode = (st->mode & ~AD7793_MODE_SEL(-1)) | - AD7793_MODE_SEL(AD7793_MODE_IDLE); - - ret = __ad7793_write_reg(st, 1, 0, AD7793_REG_MODE, - sizeof(st->mode), st->mode); -out: - spi_bus_unlock(st->spi->master); - - return ret; -} +static const struct ad_sigma_delta_info ad7793_sigma_delta_info = { + .set_channel = ad7793_set_channel, + .set_mode = ad7793_set_mode, + .has_registers = true, + .addr_shift = 3, + .read_mask = BIT(6), +}; -static const u8 ad7793_calib_arr[6][2] = { +static const struct ad_sd_calib_data ad7793_calib_arr[6] = { {AD7793_MODE_CAL_INT_ZERO, AD7793_CH_AIN1P_AIN1M}, {AD7793_MODE_CAL_INT_FULL, AD7793_CH_AIN1P_AIN1M}, {AD7793_MODE_CAL_INT_ZERO, AD7793_CH_AIN2P_AIN2M}, @@ -237,59 +102,48 @@ static const u8 ad7793_calib_arr[6][2] = { static int ad7793_calibrate_all(struct ad7793_state *st) { - int i, ret; - - for (i = 0; i < ARRAY_SIZE(ad7793_calib_arr); i++) { - ret = ad7793_calibrate(st, ad7793_calib_arr[i][0], - ad7793_calib_arr[i][1]); - if (ret) - goto out; - } - - return 0; -out: - dev_err(&st->spi->dev, "Calibration failed\n"); - return ret; + return ad_sd_calibrate_all(&st->sd, ad7793_calib_arr, + ARRAY_SIZE(ad7793_calib_arr)); } -static int ad7793_setup(struct ad7793_state *st, +static int ad7793_setup(struct iio_dev *indio_dev, const struct ad7793_platform_data *pdata) { + struct ad7793_state *st = iio_priv(indio_dev); int i, ret = -1; unsigned long long scale_uv; u32 id; /* reset the serial interface */ - ret = spi_write(st->spi, (u8 *)&ret, sizeof(ret)); + ret = spi_write(st->sd.spi, (u8 *)&ret, sizeof(ret)); if (ret < 0) goto out; msleep(1); /* Wait for at least 500us */ /* write/read test for device presence */ - ret = ad7793_read_reg(st, AD7793_REG_ID, &id, 1); + ret = ad_sd_read_reg(&st->sd, AD7793_REG_ID, 1, &id); if (ret) goto out; id &= AD7793_ID_MASK; if (!((id == AD7792_ID) || (id == AD7793_ID))) { - dev_err(&st->spi->dev, "device ID query failed\n"); + dev_err(&st->sd.spi->dev, "device ID query failed\n"); goto out; } - st->mode = (pdata->mode & ~AD7793_MODE_SEL(-1)) | - AD7793_MODE_SEL(AD7793_MODE_IDLE); - st->conf = pdata->conf & ~AD7793_CONF_CHAN(-1); + st->mode = pdata->mode; + st->conf = pdata->conf; - ret = ad7793_write_reg(st, AD7793_REG_MODE, sizeof(st->mode), st->mode); + ret = ad7793_set_mode(&st->sd, AD_SD_MODE_IDLE); if (ret) goto out; - ret = ad7793_write_reg(st, AD7793_REG_CONF, sizeof(st->conf), st->conf); + ret = ad7793_set_channel(&st->sd, 0); if (ret) goto out; - ret = ad7793_write_reg(st, AD7793_REG_IO, + ret = ad_sd_write_reg(&st->sd, AD7793_REG_IO, sizeof(pdata->io), pdata->io); if (ret) goto out; @@ -311,184 +165,10 @@ static int ad7793_setup(struct ad7793_state *st, return 0; out: - dev_err(&st->spi->dev, "setup failed\n"); - return ret; -} - -static int ad7793_ring_preenable(struct iio_dev *indio_dev) -{ - struct ad7793_state *st = iio_priv(indio_dev); - unsigned channel; - int ret; - - if (bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength)) - return -EINVAL; - ret = iio_sw_buffer_preenable(indio_dev); - if (ret < 0) - return ret; - - channel = find_first_bit(indio_dev->active_scan_mask, - indio_dev->masklength); - - st->mode = (st->mode & ~AD7793_MODE_SEL(-1)) | - AD7793_MODE_SEL(AD7793_MODE_CONT); - st->conf = (st->conf & ~AD7793_CONF_CHAN(-1)) | - AD7793_CONF_CHAN(indio_dev->channels[channel].address); - - ad7793_write_reg(st, AD7793_REG_CONF, sizeof(st->conf), st->conf); - - spi_bus_lock(st->spi->master); - __ad7793_write_reg(st, 1, 1, AD7793_REG_MODE, - sizeof(st->mode), st->mode); - - st->irq_dis = false; - enable_irq(st->spi->irq); - - return 0; -} - -static int ad7793_ring_postdisable(struct iio_dev *indio_dev) -{ - struct ad7793_state *st = iio_priv(indio_dev); - - st->mode = (st->mode & ~AD7793_MODE_SEL(-1)) | - AD7793_MODE_SEL(AD7793_MODE_IDLE); - - st->done = false; - wait_event_interruptible(st->wq_data_avail, st->done); - - if (!st->irq_dis) - disable_irq_nosync(st->spi->irq); - - __ad7793_write_reg(st, 1, 0, AD7793_REG_MODE, - sizeof(st->mode), st->mode); - - return spi_bus_unlock(st->spi->master); -} - -/** - * ad7793_trigger_handler() bh of trigger launched polling to ring buffer - **/ - -static irqreturn_t ad7793_trigger_handler(int irq, void *p) -{ - struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->indio_dev; - struct iio_buffer *ring = indio_dev->buffer; - struct ad7793_state *st = iio_priv(indio_dev); - s64 dat64[2]; - s32 *dat32 = (s32 *)dat64; - - if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength)) - __ad7793_read_reg(st, 1, 1, AD7793_REG_DATA, - dat32, - indio_dev->channels[0].scan_type.realbits/8); - - /* Guaranteed to be aligned with 8 byte boundary */ - if (indio_dev->scan_timestamp) - dat64[1] = pf->timestamp; - - ring->access->store_to(ring, (u8 *)dat64, pf->timestamp); - - iio_trigger_notify_done(indio_dev->trig); - st->irq_dis = false; - enable_irq(st->spi->irq); - - return IRQ_HANDLED; -} - -static const struct iio_buffer_setup_ops ad7793_ring_setup_ops = { - .preenable = &ad7793_ring_preenable, - .postenable = &iio_triggered_buffer_postenable, - .predisable = &iio_triggered_buffer_predisable, - .postdisable = &ad7793_ring_postdisable, - .validate_scan_mask = &iio_validate_scan_mask_onehot, -}; - -static int ad7793_register_ring_funcs_and_init(struct iio_dev *indio_dev) -{ - return iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, - &ad7793_trigger_handler, &ad7793_ring_setup_ops); -} - -static void ad7793_ring_cleanup(struct iio_dev *indio_dev) -{ - iio_triggered_buffer_cleanup(indio_dev); -} - -/** - * ad7793_data_rdy_trig_poll() the event handler for the data rdy trig - **/ -static irqreturn_t ad7793_data_rdy_trig_poll(int irq, void *private) -{ - struct ad7793_state *st = iio_priv(private); - - st->done = true; - wake_up_interruptible(&st->wq_data_avail); - disable_irq_nosync(irq); - st->irq_dis = true; - iio_trigger_poll(st->trig, iio_get_time_ns()); - - return IRQ_HANDLED; -} - -static struct iio_trigger_ops ad7793_trigger_ops = { - .owner = THIS_MODULE, -}; - -static int ad7793_probe_trigger(struct iio_dev *indio_dev) -{ - struct ad7793_state *st = iio_priv(indio_dev); - int ret; - - st->trig = iio_trigger_alloc("%s-dev%d", - spi_get_device_id(st->spi)->name, - indio_dev->id); - if (st->trig == NULL) { - ret = -ENOMEM; - goto error_ret; - } - st->trig->ops = &ad7793_trigger_ops; - - ret = request_irq(st->spi->irq, - ad7793_data_rdy_trig_poll, - IRQF_TRIGGER_LOW, - spi_get_device_id(st->spi)->name, - indio_dev); - if (ret) - goto error_free_trig; - - disable_irq_nosync(st->spi->irq); - st->irq_dis = true; - st->trig->dev.parent = &st->spi->dev; - st->trig->private_data = indio_dev; - - ret = iio_trigger_register(st->trig); - - /* select default trigger */ - indio_dev->trig = st->trig; - if (ret) - goto error_free_irq; - - return 0; - -error_free_irq: - free_irq(st->spi->irq, indio_dev); -error_free_trig: - iio_trigger_free(st->trig); -error_ret: + dev_err(&st->sd.spi->dev, "setup failed\n"); return ret; } -static void ad7793_remove_trigger(struct iio_dev *indio_dev) -{ - struct ad7793_state *st = iio_priv(indio_dev); - - iio_trigger_unregister(st->trig); - free_irq(st->spi->irq, indio_dev); - iio_trigger_free(st->trig); -} - static const u16 sample_freq_avail[16] = {0, 470, 242, 123, 62, 50, 39, 33, 19, 17, 16, 12, 10, 8, 6, 4}; @@ -531,7 +211,7 @@ static ssize_t ad7793_write_frequency(struct device *dev, mutex_lock(&indio_dev->mlock); st->mode &= ~AD7793_MODE_RATE(-1); st->mode |= AD7793_MODE_RATE(i); - ad7793_write_reg(st, AD7793_REG_MODE, + ad_sd_write_reg(&st->sd, AD7793_REG_MODE, sizeof(st->mode), st->mode); mutex_unlock(&indio_dev->mlock); ret = 0; @@ -585,26 +265,16 @@ static int ad7793_read_raw(struct iio_dev *indio_dev, long m) { struct ad7793_state *st = iio_priv(indio_dev); - int ret, smpl = 0; + int ret; unsigned long long scale_uv; bool unipolar = !!(st->conf & AD7793_CONF_UNIPOLAR); switch (m) { case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); - if (iio_buffer_enabled(indio_dev)) - ret = -EBUSY; - else - ret = ad7793_read(st, chan->address, - chan->scan_type.realbits / 8, &smpl); - mutex_unlock(&indio_dev->mlock); - + ret = ad_sigma_delta_single_conversion(indio_dev, chan, val); if (ret < 0) return ret; - *val = (smpl >> chan->scan_type.shift) & - ((1 << (chan->scan_type.realbits)) - 1); - return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: @@ -675,17 +345,18 @@ static int ad7793_write_raw(struct iio_dev *indio_dev, ret = -EINVAL; for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++) if (val2 == st->scale_avail[i][1]) { + ret = 0; tmp = st->conf; st->conf &= ~AD7793_CONF_GAIN(-1); st->conf |= AD7793_CONF_GAIN(i); - if (tmp != st->conf) { - ad7793_write_reg(st, AD7793_REG_CONF, - sizeof(st->conf), - st->conf); - ad7793_calibrate_all(st); - } - ret = 0; + if (tmp == st->conf) + break; + + ad_sd_write_reg(&st->sd, AD7793_REG_CONF, + sizeof(st->conf), st->conf); + ad7793_calibrate_all(st); + break; } break; default: @@ -696,15 +367,6 @@ static int ad7793_write_raw(struct iio_dev *indio_dev, return ret; } -static int ad7793_validate_trigger(struct iio_dev *indio_dev, - struct iio_trigger *trig) -{ - if (indio_dev->trig != trig) - return -EINVAL; - - return 0; -} - static int ad7793_write_raw_get_fmt(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, long mask) @@ -717,166 +379,32 @@ static const struct iio_info ad7793_info = { .write_raw = &ad7793_write_raw, .write_raw_get_fmt = &ad7793_write_raw_get_fmt, .attrs = &ad7793_attribute_group, - .validate_trigger = ad7793_validate_trigger, + .validate_trigger = ad_sd_validate_trigger, .driver_module = THIS_MODULE, }; static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { [ID_AD7793] = { - .channel[0] = { - .type = IIO_VOLTAGE, - .differential = 1, - .indexed = 1, - .channel = 0, - .channel2 = 0, - .address = AD7793_CH_AIN1P_AIN1M, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_OFFSET_SHARED_BIT, - .scan_index = 0, - .scan_type = IIO_ST('u', 24, 32, 0) - }, - .channel[1] = { - .type = IIO_VOLTAGE, - .differential = 1, - .indexed = 1, - .channel = 1, - .channel2 = 1, - .address = AD7793_CH_AIN2P_AIN2M, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_OFFSET_SHARED_BIT, - .scan_index = 1, - .scan_type = IIO_ST('u', 24, 32, 0) - }, - .channel[2] = { - .type = IIO_VOLTAGE, - .differential = 1, - .indexed = 1, - .channel = 2, - .channel2 = 2, - .address = AD7793_CH_AIN3P_AIN3M, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_OFFSET_SHARED_BIT, - .scan_index = 2, - .scan_type = IIO_ST('u', 24, 32, 0) - }, - .channel[3] = { - .type = IIO_VOLTAGE, - .differential = 1, - .extend_name = "shorted", - .indexed = 1, - .channel = 2, - .channel2 = 2, - .address = AD7793_CH_AIN1M_AIN1M, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_OFFSET_SHARED_BIT, - .scan_index = 3, - .scan_type = IIO_ST('u', 24, 32, 0) - }, - .channel[4] = { - .type = IIO_TEMP, - .indexed = 1, - .channel = 0, - .address = AD7793_CH_TEMP, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - .scan_index = 4, - .scan_type = IIO_ST('u', 24, 32, 0), + .channel = { + AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, 24, 32, 0), + AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, 24, 32, 0), + AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, 24, 32, 0), + AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, 24, 32, 0), + AD_SD_TEMP_CHANNEL(4, AD7793_CH_TEMP, 24, 32, 0), + AD_SD_SUPPLY_CHANNEL(5, 3, AD7793_CH_AVDD_MONITOR, 24, 32, 0), + IIO_CHAN_SOFT_TIMESTAMP(6), }, - .channel[5] = { - .type = IIO_VOLTAGE, - .extend_name = "supply", - .indexed = 1, - .channel = 4, - .address = AD7793_CH_AVDD_MONITOR, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | - IIO_CHAN_INFO_OFFSET_SHARED_BIT, - .scan_index = 5, - .scan_type = IIO_ST('u', 24, 32, 0), - }, - .channel[6] = IIO_CHAN_SOFT_TIMESTAMP(6), }, [ID_AD7792] = { - .channel[0] = { - .type = IIO_VOLTAGE, - .differential = 1, - .indexed = 1, - .channel = 0, - .channel2 = 0, - .address = AD7793_CH_AIN1P_AIN1M, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_OFFSET_SHARED_BIT, - .scan_index = 0, - .scan_type = IIO_ST('u', 16, 32, 0) - }, - .channel[1] = { - .type = IIO_VOLTAGE, - .differential = 1, - .indexed = 1, - .channel = 1, - .channel2 = 1, - .address = AD7793_CH_AIN2P_AIN2M, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_OFFSET_SHARED_BIT, - .scan_index = 1, - .scan_type = IIO_ST('u', 16, 32, 0) - }, - .channel[2] = { - .type = IIO_VOLTAGE, - .differential = 1, - .indexed = 1, - .channel = 2, - .channel2 = 2, - .address = AD7793_CH_AIN3P_AIN3M, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_OFFSET_SHARED_BIT, - .scan_index = 2, - .scan_type = IIO_ST('u', 16, 32, 0) - }, - .channel[3] = { - .type = IIO_VOLTAGE, - .differential = 1, - .extend_name = "shorted", - .indexed = 1, - .channel = 2, - .channel2 = 2, - .address = AD7793_CH_AIN1M_AIN1M, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_OFFSET_SHARED_BIT, - .scan_index = 3, - .scan_type = IIO_ST('u', 16, 32, 0) - }, - .channel[4] = { - .type = IIO_TEMP, - .indexed = 1, - .channel = 0, - .address = AD7793_CH_TEMP, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - .scan_index = 4, - .scan_type = IIO_ST('u', 16, 32, 0), + .channel = { + AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, 16, 32, 0), + AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, 16, 32, 0), + AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, 16, 32, 0), + AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, 16, 32, 0), + AD_SD_TEMP_CHANNEL(4, AD7793_CH_TEMP, 16, 32, 0), + AD_SD_SUPPLY_CHANNEL(5, 3, AD7793_CH_AVDD_MONITOR, 16, 32, 0), + IIO_CHAN_SOFT_TIMESTAMP(6), }, - .channel[5] = { - .type = IIO_VOLTAGE, - .extend_name = "supply", - .indexed = 1, - .channel = 4, - .address = AD7793_CH_AVDD_MONITOR, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | - IIO_CHAN_INFO_OFFSET_SHARED_BIT, - .scan_index = 5, - .scan_type = IIO_ST('u', 16, 32, 0), - }, - .channel[6] = IIO_CHAN_SOFT_TIMESTAMP(6), }, }; @@ -903,6 +431,8 @@ static int __devinit ad7793_probe(struct spi_device *spi) st = iio_priv(indio_dev); + ad_sd_init(&st->sd, indio_dev, spi, &ad7793_sigma_delta_info); + st->reg = regulator_get(&spi->dev, "vcc"); if (!IS_ERR(st->reg)) { ret = regulator_enable(st->reg); @@ -923,7 +453,6 @@ static int __devinit ad7793_probe(struct spi_device *spi) st->int_vref_mv = 1170; /* Build-in ref */ spi_set_drvdata(spi, indio_dev); - st->spi = spi; indio_dev->dev.parent = &spi->dev; indio_dev->name = spi_get_device_id(spi)->name; @@ -932,17 +461,11 @@ static int __devinit ad7793_probe(struct spi_device *spi) indio_dev->num_channels = 7; indio_dev->info = &ad7793_info; - init_waitqueue_head(&st->wq_data_avail); - - ret = ad7793_register_ring_funcs_and_init(indio_dev); + ret = ad_sd_setup_buffer_and_trigger(indio_dev); if (ret) goto error_disable_reg; - ret = ad7793_probe_trigger(indio_dev); - if (ret) - goto error_unreg_ring; - - ret = ad7793_setup(st, pdata); + ret = ad7793_setup(indio_dev, pdata); if (ret) goto error_remove_trigger; @@ -953,9 +476,7 @@ static int __devinit ad7793_probe(struct spi_device *spi) return 0; error_remove_trigger: - ad7793_remove_trigger(indio_dev); -error_unreg_ring: - ad7793_ring_cleanup(indio_dev); + ad_sd_cleanup_buffer_and_trigger(indio_dev); error_disable_reg: if (!IS_ERR(st->reg)) regulator_disable(st->reg); @@ -974,8 +495,7 @@ static int ad7793_remove(struct spi_device *spi) struct ad7793_state *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); - ad7793_remove_trigger(indio_dev); - ad7793_ring_cleanup(indio_dev); + ad_sd_cleanup_buffer_and_trigger(indio_dev); if (!IS_ERR(st->reg)) { regulator_disable(st->reg); diff --git a/drivers/staging/iio/adc/ad7793.h b/drivers/staging/iio/adc/ad7793.h index 64f7d41..0e296d8 100644 --- a/drivers/staging/iio/adc/ad7793.h +++ b/drivers/staging/iio/adc/ad7793.h @@ -41,6 +41,7 @@ /* Mode Register Bit Designations (AD7793_REG_MODE) */ #define AD7793_MODE_SEL(x) (((x) & 0x7) << 13) /* Operation Mode Select */ +#define AD7793_MODE_SEL_MASK (0x7 << 13) /* Operation Mode Select mask */ #define AD7793_MODE_CLKSRC(x) (((x) & 0x3) << 6) /* ADC Clock Source Select */ #define AD7793_MODE_RATE(x) ((x) & 0xF) /* Filter Update Rate Select */ @@ -70,6 +71,7 @@ #define AD7793_CONF_REFSEL (1 << 7) /* INT/EXT Reference Select */ #define AD7793_CONF_BUF (1 << 4) /* Buffered Mode Enable */ #define AD7793_CONF_CHAN(x) ((x) & 0x7) /* Channel select */ +#define AD7793_CONF_CHAN_MASK 0x7 /* Channel select mask */ #define AD7793_CH_AIN1P_AIN1M 0 /* AIN1(+) - AIN1(-) */ #define AD7793_CH_AIN2P_AIN2M 1 /* AIN2(+) - AIN2(-) */ -- cgit v0.10.2 From 3f7c3306cf385d015d84c741e5433781f83d9254 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 10 Aug 2012 17:36:00 +0100 Subject: staging:iio:ad7192: Use common Sigma Delta library Convert the ad7192 driver to make use of the new common code for devices from the Analog Devices Sigma Delta family. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index f7d7e44..3f1f2c3 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -131,8 +131,7 @@ config AD7816 config AD7192 tristate "Analog Devices AD7190 AD7192 AD7195 ADC driver" depends on SPI - select IIO_BUFFER - select IIO_TRIGGERED_BUFFER + select AD_SIGMA_DELTA help Say yes here to build support for Analog Devices AD7190, AD7192 or AD7195 SPI analog to digital converters (ADC). diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index cdb4fc4..189d951 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "ad7192.h" @@ -57,6 +58,7 @@ /* Mode Register Bit Designations (AD7192_REG_MODE) */ #define AD7192_MODE_SEL(x) (((x) & 0x7) << 21) /* Operation Mode Select */ +#define AD7192_MODE_SEL_MASK (0x7 << 21) /* Operation Mode Select Mask */ #define AD7192_MODE_DAT_STA (1 << 20) /* Status Register transmission */ #define AD7192_MODE_CLKSRC(x) (((x) & 0x3) << 18) /* Clock Source Select */ #define AD7192_MODE_SINC3 (1 << 15) /* SINC3 Filter Select */ @@ -91,7 +93,8 @@ #define AD7192_CONF_CHOP (1 << 23) /* CHOP enable */ #define AD7192_CONF_REFSEL (1 << 20) /* REFIN1/REFIN2 Reference Select */ -#define AD7192_CONF_CHAN(x) (((x) & 0xFF) << 8) /* Channel select */ +#define AD7192_CONF_CHAN(x) (((1 << (x)) & 0xFF) << 8) /* Channel select */ +#define AD7192_CONF_CHAN_MASK (0xFF << 8) /* Channel select mask */ #define AD7192_CONF_BURN (1 << 7) /* Burnout current enable */ #define AD7192_CONF_REFDET (1 << 6) /* Reference detect enable */ #define AD7192_CONF_BUF (1 << 4) /* Buffered Mode Enable */ @@ -133,12 +136,7 @@ */ struct ad7192_state { - struct spi_device *spi; - struct iio_trigger *trig; struct regulator *reg; - wait_queue_head_t wq_data_avail; - bool done; - bool irq_dis; u16 int_vref_mv; u32 mclk; u32 f_order; @@ -147,178 +145,45 @@ struct ad7192_state { u32 scale_avail[8][2]; u8 gpocon; u8 devid; - /* - * DMA (thus cache coherency maintenance) requires the - * transfer buffers to live in their own cache lines. - */ - u8 data[4] ____cacheline_aligned; -}; - -static int __ad7192_write_reg(struct ad7192_state *st, bool locked, - bool cs_change, unsigned char reg, - unsigned size, unsigned val) -{ - u8 *data = st->data; - struct spi_transfer t = { - .tx_buf = data, - .len = size + 1, - .cs_change = cs_change, - }; - struct spi_message m; - - data[0] = AD7192_COMM_WRITE | AD7192_COMM_ADDR(reg); - - switch (size) { - case 3: - data[1] = val >> 16; - data[2] = val >> 8; - data[3] = val; - break; - case 2: - data[1] = val >> 8; - data[2] = val; - break; - case 1: - data[1] = val; - break; - default: - return -EINVAL; - } - spi_message_init(&m); - spi_message_add_tail(&t, &m); - - if (locked) - return spi_sync_locked(st->spi, &m); - else - return spi_sync(st->spi, &m); -} + struct ad_sigma_delta sd; +}; -static int ad7192_write_reg(struct ad7192_state *st, - unsigned reg, unsigned size, unsigned val) +static struct ad7192_state *ad_sigma_delta_to_ad7192(struct ad_sigma_delta *sd) { - return __ad7192_write_reg(st, false, false, reg, size, val); + return container_of(sd, struct ad7192_state, sd); } -static int __ad7192_read_reg(struct ad7192_state *st, bool locked, - bool cs_change, unsigned char reg, - int *val, unsigned size) +static int ad7192_set_channel(struct ad_sigma_delta *sd, unsigned int channel) { - u8 *data = st->data; - int ret; - struct spi_transfer t[] = { - { - .tx_buf = data, - .len = 1, - }, { - .rx_buf = data, - .len = size, - .cs_change = cs_change, - }, - }; - struct spi_message m; - - data[0] = AD7192_COMM_READ | AD7192_COMM_ADDR(reg); - - spi_message_init(&m); - spi_message_add_tail(&t[0], &m); - spi_message_add_tail(&t[1], &m); - - if (locked) - ret = spi_sync_locked(st->spi, &m); - else - ret = spi_sync(st->spi, &m); + struct ad7192_state *st = ad_sigma_delta_to_ad7192(sd); - if (ret < 0) - return ret; + st->conf &= ~AD7192_CONF_CHAN_MASK; + st->conf |= AD7192_CONF_CHAN(channel); - switch (size) { - case 3: - *val = data[0] << 16 | data[1] << 8 | data[2]; - break; - case 2: - *val = data[0] << 8 | data[1]; - break; - case 1: - *val = data[0]; - break; - default: - return -EINVAL; - } - - return 0; + return ad_sd_write_reg(&st->sd, AD7192_REG_CONF, 3, st->conf); } -static int ad7192_read_reg(struct ad7192_state *st, - unsigned reg, int *val, unsigned size) +static int ad7192_set_mode(struct ad_sigma_delta *sd, + enum ad_sigma_delta_mode mode) { - return __ad7192_read_reg(st, 0, 0, reg, val, size); -} - -static int ad7192_read(struct ad7192_state *st, unsigned ch, - unsigned len, int *val) -{ - int ret; - st->conf = (st->conf & ~AD7192_CONF_CHAN(-1)) | - AD7192_CONF_CHAN(1 << ch); - st->mode = (st->mode & ~AD7192_MODE_SEL(-1)) | - AD7192_MODE_SEL(AD7192_MODE_SINGLE); - - ad7192_write_reg(st, AD7192_REG_CONF, 3, st->conf); + struct ad7192_state *st = ad_sigma_delta_to_ad7192(sd); - spi_bus_lock(st->spi->master); - st->done = false; + st->mode &= ~AD7192_MODE_SEL_MASK; + st->mode |= AD7192_MODE_SEL(mode); - ret = __ad7192_write_reg(st, 1, 1, AD7192_REG_MODE, 3, st->mode); - if (ret < 0) - goto out; - - st->irq_dis = false; - enable_irq(st->spi->irq); - wait_event_interruptible(st->wq_data_avail, st->done); - - ret = __ad7192_read_reg(st, 1, 0, AD7192_REG_DATA, val, len); -out: - spi_bus_unlock(st->spi->master); - - return ret; + return ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, st->mode); } -static int ad7192_calibrate(struct ad7192_state *st, unsigned mode, unsigned ch) -{ - int ret; - - st->conf = (st->conf & ~AD7192_CONF_CHAN(-1)) | - AD7192_CONF_CHAN(1 << ch); - st->mode = (st->mode & ~AD7192_MODE_SEL(-1)) | AD7192_MODE_SEL(mode); - - ad7192_write_reg(st, AD7192_REG_CONF, 3, st->conf); - - spi_bus_lock(st->spi->master); - st->done = false; - - ret = __ad7192_write_reg(st, 1, 1, AD7192_REG_MODE, 3, - (st->devid != ID_AD7195) ? - st->mode | AD7192_MODE_CLKDIV : - st->mode); - if (ret < 0) - goto out; - - st->irq_dis = false; - enable_irq(st->spi->irq); - wait_event_interruptible(st->wq_data_avail, st->done); - - st->mode = (st->mode & ~AD7192_MODE_SEL(-1)) | - AD7192_MODE_SEL(AD7192_MODE_IDLE); - - ret = __ad7192_write_reg(st, 1, 0, AD7192_REG_MODE, 3, st->mode); -out: - spi_bus_unlock(st->spi->master); - - return ret; -} +static const struct ad_sigma_delta_info ad7192_sigma_delta_info = { + .set_channel = ad7192_set_channel, + .set_mode = ad7192_set_mode, + .has_registers = true, + .addr_shift = 3, + .read_mask = BIT(6), +}; -static const u8 ad7192_calib_arr[8][2] = { +static const struct ad_sd_calib_data ad7192_calib_arr[8] = { {AD7192_MODE_CAL_INT_ZERO, AD7192_CH_AIN1}, {AD7192_MODE_CAL_INT_FULL, AD7192_CH_AIN1}, {AD7192_MODE_CAL_INT_ZERO, AD7192_CH_AIN2}, @@ -331,45 +196,34 @@ static const u8 ad7192_calib_arr[8][2] = { static int ad7192_calibrate_all(struct ad7192_state *st) { - int i, ret; - - for (i = 0; i < ARRAY_SIZE(ad7192_calib_arr); i++) { - ret = ad7192_calibrate(st, ad7192_calib_arr[i][0], - ad7192_calib_arr[i][1]); - if (ret) - goto out; - } - - return 0; -out: - dev_err(&st->spi->dev, "Calibration failed\n"); - return ret; + return ad_sd_calibrate_all(&st->sd, ad7192_calib_arr, + ARRAY_SIZE(ad7192_calib_arr)); } static int ad7192_setup(struct ad7192_state *st, const struct ad7192_platform_data *pdata) { - struct iio_dev *indio_dev = spi_get_drvdata(st->spi); + struct iio_dev *indio_dev = spi_get_drvdata(st->sd.spi); unsigned long long scale_uv; int i, ret, id; u8 ones[6]; /* reset the serial interface */ memset(&ones, 0xFF, 6); - ret = spi_write(st->spi, &ones, 6); + ret = spi_write(st->sd.spi, &ones, 6); if (ret < 0) goto out; msleep(1); /* Wait for at least 500us */ /* write/read test for device presence */ - ret = ad7192_read_reg(st, AD7192_REG_ID, &id, 1); + ret = ad_sd_read_reg(&st->sd, AD7192_REG_ID, 1, &id); if (ret) goto out; id &= AD7192_ID_MASK; if (id != st->devid) - dev_warn(&st->spi->dev, "device ID query failed (0x%X)\n", id); + dev_warn(&st->sd.spi->dev, "device ID query failed (0x%X)\n", id); switch (pdata->clock_source_sel) { case AD7192_CLK_EXT_MCLK1_2: @@ -422,11 +276,11 @@ static int ad7192_setup(struct ad7192_state *st, if (pdata->burnout_curr_en) st->conf |= AD7192_CONF_BURN; - ret = ad7192_write_reg(st, AD7192_REG_MODE, 3, st->mode); + ret = ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, st->mode); if (ret) goto out; - ret = ad7192_write_reg(st, AD7192_REG_CONF, 3, st->conf); + ret = ad_sd_write_reg(&st->sd, AD7192_REG_CONF, 3, st->conf); if (ret) goto out; @@ -447,181 +301,10 @@ static int ad7192_setup(struct ad7192_state *st, return 0; out: - dev_err(&st->spi->dev, "setup failed\n"); + dev_err(&st->sd.spi->dev, "setup failed\n"); return ret; } -static int ad7192_ring_preenable(struct iio_dev *indio_dev) -{ - struct ad7192_state *st = iio_priv(indio_dev); - unsigned channel; - int ret; - - if (bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength)) - return -EINVAL; - - ret = iio_sw_buffer_preenable(indio_dev); - if (ret < 0) - return ret; - - channel = find_first_bit(indio_dev->active_scan_mask, - indio_dev->masklength); - - st->mode = (st->mode & ~AD7192_MODE_SEL(-1)) | - AD7192_MODE_SEL(AD7192_MODE_CONT); - st->conf = (st->conf & ~AD7192_CONF_CHAN(-1)) | - AD7192_CONF_CHAN(1 << indio_dev->channels[channel].address); - - ad7192_write_reg(st, AD7192_REG_CONF, 3, st->conf); - - spi_bus_lock(st->spi->master); - __ad7192_write_reg(st, 1, 1, AD7192_REG_MODE, 3, st->mode); - - st->irq_dis = false; - enable_irq(st->spi->irq); - - return 0; -} - -static int ad7192_ring_postdisable(struct iio_dev *indio_dev) -{ - struct ad7192_state *st = iio_priv(indio_dev); - - st->mode = (st->mode & ~AD7192_MODE_SEL(-1)) | - AD7192_MODE_SEL(AD7192_MODE_IDLE); - - st->done = false; - wait_event_interruptible(st->wq_data_avail, st->done); - - if (!st->irq_dis) - disable_irq_nosync(st->spi->irq); - - __ad7192_write_reg(st, 1, 0, AD7192_REG_MODE, 3, st->mode); - - return spi_bus_unlock(st->spi->master); -} - -/** - * ad7192_trigger_handler() bh of trigger launched polling to ring buffer - **/ -static irqreturn_t ad7192_trigger_handler(int irq, void *p) -{ - struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->indio_dev; - struct iio_buffer *ring = indio_dev->buffer; - struct ad7192_state *st = iio_priv(indio_dev); - s64 dat64[2]; - s32 *dat32 = (s32 *)dat64; - - if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength)) - __ad7192_read_reg(st, 1, 1, AD7192_REG_DATA, - dat32, - indio_dev->channels[0].scan_type.realbits/8); - - /* Guaranteed to be aligned with 8 byte boundary */ - if (indio_dev->scan_timestamp) - dat64[1] = pf->timestamp; - - ring->access->store_to(ring, (u8 *)dat64, pf->timestamp); - - iio_trigger_notify_done(indio_dev->trig); - st->irq_dis = false; - enable_irq(st->spi->irq); - - return IRQ_HANDLED; -} - -static const struct iio_buffer_setup_ops ad7192_ring_setup_ops = { - .preenable = &ad7192_ring_preenable, - .postenable = &iio_triggered_buffer_postenable, - .predisable = &iio_triggered_buffer_predisable, - .postdisable = &ad7192_ring_postdisable, - .validate_scan_mask = &iio_validate_scan_mask_onehot, -}; - -static int ad7192_register_ring_funcs_and_init(struct iio_dev *indio_dev) -{ - return iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, - &ad7192_trigger_handler, &ad7192_ring_setup_ops); -} - -static void ad7192_ring_cleanup(struct iio_dev *indio_dev) -{ - iio_triggered_buffer_cleanup(indio_dev); -} - -/** - * ad7192_data_rdy_trig_poll() the event handler for the data rdy trig - **/ -static irqreturn_t ad7192_data_rdy_trig_poll(int irq, void *private) -{ - struct ad7192_state *st = iio_priv(private); - - st->done = true; - wake_up_interruptible(&st->wq_data_avail); - disable_irq_nosync(irq); - st->irq_dis = true; - iio_trigger_poll(st->trig, iio_get_time_ns()); - - return IRQ_HANDLED; -} - -static struct iio_trigger_ops ad7192_trigger_ops = { - .owner = THIS_MODULE, -}; - -static int ad7192_probe_trigger(struct iio_dev *indio_dev) -{ - struct ad7192_state *st = iio_priv(indio_dev); - int ret; - - st->trig = iio_trigger_alloc("%s-dev%d", - spi_get_device_id(st->spi)->name, - indio_dev->id); - if (st->trig == NULL) { - ret = -ENOMEM; - goto error_ret; - } - st->trig->ops = &ad7192_trigger_ops; - ret = request_irq(st->spi->irq, - ad7192_data_rdy_trig_poll, - IRQF_TRIGGER_LOW, - spi_get_device_id(st->spi)->name, - indio_dev); - if (ret) - goto error_free_trig; - - disable_irq_nosync(st->spi->irq); - st->irq_dis = true; - st->trig->dev.parent = &st->spi->dev; - st->trig->private_data = indio_dev; - - ret = iio_trigger_register(st->trig); - - /* select default trigger */ - indio_dev->trig = st->trig; - if (ret) - goto error_free_irq; - - return 0; - -error_free_irq: - free_irq(st->spi->irq, indio_dev); -error_free_trig: - iio_trigger_free(st->trig); -error_ret: - return ret; -} - -static void ad7192_remove_trigger(struct iio_dev *indio_dev) -{ - struct ad7192_state *st = iio_priv(indio_dev); - - iio_trigger_unregister(st->trig); - free_irq(st->spi->irq, indio_dev); - iio_trigger_free(st->trig); -} - static ssize_t ad7192_read_frequency(struct device *dev, struct device_attribute *attr, char *buf) @@ -661,7 +344,7 @@ static ssize_t ad7192_write_frequency(struct device *dev, st->mode &= ~AD7192_MODE_RATE(-1); st->mode |= AD7192_MODE_RATE(div); - ad7192_write_reg(st, AD7192_REG_MODE, 3, st->mode); + ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, st->mode); out: mutex_unlock(&indio_dev->mlock); @@ -673,7 +356,6 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, ad7192_read_frequency, ad7192_write_frequency); - static ssize_t ad7192_show_scale_available(struct device *dev, struct device_attribute *attr, char *buf) { @@ -745,7 +427,7 @@ static ssize_t ad7192_set(struct device *dev, else st->gpocon &= ~AD7192_GPOCON_BPDSW; - ad7192_write_reg(st, AD7192_REG_GPOCON, 1, st->gpocon); + ad_sd_write_reg(&st->sd, AD7192_REG_GPOCON, 1, st->gpocon); break; case AD7192_REG_MODE: if (val) @@ -753,7 +435,7 @@ static ssize_t ad7192_set(struct device *dev, else st->mode &= ~AD7192_MODE_ACX; - ad7192_write_reg(st, AD7192_REG_MODE, 3, st->mode); + ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, st->mode); break; default: ret = -EINVAL; @@ -809,27 +491,11 @@ static int ad7192_read_raw(struct iio_dev *indio_dev, long m) { struct ad7192_state *st = iio_priv(indio_dev); - int ret, smpl = 0; bool unipolar = !!(st->conf & AD7192_CONF_UNIPOLAR); switch (m) { case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); - if (iio_buffer_enabled(indio_dev)) - ret = -EBUSY; - else - ret = ad7192_read(st, chan->address, - chan->scan_type.realbits / 8, &smpl); - mutex_unlock(&indio_dev->mlock); - - if (ret < 0) - return ret; - - *val = (smpl >> chan->scan_type.shift) & - ((1 << (chan->scan_type.realbits)) - 1); - - return IIO_VAL_INT; - + return ad_sigma_delta_single_conversion(indio_dev, chan, val); case IIO_CHAN_INFO_SCALE: switch (chan->type) { case IIO_VOLTAGE: @@ -880,16 +546,16 @@ static int ad7192_write_raw(struct iio_dev *indio_dev, ret = -EINVAL; for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++) if (val2 == st->scale_avail[i][1]) { + ret = 0; tmp = st->conf; st->conf &= ~AD7192_CONF_GAIN(-1); st->conf |= AD7192_CONF_GAIN(i); - - if (tmp != st->conf) { - ad7192_write_reg(st, AD7192_REG_CONF, - 3, st->conf); - ad7192_calibrate_all(st); - } - ret = 0; + if (tmp == st->conf) + break; + ad_sd_write_reg(&st->sd, AD7192_REG_CONF, + 3, st->conf); + ad7192_calibrate_all(st); + break; } break; default: @@ -901,15 +567,6 @@ static int ad7192_write_raw(struct iio_dev *indio_dev, return ret; } -static int ad7192_validate_trigger(struct iio_dev *indio_dev, - struct iio_trigger *trig) -{ - if (indio_dev->trig != trig) - return -EINVAL; - - return 0; -} - static int ad7192_write_raw_get_fmt(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, long mask) @@ -922,7 +579,7 @@ static const struct iio_info ad7192_info = { .write_raw = &ad7192_write_raw, .write_raw_get_fmt = &ad7192_write_raw_get_fmt, .attrs = &ad7192_attribute_group, - .validate_trigger = ad7192_validate_trigger, + .validate_trigger = ad_sd_validate_trigger, .driver_module = THIS_MODULE, }; @@ -931,54 +588,19 @@ static const struct iio_info ad7195_info = { .write_raw = &ad7192_write_raw, .write_raw_get_fmt = &ad7192_write_raw_get_fmt, .attrs = &ad7195_attribute_group, - .validate_trigger = ad7192_validate_trigger, + .validate_trigger = ad_sd_validate_trigger, .driver_module = THIS_MODULE, }; -#define AD7192_CHAN_DIFF(_chan, _chan2, _name, _address, _si) \ - { .type = IIO_VOLTAGE, \ - .differential = 1, \ - .indexed = 1, \ - .extend_name = _name, \ - .channel = _chan, \ - .channel2 = _chan2, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT | \ - IIO_CHAN_INFO_OFFSET_SHARED_BIT, \ - .address = _address, \ - .scan_index = _si, \ - .scan_type = IIO_ST('u', 24, 32, 0)} - -#define AD7192_CHAN(_chan, _address, _si) \ - { .type = IIO_VOLTAGE, \ - .indexed = 1, \ - .channel = _chan, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT | \ - IIO_CHAN_INFO_OFFSET_SHARED_BIT, \ - .address = _address, \ - .scan_index = _si, \ - .scan_type = IIO_ST('u', 24, 32, 0)} - -#define AD7192_CHAN_TEMP(_chan, _address, _si) \ - { .type = IIO_TEMP, \ - .indexed = 1, \ - .channel = _chan, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ - .address = _address, \ - .scan_index = _si, \ - .scan_type = IIO_ST('u', 24, 32, 0)} - static const struct iio_chan_spec ad7192_channels[] = { - AD7192_CHAN_DIFF(1, 2, NULL, AD7192_CH_AIN1P_AIN2M, 0), - AD7192_CHAN_DIFF(3, 4, NULL, AD7192_CH_AIN3P_AIN4M, 1), - AD7192_CHAN_TEMP(0, AD7192_CH_TEMP, 2), - AD7192_CHAN_DIFF(2, 2, "shorted", AD7192_CH_AIN2P_AIN2M, 3), - AD7192_CHAN(1, AD7192_CH_AIN1, 4), - AD7192_CHAN(2, AD7192_CH_AIN2, 5), - AD7192_CHAN(3, AD7192_CH_AIN3, 6), - AD7192_CHAN(4, AD7192_CH_AIN4, 7), + AD_SD_DIFF_CHANNEL(0, 1, 2, AD7192_CH_AIN1P_AIN2M, 24, 32, 0), + AD_SD_DIFF_CHANNEL(1, 3, 4, AD7192_CH_AIN3P_AIN4M, 24, 32, 0), + AD_SD_TEMP_CHANNEL(2, AD7192_CH_TEMP, 24, 32, 0), + AD_SD_SHORTED_CHANNEL(3, 2, AD7192_CH_AIN2P_AIN2M, 24, 32, 0), + AD_SD_CHANNEL(4, 1, AD7192_CH_AIN1, 24, 32, 0), + AD_SD_CHANNEL(5, 2, AD7192_CH_AIN2, 24, 32, 0), + AD_SD_CHANNEL(6, 3, AD7192_CH_AIN3, 24, 32, 0), + AD_SD_CHANNEL(7, 4, AD7192_CH_AIN4, 24, 32, 0), IIO_CHAN_SOFT_TIMESTAMP(8), }; @@ -1022,7 +644,6 @@ static int __devinit ad7192_probe(struct spi_device *spi) dev_warn(&spi->dev, "reference voltage undefined\n"); spi_set_drvdata(spi, indio_dev); - st->spi = spi; st->devid = spi_get_device_id(spi)->driver_data; indio_dev->dev.parent = &spi->dev; indio_dev->name = spi_get_device_id(spi)->name; @@ -1034,16 +655,12 @@ static int __devinit ad7192_probe(struct spi_device *spi) else indio_dev->info = &ad7192_info; - init_waitqueue_head(&st->wq_data_avail); + ad_sd_init(&st->sd, indio_dev, spi, &ad7192_sigma_delta_info); - ret = ad7192_register_ring_funcs_and_init(indio_dev); + ret = ad_sd_setup_buffer_and_trigger(indio_dev); if (ret) goto error_disable_reg; - ret = ad7192_probe_trigger(indio_dev); - if (ret) - goto error_ring_cleanup; - ret = ad7192_setup(st, pdata); if (ret) goto error_remove_trigger; @@ -1054,9 +671,7 @@ static int __devinit ad7192_probe(struct spi_device *spi) return 0; error_remove_trigger: - ad7192_remove_trigger(indio_dev); -error_ring_cleanup: - ad7192_ring_cleanup(indio_dev); + ad_sd_cleanup_buffer_and_trigger(indio_dev); error_disable_reg: if (!IS_ERR(st->reg)) regulator_disable(st->reg); @@ -1075,8 +690,7 @@ static int ad7192_remove(struct spi_device *spi) struct ad7192_state *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); - ad7192_remove_trigger(indio_dev); - ad7192_ring_cleanup(indio_dev); + ad_sd_cleanup_buffer_and_trigger(indio_dev); if (!IS_ERR(st->reg)) { regulator_disable(st->reg); -- cgit v0.10.2 From 525e643e4812cd0ced0f40908fafaf0c4317ac73 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 10 Aug 2012 17:36:00 +0100 Subject: staging:iio:ad7793: Add support for ad7794/ad7795 The ad7794/ad7795 are similar to the ad7792/ad7793, but have 6 channels instead of 3. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index 3f1f2c3..0eab0c6 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -109,12 +109,12 @@ config AD7780 module will be called ad7780. config AD7793 - tristate "Analog Devices AD7792 AD7793 ADC driver" + tristate "Analog Devices AD7793 and similar ADCs driver" depends on SPI select AD_SIGMA_DELTA help - Say yes here to build support for Analog Devices - AD7792 and AD7793 SPI analog to digital converters (ADC). + Say yes here to build support for Analog Devices AD7792, AD7793, AD7794 + and AD7795 SPI analog to digital converters (ADC). If unsure, say N (but it's safe to say "Y"). To compile this driver as a module, choose M here: the diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c index 9033595..f11dcaf 100644 --- a/drivers/staging/iio/adc/ad7793.c +++ b/drivers/staging/iio/adc/ad7793.c @@ -1,5 +1,5 @@ /* - * AD7792/AD7793 SPI ADC driver + * AD7792/AD7793/AD7794/AD7795 SPI ADC driver * * Copyright 2011-2012 Analog Devices Inc. * @@ -37,7 +37,8 @@ */ struct ad7793_chip_info { - struct iio_chan_spec channel[7]; + const struct iio_chan_spec *channels; + unsigned int num_channels; }; struct ad7793_state { @@ -55,6 +56,8 @@ struct ad7793_state { enum ad7793_supported_device_ids { ID_AD7792, ID_AD7793, + ID_AD7794, + ID_AD7795, }; static struct ad7793_state *ad_sigma_delta_to_ad7793(struct ad_sigma_delta *sd) @@ -127,7 +130,7 @@ static int ad7793_setup(struct iio_dev *indio_dev, id &= AD7793_ID_MASK; - if (!((id == AD7792_ID) || (id == AD7793_ID))) { + if (!((id == AD7792_ID) || (id == AD7793_ID) || (id == AD7795_ID))) { dev_err(&st->sd.spi->dev, "device ID query failed\n"); goto out; } @@ -155,7 +158,7 @@ static int ad7793_setup(struct iio_dev *indio_dev, /* Populate available ADC input ranges */ for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++) { scale_uv = ((u64)st->int_vref_mv * 100000000) - >> (st->chip_info->channel[0].scan_type.realbits - + >> (st->chip_info->channels[0].scan_type.realbits - (!!(st->conf & AD7793_CONF_UNIPOLAR) ? 0 : 1)); scale_uv >>= i; @@ -383,28 +386,52 @@ static const struct iio_info ad7793_info = { .driver_module = THIS_MODULE, }; +#define DECLARE_AD7793_CHANNELS(_name, _b, _sb) \ +const struct iio_chan_spec _name##_channels[] = { \ + AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \ + AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0), \ + AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0), \ + AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), 0), \ + AD_SD_TEMP_CHANNEL(4, AD7793_CH_TEMP, (_b), (_sb), 0), \ + AD_SD_SUPPLY_CHANNEL(5, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \ + IIO_CHAN_SOFT_TIMESTAMP(6), \ +} + +#define DECLARE_AD7795_CHANNELS(_name, _b, _sb) \ +const struct iio_chan_spec _name##_channels[] = { \ + AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \ + AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0), \ + AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0), \ + AD_SD_DIFF_CHANNEL(3, 3, 3, AD7795_CH_AIN4P_AIN4M, (_b), (_sb), 0), \ + AD_SD_DIFF_CHANNEL(4, 4, 4, AD7795_CH_AIN5P_AIN5M, (_b), (_sb), 0), \ + AD_SD_DIFF_CHANNEL(5, 5, 5, AD7795_CH_AIN6P_AIN6M, (_b), (_sb), 0), \ + AD_SD_SHORTED_CHANNEL(6, 0, AD7795_CH_AIN1M_AIN1M, (_b), (_sb), 0), \ + AD_SD_TEMP_CHANNEL(7, AD7793_CH_TEMP, (_b), (_sb), 0), \ + AD_SD_SUPPLY_CHANNEL(8, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \ + IIO_CHAN_SOFT_TIMESTAMP(9), \ +} + +static DECLARE_AD7793_CHANNELS(ad7792, 16, 32); +static DECLARE_AD7793_CHANNELS(ad7793, 24, 32); +static DECLARE_AD7795_CHANNELS(ad7794, 16, 32); +static DECLARE_AD7795_CHANNELS(ad7795, 24, 32); + static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { + [ID_AD7792] = { + .channels = ad7792_channels, + .num_channels = ARRAY_SIZE(ad7792_channels), + }, [ID_AD7793] = { - .channel = { - AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, 24, 32, 0), - AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, 24, 32, 0), - AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, 24, 32, 0), - AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, 24, 32, 0), - AD_SD_TEMP_CHANNEL(4, AD7793_CH_TEMP, 24, 32, 0), - AD_SD_SUPPLY_CHANNEL(5, 3, AD7793_CH_AVDD_MONITOR, 24, 32, 0), - IIO_CHAN_SOFT_TIMESTAMP(6), - }, + .channels = ad7793_channels, + .num_channels = ARRAY_SIZE(ad7793_channels), }, - [ID_AD7792] = { - .channel = { - AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, 16, 32, 0), - AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, 16, 32, 0), - AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, 16, 32, 0), - AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, 16, 32, 0), - AD_SD_TEMP_CHANNEL(4, AD7793_CH_TEMP, 16, 32, 0), - AD_SD_SUPPLY_CHANNEL(5, 3, AD7793_CH_AVDD_MONITOR, 16, 32, 0), - IIO_CHAN_SOFT_TIMESTAMP(6), - }, + [ID_AD7794] = { + .channels = ad7794_channels, + .num_channels = ARRAY_SIZE(ad7794_channels), + }, + [ID_AD7795] = { + .channels = ad7795_channels, + .num_channels = ARRAY_SIZE(ad7795_channels), }, }; @@ -457,8 +484,8 @@ static int __devinit ad7793_probe(struct spi_device *spi) indio_dev->dev.parent = &spi->dev; indio_dev->name = spi_get_device_id(spi)->name; indio_dev->modes = INDIO_DIRECT_MODE; - indio_dev->channels = st->chip_info->channel; - indio_dev->num_channels = 7; + indio_dev->channels = st->chip_info->channels; + indio_dev->num_channels = st->chip_info->num_channels; indio_dev->info = &ad7793_info; ret = ad_sd_setup_buffer_and_trigger(indio_dev); @@ -510,6 +537,8 @@ static int ad7793_remove(struct spi_device *spi) static const struct spi_device_id ad7793_id[] = { {"ad7792", ID_AD7792}, {"ad7793", ID_AD7793}, + {"ad7794", ID_AD7794}, + {"ad7795", ID_AD7795}, {} }; MODULE_DEVICE_TABLE(spi, ad7793_id); @@ -526,5 +555,5 @@ static struct spi_driver ad7793_driver = { module_spi_driver(ad7793_driver); MODULE_AUTHOR("Michael Hennerich "); -MODULE_DESCRIPTION("Analog Devices AD7792/3 ADC"); +MODULE_DESCRIPTION("Analog Devices AD7793 and simialr ADCs"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/adc/ad7793.h b/drivers/staging/iio/adc/ad7793.h index 0e296d8..8fdd450a 100644 --- a/drivers/staging/iio/adc/ad7793.h +++ b/drivers/staging/iio/adc/ad7793.h @@ -70,8 +70,8 @@ #define AD7793_CONF_GAIN(x) (((x) & 0x7) << 8) /* Gain Select */ #define AD7793_CONF_REFSEL (1 << 7) /* INT/EXT Reference Select */ #define AD7793_CONF_BUF (1 << 4) /* Buffered Mode Enable */ -#define AD7793_CONF_CHAN(x) ((x) & 0x7) /* Channel select */ -#define AD7793_CONF_CHAN_MASK 0x7 /* Channel select mask */ +#define AD7793_CONF_CHAN(x) ((x) & 0xf) /* Channel select */ +#define AD7793_CONF_CHAN_MASK 0xf /* Channel select mask */ #define AD7793_CH_AIN1P_AIN1M 0 /* AIN1(+) - AIN1(-) */ #define AD7793_CH_AIN2P_AIN2M 1 /* AIN2(+) - AIN2(-) */ @@ -80,9 +80,15 @@ #define AD7793_CH_TEMP 6 /* Temp Sensor */ #define AD7793_CH_AVDD_MONITOR 7 /* AVDD Monitor */ +#define AD7795_CH_AIN4P_AIN4M 4 /* AIN4(+) - AIN4(-) */ +#define AD7795_CH_AIN5P_AIN5M 5 /* AIN5(+) - AIN5(-) */ +#define AD7795_CH_AIN6P_AIN6M 6 /* AIN6(+) - AIN6(-) */ +#define AD7795_CH_AIN1M_AIN1M 8 /* AIN1(-) - AIN1(-) */ + /* ID Register Bit Designations (AD7793_REG_ID) */ #define AD7792_ID 0xA #define AD7793_ID 0xB +#define AD7795_ID 0xF #define AD7793_ID_MASK 0xF /* IO (Excitation Current Sources) Register Bit Designations (AD7793_REG_IO) */ -- cgit v0.10.2 From 8c29ecd3620cce207f383fd3ab9b345061a9a8dc Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 10 Aug 2012 17:36:00 +0100 Subject: staging:iio:ad7793: Add ad7785 support The ad7785 is similar to the ad7792/ad7793, but has 20 bit wide data samples. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index 0eab0c6..a1fa172 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -113,8 +113,8 @@ config AD7793 depends on SPI select AD_SIGMA_DELTA help - Say yes here to build support for Analog Devices AD7792, AD7793, AD7794 - and AD7795 SPI analog to digital converters (ADC). + Say yes here to build support for Analog Devices AD7785, AD7792, AD7793, + AD7794 and AD7795 SPI analog to digital converters (ADC). If unsure, say N (but it's safe to say "Y"). To compile this driver as a module, choose M here: the diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c index f11dcaf..ddc7fd7 100644 --- a/drivers/staging/iio/adc/ad7793.c +++ b/drivers/staging/iio/adc/ad7793.c @@ -1,5 +1,5 @@ /* - * AD7792/AD7793/AD7794/AD7795 SPI ADC driver + * AD7785/AD7792/AD7793/AD7794/AD7795 SPI ADC driver * * Copyright 2011-2012 Analog Devices Inc. * @@ -54,6 +54,7 @@ struct ad7793_state { }; enum ad7793_supported_device_ids { + ID_AD7785, ID_AD7792, ID_AD7793, ID_AD7794, @@ -386,14 +387,14 @@ static const struct iio_info ad7793_info = { .driver_module = THIS_MODULE, }; -#define DECLARE_AD7793_CHANNELS(_name, _b, _sb) \ +#define DECLARE_AD7793_CHANNELS(_name, _b, _sb, _s) \ const struct iio_chan_spec _name##_channels[] = { \ - AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \ - AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0), \ - AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0), \ - AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), 0), \ - AD_SD_TEMP_CHANNEL(4, AD7793_CH_TEMP, (_b), (_sb), 0), \ - AD_SD_SUPPLY_CHANNEL(5, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \ + AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), (_s)), \ + AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), (_s)), \ + AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), (_s)), \ + AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), (_s)), \ + AD_SD_TEMP_CHANNEL(4, AD7793_CH_TEMP, (_b), (_sb), (_s)), \ + AD_SD_SUPPLY_CHANNEL(5, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), (_s)), \ IIO_CHAN_SOFT_TIMESTAMP(6), \ } @@ -411,12 +412,17 @@ const struct iio_chan_spec _name##_channels[] = { \ IIO_CHAN_SOFT_TIMESTAMP(9), \ } -static DECLARE_AD7793_CHANNELS(ad7792, 16, 32); -static DECLARE_AD7793_CHANNELS(ad7793, 24, 32); +static DECLARE_AD7793_CHANNELS(ad7785, 20, 32, 4); +static DECLARE_AD7793_CHANNELS(ad7792, 16, 32, 0); +static DECLARE_AD7793_CHANNELS(ad7793, 24, 32, 0); static DECLARE_AD7795_CHANNELS(ad7794, 16, 32); static DECLARE_AD7795_CHANNELS(ad7795, 24, 32); static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { + [ID_AD7785] = { + .channels = ad7785_channels, + .num_channels = ARRAY_SIZE(ad7785_channels), + }, [ID_AD7792] = { .channels = ad7792_channels, .num_channels = ARRAY_SIZE(ad7792_channels), @@ -535,6 +541,7 @@ static int ad7793_remove(struct spi_device *spi) } static const struct spi_device_id ad7793_id[] = { + {"ad7785", ID_AD7785}, {"ad7792", ID_AD7792}, {"ad7793", ID_AD7793}, {"ad7794", ID_AD7794}, -- cgit v0.10.2 From d965a8bc0cf56e0b2448b9aed6afe9066bc2616d Mon Sep 17 00:00:00 2001 From: "Kim, Milo" Date: Thu, 16 Aug 2012 08:39:00 +0100 Subject: iio: use IIO_CHAN_INFO_RAW rather than 0 (a) For better readability, replace 0 with IIO_CHAN_INFO_RAW. (b) Make same line-format as other apis() : iio_read_channel_scale() and iio_read_channel_offset() Signed-off-by: Milo(Woogyom) Kim Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index b5afc2f..a14e55d 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -239,8 +239,10 @@ int iio_read_channel_raw(struct iio_channel *chan, int *val) goto err_unlock; } - ret = chan->indio_dev->info->read_raw(chan->indio_dev, chan->channel, - val, &val2, 0); + ret = chan->indio_dev->info->read_raw(chan->indio_dev, + chan->channel, + val, &val2, + IIO_CHAN_INFO_RAW); err_unlock: mutex_unlock(&chan->indio_dev->info_exist_lock); -- cgit v0.10.2 From 88238fef16845c18abecb9285c97b0225f71d544 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 17 Aug 2012 16:57:00 +0100 Subject: iio:consumer.h: Fix include guard The symbol name for the #ifndef and the #define of the include guard do not match and thus it becomes quite ineffective. Add the missing '_' to fix this. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h index e2657e6..06ab4ec 100644 --- a/include/linux/iio/consumer.h +++ b/include/linux/iio/consumer.h @@ -8,7 +8,7 @@ * the Free Software Foundation. */ #ifndef _IIO_INKERN_CONSUMER_H_ -#define _IIO_INKERN_CONSUMER_H +#define _IIO_INKERN_CONSUMER_H_ #include struct iio_dev; -- cgit v0.10.2 From 08d6005c031631429ed307a28503e00e3970c203 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 17 Aug 2012 16:57:00 +0100 Subject: iio: Add missing include guards to headers Add include guards to the IIO headers where they are missing. This avoids compile errors due to redefined types if a file is included more than once. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/include/linux/iio/kfifo_buf.h b/include/linux/iio/kfifo_buf.h index 014d5a1..25eeac7 100644 --- a/include/linux/iio/kfifo_buf.h +++ b/include/linux/iio/kfifo_buf.h @@ -1,3 +1,5 @@ +#ifndef __LINUX_IIO_KFIFO_BUF_H__ +#define __LINUX_IIO_KFIFO_BUF_H__ #include #include @@ -6,3 +8,4 @@ struct iio_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev); void iio_kfifo_free(struct iio_buffer *r); +#endif diff --git a/include/linux/iio/machine.h b/include/linux/iio/machine.h index 400a453..809a3f0 100644 --- a/include/linux/iio/machine.h +++ b/include/linux/iio/machine.h @@ -8,6 +8,9 @@ * the Free Software Foundation. */ +#ifndef __LINUX_IIO_MACHINE_H__ +#define __LINUX_IIO_MACHINE_H__ + /** * struct iio_map - description of link between consumer and device channels * @adc_channel_label: Label used to identify the channel on the provider. @@ -22,3 +25,5 @@ struct iio_map { const char *consumer_dev_name; const char *consumer_channel; }; + +#endif diff --git a/include/linux/iio/trigger_consumer.h b/include/linux/iio/trigger_consumer.h index 60d64b3..762a3d3 100644 --- a/include/linux/iio/trigger_consumer.h +++ b/include/linux/iio/trigger_consumer.h @@ -7,6 +7,9 @@ * the Free Software Foundation. */ +#ifndef __LINUX_IIO_TRIGGER_CONSUMER_H__ +#define __LINUX_IIO_TRIGGER_CONSUMER_H__ + /** * struct iio_poll_func - poll function pair * @@ -50,3 +53,5 @@ void iio_trigger_notify_done(struct iio_trigger *trig); */ int iio_triggered_buffer_postenable(struct iio_dev *indio_dev); int iio_triggered_buffer_predisable(struct iio_dev *indio_dev); + +#endif -- cgit v0.10.2 From 161e7f6d136549d6432218f9f42f88dd443a4719 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 17 Aug 2012 16:57:00 +0100 Subject: iio:trigger_consumer.h: Add missing includes and forward declarations Add includes and forward declarations for types used in this file. This avoids compile errors if the other files have not been included before. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/include/linux/iio/trigger_consumer.h b/include/linux/iio/trigger_consumer.h index 762a3d3..c4f8c74 100644 --- a/include/linux/iio/trigger_consumer.h +++ b/include/linux/iio/trigger_consumer.h @@ -10,6 +10,12 @@ #ifndef __LINUX_IIO_TRIGGER_CONSUMER_H__ #define __LINUX_IIO_TRIGGER_CONSUMER_H__ +#include +#include + +struct iio_dev; +struct iio_trigger; + /** * struct iio_poll_func - poll function pair * -- cgit v0.10.2 From 8e8287526844441008df286536a21722277bb487 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 17 Aug 2012 18:29:00 +0100 Subject: staging:iio: Add missing __devinit and __devexit annotations Autogenerated using the following coccinelle semantic patch: // @r1@ identifier driver; identifier fn; position p; type T; @@ T driver = { .remove = ( fn@p | __devexit_p(fn@p) ) }; @r2@ identifier r1.fn; position p != r1.p; @@ fn@p @r3@ identifier r1.fn; position r1.p; @@ ( __devexit_p(fn@p) | -fn@p +__devexit_p(fn) ) @depends on !r2@ identifier r1.fn; @@ static -int fn +int __devexit fn (...) { ... } @r11@ identifier driver; identifier fn; position p; type T; @@ T driver = { .probe = fn@p }; @r12@ identifier r11.fn; position p != r11.p; @@ fn@p @depends on !r12@ identifier r11.fn; @@ static -int fn +int __devinit fn (...) { ... } // Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/accel/adis16201_core.c b/drivers/staging/iio/accel/adis16201_core.c index ec2332f..8e37d6e 100644 --- a/drivers/staging/iio/accel/adis16201_core.c +++ b/drivers/staging/iio/accel/adis16201_core.c @@ -565,7 +565,7 @@ error_ret: return ret; } -static int adis16201_remove(struct spi_device *spi) +static int __devexit adis16201_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); diff --git a/drivers/staging/iio/accel/adis16203_core.c b/drivers/staging/iio/accel/adis16203_core.c index 34b76c5..002fa9d 100644 --- a/drivers/staging/iio/accel/adis16203_core.c +++ b/drivers/staging/iio/accel/adis16203_core.c @@ -500,7 +500,7 @@ error_ret: return ret; } -static int adis16203_remove(struct spi_device *spi) +static int __devexit adis16203_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c index 02fb101..05bdb7c 100644 --- a/drivers/staging/iio/accel/adis16204_core.c +++ b/drivers/staging/iio/accel/adis16204_core.c @@ -558,7 +558,7 @@ error_ret: return ret; } -static int adis16204_remove(struct spi_device *spi) +static int __devexit adis16204_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c index 4fa2229..b7333bf 100644 --- a/drivers/staging/iio/accel/adis16209_core.c +++ b/drivers/staging/iio/accel/adis16209_core.c @@ -573,7 +573,7 @@ error_ret: return ret; } -static int adis16209_remove(struct spi_device *spi) +static int __devexit adis16209_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c index c31e1ec..c755089 100644 --- a/drivers/staging/iio/accel/adis16220_core.c +++ b/drivers/staging/iio/accel/adis16220_core.c @@ -663,7 +663,7 @@ error_ret: return ret; } -static int adis16220_remove(struct spi_device *spi) +static int __devexit adis16220_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c index dafc0d8..0fc26a49 100644 --- a/drivers/staging/iio/accel/adis16240_core.c +++ b/drivers/staging/iio/accel/adis16240_core.c @@ -619,7 +619,7 @@ error_ret: return ret; } -static int adis16240_remove(struct spi_device *spi) +static int __devexit adis16240_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c index 0c2b4ba..54ce17f 100644 --- a/drivers/staging/iio/accel/lis3l02dq_core.c +++ b/drivers/staging/iio/accel/lis3l02dq_core.c @@ -780,7 +780,7 @@ err_ret: } /* fixme, confirm ordering in this function */ -static int lis3l02dq_remove(struct spi_device *spi) +static int __devexit lis3l02dq_remove(struct spi_device *spi) { int ret; struct iio_dev *indio_dev = spi_get_drvdata(spi); diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c index cc040e1..581cdbd 100644 --- a/drivers/staging/iio/accel/sca3000_core.c +++ b/drivers/staging/iio/accel/sca3000_core.c @@ -1233,7 +1233,7 @@ error_ret: return ret; } -static int sca3000_remove(struct spi_device *spi) +static int __devexit sca3000_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); struct sca3000_state *st = iio_priv(indio_dev); diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index 189d951..c351cae 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c @@ -684,7 +684,7 @@ error_put_reg: return ret; } -static int ad7192_remove(struct spi_device *spi) +static int __devexit ad7192_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); struct ad7192_state *st = iio_priv(indio_dev); diff --git a/drivers/staging/iio/adc/ad7476_core.c b/drivers/staging/iio/adc/ad7476_core.c index 4d30a79..4f6d59e 100644 --- a/drivers/staging/iio/adc/ad7476_core.c +++ b/drivers/staging/iio/adc/ad7476_core.c @@ -196,7 +196,7 @@ error_ret: return ret; } -static int ad7476_remove(struct spi_device *spi) +static int __devexit ad7476_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); struct ad7476_state *st = iio_priv(indio_dev); diff --git a/drivers/staging/iio/adc/ad7780.c b/drivers/staging/iio/adc/ad7780.c index 853f8b1..5f807ce 100644 --- a/drivers/staging/iio/adc/ad7780.c +++ b/drivers/staging/iio/adc/ad7780.c @@ -225,7 +225,7 @@ error_put_reg: return ret; } -static int ad7780_remove(struct spi_device *spi) +static int __devexit ad7780_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); struct ad7780_state *st = iio_priv(indio_dev); diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c index ddc7fd7..691a7be 100644 --- a/drivers/staging/iio/adc/ad7793.c +++ b/drivers/staging/iio/adc/ad7793.c @@ -522,7 +522,7 @@ error_put_reg: return ret; } -static int ad7793_remove(struct spi_device *spi) +static int __devexit ad7793_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); struct ad7793_state *st = iio_priv(indio_dev); diff --git a/drivers/staging/iio/adc/ad7887_core.c b/drivers/staging/iio/adc/ad7887_core.c index 397b849..5517905 100644 --- a/drivers/staging/iio/adc/ad7887_core.c +++ b/drivers/staging/iio/adc/ad7887_core.c @@ -219,7 +219,7 @@ error_put_reg: return ret; } -static int ad7887_remove(struct spi_device *spi) +static int __devexit ad7887_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); struct ad7887_state *st = iio_priv(indio_dev); diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c index 816bb2c..adb90fe 100644 --- a/drivers/staging/iio/adc/max1363_core.c +++ b/drivers/staging/iio/adc/max1363_core.c @@ -1367,7 +1367,7 @@ error_out: return ret; } -static int max1363_remove(struct i2c_client *client) +static int __devexit max1363_remove(struct i2c_client *client) { struct iio_dev *indio_dev = i2c_get_clientdata(client); struct max1363_state *st = iio_priv(indio_dev); @@ -1434,7 +1434,7 @@ static struct i2c_driver max1363_driver = { .name = "max1363", }, .probe = max1363_probe, - .remove = max1363_remove, + .remove = __devexit_p(max1363_remove), .id_table = max1363_id, }; module_i2c_driver(max1363_driver); diff --git a/drivers/staging/iio/gyro/adis16060_core.c b/drivers/staging/iio/gyro/adis16060_core.c index 9931e20..87151a7 100644 --- a/drivers/staging/iio/gyro/adis16060_core.c +++ b/drivers/staging/iio/gyro/adis16060_core.c @@ -184,7 +184,7 @@ error_ret: } /* fixme, confirm ordering in this function */ -static int adis16060_r_remove(struct spi_device *spi) +static int __devexit adis16060_r_remove(struct spi_device *spi) { iio_device_unregister(spi_get_drvdata(spi)); iio_device_free(spi_get_drvdata(spi)); @@ -210,7 +210,7 @@ error_ret: return ret; } -static int adis16060_w_remove(struct spi_device *spi) +static int __devexit adis16060_w_remove(struct spi_device *spi) { return 0; } diff --git a/drivers/staging/iio/gyro/adis16080_core.c b/drivers/staging/iio/gyro/adis16080_core.c index 345e4fa..a739025 100644 --- a/drivers/staging/iio/gyro/adis16080_core.c +++ b/drivers/staging/iio/gyro/adis16080_core.c @@ -177,7 +177,7 @@ error_ret: } /* fixme, confirm ordering in this function */ -static int adis16080_remove(struct spi_device *spi) +static int __devexit adis16080_remove(struct spi_device *spi) { iio_device_unregister(spi_get_drvdata(spi)); iio_device_free(spi_get_drvdata(spi)); diff --git a/drivers/staging/iio/gyro/adis16130_core.c b/drivers/staging/iio/gyro/adis16130_core.c index bf61cd0..fbf96b0 100644 --- a/drivers/staging/iio/gyro/adis16130_core.c +++ b/drivers/staging/iio/gyro/adis16130_core.c @@ -154,7 +154,7 @@ error_ret: } /* fixme, confirm ordering in this function */ -static int adis16130_remove(struct spi_device *spi) +static int __devexit adis16130_remove(struct spi_device *spi) { iio_device_unregister(spi_get_drvdata(spi)); iio_device_free(spi_get_drvdata(spi)); diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c index 93aa431..dec2504 100644 --- a/drivers/staging/iio/gyro/adis16260_core.c +++ b/drivers/staging/iio/gyro/adis16260_core.c @@ -698,7 +698,7 @@ error_ret: return ret; } -static int adis16260_remove(struct spi_device *spi) +static int __devexit adis16260_remove(struct spi_device *spi) { int ret; struct iio_dev *indio_dev = spi_get_drvdata(spi); diff --git a/drivers/staging/iio/gyro/adxrs450_core.c b/drivers/staging/iio/gyro/adxrs450_core.c index 6513119..d93527d 100644 --- a/drivers/staging/iio/gyro/adxrs450_core.c +++ b/drivers/staging/iio/gyro/adxrs450_core.c @@ -409,7 +409,7 @@ error_ret: return ret; } -static int adxrs450_remove(struct spi_device *spi) +static int __devexit adxrs450_remove(struct spi_device *spi) { iio_device_unregister(spi_get_drvdata(spi)); iio_device_free(spi_get_drvdata(spi)); diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c index 4ce9e3d..b9f8438 100644 --- a/drivers/staging/iio/imu/adis16400_core.c +++ b/drivers/staging/iio/imu/adis16400_core.c @@ -1204,7 +1204,7 @@ error_ret: } /* fixme, confirm ordering in this function */ -static int adis16400_remove(struct spi_device *spi) +static int __devexit adis16400_remove(struct spi_device *spi) { int ret; struct iio_dev *indio_dev = spi_get_drvdata(spi); diff --git a/drivers/staging/iio/light/tsl2563.c b/drivers/staging/iio/light/tsl2563.c index 9d740be..954ca2c 100644 --- a/drivers/staging/iio/light/tsl2563.c +++ b/drivers/staging/iio/light/tsl2563.c @@ -805,7 +805,7 @@ fail1: return err; } -static int tsl2563_remove(struct i2c_client *client) +static int __devexit tsl2563_remove(struct i2c_client *client) { struct tsl2563_chip *chip = i2c_get_clientdata(client); struct iio_dev *indio_dev = iio_priv_to_dev(chip); diff --git a/drivers/staging/iio/meter/ade7753.c b/drivers/staging/iio/meter/ade7753.c index f04ece7..6caf80c 100644 --- a/drivers/staging/iio/meter/ade7753.c +++ b/drivers/staging/iio/meter/ade7753.c @@ -553,7 +553,7 @@ error_ret: } /* fixme, confirm ordering in this function */ -static int ade7753_remove(struct spi_device *spi) +static int __devexit ade7753_remove(struct spi_device *spi) { int ret; struct iio_dev *indio_dev = spi_get_drvdata(spi); diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c index 6cee28a..ab912ca 100644 --- a/drivers/staging/iio/meter/ade7754.c +++ b/drivers/staging/iio/meter/ade7754.c @@ -575,7 +575,7 @@ error_ret: } /* fixme, confirm ordering in this function */ -static int ade7754_remove(struct spi_device *spi) +static int __devexit ade7754_remove(struct spi_device *spi) { int ret; struct iio_dev *indio_dev = spi_get_drvdata(spi); diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c index 6d3725a..958f8f2 100644 --- a/drivers/staging/iio/meter/ade7758_core.c +++ b/drivers/staging/iio/meter/ade7758_core.c @@ -962,7 +962,7 @@ error_ret: return ret; } -static int ade7758_remove(struct spi_device *spi) +static int __devexit ade7758_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); struct ade7758_state *st = iio_priv(indio_dev); diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c index b3f7e0fa9..d494052 100644 --- a/drivers/staging/iio/meter/ade7759.c +++ b/drivers/staging/iio/meter/ade7759.c @@ -497,7 +497,7 @@ error_ret: } /* fixme, confirm ordering in this function */ -static int ade7759_remove(struct spi_device *spi) +static int __devexit ade7759_remove(struct spi_device *spi) { int ret; struct iio_dev *indio_dev = spi_get_drvdata(spi); diff --git a/drivers/staging/iio/meter/ade7854-spi.c b/drivers/staging/iio/meter/ade7854-spi.c index 9fb2f8b..7dae035 100644 --- a/drivers/staging/iio/meter/ade7854-spi.c +++ b/drivers/staging/iio/meter/ade7854-spi.c @@ -330,7 +330,7 @@ static int __devinit ade7854_spi_probe(struct spi_device *spi) return 0; } -static int ade7854_spi_remove(struct spi_device *spi) +static int __devexit ade7854_spi_remove(struct spi_device *spi) { ade7854_remove(spi_get_drvdata(spi)); diff --git a/drivers/staging/iio/trigger/iio-trig-gpio.c b/drivers/staging/iio/trigger/iio-trig-gpio.c index 90b2684..de26d54 100644 --- a/drivers/staging/iio/trigger/iio-trig-gpio.c +++ b/drivers/staging/iio/trigger/iio-trig-gpio.c @@ -51,7 +51,7 @@ static const struct iio_trigger_ops iio_gpio_trigger_ops = { .owner = THIS_MODULE, }; -static int iio_gpio_trigger_probe(struct platform_device *pdev) +static int __devinit iio_gpio_trigger_probe(struct platform_device *pdev) { struct iio_gpio_trigger_info *trig_info; struct iio_trigger *trig, *trig2; @@ -130,7 +130,7 @@ error_free_completed_registrations: return ret; } -static int iio_gpio_trigger_remove(struct platform_device *pdev) +static int __devexit iio_gpio_trigger_remove(struct platform_device *pdev) { struct iio_trigger *trig, *trig2; struct iio_gpio_trigger_info *trig_info; @@ -153,7 +153,7 @@ static int iio_gpio_trigger_remove(struct platform_device *pdev) static struct platform_driver iio_gpio_trigger_driver = { .probe = iio_gpio_trigger_probe, - .remove = iio_gpio_trigger_remove, + .remove = __devexit_p(iio_gpio_trigger_remove), .driver = { .name = "iio_gpio_trigger", .owner = THIS_MODULE, diff --git a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c index 4ceaa18..b837801 100644 --- a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c +++ b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c @@ -101,7 +101,7 @@ static const struct iio_trigger_ops iio_prtc_trigger_ops = { .set_trigger_state = &iio_trig_periodic_rtc_set_state, }; -static int iio_trig_periodic_rtc_probe(struct platform_device *dev) +static int __devinit iio_trig_periodic_rtc_probe(struct platform_device *dev) { char **pdata = dev->dev.platform_data; struct iio_prtc_trigger_info *trig_info; @@ -167,7 +167,7 @@ error_free_completed_registrations: return ret; } -static int iio_trig_periodic_rtc_remove(struct platform_device *dev) +static int __devexit iio_trig_periodic_rtc_remove(struct platform_device *dev) { struct iio_trigger *trig, *trig2; struct iio_prtc_trigger_info *trig_info; @@ -188,7 +188,7 @@ static int iio_trig_periodic_rtc_remove(struct platform_device *dev) static struct platform_driver iio_trig_periodic_rtc_driver = { .probe = iio_trig_periodic_rtc_probe, - .remove = iio_trig_periodic_rtc_remove, + .remove = __devexit_p(iio_trig_periodic_rtc_remove), .driver = { .name = "iio_prtc_trigger", .owner = THIS_MODULE, -- cgit v0.10.2 From c559afbfb08c7eac215ba417251225d3a8e01062 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 30 Jun 2012 13:52:00 +0100 Subject: iio:kfifo_buf Take advantage of the fixed record size used in IIO By bypassing the standard macros for setting up the kfifo we can take advantage of the fixed record size implementation without having to have a type to pass in (from which the size of an element is normally established). In IIO we have variable 'scans' as our records in which any element can be present or not. They do not however vary when we are actually filling or reading from the buffer. Thus we have a fixed record size whenever we are actually running. As setup and tear down are not in the fast path we can take the overhead of reinitializing the kfifo every time. Signed-off-by: Jonathan Cameron Tested-by: Lars-Peter Clausen diff --git a/drivers/iio/kfifo_buf.c b/drivers/iio/kfifo_buf.c index 6bf9d05..8a6d28c 100644 --- a/drivers/iio/kfifo_buf.c +++ b/drivers/iio/kfifo_buf.c @@ -22,7 +22,8 @@ static inline int __iio_allocate_kfifo(struct iio_kfifo *buf, return -EINVAL; __iio_update_buffer(&buf->buffer, bytes_per_datum, length); - return kfifo_alloc(&buf->kf, bytes_per_datum*length, GFP_KERNEL); + return __kfifo_alloc((struct __kfifo *)&buf->kf, length, + bytes_per_datum, GFP_KERNEL); } static int iio_request_update_kfifo(struct iio_buffer *r) @@ -94,9 +95,10 @@ static int iio_store_to_kfifo(struct iio_buffer *r, { int ret; struct iio_kfifo *kf = iio_to_kfifo(r); - ret = kfifo_in(&kf->kf, data, r->bytes_per_datum); - if (ret != r->bytes_per_datum) + ret = kfifo_in(&kf->kf, data, 1); + if (ret != 1) return -EBUSY; + return 0; } @@ -109,7 +111,6 @@ static int iio_read_first_n_kfifo(struct iio_buffer *r, if (n < r->bytes_per_datum) return -EINVAL; - n = rounddown(n, r->bytes_per_datum); ret = kfifo_to_user(&kf->kf, buf, n, &copied); return copied; -- cgit v0.10.2 From 08ce9b44b53c580987b6a63df4e2206e45e20b92 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Mon, 27 Aug 2012 18:40:04 +0100 Subject: iio:kfifo_buf improve error handling in read_first_n. These two elements were originally in the patch iio:kfifo_buf Take advantage of the fixed record size used in IIO but Lars-Peter Clausen pointed out they should not have been so here they are. Signed-off-by: Jonathan Cameron Tested-by: Lars-Peter Clausen diff --git a/drivers/iio/kfifo_buf.c b/drivers/iio/kfifo_buf.c index 8a6d28c..6ec763f 100644 --- a/drivers/iio/kfifo_buf.c +++ b/drivers/iio/kfifo_buf.c @@ -108,10 +108,12 @@ static int iio_read_first_n_kfifo(struct iio_buffer *r, int ret, copied; struct iio_kfifo *kf = iio_to_kfifo(r); - if (n < r->bytes_per_datum) + if (n < r->bytes_per_datum || r->bytes_per_datum == 0) return -EINVAL; ret = kfifo_to_user(&kf->kf, buf, n, &copied); + if (ret < 0) + return ret; return copied; } -- cgit v0.10.2 From 7c388ec1d4bc55b72802afbddb26ab87bc762438 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 30 Jun 2012 13:52:00 +0100 Subject: iio: kfifo - add poll support. This buffer implementation was missing poll support. Signed-off-by: Jonathan Cameron Tested-by: Lars-Peter Clausen Acked-by: srinivas pandruvada diff --git a/drivers/iio/kfifo_buf.c b/drivers/iio/kfifo_buf.c index 6ec763f..63da424 100644 --- a/drivers/iio/kfifo_buf.c +++ b/drivers/iio/kfifo_buf.c @@ -6,6 +6,7 @@ #include #include #include +#include struct iio_kfifo { struct iio_buffer buffer; @@ -36,6 +37,7 @@ static int iio_request_update_kfifo(struct iio_buffer *r) kfifo_free(&buf->kf); ret = __iio_allocate_kfifo(buf, buf->buffer.bytes_per_datum, buf->buffer.length); + r->stufftoread = false; error_ret: return ret; } @@ -82,6 +84,9 @@ static int iio_set_bytes_per_datum_kfifo(struct iio_buffer *r, size_t bpd) static int iio_set_length_kfifo(struct iio_buffer *r, int length) { + /* Avoid an invalid state */ + if (length < 2) + length = 2; if (r->length != length) { r->length = length; iio_mark_update_needed_kfifo(r); @@ -98,6 +103,8 @@ static int iio_store_to_kfifo(struct iio_buffer *r, ret = kfifo_in(&kf->kf, data, 1); if (ret != 1) return -EBUSY; + r->stufftoread = true; + wake_up_interruptible(&r->pollq); return 0; } @@ -115,6 +122,12 @@ static int iio_read_first_n_kfifo(struct iio_buffer *r, if (ret < 0) return ret; + if (kfifo_is_empty(&kf->kf)) + r->stufftoread = false; + /* verify it is still empty to avoid race */ + if (!kfifo_is_empty(&kf->kf)) + r->stufftoread = true; + return copied; } @@ -139,7 +152,7 @@ struct iio_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev) iio_buffer_init(&kf->buffer); kf->buffer.attrs = &iio_kfifo_attribute_group; kf->buffer.access = &kfifo_access_funcs; - + kf->buffer.length = 2; return &kf->buffer; } EXPORT_SYMBOL(iio_kfifo_allocate); -- cgit v0.10.2 From 91b4171f4e7e2d49aee54259b50e703e09bcff20 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Wed, 22 Aug 2012 20:42:00 +0100 Subject: staging iio: lis3l02dq cleanup fixes some typos, whitespace, comments Signed-off-by: Peter Meerwald Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/accel/lis3l02dq.h b/drivers/staging/iio/accel/lis3l02dq.h index ae5f225..ad51658 100644 --- a/drivers/staging/iio/accel/lis3l02dq.h +++ b/drivers/staging/iio/accel/lis3l02dq.h @@ -28,7 +28,7 @@ /* Control Register (1 of 2) */ #define LIS3L02DQ_REG_CTRL_1_ADDR 0x20 /* Power ctrl - either bit set corresponds to on*/ -#define LIS3L02DQ_REG_CTRL_1_PD_ON 0xC0 +#define LIS3L02DQ_REG_CTRL_1_PD_ON 0xC0 /* Decimation Factor */ #define LIS3L02DQ_DEC_MASK 0x30 @@ -73,14 +73,14 @@ /* Interrupt related stuff */ #define LIS3L02DQ_REG_WAKE_UP_CFG_ADDR 0x23 -/* Switch from or combination fo conditions to and */ +/* Switch from or combination of conditions to and */ #define LIS3L02DQ_REG_WAKE_UP_CFG_BOOLEAN_AND 0x80 /* Latch interrupt request, * if on ack must be given by reading the ack register */ #define LIS3L02DQ_REG_WAKE_UP_CFG_LATCH_SRC 0x40 -/* Z Interrupt on High (above threshold)*/ +/* Z Interrupt on High (above threshold) */ #define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Z_HIGH 0x20 /* Z Interrupt on Low */ #define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Z_LOW 0x10 @@ -117,13 +117,13 @@ #define LIS3L02DQ_REG_STATUS_Y_OVERRUN 0x20 #define LIS3L02DQ_REG_STATUS_X_OVERRUN 0x10 /* XYZ new data available - first is all 3 available? */ -#define LIS3L02DQ_REG_STATUS_XYZ_NEW_DATA 0x08 +#define LIS3L02DQ_REG_STATUS_XYZ_NEW_DATA 0x08 #define LIS3L02DQ_REG_STATUS_Z_NEW_DATA 0x04 #define LIS3L02DQ_REG_STATUS_Y_NEW_DATA 0x02 #define LIS3L02DQ_REG_STATUS_X_NEW_DATA 0x01 /* The accelerometer readings - low and high bytes. -Form of high byte dependent on justification set in ctrl reg */ + * Form of high byte dependent on justification set in ctrl reg */ #define LIS3L02DQ_REG_OUT_X_L_ADDR 0x28 #define LIS3L02DQ_REG_OUT_X_H_ADDR 0x29 #define LIS3L02DQ_REG_OUT_Y_L_ADDR 0x2A @@ -150,9 +150,9 @@ Form of high byte dependent on justification set in ctrl reg */ * struct lis3l02dq_state - device instance specific data * @us: actual spi_device * @trig: data ready trigger registered with iio + * @buf_lock: mutex to protect tx and rx * @tx: transmit buffer * @rx: receive buffer - * @buf_lock: mutex to protect tx and rx **/ struct lis3l02dq_state { struct spi_device *us; diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c index 54ce17f..0144afe 100644 --- a/drivers/staging/iio/accel/lis3l02dq_core.c +++ b/drivers/staging/iio/accel/lis3l02dq_core.c @@ -392,7 +392,7 @@ static int lis3l02dq_initial_setup(struct iio_dev *indio_dev) dev_err(&st->us->dev, "problem with setup control register 1"); goto err_ret; } - /* Repeat as sometimes doesn't work first time?*/ + /* Repeat as sometimes doesn't work first time? */ ret = lis3l02dq_spi_write_reg_8(indio_dev, LIS3L02DQ_REG_CTRL_1_ADDR, val); @@ -686,7 +686,7 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi) goto error_ret; } st = iio_priv(indio_dev); - /* this is only used tor removal purposes */ + /* this is only used for removal purposes */ spi_set_drvdata(spi, indio_dev); st->us = spi; diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c index 18d108f..7da2703 100644 --- a/drivers/staging/iio/accel/lis3l02dq_ring.c +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c @@ -14,7 +14,7 @@ #include "lis3l02dq.h" /** - * combine_8_to_16() utility function to munge to u8s into u16 + * combine_8_to_16() utility function to munge two u8s into u16 **/ static inline u16 combine_8_to_16(u8 lower, u8 upper) { @@ -49,7 +49,7 @@ static const u8 read_all_tx_array[] = { /** * lis3l02dq_read_all() Reads all channels currently selected - * @st: device specific state + * @indio_dev: IIO device state * @rx_array: (dma capable) receive array, must be at least * 4*number of channels **/ @@ -170,22 +170,22 @@ __lis3l02dq_write_data_ready_config(struct iio_dev *indio_dev, bool state) bool currentlyset; struct lis3l02dq_state *st = iio_priv(indio_dev); -/* Get the current event mask register */ + /* Get the current event mask register */ ret = lis3l02dq_spi_read_reg_8(indio_dev, LIS3L02DQ_REG_CTRL_2_ADDR, &valold); if (ret) goto error_ret; -/* Find out if data ready is already on */ + /* Find out if data ready is already on */ currentlyset = valold & LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION; -/* Disable requested */ + /* Disable requested */ if (!state && currentlyset) { - /* disable the data ready signal */ + /* Disable the data ready signal */ valold &= ~LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION; - /* The double write is to overcome a hardware bug?*/ + /* The double write is to overcome a hardware bug? */ ret = lis3l02dq_spi_write_reg_8(indio_dev, LIS3L02DQ_REG_CTRL_2_ADDR, valold); @@ -197,10 +197,10 @@ __lis3l02dq_write_data_ready_config(struct iio_dev *indio_dev, bool state) if (ret) goto error_ret; st->trigger_on = false; -/* Enable requested */ + /* Enable requested */ } else if (state && !currentlyset) { - /* if not set, enable requested */ - /* first disable all events */ + /* If not set, enable requested + * first disable all events */ ret = lis3l02dq_disable_all_events(indio_dev); if (ret < 0) goto error_ret; @@ -239,7 +239,7 @@ static int lis3l02dq_data_rdy_trigger_set_state(struct iio_trigger *trig, if (state == false) { /* * A possible quirk with the handler is currently worked around - * by ensuring outstanding read events are cleared. + * by ensuring outstanding read events are cleared. */ ret = lis3l02dq_read_all(indio_dev, NULL); } @@ -250,7 +250,7 @@ static int lis3l02dq_data_rdy_trigger_set_state(struct iio_trigger *trig, } /** - * lis3l02dq_trig_try_reen() try renabling irq for data rdy trigger + * lis3l02dq_trig_try_reen() try reenabling irq for data rdy trigger * @trig: the datardy trigger */ static int lis3l02dq_trig_try_reen(struct iio_trigger *trig) @@ -259,8 +259,8 @@ static int lis3l02dq_trig_try_reen(struct iio_trigger *trig) struct lis3l02dq_state *st = iio_priv(indio_dev); int i; - /* If gpio still high (or high again) */ - /* In theory possible we will need to do this several times */ + /* If gpio still high (or high again) + * In theory possible we will need to do this several times */ for (i = 0; i < 5; i++) if (gpio_get_value(irq_to_gpio(st->us->irq))) lis3l02dq_read_all(indio_dev, NULL); -- cgit v0.10.2 From f5ed9c35bd2af6d9d171290d3dc45004f4f79bcf Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 26 Aug 2012 17:00:00 +0100 Subject: drivers/staging/iio/adc/spear_adc.c: use clk_prepare_enable and clk_disable_unprepare Clk_prepare_enable and clk_disable_unprepare combine clk_prepare and clk_enable, and clk_disable and clk_unprepare. They make the code more concise, and ensure that clk_unprepare is called when clk_enable fails. A simplified version of the semantic patch that introduces calls to these functions is as follows: (http://coccinelle.lip6.fr/) // @@ expression e; @@ - clk_prepare(e); - clk_enable(e); + clk_prepare_enable(e); @@ expression e; @@ - clk_disable(e); - clk_unprepare(e); + clk_disable_unprepare(e); // Signed-off-by: Julia Lawall Reviewed-by: Viresh Kumar Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/adc/spear_adc.c b/drivers/staging/iio/adc/spear_adc.c index 675c427..0b83e2e 100644 --- a/drivers/staging/iio/adc/spear_adc.c +++ b/drivers/staging/iio/adc/spear_adc.c @@ -330,36 +330,30 @@ static int __devinit spear_adc_probe(struct platform_device *pdev) goto errout3; } - ret = clk_prepare(info->clk); - if (ret) { - dev_err(dev, "failed preparing clock\n"); - goto errout4; - } - - ret = clk_enable(info->clk); + ret = clk_prepare_enable(info->clk); if (ret) { dev_err(dev, "failed enabling clock\n"); - goto errout5; + goto errout4; } irq = platform_get_irq(pdev, 0); if ((irq < 0) || (irq >= NR_IRQS)) { dev_err(dev, "failed getting interrupt resource\n"); ret = -EINVAL; - goto errout6; + goto errout5; } ret = devm_request_irq(dev, irq, spear_adc_isr, 0, MOD_NAME, info); if (ret < 0) { dev_err(dev, "failed requesting interrupt\n"); - goto errout6; + goto errout5; } if (of_property_read_u32(np, "sampling-frequency", &info->sampling_freq)) { dev_err(dev, "sampling-frequency missing in DT\n"); ret = -EINVAL; - goto errout6; + goto errout5; } /* @@ -389,16 +383,14 @@ static int __devinit spear_adc_probe(struct platform_device *pdev) ret = iio_device_register(iodev); if (ret) - goto errout6; + goto errout5; dev_info(dev, "SPEAR ADC driver loaded, IRQ %d\n", irq); return 0; -errout6: - clk_disable(info->clk); errout5: - clk_unprepare(info->clk); + clk_disable_unprepare(info->clk); errout4: clk_put(info->clk); errout3: @@ -416,8 +408,7 @@ static int __devexit spear_adc_remove(struct platform_device *pdev) iio_device_unregister(iodev); platform_set_drvdata(pdev, NULL); - clk_disable(info->clk); - clk_unprepare(info->clk); + clk_disable_unprepare(info->clk); clk_put(info->clk); iounmap(info->adc_base_spear6xx); iio_device_free(iodev); -- cgit v0.10.2 From 00062a9c2e772345388cd352695790f00a95b934 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 26 Aug 2012 17:00:00 +0100 Subject: drivers/iio/adc/at91_adc.c: use clk_prepare_enable and clk_disable_unprepare Clk_prepare_enable and clk_disable_unprepare combine clk_prepare and clk_enable, and clk_disable and clk_unprepare. They make the code more concise, and ensure that clk_unprepare is called when clk_enable fails. A simplified version of the semantic patch that introduces calls to these functions is as follows: (http://coccinelle.lip6.fr/) // @@ expression e; @@ - clk_prepare(e); - clk_enable(e); + clk_prepare_enable(e); @@ expression e; @@ - clk_disable(e); - clk_unprepare(e); + clk_disable_unprepare(e); // Signed-off-by: Julia Lawall Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index 98c96f9..c1e4690 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -589,18 +589,13 @@ static int __devinit at91_adc_probe(struct platform_device *pdev) goto error_free_irq; } - ret = clk_prepare(st->clk); + ret = clk_prepare_enable(st->clk); if (ret) { - dev_err(&pdev->dev, "Could not prepare the clock.\n"); + dev_err(&pdev->dev, + "Could not prepare or enable the clock.\n"); goto error_free_irq; } - ret = clk_enable(st->clk); - if (ret) { - dev_err(&pdev->dev, "Could not enable the clock.\n"); - goto error_unprepare_clk; - } - st->adc_clk = devm_clk_get(&pdev->dev, "adc_op_clk"); if (IS_ERR(st->adc_clk)) { dev_err(&pdev->dev, "Failed to get the ADC clock.\n"); @@ -608,18 +603,13 @@ static int __devinit at91_adc_probe(struct platform_device *pdev) goto error_disable_clk; } - ret = clk_prepare(st->adc_clk); + ret = clk_prepare_enable(st->adc_clk); if (ret) { - dev_err(&pdev->dev, "Could not prepare the ADC clock.\n"); + dev_err(&pdev->dev, + "Could not prepare or enable the ADC clock.\n"); goto error_disable_clk; } - ret = clk_enable(st->adc_clk); - if (ret) { - dev_err(&pdev->dev, "Could not enable the ADC clock.\n"); - goto error_unprepare_adc_clk; - } - /* * Prescaler rate computation using the formula from the Atmel's * datasheet : ADC Clock = MCK / ((Prescaler + 1) * 2), ADC Clock being @@ -681,13 +671,9 @@ error_remove_triggers: error_unregister_buffer: at91_adc_buffer_remove(idev); error_disable_adc_clk: - clk_disable(st->adc_clk); -error_unprepare_adc_clk: - clk_unprepare(st->adc_clk); + clk_disable_unprepare(st->adc_clk); error_disable_clk: - clk_disable(st->clk); -error_unprepare_clk: - clk_unprepare(st->clk); + clk_disable_unprepare(st->clk); error_free_irq: free_irq(st->irq, idev); error_free_device: @@ -705,8 +691,7 @@ static int __devexit at91_adc_remove(struct platform_device *pdev) at91_adc_trigger_remove(idev); at91_adc_buffer_remove(idev); clk_disable_unprepare(st->adc_clk); - clk_disable(st->clk); - clk_unprepare(st->clk); + clk_disable_unprepare(st->clk); free_irq(st->irq, idev); iio_device_free(idev); -- cgit v0.10.2 From c3668a0f8097af2f24a5fd67695f4ee830f99eda Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Sun, 26 Aug 2012 13:43:00 +0100 Subject: iio: document missing elements Signed-off-by: Peter Meerwald Signed-off-by: Jonathan Cameron diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index b18e74e..2c395a8 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -229,6 +229,7 @@ ssize_t iio_enum_write(struct iio_dev *indio_dev, * @indexed: Specify the channel has a numerical index. If not, * the channel index number will be suppressed for sysfs * attributes but not for event codes. + * @output: Channel is output. * @differential: Channel is differential. */ struct iio_chan_spec { @@ -312,6 +313,9 @@ struct iio_dev; * Meaning is event dependent. * @validate_trigger: function to validate the trigger when the * current trigger gets changed. + * @update_scan_mode: function to configure device and scan buffer when + * channels have changed + * @debugfs_reg_access: function to read or write register value of device **/ struct iio_info { struct module *driver_module; diff --git a/include/linux/iio/trigger.h b/include/linux/iio/trigger.h index a981994..f0af267 100644 --- a/include/linux/iio/trigger.h +++ b/include/linux/iio/trigger.h @@ -39,7 +39,7 @@ struct iio_trigger_ops { /** * struct iio_trigger - industrial I/O trigger device - * + * @ops: [DRIVER] operations structure * @id: [INTERN] unique id number * @name: [DRIVER] unique name * @dev: [DRIVER] associated device (if relevant) @@ -104,7 +104,8 @@ void iio_trigger_unregister(struct iio_trigger *trig_info); /** * iio_trigger_poll() - called on a trigger occurring - * @trig: trigger which occurred + * @trig: trigger which occurred + * @time: timestamp when trigger occurred * * Typically called in relevant hardware interrupt handler. **/ -- cgit v0.10.2 From d25b3808db3a03deb12ffc0660c757b4a619f262 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Sun, 26 Aug 2012 13:43:00 +0100 Subject: iio: fix typos Signed-off-by: Peter Meerwald Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 2ec266e..47c1ffa 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -729,7 +729,7 @@ static int iio_device_register_sysfs(struct iio_dev *indio_dev) attrcount = attrcount_orig; /* * New channel registration method - relies on the fact a group does - * not need to be initialized if it is name is NULL. + * not need to be initialized if its name is NULL. */ if (indio_dev->channels) for (i = 0; i < indio_dev->num_channels; i++) { diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 2c395a8..677e3d8 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -164,7 +164,7 @@ ssize_t iio_enum_write(struct iio_dev *indio_dev, * IIO_ENUM() - Initialize enum extended channel attribute * @_name: Attribute name * @_shared: Whether the attribute is shared between all channels - * @_e: Pointer to a iio_enum struct + * @_e: Pointer to an iio_enum struct * * This should usually be used together with IIO_ENUM_AVAILABLE() */ @@ -180,9 +180,9 @@ ssize_t iio_enum_write(struct iio_dev *indio_dev, /** * IIO_ENUM_AVAILABLE() - Initialize enum available extended channel attribute * @_name: Attribute name ("_available" will be appended to the name) - * @_e: Pointer to a iio_enum struct + * @_e: Pointer to an iio_enum struct * - * Creates a read only attribute which list all the available enum items in a + * Creates a read only attribute which lists all the available enum items in a * space separated list. This should usually be used together with IIO_ENUM() */ #define IIO_ENUM_AVAILABLE(_name, _e) \ -- cgit v0.10.2 From 99698b45670a37b5304d5c6a743c8e96baa9ed8f Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Sun, 26 Aug 2012 13:43:00 +0100 Subject: iio: whitespace cleanup and removal of semicolon after functions Signed-off-by: Peter Meerwald Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 4add9bb..774891c 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -422,7 +422,7 @@ ssize_t iio_buffer_store_enable(struct device *dev, ret = indio_dev->setup_ops->preenable(indio_dev); if (ret) { printk(KERN_ERR - "Buffer not started:" + "Buffer not started: " "buffer preenable failed\n"); goto error_ret; } @@ -431,12 +431,12 @@ ssize_t iio_buffer_store_enable(struct device *dev, ret = buffer->access->request_update(buffer); if (ret) { printk(KERN_INFO - "Buffer not started:" + "Buffer not started: " "buffer parameter update failed\n"); goto error_ret; } } - /* Definitely possible for devices to support both of these.*/ + /* Definitely possible for devices to support both of these. */ if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) { if (!indio_dev->trig) { printk(KERN_INFO @@ -456,7 +456,7 @@ ssize_t iio_buffer_store_enable(struct device *dev, ret = indio_dev->setup_ops->postenable(indio_dev); if (ret) { printk(KERN_INFO - "Buffer not started:" + "Buffer not started: " "postenable failed\n"); indio_dev->currentmode = previous_mode; if (indio_dev->setup_ops->postdisable) @@ -657,7 +657,7 @@ EXPORT_SYMBOL_GPL(iio_scan_mask_query); /** * struct iio_demux_table() - table describing demux memcpy ops * @from: index to copy from - * @to: index to copy to + * @to: index to copy to * @length: how many bytes to copy * @l: list head used for management */ diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 47c1ffa..a288792 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -29,7 +29,7 @@ #include #include -/* IDA to assign each registered device a unique id*/ +/* IDA to assign each registered device a unique id */ static DEFINE_IDA(iio_ida); static dev_t iio_devt; diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 677e3d8..057d603 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -371,10 +371,10 @@ struct iio_info { * scan mask is valid for the device. */ struct iio_buffer_setup_ops { - int (*preenable)(struct iio_dev *); - int (*postenable)(struct iio_dev *); - int (*predisable)(struct iio_dev *); - int (*postdisable)(struct iio_dev *); + int (*preenable)(struct iio_dev *); + int (*postenable)(struct iio_dev *); + int (*predisable)(struct iio_dev *); + int (*postdisable)(struct iio_dev *); bool (*validate_scan_mask)(struct iio_dev *indio_dev, const unsigned long *scan_mask); }; diff --git a/include/linux/iio/trigger.h b/include/linux/iio/trigger.h index f0af267..20239da 100644 --- a/include/linux/iio/trigger.h +++ b/include/linux/iio/trigger.h @@ -29,7 +29,7 @@ struct iio_subirq { * instances of a given device. **/ struct iio_trigger_ops { - struct module *owner; + struct module *owner; int (*set_trigger_state)(struct iio_trigger *trig, bool state); int (*try_reenable)(struct iio_trigger *trig); int (*validate_device)(struct iio_trigger *trig, @@ -76,19 +76,19 @@ struct iio_trigger { static inline struct iio_trigger *to_iio_trigger(struct device *d) { return container_of(d, struct iio_trigger, dev); -}; +} static inline void iio_trigger_put(struct iio_trigger *trig) { module_put(trig->ops->owner); put_device(&trig->dev); -}; +} static inline void iio_trigger_get(struct iio_trigger *trig) { get_device(&trig->dev); __module_get(trig->ops->owner); -}; +} /** * iio_trigger_register() - register a trigger with the IIO core -- cgit v0.10.2 From e58bf5332d8ccc14ae0788e5541d4b8327728f5b Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Mon, 27 Aug 2012 22:12:00 +0100 Subject: iio: fix spelling of subsystem Signed-off-by: Peter Meerwald Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig index d4984c8..56825e6 100644 --- a/drivers/iio/Kconfig +++ b/drivers/iio/Kconfig @@ -1,5 +1,5 @@ # -# Industrial I/O subsytem configuration +# Industrial I/O subsystem configuration # menuconfig IIO diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig index 04cd6ec..ca56c75 100644 --- a/drivers/staging/iio/Kconfig +++ b/drivers/staging/iio/Kconfig @@ -1,5 +1,5 @@ # -# Industrial I/O subsytem configuration +# Industrial I/O subsystem configuration # menu "IIO staging drivers" depends on IIO -- cgit v0.10.2 From 3ec36a2cf0d50db61e15c6ee77d1dcdc73a7aca5 Mon Sep 17 00:00:00 2001 From: Jean-Francois Dagenais Date: Tue, 21 Aug 2012 15:28:00 +0100 Subject: iio:ad5446: Add support for I2C based DACs This patch adds support for I2C based single channel DACs to the ad5446 driver. Specifically AD5602, AD5612 and AD5622. V1: from Lars-Peter Clausen V2: Split the device IDs into two enums and move them to the c file. Signed-off-by: Jean-Francois Dagenais Acked-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig index 1be15fa..293b61d 100644 --- a/drivers/iio/dac/Kconfig +++ b/drivers/iio/dac/Kconfig @@ -57,11 +57,12 @@ config AD5624R_SPI config AD5446 tristate "Analog Devices AD5446 and similar single channel DACs driver" - depends on SPI + depends on (SPI_MASTER || I2C) help - Say yes here to build support for Analog Devices AD5444, AD5446, AD5450, - AD5451, AD5452, AD5453, AD5512A, AD5541A, AD5542A, AD5543, AD5553, AD5601, - AD5611, AD5620, AD5621, AD5640, AD5660, AD5662 DACs. + Say yes here to build support for Analog Devices AD5602, AD5612, AD5622, + AD5444, AD5446, AD5450, AD5451, AD5452, AD5453, AD5512A, AD5541A, AD5542A, + AD5543, AD5553, AD5601, AD5611, AD5620, AD5621, AD5640, AD5660, AD5662 + DACs. To compile this driver as a module, choose M here: the module will be called ad5446. diff --git a/drivers/iio/dac/ad5446.c b/drivers/iio/dac/ad5446.c index 2ca5059..241665b 100644 --- a/drivers/iio/dac/ad5446.c +++ b/drivers/iio/dac/ad5446.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -23,23 +24,6 @@ #include "ad5446.h" -static int ad5446_write(struct ad5446_state *st, unsigned val) -{ - __be16 data = cpu_to_be16(val); - return spi_write(st->spi, &data, sizeof(data)); -} - -static int ad5660_write(struct ad5446_state *st, unsigned val) -{ - uint8_t data[3]; - - data[0] = (val >> 16) & 0xFF; - data[1] = (val >> 8) & 0xFF; - data[2] = val & 0xFF; - - return spi_write(st->spi, data, sizeof(data)); -} - static const char * const ad5446_powerdown_modes[] = { "1kohm_to_gnd", "100kohm_to_gnd", "three_state" }; @@ -110,7 +94,7 @@ static ssize_t ad5446_write_dac_powerdown(struct iio_dev *indio_dev, return ret ? ret : len; } -static const struct iio_chan_spec_ext_info ad5064_ext_info_powerdown[] = { +static const struct iio_chan_spec_ext_info ad5446_ext_info_powerdown[] = { { .name = "powerdown", .read = ad5446_read_dac_powerdown, @@ -136,84 +120,7 @@ static const struct iio_chan_spec_ext_info ad5064_ext_info_powerdown[] = { _AD5446_CHANNEL(bits, storage, shift, NULL) #define AD5446_CHANNEL_POWERDOWN(bits, storage, shift) \ - _AD5446_CHANNEL(bits, storage, shift, ad5064_ext_info_powerdown) - -static const struct ad5446_chip_info ad5446_chip_info_tbl[] = { - [ID_AD5444] = { - .channel = AD5446_CHANNEL(12, 16, 2), - .write = ad5446_write, - }, - [ID_AD5446] = { - .channel = AD5446_CHANNEL(14, 16, 0), - .write = ad5446_write, - }, - [ID_AD5450] = { - .channel = AD5446_CHANNEL(8, 16, 6), - .write = ad5446_write, - }, - [ID_AD5451] = { - .channel = AD5446_CHANNEL(10, 16, 4), - .write = ad5446_write, - }, - [ID_AD5541A] = { - .channel = AD5446_CHANNEL(16, 16, 0), - .write = ad5446_write, - }, - [ID_AD5512A] = { - .channel = AD5446_CHANNEL(12, 16, 4), - .write = ad5446_write, - }, - [ID_AD5553] = { - .channel = AD5446_CHANNEL(14, 16, 0), - .write = ad5446_write, - }, - [ID_AD5601] = { - .channel = AD5446_CHANNEL_POWERDOWN(8, 16, 6), - .write = ad5446_write, - }, - [ID_AD5611] = { - .channel = AD5446_CHANNEL_POWERDOWN(10, 16, 4), - .write = ad5446_write, - }, - [ID_AD5621] = { - .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2), - .write = ad5446_write, - }, - [ID_AD5620_2500] = { - .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2), - .int_vref_mv = 2500, - .write = ad5446_write, - }, - [ID_AD5620_1250] = { - .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2), - .int_vref_mv = 1250, - .write = ad5446_write, - }, - [ID_AD5640_2500] = { - .channel = AD5446_CHANNEL_POWERDOWN(14, 16, 0), - .int_vref_mv = 2500, - .write = ad5446_write, - }, - [ID_AD5640_1250] = { - .channel = AD5446_CHANNEL_POWERDOWN(14, 16, 0), - .int_vref_mv = 1250, - .write = ad5446_write, - }, - [ID_AD5660_2500] = { - .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0), - .int_vref_mv = 2500, - .write = ad5660_write, - }, - [ID_AD5660_1250] = { - .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0), - .int_vref_mv = 1250, - .write = ad5660_write, - }, - [ID_AD5662] = { - .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0), - .write = ad5660_write, - }, -}; + _AD5446_CHANNEL(bits, storage, shift, ad5446_ext_info_powerdown) static int ad5446_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, @@ -272,14 +179,15 @@ static const struct iio_info ad5446_info = { .driver_module = THIS_MODULE, }; -static int __devinit ad5446_probe(struct spi_device *spi) +static int __devinit ad5446_probe(struct device *dev, const char *name, + const struct ad5446_chip_info *chip_info) { struct ad5446_state *st; struct iio_dev *indio_dev; struct regulator *reg; int ret, voltage_uv = 0; - reg = regulator_get(&spi->dev, "vcc"); + reg = regulator_get(dev, "vcc"); if (!IS_ERR(reg)) { ret = regulator_enable(reg); if (ret) @@ -294,16 +202,15 @@ static int __devinit ad5446_probe(struct spi_device *spi) goto error_disable_reg; } st = iio_priv(indio_dev); - st->chip_info = - &ad5446_chip_info_tbl[spi_get_device_id(spi)->driver_data]; + st->chip_info = chip_info; - spi_set_drvdata(spi, indio_dev); + dev_set_drvdata(dev, indio_dev); st->reg = reg; - st->spi = spi; + st->dev = dev; - /* Establish that the iio_dev is a child of the spi device */ - indio_dev->dev.parent = &spi->dev; - indio_dev->name = spi_get_device_id(spi)->name; + /* Establish that the iio_dev is a child of the device */ + indio_dev->dev.parent = dev; + indio_dev->name = name; indio_dev->info = &ad5446_info; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->channels = &st->chip_info->channel; @@ -316,7 +223,7 @@ static int __devinit ad5446_probe(struct spi_device *spi) else if (voltage_uv) st->vref_mv = voltage_uv / 1000; else - dev_warn(&spi->dev, "reference voltage unspecified\n"); + dev_warn(dev, "reference voltage unspecified\n"); ret = iio_device_register(indio_dev); if (ret) @@ -336,9 +243,9 @@ error_put_reg: return ret; } -static int ad5446_remove(struct spi_device *spi) +static int ad5446_remove(struct device *dev) { - struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct iio_dev *indio_dev = dev_get_drvdata(dev); struct ad5446_state *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); @@ -351,7 +258,133 @@ static int ad5446_remove(struct spi_device *spi) return 0; } -static const struct spi_device_id ad5446_id[] = { +#if IS_ENABLED(CONFIG_SPI_MASTER) + +static int ad5446_write(struct ad5446_state *st, unsigned val) +{ + struct spi_device *spi = to_spi_device(st->dev); + __be16 data = cpu_to_be16(val); + + return spi_write(spi, &data, sizeof(data)); +} + +static int ad5660_write(struct ad5446_state *st, unsigned val) +{ + struct spi_device *spi = to_spi_device(st->dev); + uint8_t data[3]; + + data[0] = (val >> 16) & 0xFF; + data[1] = (val >> 8) & 0xFF; + data[2] = val & 0xFF; + + return spi_write(spi, data, sizeof(data)); +} + +/** + * ad5446_supported_spi_device_ids: + * The AD5620/40/60 parts are available in different fixed internal reference + * voltage options. The actual part numbers may look differently + * (and a bit cryptic), however this style is used to make clear which + * parts are supported here. + */ +enum ad5446_supported_spi_device_ids { + ID_AD5444, + ID_AD5446, + ID_AD5450, + ID_AD5451, + ID_AD5541A, + ID_AD5512A, + ID_AD5553, + ID_AD5601, + ID_AD5611, + ID_AD5621, + ID_AD5620_2500, + ID_AD5620_1250, + ID_AD5640_2500, + ID_AD5640_1250, + ID_AD5660_2500, + ID_AD5660_1250, + ID_AD5662, +}; + +static const struct ad5446_chip_info ad5446_spi_chip_info[] = { + [ID_AD5444] = { + .channel = AD5446_CHANNEL(12, 16, 2), + .write = ad5446_write, + }, + [ID_AD5446] = { + .channel = AD5446_CHANNEL(14, 16, 0), + .write = ad5446_write, + }, + [ID_AD5450] = { + .channel = AD5446_CHANNEL(8, 16, 6), + .write = ad5446_write, + }, + [ID_AD5451] = { + .channel = AD5446_CHANNEL(10, 16, 4), + .write = ad5446_write, + }, + [ID_AD5541A] = { + .channel = AD5446_CHANNEL(16, 16, 0), + .write = ad5446_write, + }, + [ID_AD5512A] = { + .channel = AD5446_CHANNEL(12, 16, 4), + .write = ad5446_write, + }, + [ID_AD5553] = { + .channel = AD5446_CHANNEL(14, 16, 0), + .write = ad5446_write, + }, + [ID_AD5601] = { + .channel = AD5446_CHANNEL_POWERDOWN(8, 16, 6), + .write = ad5446_write, + }, + [ID_AD5611] = { + .channel = AD5446_CHANNEL_POWERDOWN(10, 16, 4), + .write = ad5446_write, + }, + [ID_AD5621] = { + .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2), + .write = ad5446_write, + }, + [ID_AD5620_2500] = { + .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2), + .int_vref_mv = 2500, + .write = ad5446_write, + }, + [ID_AD5620_1250] = { + .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2), + .int_vref_mv = 1250, + .write = ad5446_write, + }, + [ID_AD5640_2500] = { + .channel = AD5446_CHANNEL_POWERDOWN(14, 16, 0), + .int_vref_mv = 2500, + .write = ad5446_write, + }, + [ID_AD5640_1250] = { + .channel = AD5446_CHANNEL_POWERDOWN(14, 16, 0), + .int_vref_mv = 1250, + .write = ad5446_write, + }, + [ID_AD5660_2500] = { + .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0), + .int_vref_mv = 2500, + .write = ad5660_write, + }, + [ID_AD5660_1250] = { + .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0), + .int_vref_mv = 1250, + .write = ad5660_write, + }, + [ID_AD5662] = { + .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0), + .write = ad5660_write, + }, +}; + +static const struct spi_device_id ad5446_spi_ids[] = { {"ad5444", ID_AD5444}, {"ad5446", ID_AD5446}, {"ad5450", ID_AD5450}, @@ -375,18 +408,157 @@ static const struct spi_device_id ad5446_id[] = { {"ad5662", ID_AD5662}, {} }; -MODULE_DEVICE_TABLE(spi, ad5446_id); +MODULE_DEVICE_TABLE(spi, ad5446_spi_ids); + +static int __devinit ad5446_spi_probe(struct spi_device *spi) +{ + const struct spi_device_id *id = spi_get_device_id(spi); + + return ad5446_probe(&spi->dev, id->name, + &ad5446_spi_chip_info[id->driver_data]); +} -static struct spi_driver ad5446_driver = { +static int __devexit ad5446_spi_remove(struct spi_device *spi) +{ + return ad5446_remove(&spi->dev); +} + +static struct spi_driver ad5446_spi_driver = { .driver = { .name = "ad5446", .owner = THIS_MODULE, }, - .probe = ad5446_probe, - .remove = __devexit_p(ad5446_remove), - .id_table = ad5446_id, + .probe = ad5446_spi_probe, + .remove = __devexit_p(ad5446_spi_remove), + .id_table = ad5446_spi_ids, +}; + +static int __init ad5446_spi_register_driver(void) +{ + return spi_register_driver(&ad5446_spi_driver); +} + +static void ad5446_spi_unregister_driver(void) +{ + spi_unregister_driver(&ad5446_spi_driver); +} + +#else + +static inline int ad5446_spi_register_driver(void) { return 0; } +static inline void ad5446_spi_unregister_driver(void) { } + +#endif + +#if IS_ENABLED(CONFIG_I2C) + +static int ad5622_write(struct ad5446_state *st, unsigned val) +{ + struct i2c_client *client = to_i2c_client(st->dev); + __be16 data = cpu_to_be16(val); + + return i2c_master_send(client, (char *)&data, sizeof(data)); +} + +/** + * ad5446_supported_i2c_device_ids: + * The AD5620/40/60 parts are available in different fixed internal reference + * voltage options. The actual part numbers may look differently + * (and a bit cryptic), however this style is used to make clear which + * parts are supported here. + */ +enum ad5446_supported_i2c_device_ids { + ID_AD5602, + ID_AD5612, + ID_AD5622, +}; + +static const struct ad5446_chip_info ad5446_i2c_chip_info[] = { + [ID_AD5602] = { + .channel = AD5446_CHANNEL_POWERDOWN(8, 16, 4), + .write = ad5622_write, + }, + [ID_AD5612] = { + .channel = AD5446_CHANNEL_POWERDOWN(10, 16, 2), + .write = ad5622_write, + }, + [ID_AD5622] = { + .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 0), + .write = ad5622_write, + }, }; -module_spi_driver(ad5446_driver); + +static int __devinit ad5446_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + return ad5446_probe(&i2c->dev, id->name, + &ad5446_i2c_chip_info[id->driver_data]); +} + +static int __devexit ad5446_i2c_remove(struct i2c_client *i2c) +{ + return ad5446_remove(&i2c->dev); +} + +static const struct i2c_device_id ad5446_i2c_ids[] = { + {"ad5602", ID_AD5602}, + {"ad5612", ID_AD5612}, + {"ad5622", ID_AD5622}, + {} +}; +MODULE_DEVICE_TABLE(i2c, ad5446_i2c_ids); + +static struct i2c_driver ad5446_i2c_driver = { + .driver = { + .name = "ad5446", + .owner = THIS_MODULE, + }, + .probe = ad5446_i2c_probe, + .remove = __devexit_p(ad5446_i2c_remove), + .id_table = ad5446_i2c_ids, +}; + +static int __init ad5446_i2c_register_driver(void) +{ + return i2c_add_driver(&ad5446_i2c_driver); +} + +static void __exit ad5446_i2c_unregister_driver(void) +{ + i2c_del_driver(&ad5446_i2c_driver); +} + +#else + +static inline int ad5446_i2c_register_driver(void) { return 0; } +static inline void ad5446_i2c_unregister_driver(void) { } + +#endif + +static int __init ad5446_init(void) +{ + int ret; + + ret = ad5446_spi_register_driver(); + if (ret) + return ret; + + ret = ad5446_i2c_register_driver(); + if (ret) { + ad5446_spi_unregister_driver(); + return ret; + } + + return 0; +} +module_init(ad5446_init); + +static void __exit ad5446_exit(void) +{ + ad5446_i2c_unregister_driver(); + ad5446_spi_unregister_driver(); +} +module_exit(ad5446_exit); MODULE_AUTHOR("Michael Hennerich "); MODULE_DESCRIPTION("Analog Devices AD5444/AD5446 DAC"); diff --git a/drivers/iio/dac/ad5446.h b/drivers/iio/dac/ad5446.h index 2934269..6b7a176 100644 --- a/drivers/iio/dac/ad5446.h +++ b/drivers/iio/dac/ad5446.h @@ -38,7 +38,7 @@ */ struct ad5446_state { - struct spi_device *spi; + struct device *dev; const struct ad5446_chip_info *chip_info; struct regulator *reg; unsigned short vref_mv; @@ -60,32 +60,5 @@ struct ad5446_chip_info { int (*write)(struct ad5446_state *st, unsigned val); }; -/** - * ad5446_supported_device_ids: - * The AD5620/40/60 parts are available in different fixed internal reference - * voltage options. The actual part numbers may look differently - * (and a bit cryptic), however this style is used to make clear which - * parts are supported here. - */ - -enum ad5446_supported_device_ids { - ID_AD5444, - ID_AD5446, - ID_AD5450, - ID_AD5451, - ID_AD5541A, - ID_AD5512A, - ID_AD5553, - ID_AD5601, - ID_AD5611, - ID_AD5621, - ID_AD5620_2500, - ID_AD5620_1250, - ID_AD5640_2500, - ID_AD5640_1250, - ID_AD5660_2500, - ID_AD5660_1250, - ID_AD5662, -}; #endif /* IIO_DAC_AD5446_H_ */ -- cgit v0.10.2 From 2e15c903c1e6238735775b9ce491fa4f942cd5fc Mon Sep 17 00:00:00 2001 From: Jean-Francois Dagenais Date: Tue, 21 Aug 2012 15:28:00 +0100 Subject: iio:ad5446: get rid of private header file Most of the defines in there were not even used, and the structs left are private to the .c file. Makes the driver more in line with most of the kernel drivers. Signed-off-by: Jean-Francois Dagenais Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/dac/ad5446.c b/drivers/iio/dac/ad5446.c index 241665b..7f11c1c 100644 --- a/drivers/iio/dac/ad5446.c +++ b/drivers/iio/dac/ad5446.c @@ -22,7 +22,40 @@ #include #include -#include "ad5446.h" +#define MODE_PWRDWN_1k 0x1 +#define MODE_PWRDWN_100k 0x2 +#define MODE_PWRDWN_TRISTATE 0x3 + +/** + * struct ad5446_state - driver instance specific data + * @spi: spi_device + * @chip_info: chip model specific constants, available modes etc + * @reg: supply regulator + * @vref_mv: actual reference voltage used + */ + +struct ad5446_state { + struct device *dev; + const struct ad5446_chip_info *chip_info; + struct regulator *reg; + unsigned short vref_mv; + unsigned cached_val; + unsigned pwr_down_mode; + unsigned pwr_down; +}; + +/** + * struct ad5446_chip_info - chip specific information + * @channel: channel spec for the DAC + * @int_vref_mv: AD5620/40/60: the internal reference voltage + * @write: chip specific helper function to write to the register + */ + +struct ad5446_chip_info { + struct iio_chan_spec channel; + u16 int_vref_mv; + int (*write)(struct ad5446_state *st, unsigned val); +}; static const char * const ad5446_powerdown_modes[] = { "1kohm_to_gnd", "100kohm_to_gnd", "three_state" diff --git a/drivers/iio/dac/ad5446.h b/drivers/iio/dac/ad5446.h deleted file mode 100644 index 6b7a176..0000000 --- a/drivers/iio/dac/ad5446.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * AD5446 SPI DAC driver - * - * Copyright 2010 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ -#ifndef IIO_DAC_AD5446_H_ -#define IIO_DAC_AD5446_H_ - -/* DAC Control Bits */ - -#define AD5446_LOAD (0x0 << 14) /* Load and update */ -#define AD5446_SDO_DIS (0x1 << 14) /* Disable SDO */ -#define AD5446_NOP (0x2 << 14) /* No operation */ -#define AD5446_CLK_RISING (0x3 << 14) /* Clock data on rising edge */ - -#define AD5620_LOAD (0x0 << 14) /* Load and update Norm Operation*/ -#define AD5620_PWRDWN_1k (0x1 << 14) /* Power-down: 1kOhm to GND */ -#define AD5620_PWRDWN_100k (0x2 << 14) /* Power-down: 100kOhm to GND */ -#define AD5620_PWRDWN_TRISTATE (0x3 << 14) /* Power-down: Three-state */ - -#define AD5660_LOAD (0x0 << 16) /* Load and update Norm Operation*/ -#define AD5660_PWRDWN_1k (0x1 << 16) /* Power-down: 1kOhm to GND */ -#define AD5660_PWRDWN_100k (0x2 << 16) /* Power-down: 100kOhm to GND */ -#define AD5660_PWRDWN_TRISTATE (0x3 << 16) /* Power-down: Three-state */ - -#define MODE_PWRDWN_1k 0x1 -#define MODE_PWRDWN_100k 0x2 -#define MODE_PWRDWN_TRISTATE 0x3 - -/** - * struct ad5446_state - driver instance specific data - * @spi: spi_device - * @chip_info: chip model specific constants, available modes etc - * @reg: supply regulator - * @vref_mv: actual reference voltage used - */ - -struct ad5446_state { - struct device *dev; - const struct ad5446_chip_info *chip_info; - struct regulator *reg; - unsigned short vref_mv; - unsigned cached_val; - unsigned pwr_down_mode; - unsigned pwr_down; -}; - -/** - * struct ad5446_chip_info - chip specific information - * @channel: channel spec for the DAC - * @int_vref_mv: AD5620/40/60: the internal reference voltage - * @write: chip specific helper function to write to the register - */ - -struct ad5446_chip_info { - struct iio_chan_spec channel; - u16 int_vref_mv; - int (*write)(struct ad5446_state *st, unsigned val); -}; - - -#endif /* IIO_DAC_AD5446_H_ */ -- cgit v0.10.2 From c8b95952e7ad2ff850153a12f090f810bf90f27c Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 2 Sep 2012 21:27:56 +0100 Subject: IIO: Update email address for Jonathan Cameron. Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index a288792..fa3b9f5 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -980,6 +980,6 @@ EXPORT_SYMBOL(iio_device_unregister); subsys_initcall(iio_init); module_exit(iio_exit); -MODULE_AUTHOR("Jonathan Cameron "); +MODULE_AUTHOR("Jonathan Cameron "); MODULE_DESCRIPTION("Industrial I/O core"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 0f8c9620046d698b8a00d38d25dcdc1d2fa23592 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 2 Sep 2012 21:34:59 +0100 Subject: staging:iio: Update email address for Jonathan Cameron. Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/TODO b/drivers/staging/iio/TODO index cf3f948..04c2326 100644 --- a/drivers/staging/iio/TODO +++ b/drivers/staging/iio/TODO @@ -69,5 +69,5 @@ Documentation 1) Lots of cleanup and expansion. 2) Some device require individual docs. -Contact: Jonathan Cameron . +Contact: Jonathan Cameron . Mailing list: linux-iio@vger.kernel.org diff --git a/drivers/staging/iio/accel/kxsd9.c b/drivers/staging/iio/accel/kxsd9.c index 713469f..fdd5fbd 100644 --- a/drivers/staging/iio/accel/kxsd9.c +++ b/drivers/staging/iio/accel/kxsd9.c @@ -2,7 +2,7 @@ * kxsd9.c simple support for the Kionix KXSD9 3D * accelerometer. * - * Copyright (c) 2008-2009 Jonathan Cameron + * Copyright (c) 2008-2009 Jonathan Cameron * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -286,6 +286,6 @@ static struct spi_driver kxsd9_driver = { }; module_spi_driver(kxsd9_driver); -MODULE_AUTHOR("Jonathan Cameron "); +MODULE_AUTHOR("Jonathan Cameron "); MODULE_DESCRIPTION("Kionix KXSD9 SPI driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/accel/lis3l02dq.h b/drivers/staging/iio/accel/lis3l02dq.h index ad51658..f9bcd41 100644 --- a/drivers/staging/iio/accel/lis3l02dq.h +++ b/drivers/staging/iio/accel/lis3l02dq.h @@ -2,7 +2,7 @@ * LISL02DQ.h -- support STMicroelectronics LISD02DQ * 3d 2g Linear Accelerometers via SPI * - * Copyright (c) 2007 Jonathan Cameron + * Copyright (c) 2007 Jonathan Cameron * * Loosely based upon tle62x0.c * diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c index 0144afe..d900d63 100644 --- a/drivers/staging/iio/accel/lis3l02dq_core.c +++ b/drivers/staging/iio/accel/lis3l02dq_core.c @@ -2,7 +2,7 @@ * lis3l02dq.c support STMicroelectronics LISD02DQ * 3d 2g Linear Accelerometers via SPI * - * Copyright (c) 2007 Jonathan Cameron + * Copyright (c) 2007 Jonathan Cameron * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -818,7 +818,7 @@ static struct spi_driver lis3l02dq_driver = { }; module_spi_driver(lis3l02dq_driver); -MODULE_AUTHOR("Jonathan Cameron "); +MODULE_AUTHOR("Jonathan Cameron "); MODULE_DESCRIPTION("ST LIS3L02DQ Accelerometer SPI driver"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("spi:lis3l02dq"); diff --git a/drivers/staging/iio/accel/sca3000.h b/drivers/staging/iio/accel/sca3000.h index 131daac..c1016c5 100644 --- a/drivers/staging/iio/accel/sca3000.h +++ b/drivers/staging/iio/accel/sca3000.h @@ -2,7 +2,7 @@ * sca3000.c -- support VTI sca3000 series accelerometers * via SPI * - * Copyright (c) 2007 Jonathan Cameron + * Copyright (c) 2007 Jonathan Cameron * * Partly based upon tle62x0.c * diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c index 581cdbd..6d72d97 100644 --- a/drivers/staging/iio/accel/sca3000_core.c +++ b/drivers/staging/iio/accel/sca3000_core.c @@ -5,7 +5,7 @@ * under the terms of the GNU General Public License version 2 as published by * the Free Software Foundation. * - * Copyright (c) 2009 Jonathan Cameron + * Copyright (c) 2009 Jonathan Cameron * * See industrialio/accels/sca3000.h for comments. */ @@ -1272,6 +1272,6 @@ static struct spi_driver sca3000_driver = { }; module_spi_driver(sca3000_driver); -MODULE_AUTHOR("Jonathan Cameron "); +MODULE_AUTHOR("Jonathan Cameron "); MODULE_DESCRIPTION("VTI SCA3000 Series Accelerometers SPI driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c index b7e1a00..cbec2f1 100644 --- a/drivers/staging/iio/accel/sca3000_ring.c +++ b/drivers/staging/iio/accel/sca3000_ring.c @@ -5,7 +5,7 @@ * under the terms of the GNU General Public License version 2 as published by * the Free Software Foundation. * - * Copyright (c) 2009 Jonathan Cameron + * Copyright (c) 2009 Jonathan Cameron * */ diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c index adb90fe..d7b4ffc 100644 --- a/drivers/staging/iio/adc/max1363_core.c +++ b/drivers/staging/iio/adc/max1363_core.c @@ -1439,6 +1439,6 @@ static struct i2c_driver max1363_driver = { }; module_i2c_driver(max1363_driver); -MODULE_AUTHOR("Jonathan Cameron "); +MODULE_AUTHOR("Jonathan Cameron "); MODULE_DESCRIPTION("Maxim 1363 ADC"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/iio_dummy_evgen.c b/drivers/staging/iio/iio_dummy_evgen.c index 0cd4fe9..74e24e8 100644 --- a/drivers/staging/iio/iio_dummy_evgen.c +++ b/drivers/staging/iio/iio_dummy_evgen.c @@ -216,6 +216,6 @@ static __exit void iio_dummy_evgen_exit(void) } module_exit(iio_dummy_evgen_exit); -MODULE_AUTHOR("Jonathan Cameron "); +MODULE_AUTHOR("Jonathan Cameron "); MODULE_DESCRIPTION("IIO dummy driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/iio_hwmon.c b/drivers/staging/iio/iio_hwmon.c index 4bb017a..69d4a3b 100644 --- a/drivers/staging/iio/iio_hwmon.c +++ b/drivers/staging/iio/iio_hwmon.c @@ -217,6 +217,6 @@ static struct platform_driver __refdata iio_hwmon_driver = { module_platform_driver(iio_hwmon_driver); -MODULE_AUTHOR("Jonathan Cameron "); +MODULE_AUTHOR("Jonathan Cameron "); MODULE_DESCRIPTION("IIO to hwmon driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/iio_simple_dummy.c b/drivers/staging/iio/iio_simple_dummy.c index 22eea83..029bcc6 100644 --- a/drivers/staging/iio/iio_simple_dummy.c +++ b/drivers/staging/iio/iio_simple_dummy.c @@ -558,6 +558,6 @@ static __exit void iio_dummy_exit(void) } module_exit(iio_dummy_exit); -MODULE_AUTHOR("Jonathan Cameron "); +MODULE_AUTHOR("Jonathan Cameron "); MODULE_DESCRIPTION("IIO dummy driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/imu/adis16400.h b/drivers/staging/iio/imu/adis16400.h index 9dd9f14..d59d7ac 100644 --- a/drivers/staging/iio/imu/adis16400.h +++ b/drivers/staging/iio/imu/adis16400.h @@ -5,7 +5,7 @@ * 3d 2.5gauss magnetometers via SPI * * Copyright (c) 2009 Manuel Stahl - * Copyright (c) 2007 Jonathan Cameron + * Copyright (c) 2007 Jonathan Cameron * * Loosely based upon lis3l02dq.h * diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c index b9f8438..5397497 100644 --- a/drivers/staging/iio/imu/adis16400_core.c +++ b/drivers/staging/iio/imu/adis16400_core.c @@ -5,7 +5,7 @@ * 3d Magnetometers via SPI * * Copyright (c) 2009 Manuel Stahl - * Copyright (c) 2007 Jonathan Cameron + * Copyright (c) 2007 Jonathan Cameron * Copyright (c) 2011 Analog Devices Inc. * * This program is free software; you can redistribute it and/or modify diff --git a/drivers/staging/iio/magnetometer/hmc5843.c b/drivers/staging/iio/magnetometer/hmc5843.c index 6c3e50f..10e0954 100644 --- a/drivers/staging/iio/magnetometer/hmc5843.c +++ b/drivers/staging/iio/magnetometer/hmc5843.c @@ -1,6 +1,6 @@ /* Copyright (C) 2010 Texas Instruments Author: Shubhrajyoti Datta - Acknowledgement: Jonathan Cameron for valuable inputs. + Acknowledgement: Jonathan Cameron for valuable inputs. Support for HMC5883 and HMC5883L by Peter Meerwald . diff --git a/drivers/staging/iio/ring_hw.h b/drivers/staging/iio/ring_hw.h index cad8a2e..39c14a7 100644 --- a/drivers/staging/iio/ring_hw.h +++ b/drivers/staging/iio/ring_hw.h @@ -5,7 +5,7 @@ * under the terms of the GNU General Public License version 2 as published by * the Free Software Foundation. * - * Copyright (c) 2009 Jonathan Cameron + * Copyright (c) 2009 Jonathan Cameron * */ diff --git a/drivers/staging/iio/trigger/iio-trig-gpio.c b/drivers/staging/iio/trigger/iio-trig-gpio.c index de26d54..5ff4d7f 100644 --- a/drivers/staging/iio/trigger/iio-trig-gpio.c +++ b/drivers/staging/iio/trigger/iio-trig-gpio.c @@ -162,6 +162,6 @@ static struct platform_driver iio_gpio_trigger_driver = { module_platform_driver(iio_gpio_trigger_driver); -MODULE_AUTHOR("Jonathan Cameron "); +MODULE_AUTHOR("Jonathan Cameron "); MODULE_DESCRIPTION("Example gpio trigger for the iio subsystem"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c index b837801..a3de76d 100644 --- a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c +++ b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c @@ -197,6 +197,6 @@ static struct platform_driver iio_trig_periodic_rtc_driver = { module_platform_driver(iio_trig_periodic_rtc_driver); -MODULE_AUTHOR("Jonathan Cameron "); +MODULE_AUTHOR("Jonathan Cameron "); MODULE_DESCRIPTION("Periodic realtime clock trigger for the iio subsystem"); MODULE_LICENSE("GPL v2"); -- cgit v0.10.2 From 07ad99c9e32173852997523eb920950902563941 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sun, 26 Aug 2012 02:52:35 +0530 Subject: staging: gdm72xx: use kzalloc to allocate usb_tx structure the code under alloc_tx_struct does the allocation of usb_tx structure using kmalloc, and memsets the allocated pointer, instead we can directly use kzalloc so that the allocated memory is set with zeros Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/gdm72xx/gdm_sdio.c b/drivers/staging/gdm72xx/gdm_sdio.c index 3e43c01..ec64d94 100644 --- a/drivers/staging/gdm72xx/gdm_sdio.c +++ b/drivers/staging/gdm72xx/gdm_sdio.c @@ -62,12 +62,10 @@ static struct sdio_tx *alloc_tx_struct(struct tx_cxt *tx) { struct sdio_tx *t = NULL; - t = kmalloc(sizeof(*t), GFP_ATOMIC); + t = kzalloc(sizeof(*t), GFP_ATOMIC); if (t == NULL) goto out; - memset(t, 0, sizeof(*t)); - t->buf = kmalloc(TX_BUF_SIZE, GFP_ATOMIC); if (t->buf == NULL) goto out; diff --git a/drivers/staging/gdm72xx/gdm_usb.c b/drivers/staging/gdm72xx/gdm_usb.c index d48d49c..c7a22fa 100644 --- a/drivers/staging/gdm72xx/gdm_usb.c +++ b/drivers/staging/gdm72xx/gdm_usb.c @@ -75,12 +75,10 @@ static struct usb_tx *alloc_tx_struct(struct tx_cxt *tx) { struct usb_tx *t = NULL; - t = kmalloc(sizeof(*t), GFP_ATOMIC); + t = kzalloc(sizeof(*t), GFP_ATOMIC); if (t == NULL) goto out; - memset(t, 0, sizeof(*t)); - t->urb = usb_alloc_urb(0, GFP_ATOMIC); t->buf = kmalloc(TX_BUF_SIZE, GFP_ATOMIC); if (t->urb == NULL || t->buf == NULL) -- cgit v0.10.2 From f1efd9fe08a9ada843cd99f949a130555df045bd Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 4 Sep 2012 16:04:36 +0100 Subject: staging: gdm72xx: Fix bogus test Test the return as we should Resolves-bug: https://bugzilla.kernel.org/show_bug.cgi?id=46921 Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/gdm72xx/gdm_sdio.c b/drivers/staging/gdm72xx/gdm_sdio.c index ec64d94..f824290 100644 --- a/drivers/staging/gdm72xx/gdm_sdio.c +++ b/drivers/staging/gdm72xx/gdm_sdio.c @@ -678,7 +678,7 @@ static int sdio_wimax_probe(struct sdio_func *func, phy_dev->rcv_func = gdm_sdio_receive; ret = init_sdio(sdev); - if (sdev < 0) + if (ret < 0) goto out; sdev->func = func; -- cgit v0.10.2 From f5f9a3ff04feb6851bcfbb278c506d74037e54b9 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 17 Aug 2012 18:05:01 -0700 Subject: staging: comedi: adv_pci1710: remove function trace messages The macros PCI171X_EXTDEBUG and DPRINTK enable a number of function trace messages. These trace messages should not be in the final driver. Remove them. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 6b4d0d6..7c4f0de 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -52,17 +52,8 @@ Configuration options: * correct channel number on every 12 bit * sample */ -#undef PCI171X_EXTDEBUG - #define DRV_NAME "adv_pci1710" -#undef DPRINTK -#ifdef PCI171X_EXTDEBUG -#define DPRINTK(fmt, args...) printk(fmt, ## args) -#else -#define DPRINTK(fmt, args...) -#endif - #define PCI_VENDOR_ID_ADVANTECH 0x13fe /* hardware types of the cards */ @@ -318,7 +309,6 @@ static int pci171x_insn_read_ai(struct comedi_device *dev, unsigned int idata; #endif - DPRINTK("adv_pci1710 EDBG: BGN: pci171x_insn_read_ai(...)\n"); devpriv->CntrlReg &= Control_CNT0; devpriv->CntrlReg |= Control_SW; /* set software trigger */ outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL); @@ -327,32 +317,18 @@ static int pci171x_insn_read_ai(struct comedi_device *dev, setup_channel_list(dev, s, &insn->chanspec, 1, 1); - DPRINTK("adv_pci1710 A ST=%4x IO=%x\n", - inw(dev->iobase + PCI171x_STATUS), - dev->iobase + PCI171x_STATUS); for (n = 0; n < insn->n; n++) { outw(0, dev->iobase + PCI171x_SOFTTRG); /* start conversion */ - DPRINTK("adv_pci1710 B n=%d ST=%4x\n", n, - inw(dev->iobase + PCI171x_STATUS)); /* udelay(1); */ - DPRINTK("adv_pci1710 C n=%d ST=%4x\n", n, - inw(dev->iobase + PCI171x_STATUS)); timeout = 100; while (timeout--) { if (!(inw(dev->iobase + PCI171x_STATUS) & Status_FE)) goto conv_finish; - if (!(timeout % 10)) - DPRINTK("adv_pci1710 D n=%d tm=%d ST=%4x\n", n, - timeout, - inw(dev->iobase + PCI171x_STATUS)); } comedi_error(dev, "A/D insn timeout"); outb(0, dev->iobase + PCI171x_CLRFIFO); outb(0, dev->iobase + PCI171x_CLRINT); data[n] = 0; - DPRINTK - ("adv_pci1710 EDBG: END: pci171x_insn_read_ai(...) n=%d\n", - n); return -ETIME; conv_finish: @@ -373,7 +349,6 @@ conv_finish: outb(0, dev->iobase + PCI171x_CLRFIFO); outb(0, dev->iobase + PCI171x_CLRINT); - DPRINTK("adv_pci1710 EDBG: END: pci171x_insn_read_ai(...) n=%d\n", n); return n; } @@ -584,7 +559,6 @@ static void interrupt_pci1710_every_sample(void *d) short sampl; #endif - DPRINTK("adv_pci1710 EDBG: BGN: interrupt_pci1710_every_sample(...)\n"); m = inw(dev->iobase + PCI171x_STATUS); if (m & Status_FE) { printk("comedi%d: A/D FIFO empty (%4x)\n", dev->minor, m); @@ -605,11 +579,9 @@ static void interrupt_pci1710_every_sample(void *d) outb(0, dev->iobase + PCI171x_CLRINT); /* clear our INT request */ - DPRINTK("FOR "); for (; !(inw(dev->iobase + PCI171x_STATUS) & Status_FE);) { #ifdef PCI171x_PARANOIDCHECK sampl = inw(dev->iobase + PCI171x_AD_DATA); - DPRINTK("%04x:", sampl); if (this_board->cardtype != TYPE_PCI1713) if ((sampl & 0xf000) != devpriv->act_chanlist[s->async->cur_chan]) { @@ -626,8 +598,6 @@ static void interrupt_pci1710_every_sample(void *d) comedi_event(dev, s); return; } - DPRINTK("%8d %2d %8d~", s->async->buf_int_ptr, - s->async->cur_chan, s->async->buf_int_count); comedi_buf_put(s->async, sampl & 0x0fff); #else comedi_buf_put(s->async, @@ -641,11 +611,6 @@ static void interrupt_pci1710_every_sample(void *d) if (s->async->cur_chan == 0) { /* one scan done */ devpriv->ai_act_scan++; - DPRINTK - ("adv_pci1710 EDBG: EOS1 bic %d bip %d buc %d bup %d\n", - s->async->buf_int_count, s->async->buf_int_ptr, - s->async->buf_user_count, s->async->buf_user_ptr); - DPRINTK("adv_pci1710 EDBG: EOS2\n"); if ((!devpriv->neverending_ai) && (devpriv->ai_act_scan >= devpriv->ai_scans)) { /* all data sampled */ @@ -658,7 +623,6 @@ static void interrupt_pci1710_every_sample(void *d) } outb(0, dev->iobase + PCI171x_CLRINT); /* clear our INT request */ - DPRINTK("adv_pci1710 EDBG: END: interrupt_pci1710_every_sample(...)\n"); comedi_event(dev, s); } @@ -673,8 +637,7 @@ static int move_block_from_fifo(struct comedi_device *dev, #ifdef PCI171x_PARANOIDCHECK int sampl; #endif - DPRINTK("adv_pci1710 EDBG: BGN: move_block_from_fifo(...,%d,%d)\n", n, - turn); + j = s->async->cur_chan; for (i = 0; i < n; i++) { #ifdef PCI171x_PARANOIDCHECK @@ -705,7 +668,6 @@ static int move_block_from_fifo(struct comedi_device *dev, } } s->async->cur_chan = j; - DPRINTK("adv_pci1710 EDBG: END: move_block_from_fifo(...)\n"); return 0; } @@ -718,7 +680,6 @@ static void interrupt_pci1710_half_fifo(void *d) struct comedi_subdevice *s = dev->subdevices + 0; int m, samplesinbuf; - DPRINTK("adv_pci1710 EDBG: BGN: interrupt_pci1710_half_fifo(...)\n"); m = inw(dev->iobase + PCI171x_STATUS); if (!(m & Status_FH)) { printk("comedi%d: A/D FIFO not half full! (%4x)\n", @@ -760,7 +721,6 @@ static void interrupt_pci1710_half_fifo(void *d) return; } outb(0, dev->iobase + PCI171x_CLRINT); /* clear our INT request */ - DPRINTK("adv_pci1710 EDBG: END: interrupt_pci1710_half_fifo(...)\n"); comedi_event(dev, s); } @@ -772,17 +732,12 @@ static irqreturn_t interrupt_service_pci1710(int irq, void *d) { struct comedi_device *dev = d; - DPRINTK("adv_pci1710 EDBG: BGN: interrupt_service_pci1710(%d,...)\n", - irq); if (!dev->attached) /* is device attached? */ return IRQ_NONE; /* no, exit */ /* is this interrupt from our board? */ if (!(inw(dev->iobase + PCI171x_STATUS) & Status_IRQ)) return IRQ_NONE; /* no, exit */ - DPRINTK("adv_pci1710 EDBG: interrupt_service_pci1710() ST: %4x\n", - inw(dev->iobase + PCI171x_STATUS)); - if (devpriv->ai_et) { /* Switch from initial TRIG_EXT to TRIG_xxx. */ devpriv->ai_et = 0; devpriv->CntrlReg &= Control_CNT0; @@ -802,7 +757,6 @@ static irqreturn_t interrupt_service_pci1710(int irq, void *d) } else { interrupt_pci1710_half_fifo(d); } - DPRINTK("adv_pci1710 EDBG: END: interrupt_service_pci1710(...)\n"); return IRQ_HANDLED; } @@ -815,8 +769,6 @@ static int pci171x_ai_docmd_and_mode(int mode, struct comedi_device *dev, unsigned int divisor1 = 0, divisor2 = 0; unsigned int seglen; - DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_docmd_and_mode(%d,...)\n", - mode); start_pacer(dev, -1, 0, 0); /* stop pacer */ seglen = check_channel_list(dev, s, devpriv->ai_chanlist, @@ -869,10 +821,6 @@ static int pci171x_ai_docmd_and_mode(int mode, struct comedi_device *dev, i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1, &divisor2, &devpriv->ai_timer1, devpriv->ai_flags & TRIG_ROUND_MASK); - DPRINTK - ("adv_pci1710 EDBG: OSC base=%u div1=%u div2=%u timer=%u\n", - devpriv->i8254_osc_base, divisor1, divisor2, - devpriv->ai_timer1); outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL); if (mode != 2) { /* start pacer */ @@ -888,27 +836,9 @@ static int pci171x_ai_docmd_and_mode(int mode, struct comedi_device *dev, break; } - DPRINTK("adv_pci1710 EDBG: END: pci171x_ai_docmd_and_mode(...)\n"); return 0; } -#ifdef PCI171X_EXTDEBUG -/* -============================================================================== -*/ -static void pci171x_cmdtest_out(int e, struct comedi_cmd *cmd) -{ - printk("adv_pci1710 e=%d startsrc=%x scansrc=%x convsrc=%x\n", e, - cmd->start_src, cmd->scan_begin_src, cmd->convert_src); - printk("adv_pci1710 e=%d startarg=%d scanarg=%d convarg=%d\n", e, - cmd->start_arg, cmd->scan_begin_arg, cmd->convert_arg); - printk("adv_pci1710 e=%d stopsrc=%x scanend=%x\n", e, cmd->stop_src, - cmd->scan_end_src); - printk("adv_pci1710 e=%d stoparg=%d scanendarg=%d chanlistlen=%d\n", - e, cmd->stop_arg, cmd->scan_end_arg, cmd->chanlist_len); -} -#endif - /* ============================================================================== */ @@ -920,10 +850,6 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, int tmp; unsigned int divisor1 = 0, divisor2 = 0; - DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...)\n"); -#ifdef PCI171X_EXTDEBUG - pci171x_cmdtest_out(-1, cmd); -#endif /* step 1: make sure trigger sources are trivially valid */ tmp = cmd->start_src; @@ -951,15 +877,8 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, if (!cmd->stop_src || tmp != cmd->stop_src) err++; - if (err) { -#ifdef PCI171X_EXTDEBUG - pci171x_cmdtest_out(1, cmd); -#endif - DPRINTK( - "adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=1\n", - err); + if (err) return 1; - } /* step2: make sure trigger srcs are unique and mutually compatible */ @@ -984,15 +903,8 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT) err++; - if (err) { -#ifdef PCI171X_EXTDEBUG - pci171x_cmdtest_out(2, cmd); -#endif - DPRINTK( - "adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=2\n", - err); + if (err) return 2; - } /* step 3: make sure arguments are trivially compatible */ @@ -1034,15 +946,8 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, } } - if (err) { -#ifdef PCI171X_EXTDEBUG - pci171x_cmdtest_out(3, cmd); -#endif - DPRINTK( - "adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=3\n", - err); + if (err) return 3; - } /* step 4: fix up any arguments */ @@ -1057,12 +962,8 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, err++; } - if (err) { - DPRINTK - ("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=4\n", - err); + if (err) return 4; - } /* step 5: complain about special chanlist considerations */ @@ -1072,7 +973,6 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, return 5; /* incorrect channels list */ } - DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) ret=0\n"); return 0; } @@ -1083,7 +983,6 @@ static int pci171x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { struct comedi_cmd *cmd = &s->async->cmd; - DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmd(...)\n"); devpriv->ai_n_chan = cmd->chanlist_len; devpriv->ai_chanlist = cmd->chanlist; devpriv->ai_flags = cmd->flags; @@ -1126,7 +1025,6 @@ static int check_channel_list(struct comedi_device *dev, unsigned int chansegment[32]; unsigned int i, nowmustbechan, seglen, segpos; - DPRINTK("adv_pci1710 EDBG: check_channel_list(...,%d)\n", n_chan); /* correct channel and range number check itself comedi/range.c */ if (n_chan < 1) { comedi_error(dev, "range/channel list is empty!"); @@ -1179,12 +1077,9 @@ static void setup_channel_list(struct comedi_device *dev, { unsigned int i, range, chanprog; - DPRINTK("adv_pci1710 EDBG: setup_channel_list(...,%d,%d)\n", n_chan, - seglen); devpriv->act_chanlist_len = seglen; devpriv->act_chanlist_pos = 0; - DPRINTK("SegLen: %d\n", seglen); for (i = 0; i < seglen; i++) { /* store range list to card */ chanprog = muxonechan[CR_CHAN(chanlist[i])]; outw(chanprog, dev->iobase + PCI171x_MUX); /* select channel */ @@ -1196,8 +1091,6 @@ static void setup_channel_list(struct comedi_device *dev, devpriv->act_chanlist[i] = (CR_CHAN(chanlist[i]) << 12) & 0xf000; #endif - DPRINTK("GS: %2d. [%4x]=%4x %4x\n", i, chanprog, range, - devpriv->act_chanlist[i]); } #ifdef PCI171x_PARANOIDCHECK for ( ; i < n_chan; i++) { /* store remainder of channel list */ @@ -1210,9 +1103,6 @@ static void setup_channel_list(struct comedi_device *dev, CR_CHAN(chanlist[0]) | (CR_CHAN(chanlist[seglen - 1]) << 8); /* select channel interval to scan */ outw(devpriv->ai_et_MuxVal, dev->iobase + PCI171x_MUX); - DPRINTK("MUX: %4x L%4x.H%4x\n", - CR_CHAN(chanlist[0]) | (CR_CHAN(chanlist[seglen - 1]) << 8), - CR_CHAN(chanlist[0]), CR_CHAN(chanlist[seglen - 1])); } /* @@ -1221,8 +1111,6 @@ static void setup_channel_list(struct comedi_device *dev, static void start_pacer(struct comedi_device *dev, int mode, unsigned int divisor1, unsigned int divisor2) { - DPRINTK("adv_pci1710 EDBG: BGN: start_pacer(%d,%u,%u)\n", mode, - divisor1, divisor2); outw(0xb4, dev->iobase + PCI171x_CNTCTRL); outw(0x74, dev->iobase + PCI171x_CNTCTRL); @@ -1232,7 +1120,6 @@ static void start_pacer(struct comedi_device *dev, int mode, outw(divisor1 & 0xff, dev->iobase + PCI171x_CNT1); outw((divisor1 >> 8) & 0xff, dev->iobase + PCI171x_CNT1); } - DPRINTK("adv_pci1710 EDBG: END: start_pacer(...)\n"); } /* @@ -1241,8 +1128,6 @@ static void start_pacer(struct comedi_device *dev, int mode, static int pci171x_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { - DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cancel(...)\n"); - switch (this_board->cardtype) { default: devpriv->CntrlReg &= Control_CNT0; @@ -1261,7 +1146,6 @@ static int pci171x_ai_cancel(struct comedi_device *dev, devpriv->ai_buf_ptr = 0; devpriv->neverending_ai = 0; - DPRINTK("adv_pci1710 EDBG: END: pci171x_ai_cancel(...)\n"); return 0; } @@ -1270,7 +1154,6 @@ static int pci171x_ai_cancel(struct comedi_device *dev, */ static int pci171x_reset(struct comedi_device *dev) { - DPRINTK("adv_pci1710 EDBG: BGN: pci171x_reset(...)\n"); outw(0x30, dev->iobase + PCI171x_CNTCTRL); devpriv->CntrlReg = Control_SW | Control_CNT0; /* Software trigger, CNT0=external */ outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL); /* reset any operations */ @@ -1291,7 +1174,6 @@ static int pci171x_reset(struct comedi_device *dev) outb(0, dev->iobase + PCI171x_CLRFIFO); /* clear FIFO */ outb(0, dev->iobase + PCI171x_CLRINT); /* clear INT request */ - DPRINTK("adv_pci1710 EDBG: END: pci171x_reset(...)\n"); return 0; } @@ -1300,7 +1182,6 @@ static int pci171x_reset(struct comedi_device *dev) */ static int pci1720_reset(struct comedi_device *dev) { - DPRINTK("adv_pci1710 EDBG: BGN: pci1720_reset(...)\n"); outb(Syncont_SC0, dev->iobase + PCI1720_SYNCONT); /* set synchronous output mode */ devpriv->da_ranges = 0xAA; outb(devpriv->da_ranges, dev->iobase + PCI1720_RANGE); /* set all ranges to +/-5V */ @@ -1313,7 +1194,6 @@ static int pci1720_reset(struct comedi_device *dev) devpriv->ao_data[1] = 0x0800; devpriv->ao_data[2] = 0x0800; devpriv->ao_data[3] = 0x0800; - DPRINTK("adv_pci1710 EDBG: END: pci1720_reset(...)\n"); return 0; } @@ -1322,14 +1202,12 @@ static int pci1720_reset(struct comedi_device *dev) */ static int pci1710_reset(struct comedi_device *dev) { - DPRINTK("adv_pci1710 EDBG: BGN: pci1710_reset(...)\n"); switch (this_board->cardtype) { case TYPE_PCI1720: return pci1720_reset(dev); default: return pci171x_reset(dev); } - DPRINTK("adv_pci1710 EDBG: END: pci1710_reset(...)\n"); } static struct pci_dev *pci1710_find_pci_dev(struct comedi_device *dev, -- cgit v0.10.2 From 6bd65164363ff0e8ea7720f71fedba8bd0eaba9a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 17 Aug 2012 18:05:22 -0700 Subject: staging: comedi: adv_pci1710: remove devpriv and this_board macros These macros rely on a local variable having a specific name. Remove them and use the comedi_board() helper to get the this_board pointer. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 7c4f0de..7f27c59 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -269,9 +269,6 @@ struct pci1710_private { * internal state */ }; -#define devpriv ((struct pci1710_private *)dev->private) -#define this_board ((const struct boardtype *)dev->board_ptr) - /* ============================================================================== */ @@ -304,8 +301,10 @@ static int pci171x_insn_read_ai(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pci1710_private *devpriv = dev->private; int n, timeout; #ifdef PCI171x_PARANOIDCHECK + const struct boardtype *this_board = comedi_board(dev); unsigned int idata; #endif @@ -359,6 +358,7 @@ static int pci171x_insn_write_ao(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pci1710_private *devpriv = dev->private; int n, chan, range, ofs; chan = CR_CHAN(insn->chanspec); @@ -391,6 +391,7 @@ static int pci171x_insn_read_ao(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pci1710_private *devpriv = dev->private; int n, chan; chan = CR_CHAN(insn->chanspec); @@ -461,6 +462,7 @@ static int pci171x_insn_counter_write(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct pci1710_private *devpriv = dev->private; uint msb, lsb, ccntrl, status; lsb = data[0] & 0x00FF; @@ -492,6 +494,7 @@ static int pci171x_insn_counter_config(struct comedi_device *dev, { #ifdef unused /* This doesn't work like a normal Comedi counter config */ + struct pci1710_private *devpriv = dev->private; uint ccntrl = 0; devpriv->cnt0_write_wait = data[0] & 0x20; @@ -527,6 +530,7 @@ static int pci1720_insn_write_ao(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pci1710_private *devpriv = dev->private; int n, rangereg, chan; chan = CR_CHAN(insn->chanspec); @@ -553,9 +557,11 @@ static int pci1720_insn_write_ao(struct comedi_device *dev, static void interrupt_pci1710_every_sample(void *d) { struct comedi_device *dev = d; + struct pci1710_private *devpriv = dev->private; struct comedi_subdevice *s = dev->subdevices + 0; int m; #ifdef PCI171x_PARANOIDCHECK + const struct boardtype *this_board = comedi_board(dev); short sampl; #endif @@ -633,8 +639,10 @@ static void interrupt_pci1710_every_sample(void *d) static int move_block_from_fifo(struct comedi_device *dev, struct comedi_subdevice *s, int n, int turn) { + struct pci1710_private *devpriv = dev->private; int i, j; #ifdef PCI171x_PARANOIDCHECK + const struct boardtype *this_board = comedi_board(dev); int sampl; #endif @@ -677,6 +685,8 @@ static int move_block_from_fifo(struct comedi_device *dev, static void interrupt_pci1710_half_fifo(void *d) { struct comedi_device *dev = d; + const struct boardtype *this_board = comedi_board(dev); + struct pci1710_private *devpriv = dev->private; struct comedi_subdevice *s = dev->subdevices + 0; int m, samplesinbuf; @@ -731,6 +741,7 @@ static void interrupt_pci1710_half_fifo(void *d) static irqreturn_t interrupt_service_pci1710(int irq, void *d) { struct comedi_device *dev = d; + struct pci1710_private *devpriv = dev->private; if (!dev->attached) /* is device attached? */ return IRQ_NONE; /* no, exit */ @@ -766,6 +777,8 @@ static irqreturn_t interrupt_service_pci1710(int irq, void *d) static int pci171x_ai_docmd_and_mode(int mode, struct comedi_device *dev, struct comedi_subdevice *s) { + const struct boardtype *this_board = comedi_board(dev); + struct pci1710_private *devpriv = dev->private; unsigned int divisor1 = 0, divisor2 = 0; unsigned int seglen; @@ -846,6 +859,8 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { + const struct boardtype *this_board = comedi_board(dev); + struct pci1710_private *devpriv = dev->private; int err = 0; int tmp; unsigned int divisor1 = 0, divisor2 = 0; @@ -981,6 +996,7 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, */ static int pci171x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pci1710_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; devpriv->ai_n_chan = cmd->chanlist_len; @@ -1075,6 +1091,8 @@ static void setup_channel_list(struct comedi_device *dev, unsigned int *chanlist, unsigned int n_chan, unsigned int seglen) { + const struct boardtype *this_board = comedi_board(dev); + struct pci1710_private *devpriv = dev->private; unsigned int i, range, chanprog; devpriv->act_chanlist_len = seglen; @@ -1128,6 +1146,9 @@ static void start_pacer(struct comedi_device *dev, int mode, static int pci171x_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + const struct boardtype *this_board = comedi_board(dev); + struct pci1710_private *devpriv = dev->private; + switch (this_board->cardtype) { default: devpriv->CntrlReg &= Control_CNT0; @@ -1154,6 +1175,9 @@ static int pci171x_ai_cancel(struct comedi_device *dev, */ static int pci171x_reset(struct comedi_device *dev) { + const struct boardtype *this_board = comedi_board(dev); + struct pci1710_private *devpriv = dev->private; + outw(0x30, dev->iobase + PCI171x_CNTCTRL); devpriv->CntrlReg = Control_SW | Control_CNT0; /* Software trigger, CNT0=external */ outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL); /* reset any operations */ @@ -1182,6 +1206,8 @@ static int pci171x_reset(struct comedi_device *dev) */ static int pci1720_reset(struct comedi_device *dev) { + struct pci1710_private *devpriv = dev->private; + outb(Syncont_SC0, dev->iobase + PCI1720_SYNCONT); /* set synchronous output mode */ devpriv->da_ranges = 0xAA; outb(devpriv->da_ranges, dev->iobase + PCI1720_RANGE); /* set all ranges to +/-5V */ @@ -1202,6 +1228,8 @@ static int pci1720_reset(struct comedi_device *dev) */ static int pci1710_reset(struct comedi_device *dev) { + const struct boardtype *this_board = comedi_board(dev); + switch (this_board->cardtype) { case TYPE_PCI1720: return pci1720_reset(dev); @@ -1213,6 +1241,7 @@ static int pci1710_reset(struct comedi_device *dev) static struct pci_dev *pci1710_find_pci_dev(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct boardtype *this_board = comedi_board(dev); struct pci_dev *pcidev = NULL; int bus = it->options[0]; int slot = it->options[1]; @@ -1252,6 +1281,8 @@ static struct pci_dev *pci1710_find_pci_dev(struct comedi_device *dev, static int pci1710_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct boardtype *this_board; + struct pci1710_private *devpriv; struct pci_dev *pcidev; struct comedi_subdevice *s; int ret, subdev, n_subdevices; @@ -1259,14 +1290,16 @@ static int pci1710_attach(struct comedi_device *dev, dev_info(dev->class_dev, DRV_NAME ": attach\n"); - ret = alloc_private(dev, sizeof(struct pci1710_private)); + ret = alloc_private(dev, sizeof(*devpriv)); if (ret < 0) return -ENOMEM; + devpriv = dev->private; pcidev = pci1710_find_pci_dev(dev, it); if (!pcidev) return -EIO; comedi_set_hw_dev(dev, &pcidev->dev); + this_board = comedi_board(dev); ret = comedi_pci_enable(pcidev, DRV_NAME); if (ret) @@ -1408,9 +1441,10 @@ static int pci1710_attach(struct comedi_device *dev, static void pci1710_detach(struct comedi_device *dev) { + struct pci1710_private *devpriv = dev->private; struct pci_dev *pcidev = comedi_to_pci_dev(dev); - if (dev->private) { + if (devpriv) { if (devpriv->valid) pci1710_reset(dev); if (dev->irq) -- cgit v0.10.2 From e199ec9521602ec18d727c3a36618ef6b532f72f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 17 Aug 2012 18:05:52 -0700 Subject: staging: comedi: adv_pci1710: convert boardinfo initialization to C99 format Convert the boardinfo initialization to C99 format to make it less error prone. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 7f27c59..58de025 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -202,40 +202,124 @@ struct boardtype { }; static const struct boardtype boardtypes[] = { - {"pci1710", 0x1710, - IORANGE_171x, 1, TYPE_PCI171X, - 16, 8, 2, 16, 16, 1, 0x0fff, 0x0fff, - &range_pci1710_3, range_codes_pci1710_3, - &range_pci171x_da, - 10000, 2048}, - {"pci1710hg", 0x1710, - IORANGE_171x, 1, TYPE_PCI171X, - 16, 8, 2, 16, 16, 1, 0x0fff, 0x0fff, - &range_pci1710hg, range_codes_pci1710hg, - &range_pci171x_da, - 10000, 2048}, - {"pci1711", 0x1711, - IORANGE_171x, 1, TYPE_PCI171X, - 16, 0, 2, 16, 16, 1, 0x0fff, 0x0fff, - &range_pci17x1, range_codes_pci17x1, &range_pci171x_da, - 10000, 512}, - {"pci1713", 0x1713, - IORANGE_171x, 1, TYPE_PCI1713, - 32, 16, 0, 0, 0, 0, 0x0fff, 0x0000, - &range_pci1710_3, range_codes_pci1710_3, NULL, - 10000, 2048}, - {"pci1720", 0x1720, - IORANGE_1720, 0, TYPE_PCI1720, - 0, 0, 4, 0, 0, 0, 0x0000, 0x0fff, - NULL, NULL, &range_pci1720, - 0, 0}, - {"pci1731", 0x1731, - IORANGE_171x, 1, TYPE_PCI171X, - 16, 0, 0, 16, 16, 0, 0x0fff, 0x0000, - &range_pci17x1, range_codes_pci17x1, NULL, - 10000, 512}, - /* dummy entry corresponding to driver name */ - {.name = DRV_NAME}, + { + .name = "pci1710", + .device_id = 0x1710, + .iorange = IORANGE_171x, + .have_irq = 1, + .cardtype = TYPE_PCI171X, + .n_aichan = 16, + .n_aichand = 8, + .n_aochan = 2, + .n_dichan = 16, + .n_dochan = 16, + .n_counter = 1, + .ai_maxdata = 0x0fff, + .ao_maxdata = 0x0fff, + .rangelist_ai = &range_pci1710_3, + .rangecode_ai = range_codes_pci1710_3, + .rangelist_ao = &range_pci171x_da, + .ai_ns_min = 10000, + .fifo_half_size = 2048, + }, { + .name = "pci1710hg", + .device_id = 0x1710, + .iorange = IORANGE_171x, + .have_irq = 1, + .cardtype = TYPE_PCI171X, + .n_aichan = 16, + .n_aichand = 8, + .n_aochan = 2, + .n_dichan = 16, + .n_dochan = 16, + .n_counter = 1, + .ai_maxdata = 0x0fff, + .ao_maxdata = 0x0fff, + .rangelist_ai = &range_pci1710hg, + .rangecode_ai = range_codes_pci1710hg, + .rangelist_ao = &range_pci171x_da, + .ai_ns_min = 10000, + .fifo_half_size = 2048, + }, { + .name = "pci1711", + .device_id = 0x1711, + .iorange = IORANGE_171x, + .have_irq = 1, + .cardtype = TYPE_PCI171X, + .n_aichan = 16, + .n_aichand = 0, + .n_aochan = 2, + .n_dichan = 16, + .n_dochan = 16, + .n_counter = 1, + .ai_maxdata = 0x0fff, + .ao_maxdata = 0x0fff, + .rangelist_ai = &range_pci17x1, + .rangecode_ai = range_codes_pci17x1, + .rangelist_ao = &range_pci171x_da, + .ai_ns_min = 10000, + .fifo_half_size = 512, + }, { + .name = "pci1713", + .device_id = 0x1713, + .iorange = IORANGE_171x, + .have_irq = 1, + .cardtype = TYPE_PCI1713, + .n_aichan = 32, + .n_aichand = 16, + .n_aochan = 0, + .n_dichan = 0, + .n_dochan = 0, + .n_counter = 0, + .ai_maxdata = 0x0fff, + .ao_maxdata = 0x0000, + .rangelist_ai = &range_pci1710_3, + .rangecode_ai = range_codes_pci1710_3, + .rangelist_ao = NULL, + .ai_ns_min = 10000, + .fifo_half_size = 2048, + }, { + .name = "pci1720", + .device_id = 0x1720, + .iorange = IORANGE_1720, + .have_irq = 0, + .cardtype = TYPE_PCI1720, + .n_aichan = 0, + .n_aichand = 0, + .n_aochan = 4, + .n_dichan = 0, + .n_dochan = 0, + .n_counter = 0, + .ai_maxdata = 0x0000, + .ao_maxdata = 0x0fff, + .rangelist_ai = NULL, + .rangecode_ai = NULL, + .rangelist_ao = &range_pci1720, + .ai_ns_min = 0, + .fifo_half_size = 0, + }, { + .name = "pci1731", + .device_id = 0x1731, + .iorange = IORANGE_171x, + .have_irq = 1, + .cardtype = TYPE_PCI171X, + .n_aichan = 16, + .n_aichand = 0, + .n_aochan = 0, + .n_dichan = 16, + .n_dochan = 16, + .n_counter = 0, + .ai_maxdata = 0x0fff, + .ao_maxdata = 0x0000, + .rangelist_ai = &range_pci17x1, + .rangecode_ai = range_codes_pci17x1, + .rangelist_ao = NULL, + .ai_ns_min = 10000, + .fifo_half_size = 512, + }, { + /* dummy entry corresponding to driver name */ + .name = DRV_NAME, + }, }; struct pci1710_private { -- cgit v0.10.2 From 14e065b3a1dba2b29fc55d92512dad8761e098cf Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 17 Aug 2012 18:06:19 -0700 Subject: staging: comedi: adv_pci1710: remove '0' and 'NULL' boardinfo data Remove all the boardinfo data that is set to '0' or 'NULL'. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 58de025..5bea385 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -247,7 +247,6 @@ static const struct boardtype boardtypes[] = { .have_irq = 1, .cardtype = TYPE_PCI171X, .n_aichan = 16, - .n_aichand = 0, .n_aochan = 2, .n_dichan = 16, .n_dochan = 16, @@ -267,36 +266,19 @@ static const struct boardtype boardtypes[] = { .cardtype = TYPE_PCI1713, .n_aichan = 32, .n_aichand = 16, - .n_aochan = 0, - .n_dichan = 0, - .n_dochan = 0, - .n_counter = 0, .ai_maxdata = 0x0fff, - .ao_maxdata = 0x0000, .rangelist_ai = &range_pci1710_3, .rangecode_ai = range_codes_pci1710_3, - .rangelist_ao = NULL, .ai_ns_min = 10000, .fifo_half_size = 2048, }, { .name = "pci1720", .device_id = 0x1720, .iorange = IORANGE_1720, - .have_irq = 0, .cardtype = TYPE_PCI1720, - .n_aichan = 0, - .n_aichand = 0, .n_aochan = 4, - .n_dichan = 0, - .n_dochan = 0, - .n_counter = 0, - .ai_maxdata = 0x0000, .ao_maxdata = 0x0fff, - .rangelist_ai = NULL, - .rangecode_ai = NULL, .rangelist_ao = &range_pci1720, - .ai_ns_min = 0, - .fifo_half_size = 0, }, { .name = "pci1731", .device_id = 0x1731, @@ -304,16 +286,11 @@ static const struct boardtype boardtypes[] = { .have_irq = 1, .cardtype = TYPE_PCI171X, .n_aichan = 16, - .n_aichand = 0, - .n_aochan = 0, .n_dichan = 16, .n_dochan = 16, - .n_counter = 0, .ai_maxdata = 0x0fff, - .ao_maxdata = 0x0000, .rangelist_ai = &range_pci17x1, .rangecode_ai = range_codes_pci17x1, - .rangelist_ao = NULL, .ai_ns_min = 10000, .fifo_half_size = 512, }, { -- cgit v0.10.2 From 4fa7bbeccaeadac408824303c84baa6f04916c5e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 17 Aug 2012 18:06:41 -0700 Subject: staging: comedi: adv_pci1710: remove forward declarations Move some of the functions to remove the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 5bea385..66bd385 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -330,30 +330,108 @@ struct pci1710_private { * internal state */ }; +/* used for gain list programming */ +static const unsigned int muxonechan[] = { + 0x0000, 0x0101, 0x0202, 0x0303, 0x0404, 0x0505, 0x0606, 0x0707, + 0x0808, 0x0909, 0x0a0a, 0x0b0b, 0x0c0c, 0x0d0d, 0x0e0e, 0x0f0f, + 0x1010, 0x1111, 0x1212, 0x1313, 0x1414, 0x1515, 0x1616, 0x1717, + 0x1818, 0x1919, 0x1a1a, 0x1b1b, 0x1c1c, 0x1d1d, 0x1e1e, 0x1f1f +}; + /* ============================================================================== + Check if channel list from user is builded correctly + If it's ok, then program scan/gain logic. + This works for all cards. */ - static int check_channel_list(struct comedi_device *dev, struct comedi_subdevice *s, - unsigned int *chanlist, unsigned int n_chan); + unsigned int *chanlist, unsigned int n_chan) +{ + unsigned int chansegment[32]; + unsigned int i, nowmustbechan, seglen, segpos; + + /* correct channel and range number check itself comedi/range.c */ + if (n_chan < 1) { + comedi_error(dev, "range/channel list is empty!"); + return 0; + } + + if (n_chan == 1) + return 1; /* seglen=1 */ + + chansegment[0] = chanlist[0]; /* first channel is every time ok */ + for (i = 1, seglen = 1; i < n_chan; i++, seglen++) { + if (chanlist[0] == chanlist[i]) + break; /* we detected a loop, stop */ + if ((CR_CHAN(chanlist[i]) & 1) && + (CR_AREF(chanlist[i]) == AREF_DIFF)) { + comedi_error(dev, "Odd channel cannot be differential input!\n"); + return 0; + } + nowmustbechan = (CR_CHAN(chansegment[i - 1]) + 1) % s->n_chan; + if (CR_AREF(chansegment[i - 1]) == AREF_DIFF) + nowmustbechan = (nowmustbechan + 1) % s->n_chan; + if (nowmustbechan != CR_CHAN(chanlist[i])) { + printk("channel list must be continuous! chanlist[%i]=%d but must be %d or %d!\n", + i, CR_CHAN(chanlist[i]), nowmustbechan, + CR_CHAN(chanlist[0])); + return 0; + } + chansegment[i] = chanlist[i]; /* next correct channel in list */ + } + + for (i = 0, segpos = 0; i < n_chan; i++) { + if (chanlist[i] != chansegment[i % seglen]) { + printk("bad channel, reference or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n", + i, CR_CHAN(chansegment[i]), + CR_RANGE(chansegment[i]), + CR_AREF(chansegment[i]), + CR_CHAN(chanlist[i % seglen]), + CR_RANGE(chanlist[i % seglen]), + CR_AREF(chansegment[i % seglen])); + return 0; + } + } + return seglen; +} + static void setup_channel_list(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int *chanlist, unsigned int n_chan, - unsigned int seglen); -static void start_pacer(struct comedi_device *dev, int mode, - unsigned int divisor1, unsigned int divisor2); -static int pci1710_reset(struct comedi_device *dev); -static int pci171x_ai_cancel(struct comedi_device *dev, - struct comedi_subdevice *s); + unsigned int seglen) +{ + const struct boardtype *this_board = comedi_board(dev); + struct pci1710_private *devpriv = dev->private; + unsigned int i, range, chanprog; -/* used for gain list programming */ -static const unsigned int muxonechan[] = { - 0x0000, 0x0101, 0x0202, 0x0303, 0x0404, 0x0505, 0x0606, 0x0707, - 0x0808, 0x0909, 0x0a0a, 0x0b0b, 0x0c0c, 0x0d0d, 0x0e0e, 0x0f0f, - 0x1010, 0x1111, 0x1212, 0x1313, 0x1414, 0x1515, 0x1616, 0x1717, - 0x1818, 0x1919, 0x1a1a, 0x1b1b, 0x1c1c, 0x1d1d, 0x1e1e, 0x1f1f -}; + devpriv->act_chanlist_len = seglen; + devpriv->act_chanlist_pos = 0; + + for (i = 0; i < seglen; i++) { /* store range list to card */ + chanprog = muxonechan[CR_CHAN(chanlist[i])]; + outw(chanprog, dev->iobase + PCI171x_MUX); /* select channel */ + range = this_board->rangecode_ai[CR_RANGE(chanlist[i])]; + if (CR_AREF(chanlist[i]) == AREF_DIFF) + range |= 0x0020; + outw(range, dev->iobase + PCI171x_RANGE); /* select gain */ +#ifdef PCI171x_PARANOIDCHECK + devpriv->act_chanlist[i] = + (CR_CHAN(chanlist[i]) << 12) & 0xf000; +#endif + } +#ifdef PCI171x_PARANOIDCHECK + for ( ; i < n_chan; i++) { /* store remainder of channel list */ + devpriv->act_chanlist[i] = + (CR_CHAN(chanlist[i]) << 12) & 0xf000; + } +#endif + + devpriv->ai_et_MuxVal = + CR_CHAN(chanlist[0]) | (CR_CHAN(chanlist[seglen - 1]) << 8); + /* select channel interval to scan */ + outw(devpriv->ai_et_MuxVal, dev->iobase + PCI171x_MUX); +} /* ============================================================================== @@ -494,6 +572,23 @@ static int pci171x_insn_bits_do(struct comedi_device *dev, /* ============================================================================== */ +static void start_pacer(struct comedi_device *dev, int mode, + unsigned int divisor1, unsigned int divisor2) +{ + outw(0xb4, dev->iobase + PCI171x_CNTCTRL); + outw(0x74, dev->iobase + PCI171x_CNTCTRL); + + if (mode == 1) { + outw(divisor2 & 0xff, dev->iobase + PCI171x_CNT2); + outw((divisor2 >> 8) & 0xff, dev->iobase + PCI171x_CNT2); + outw(divisor1 & 0xff, dev->iobase + PCI171x_CNT1); + outw((divisor1 >> 8) & 0xff, dev->iobase + PCI171x_CNT1); + } +} + +/* +============================================================================== +*/ static int pci171x_insn_counter_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, @@ -615,6 +710,36 @@ static int pci1720_insn_write_ao(struct comedi_device *dev, /* ============================================================================== */ +static int pci171x_ai_cancel(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + const struct boardtype *this_board = comedi_board(dev); + struct pci1710_private *devpriv = dev->private; + + switch (this_board->cardtype) { + default: + devpriv->CntrlReg &= Control_CNT0; + devpriv->CntrlReg |= Control_SW; + + outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL); /* reset any operations */ + start_pacer(dev, -1, 0, 0); + outb(0, dev->iobase + PCI171x_CLRFIFO); + outb(0, dev->iobase + PCI171x_CLRINT); + break; + } + + devpriv->ai_do = 0; + devpriv->ai_act_scan = 0; + s->async->cur_chan = 0; + devpriv->ai_buf_ptr = 0; + devpriv->neverending_ai = 0; + + return 0; +} + +/* +============================================================================== +*/ static void interrupt_pci1710_every_sample(void *d) { struct comedi_device *dev = d; @@ -1091,148 +1216,6 @@ static int pci171x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* ============================================================================== - Check if channel list from user is builded correctly - If it's ok, then program scan/gain logic. - This works for all cards. -*/ -static int check_channel_list(struct comedi_device *dev, - struct comedi_subdevice *s, - unsigned int *chanlist, unsigned int n_chan) -{ - unsigned int chansegment[32]; - unsigned int i, nowmustbechan, seglen, segpos; - - /* correct channel and range number check itself comedi/range.c */ - if (n_chan < 1) { - comedi_error(dev, "range/channel list is empty!"); - return 0; - } - - if (n_chan == 1) - return 1; /* seglen=1 */ - - chansegment[0] = chanlist[0]; /* first channel is every time ok */ - for (i = 1, seglen = 1; i < n_chan; i++, seglen++) { - if (chanlist[0] == chanlist[i]) - break; /* we detected a loop, stop */ - if ((CR_CHAN(chanlist[i]) & 1) && - (CR_AREF(chanlist[i]) == AREF_DIFF)) { - comedi_error(dev, "Odd channel cannot be differential input!\n"); - return 0; - } - nowmustbechan = (CR_CHAN(chansegment[i - 1]) + 1) % s->n_chan; - if (CR_AREF(chansegment[i - 1]) == AREF_DIFF) - nowmustbechan = (nowmustbechan + 1) % s->n_chan; - if (nowmustbechan != CR_CHAN(chanlist[i])) { - printk("channel list must be continuous! chanlist[%i]=%d but must be %d or %d!\n", - i, CR_CHAN(chanlist[i]), nowmustbechan, - CR_CHAN(chanlist[0])); - return 0; - } - chansegment[i] = chanlist[i]; /* next correct channel in list */ - } - - for (i = 0, segpos = 0; i < n_chan; i++) { - if (chanlist[i] != chansegment[i % seglen]) { - printk("bad channel, reference or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n", - i, CR_CHAN(chansegment[i]), - CR_RANGE(chansegment[i]), - CR_AREF(chansegment[i]), - CR_CHAN(chanlist[i % seglen]), - CR_RANGE(chanlist[i % seglen]), - CR_AREF(chansegment[i % seglen])); - return 0; - } - } - return seglen; -} - -static void setup_channel_list(struct comedi_device *dev, - struct comedi_subdevice *s, - unsigned int *chanlist, unsigned int n_chan, - unsigned int seglen) -{ - const struct boardtype *this_board = comedi_board(dev); - struct pci1710_private *devpriv = dev->private; - unsigned int i, range, chanprog; - - devpriv->act_chanlist_len = seglen; - devpriv->act_chanlist_pos = 0; - - for (i = 0; i < seglen; i++) { /* store range list to card */ - chanprog = muxonechan[CR_CHAN(chanlist[i])]; - outw(chanprog, dev->iobase + PCI171x_MUX); /* select channel */ - range = this_board->rangecode_ai[CR_RANGE(chanlist[i])]; - if (CR_AREF(chanlist[i]) == AREF_DIFF) - range |= 0x0020; - outw(range, dev->iobase + PCI171x_RANGE); /* select gain */ -#ifdef PCI171x_PARANOIDCHECK - devpriv->act_chanlist[i] = - (CR_CHAN(chanlist[i]) << 12) & 0xf000; -#endif - } -#ifdef PCI171x_PARANOIDCHECK - for ( ; i < n_chan; i++) { /* store remainder of channel list */ - devpriv->act_chanlist[i] = - (CR_CHAN(chanlist[i]) << 12) & 0xf000; - } -#endif - - devpriv->ai_et_MuxVal = - CR_CHAN(chanlist[0]) | (CR_CHAN(chanlist[seglen - 1]) << 8); - /* select channel interval to scan */ - outw(devpriv->ai_et_MuxVal, dev->iobase + PCI171x_MUX); -} - -/* -============================================================================== -*/ -static void start_pacer(struct comedi_device *dev, int mode, - unsigned int divisor1, unsigned int divisor2) -{ - outw(0xb4, dev->iobase + PCI171x_CNTCTRL); - outw(0x74, dev->iobase + PCI171x_CNTCTRL); - - if (mode == 1) { - outw(divisor2 & 0xff, dev->iobase + PCI171x_CNT2); - outw((divisor2 >> 8) & 0xff, dev->iobase + PCI171x_CNT2); - outw(divisor1 & 0xff, dev->iobase + PCI171x_CNT1); - outw((divisor1 >> 8) & 0xff, dev->iobase + PCI171x_CNT1); - } -} - -/* -============================================================================== -*/ -static int pci171x_ai_cancel(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - const struct boardtype *this_board = comedi_board(dev); - struct pci1710_private *devpriv = dev->private; - - switch (this_board->cardtype) { - default: - devpriv->CntrlReg &= Control_CNT0; - devpriv->CntrlReg |= Control_SW; - - outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL); /* reset any operations */ - start_pacer(dev, -1, 0, 0); - outb(0, dev->iobase + PCI171x_CLRFIFO); - outb(0, dev->iobase + PCI171x_CLRINT); - break; - } - - devpriv->ai_do = 0; - devpriv->ai_act_scan = 0; - s->async->cur_chan = 0; - devpriv->ai_buf_ptr = 0; - devpriv->neverending_ai = 0; - - return 0; -} - -/* -============================================================================== */ static int pci171x_reset(struct comedi_device *dev) { -- cgit v0.10.2 From 3b7cc136e1990ddc0a7f07c2a99a3500e51470bc Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 17 Aug 2012 18:16:18 -0700 Subject: staging: comedi: adv_pci1723: remove function trace messages Remove the DPRINTK function trace messages. These should not be in the final driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index dfde0f6..3c4978a 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -168,7 +168,6 @@ struct pci1723_private { static int pci1723_reset(struct comedi_device *dev) { int i; - DPRINTK("adv_pci1723 EDBG: BGN: pci1723_reset(...)\n"); outw(0x01, dev->iobase + PCI1723_SYN_SET); /* set synchronous output mode */ @@ -190,7 +189,6 @@ static int pci1723_reset(struct comedi_device *dev) /* set asynchronous output mode */ outw(0, dev->iobase + PCI1723_SYN_SET); - DPRINTK("adv_pci1723 EDBG: END: pci1723_reset(...)\n"); return 0; } @@ -201,7 +199,6 @@ static int pci1723_insn_read_ao(struct comedi_device *dev, int n, chan; chan = CR_CHAN(insn->chanspec); - DPRINTK(" adv_PCI1723 DEBUG: pci1723_insn_read_ao() -----\n"); for (n = 0; n < insn->n; n++) data[n] = devpriv->ao_data[chan]; @@ -218,8 +215,6 @@ static int pci1723_ao_write_winsn(struct comedi_device *dev, int n, chan; chan = CR_CHAN(insn->chanspec); - DPRINTK("PCI1723: the pci1723_ao_write_winsn() ------\n"); - for (n = 0; n < insn->n; n++) { devpriv->ao_data[chan] = data[n]; -- cgit v0.10.2 From e201ad6dc3272e9731f896c818f0caacbbe9a1c2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 17 Aug 2012 18:16:53 -0700 Subject: staging: comedi: adv_pci1723: remove devpriv and this_board macros The devpriv macro relies on a local variable having a specific name. Remove it. The this_board macro in this driver is a bit different in this driver. In other comedi drivers, this macro returns the dev->board_ptr. In this driver its simply 'boardtypes' which returns the first boardinfo element. Remove this macro also by making sure the dev->board_ptr is set in the pci1723_find_pci_dev() function and using the comedi_board() helper to get the pointer in pci1723_attach(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index 3c4978a..cc67dccb 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -157,16 +157,12 @@ struct pci1723_private { short ao_data[8]; /* data output buffer */ }; -/* The following macro to make it easy to access the private structure. */ -#define devpriv ((struct pci1723_private *)dev->private) - -#define this_board boardtypes - /* * The pci1723 card reset; */ static int pci1723_reset(struct comedi_device *dev) { + struct pci1723_private *devpriv = dev->private; int i; outw(0x01, dev->iobase + PCI1723_SYN_SET); @@ -196,6 +192,7 @@ static int pci1723_insn_read_ao(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pci1723_private *devpriv = dev->private; int n, chan; chan = CR_CHAN(insn->chanspec); @@ -212,6 +209,7 @@ static int pci1723_ao_write_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pci1723_private *devpriv = dev->private; int n, chan; chan = CR_CHAN(insn->chanspec); @@ -296,6 +294,7 @@ static struct pci_dev *pci1723_find_pci_dev(struct comedi_device *dev, } if (pcidev->vendor != PCI_VENDOR_ID_ADVANTECH) continue; + dev->board_ptr = &boardtypes[0]; return pcidev; } dev_err(dev->class_dev, @@ -307,32 +306,29 @@ static struct pci_dev *pci1723_find_pci_dev(struct comedi_device *dev, static int pci1723_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct pci1723_board *this_board; + struct pci1723_private *devpriv; struct pci_dev *pcidev; struct comedi_subdevice *s; int ret, subdev, n_subdevices; - printk(KERN_ERR "comedi%d: adv_pci1723: board=%s", - dev->minor, this_board->name); - - ret = alloc_private(dev, sizeof(struct pci1723_private)); - if (ret < 0) { - printk(" - Allocation failed!\n"); - return -ENOMEM; - } + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret < 0) + return ret; + devpriv = dev->private; pcidev = pci1723_find_pci_dev(dev, it); if (!pcidev) return -EIO; comedi_set_hw_dev(dev, &pcidev->dev); + this_board = comedi_board(dev); + dev->board_name = this_board->name; - ret = comedi_pci_enable(pcidev, "adv_pci1723"); + ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) return ret; - dev->iobase = pci_resource_start(pcidev, 2); - dev->board_name = this_board->name; - n_subdevices = 0; if (this_board->n_aochan) @@ -399,14 +395,17 @@ static int pci1723_attach(struct comedi_device *dev, pci1723_reset(dev); + dev_info(dev->class_dev, "%s attached\n", dev->board_name); + return 0; } static void pci1723_detach(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct pci1723_private *devpriv = dev->private; - if (dev->private) { + if (devpriv) { if (devpriv->valid) pci1723_reset(dev); } -- cgit v0.10.2 From 25e443373c171b77a1404d21396c38f12f255e16 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 17 Aug 2012 18:17:14 -0700 Subject: staging: comedi: adv_pci1723: remove range_pci1723 This comedi_lrange is the same as the global range_bipolar10 exported by the comedi core. Use that range instead. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index cc67dccb..a790bb7 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -114,11 +114,6 @@ TODO: /* static unsigned short pci_list_builded=0; =1 list of card is know */ -static const struct comedi_lrange range_pci1723 = { 1, { - BIP_RANGE(10) - } -}; - /* * Board descriptions for pci1723 boards. */ @@ -144,7 +139,7 @@ static const struct pci1723_board boardtypes[] = { .n_aochan = 8, .n_diochan = 16, .ao_maxdata = 0xffff, - .rangelist_ao = &range_pci1723, + .rangelist_ao = &range_bipolar10, }, }; -- cgit v0.10.2 From 11d853f955eca03218fe71f6911d02163013fa4d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 17 Aug 2012 18:17:38 -0700 Subject: staging: comedi: adv_pci1723: fix initial dio subdevice state and io_bits The initial state and io_bits for the dio subdevice is determined in the pci1723_attach() but it's being saved in the wrong subdevice. Move the code so it gets saved correctly. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index a790bb7..68ca075 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -350,6 +350,21 @@ static int pci1723_attach(struct comedi_device *dev, s->insn_write = pci1723_ao_write_winsn; s->insn_read = pci1723_insn_read_ao; + subdev++; + } + + if (this_board->n_diochan) { + s = dev->subdevices + subdev; + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = + SDF_READABLE | SDF_WRITABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = this_board->n_diochan; + s->maxdata = 1; + s->len_chanlist = this_board->n_diochan; + s->range_table = &range_digital; + s->insn_config = pci1723_dio_insn_config; + s->insn_bits = pci1723_dio_insn_bits; + /* read DIO config */ switch (inw(dev->iobase + PCI1723_DIGITAL_IO_PORT_MODE) & 0x03) { @@ -372,20 +387,6 @@ static int pci1723_attach(struct comedi_device *dev, subdev++; } - if (this_board->n_diochan) { - s = dev->subdevices + subdev; - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = - SDF_READABLE | SDF_WRITABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = this_board->n_diochan; - s->maxdata = 1; - s->len_chanlist = this_board->n_diochan; - s->range_table = &range_digital; - s->insn_config = pci1723_dio_insn_config; - s->insn_bits = pci1723_dio_insn_bits; - subdev++; - } - devpriv->valid = 1; pci1723_reset(dev); -- cgit v0.10.2 From c8d3739dd30c0b1cdc34608bf292249f7fa34ed6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 17 Aug 2012 18:17:57 -0700 Subject: staging: comedi: adv_pci1723: remove boardinfo This driver only supports one board type. Remove the boardinfo and associated code. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index 68ca075..21dfde2 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -52,11 +52,6 @@ TODO: #define PCI_VENDOR_ID_ADVANTECH 0x13fe /* Advantech PCI vendor ID */ -/* hardware types of the cards */ -#define TYPE_PCI1723 0 - -#define IORANGE_1723 0x2A - /* all the registers for the pci1723 board */ #define PCI1723_DA(N) ((N)<<1) /* W: D/A register N (0 to 7) */ @@ -112,37 +107,6 @@ TODO: #define PCI1723_SELECT_CALIBRATION 0x28 /* Select the calibration Ref_V */ -/* static unsigned short pci_list_builded=0; =1 list of card is know */ - -/* - * Board descriptions for pci1723 boards. - */ -struct pci1723_board { - const char *name; - int vendor_id; /* PCI vendor a device ID of card */ - int device_id; - int iorange; - char cardtype; - int n_aochan; /* num of D/A chans */ - int n_diochan; /* num of DIO chans */ - int ao_maxdata; /* resolution of D/A */ - const struct comedi_lrange *rangelist_ao; /* rangelist for D/A */ -}; - -static const struct pci1723_board boardtypes[] = { - { - .name = "pci1723", - .vendor_id = PCI_VENDOR_ID_ADVANTECH, - .device_id = 0x1723, - .iorange = IORANGE_1723, - .cardtype = TYPE_PCI1723, - .n_aochan = 8, - .n_diochan = 16, - .ao_maxdata = 0xffff, - .rangelist_ao = &range_bipolar10, - }, -}; - /* This structure is for data unique to this hardware driver. */ struct pci1723_private { int valid; /* card is usable; */ @@ -289,7 +253,8 @@ static struct pci_dev *pci1723_find_pci_dev(struct comedi_device *dev, } if (pcidev->vendor != PCI_VENDOR_ID_ADVANTECH) continue; - dev->board_ptr = &boardtypes[0]; + if (pcidev->device != 0x1723) + continue; return pcidev; } dev_err(dev->class_dev, @@ -301,11 +266,10 @@ static struct pci_dev *pci1723_find_pci_dev(struct comedi_device *dev, static int pci1723_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - const struct pci1723_board *this_board; struct pci1723_private *devpriv; struct pci_dev *pcidev; struct comedi_subdevice *s; - int ret, subdev, n_subdevices; + int ret; ret = alloc_private(dev, sizeof(*devpriv)); if (ret < 0) @@ -316,76 +280,57 @@ static int pci1723_attach(struct comedi_device *dev, if (!pcidev) return -EIO; comedi_set_hw_dev(dev, &pcidev->dev); - this_board = comedi_board(dev); - dev->board_name = this_board->name; + dev->board_name = dev->driver->driver_name; ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) return ret; dev->iobase = pci_resource_start(pcidev, 2); - n_subdevices = 0; - - if (this_board->n_aochan) - n_subdevices++; - if (this_board->n_diochan) - n_subdevices++; - - ret = comedi_alloc_subdevices(dev, n_subdevices); + ret = comedi_alloc_subdevices(dev, 2); if (ret) return ret; pci1723_reset(dev); - subdev = 0; - if (this_board->n_aochan) { - s = dev->subdevices + subdev; - dev->write_subdev = s; - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = this_board->n_aochan; - s->maxdata = this_board->ao_maxdata; - s->len_chanlist = this_board->n_aochan; - s->range_table = this_board->rangelist_ao; - - s->insn_write = pci1723_ao_write_winsn; - s->insn_read = pci1723_insn_read_ao; - - subdev++; - } - - if (this_board->n_diochan) { - s = dev->subdevices + subdev; - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = - SDF_READABLE | SDF_WRITABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = this_board->n_diochan; - s->maxdata = 1; - s->len_chanlist = this_board->n_diochan; - s->range_table = &range_digital; - s->insn_config = pci1723_dio_insn_config; - s->insn_bits = pci1723_dio_insn_bits; - - /* read DIO config */ - switch (inw(dev->iobase + PCI1723_DIGITAL_IO_PORT_MODE) - & 0x03) { - case 0x00: /* low byte output, high byte output */ - s->io_bits = 0xFFFF; - break; - case 0x01: /* low byte input, high byte output */ - s->io_bits = 0xFF00; - break; - case 0x02: /* low byte output, high byte input */ - s->io_bits = 0x00FF; - break; - case 0x03: /* low byte input, high byte input */ - s->io_bits = 0x0000; - break; - } - /* read DIO port state */ - s->state = inw(dev->iobase + PCI1723_READ_DIGITAL_INPUT_DATA); - subdev++; + s = dev->subdevices + 0; + dev->write_subdev = s; + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = 8; + s->maxdata = 0xffff; + s->len_chanlist = 8; + s->range_table = &range_bipolar10; + s->insn_write = pci1723_ao_write_winsn; + s->insn_read = pci1723_insn_read_ao; + + s = dev->subdevices + 1; + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 16; + s->maxdata = 1; + s->len_chanlist = 16; + s->range_table = &range_digital; + s->insn_config = pci1723_dio_insn_config; + s->insn_bits = pci1723_dio_insn_bits; + + /* read DIO config */ + switch (inw(dev->iobase + PCI1723_DIGITAL_IO_PORT_MODE) & 0x03) { + case 0x00: /* low byte output, high byte output */ + s->io_bits = 0xFFFF; + break; + case 0x01: /* low byte input, high byte output */ + s->io_bits = 0xFF00; + break; + case 0x02: /* low byte output, high byte input */ + s->io_bits = 0x00FF; + break; + case 0x03: /* low byte input, high byte input */ + s->io_bits = 0x0000; + break; } + /* read DIO port state */ + s->state = inw(dev->iobase + PCI1723_READ_DIGITAL_INPUT_DATA); devpriv->valid = 1; -- cgit v0.10.2 From 5222687a7fafdb8633151269103714f2075e9c3d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 17 Aug 2012 18:18:16 -0700 Subject: staging: comedi: adv_pci1723: use attach_pci callback Convert this PCI driver to use the comedi PCI auto config attach mechanism by adding an 'attach_pci' callback function. Since the driver does not require any external configuration options, and the legacy 'attach' callback is now optional, remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index 21dfde2..63f0985 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -238,50 +238,21 @@ static int pci1723_dio_insn_bits(struct comedi_device *dev, return insn->n; } -static struct pci_dev *pci1723_find_pci_dev(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - struct pci_dev *pcidev = NULL; - int bus = it->options[0]; - int slot = it->options[1]; - - for_each_pci_dev(pcidev) { - if (bus || slot) { - if (bus != pcidev->bus->number || - slot != PCI_SLOT(pcidev->devfn)) - continue; - } - if (pcidev->vendor != PCI_VENDOR_ID_ADVANTECH) - continue; - if (pcidev->device != 0x1723) - continue; - return pcidev; - } - dev_err(dev->class_dev, - "No supported board found! (req. bus %d, slot %d)\n", - bus, slot); - return NULL; -} - -static int pci1723_attach(struct comedi_device *dev, - struct comedi_devconfig *it) +static int pci1723_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) { struct pci1723_private *devpriv; - struct pci_dev *pcidev; struct comedi_subdevice *s; int ret; + comedi_set_hw_dev(dev, &pcidev->dev); + dev->board_name = dev->driver->driver_name; + ret = alloc_private(dev, sizeof(*devpriv)); if (ret < 0) return ret; devpriv = dev->private; - pcidev = pci1723_find_pci_dev(dev, it); - if (!pcidev) - return -EIO; - comedi_set_hw_dev(dev, &pcidev->dev); - dev->board_name = dev->driver->driver_name; - ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) return ret; @@ -353,14 +324,13 @@ static void pci1723_detach(struct comedi_device *dev) if (pcidev) { if (dev->iobase) comedi_pci_disable(pcidev); - pci_dev_put(pcidev); } } static struct comedi_driver adv_pci1723_driver = { .driver_name = "adv_pci1723", .module = THIS_MODULE, - .attach = pci1723_attach, + .attach_pci = pci1723_attach_pci, .detach = pci1723_detach, }; -- cgit v0.10.2 From edf51472131eedc824609a7bab3be43056cb9eff Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 17 Aug 2012 18:18:40 -0700 Subject: staging: comedi: adv_pci1723: cleanup card reset Only one 'reset' of the card is required in the attach. Remove the one before setting up the subdevices and leave the one before exiting the attach function. The 'valid' variable in the private data is not needed. This variable is used in the detach to determine if it's ok to call the 'reset' function. Checking if dev->iobase is valid works just as well. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index 63f0985..cbce06a 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -107,12 +107,8 @@ TODO: #define PCI1723_SELECT_CALIBRATION 0x28 /* Select the calibration Ref_V */ -/* This structure is for data unique to this hardware driver. */ struct pci1723_private { - int valid; /* card is usable; */ - unsigned char da_range[8]; /* D/A output range for each channel */ - short ao_data[8]; /* data output buffer */ }; @@ -262,8 +258,6 @@ static int pci1723_attach_pci(struct comedi_device *dev, if (ret) return ret; - pci1723_reset(dev); - s = dev->subdevices + 0; dev->write_subdev = s; s->type = COMEDI_SUBD_AO; @@ -303,8 +297,6 @@ static int pci1723_attach_pci(struct comedi_device *dev, /* read DIO port state */ s->state = inw(dev->iobase + PCI1723_READ_DIGITAL_INPUT_DATA); - devpriv->valid = 1; - pci1723_reset(dev); dev_info(dev->class_dev, "%s attached\n", dev->board_name); @@ -315,15 +307,12 @@ static int pci1723_attach_pci(struct comedi_device *dev, static void pci1723_detach(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - struct pci1723_private *devpriv = dev->private; - if (devpriv) { - if (devpriv->valid) - pci1723_reset(dev); - } if (pcidev) { - if (dev->iobase) + if (dev->iobase) { + pci1723_reset(dev); comedi_pci_disable(pcidev); + } } } -- cgit v0.10.2 From b850b2635f75c7092b1febc9a733a1b532c9dc7b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 17 Aug 2012 18:18:59 -0700 Subject: staging: comedi: adv_pci_dio: remove function trace messages Remove the DPRINTK function trace messages and associated PCI_DIO_EXTDEBUG define. These should not be in the final driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 2d4cb7f..69508c8 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -36,15 +36,6 @@ Configuration options: #include "8255.h" #include "8253.h" -#undef PCI_DIO_EXTDEBUG /* if defined, enable extensive debug logging */ - -#undef DPRINTK -#ifdef PCI_DIO_EXTDEBUG -#define DPRINTK(fmt, args...) printk(fmt, ## args) -#else -#define DPRINTK(fmt, args...) -#endif - #define PCI_VENDOR_ID_ADVANTECH 0x13fe /* hardware types of the cards */ @@ -816,8 +807,6 @@ static int pci1760_reset(struct comedi_device *dev) */ static int pci_dio_reset(struct comedi_device *dev) { - DPRINTK("adv_pci_dio EDBG: BGN: pci171x_reset(...)\n"); - switch (this_board->cardtype) { case TYPE_PCI1730: outb(0, dev->iobase + PCI1730_DO); /* clear outputs */ @@ -917,8 +906,6 @@ static int pci_dio_reset(struct comedi_device *dev) break; } - DPRINTK("adv_pci_dio EDBG: END: pci171x_reset(...)\n"); - return 0; } -- cgit v0.10.2 From 242f5223aefe577426324c9d7e29775a0e492bb7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 17 Aug 2012 18:19:18 -0700 Subject: staging: comedi: adv_pci_dio: remove devpriv and this_board macros These macros rely on a local variable having a specific name. Remove them and use the comedi_board() helper to get the this_board pointer. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 69508c8..97fc6b8 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -392,9 +392,6 @@ struct pci_dio_private { unsigned short IDIFiltrHigh[8]; /* IDI's filter value high signal */ }; -#define devpriv ((struct pci_dio_private *)dev->private) -#define this_board ((const struct dio_boardtype *)dev->board_ptr) - /* ============================================================================== */ @@ -685,6 +682,7 @@ static int pci1760_insn_cnt_write(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pci_dio_private *devpriv = dev->private; int ret; unsigned char chan = CR_CHAN(insn->chanspec) & 0x07; unsigned char bitmask = 1 << chan; @@ -727,6 +725,7 @@ static int pci1760_insn_cnt_write(struct comedi_device *dev, */ static int pci1760_reset(struct comedi_device *dev) { + struct pci_dio_private *devpriv = dev->private; int i; unsigned char omb[4] = { 0x00, 0x00, 0x00, 0x00 }; unsigned char imb[4]; @@ -807,6 +806,8 @@ static int pci1760_reset(struct comedi_device *dev) */ static int pci_dio_reset(struct comedi_device *dev) { + const struct dio_boardtype *this_board = comedi_board(dev); + switch (this_board->cardtype) { case TYPE_PCI1730: outb(0, dev->iobase + PCI1730_DO); /* clear outputs */ @@ -968,6 +969,8 @@ static int pci1760_attach(struct comedi_device *dev, static int pci_dio_add_di(struct comedi_device *dev, struct comedi_subdevice *s, const struct diosubd_data *d, int subdev) { + const struct dio_boardtype *this_board = comedi_board(dev); + s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | d->specflags; if (d->chans > 16) @@ -995,6 +998,8 @@ static int pci_dio_add_di(struct comedi_device *dev, struct comedi_subdevice *s, static int pci_dio_add_do(struct comedi_device *dev, struct comedi_subdevice *s, const struct diosubd_data *d, int subdev) { + const struct dio_boardtype *this_board = comedi_board(dev); + s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; if (d->chans > 16) @@ -1069,27 +1074,29 @@ static struct pci_dev *pci_dio_find_pci_dev(struct comedi_device *dev, static int pci_dio_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct dio_boardtype *this_board; + struct pci_dio_private *devpriv; struct pci_dev *pcidev; struct comedi_subdevice *s; int ret, subdev, n_subdevices, i, j; - ret = alloc_private(dev, sizeof(struct pci_dio_private)); + ret = alloc_private(dev, sizeof(*devpriv)); if (ret < 0) - return -ENOMEM; + return ret; + devpriv = dev->private; pcidev = pci_dio_find_pci_dev(dev, it); if (!pcidev) return -EIO; comedi_set_hw_dev(dev, &pcidev->dev); + this_board = comedi_board(dev); + dev->board_name = this_board->name; - if (comedi_pci_enable(pcidev, dev->driver->driver_name)) { - dev_err(dev->class_dev, - "Error: Can't enable PCI device and request regions!\n"); - return -EIO; - } + ret = comedi_pci_enable(pcidev, dev->board_name); + if (ret) + return ret; dev->iobase = pci_resource_start(pcidev, this_board->main_pci_region); - dev->board_name = this_board->name; if (this_board->cardtype == TYPE_PCI1760) { n_subdevices = 4; /* 8 IDI, 8 IDO, 2 PWM, 8 CNT */ @@ -1165,12 +1172,14 @@ static int pci_dio_attach(struct comedi_device *dev, static void pci_dio_detach(struct comedi_device *dev) { + const struct dio_boardtype *this_board = comedi_board(dev); + struct pci_dio_private *devpriv = dev->private; struct pci_dev *pcidev = comedi_to_pci_dev(dev); int i, j; struct comedi_subdevice *s; int subdev; - if (dev->private) { + if (devpriv) { if (devpriv->valid) pci_dio_reset(dev); subdev = 0; -- cgit v0.10.2 From e5200165a9f34d75150e9de7b40dfcf8359bb5c7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 17 Aug 2012 18:19:36 -0700 Subject: staging: comedi: adv_pci_dio: use attach_pci callback Convert this PCI driver to use the comedi PCI auto config attach mechanism by adding an 'attach_pci' callback function. Since the driver does not require any external configuration options, and the legacy 'attach' callback is now optional, remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 97fc6b8..36b7c8d 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -913,8 +913,7 @@ static int pci_dio_reset(struct comedi_device *dev) /* ============================================================================== */ -static int pci1760_attach(struct comedi_device *dev, - struct comedi_devconfig *it) +static int pci1760_attach(struct comedi_device *dev) { struct comedi_subdevice *s; int subdev = 0; @@ -1042,60 +1041,45 @@ static int pci_dio_add_8254(struct comedi_device *dev, return 0; } -static struct pci_dev *pci_dio_find_pci_dev(struct comedi_device *dev, - struct comedi_devconfig *it) +static const void *pci_dio_find_boardinfo(struct comedi_device *dev, + struct pci_dev *pcidev) { - struct pci_dev *pcidev = NULL; - int bus = it->options[0]; - int slot = it->options[1]; + const struct dio_boardtype *this_board; int i; - for_each_pci_dev(pcidev) { - if (bus || slot) { - if (bus != pcidev->bus->number || - slot != PCI_SLOT(pcidev->devfn)) - continue; - } - for (i = 0; i < ARRAY_SIZE(boardtypes); ++i) { - if (boardtypes[i].vendor_id != pcidev->vendor) - continue; - if (boardtypes[i].device_id != pcidev->device) - continue; - dev->board_ptr = boardtypes + i; - return pcidev; - } + for (i = 0; i < ARRAY_SIZE(boardtypes); ++i) { + this_board = &boardtypes[i]; + if (this_board->vendor_id == pcidev->vendor && + this_board->device_id == pcidev->device) + return this_board; } - dev_err(dev->class_dev, - "No supported board found! (req. bus %d, slot %d)\n", - bus, slot); return NULL; } -static int pci_dio_attach(struct comedi_device *dev, - struct comedi_devconfig *it) +static int pci_dio_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) { const struct dio_boardtype *this_board; struct pci_dio_private *devpriv; - struct pci_dev *pcidev; struct comedi_subdevice *s; int ret, subdev, n_subdevices, i, j; + comedi_set_hw_dev(dev, &pcidev->dev); + + this_board = pci_dio_find_boardinfo(dev, pcidev); + if (!this_board) + return -ENODEV; + dev->board_ptr = this_board; + dev->board_name = this_board->name; + ret = alloc_private(dev, sizeof(*devpriv)); if (ret < 0) return ret; devpriv = dev->private; - pcidev = pci_dio_find_pci_dev(dev, it); - if (!pcidev) - return -EIO; - comedi_set_hw_dev(dev, &pcidev->dev); - this_board = comedi_board(dev); - dev->board_name = this_board->name; - ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) return ret; - dev->iobase = pci_resource_start(pcidev, this_board->main_pci_region); if (this_board->cardtype == TYPE_PCI1760) { @@ -1161,7 +1145,7 @@ static int pci_dio_attach(struct comedi_device *dev, } if (this_board->cardtype == TYPE_PCI1760) - pci1760_attach(dev, it); + pci1760_attach(dev); devpriv->valid = 1; @@ -1211,15 +1195,14 @@ static void pci_dio_detach(struct comedi_device *dev) if (pcidev) { if (dev->iobase) comedi_pci_disable(pcidev); - pci_dev_put(pcidev); } } static struct comedi_driver adv_pci_dio_driver = { .driver_name = "adv_pci_dio", .module = THIS_MODULE, - .attach = pci_dio_attach, - .detach = pci_dio_detach + .attach_pci = pci_dio_attach_pci, + .detach = pci_dio_detach, }; static int __devinit adv_pci_dio_pci_probe(struct pci_dev *dev, -- cgit v0.10.2 From 59bd675298672dc29b95ec0b7622b04bdab0569a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 17 Aug 2012 18:19:56 -0700 Subject: staging: comedi: adv_pci_dio: convert boardinfo initialization to C99 format Convert the boardinfo initialization to C99 format to make it less error prone. The struct diosubd_data information is not converted to C99 format yet because some of it will be removed. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 36b7c8d..0d1b441 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -250,126 +250,233 @@ struct dio_boardtype { }; static const struct dio_boardtype boardtypes[] = { - {"pci1730", PCI_VENDOR_ID_ADVANTECH, 0x1730, PCIDIO_MAINREG, - TYPE_PCI1730, - { {16, PCI1730_DI, 2, 0}, {16, PCI1730_IDI, 2, 0} }, - { {16, PCI1730_DO, 2, 0}, {16, PCI1730_IDO, 2, 0} }, - { {0, 0, 0, 0}, {0, 0, 0, 0} }, - {4, PCI173x_BOARDID, 1, SDF_INTERNAL}, - { {0, 0, 0, 0} }, - IO_8b}, - {"pci1733", PCI_VENDOR_ID_ADVANTECH, 0x1733, PCIDIO_MAINREG, - TYPE_PCI1733, - { {0, 0, 0, 0}, {32, PCI1733_IDI, 4, 0} }, - { {0, 0, 0, 0}, {0, 0, 0, 0} }, - { {0, 0, 0, 0}, {0, 0, 0, 0} }, - {4, PCI173x_BOARDID, 1, SDF_INTERNAL}, - { {0, 0, 0, 0} }, - IO_8b}, - {"pci1734", PCI_VENDOR_ID_ADVANTECH, 0x1734, PCIDIO_MAINREG, - TYPE_PCI1734, - { {0, 0, 0, 0}, {0, 0, 0, 0} }, - { {0, 0, 0, 0}, {32, PCI1734_IDO, 4, 0} }, - { {0, 0, 0, 0}, {0, 0, 0, 0} }, - {4, PCI173x_BOARDID, 1, SDF_INTERNAL}, - { {0, 0, 0, 0} }, - IO_8b}, - {"pci1735", PCI_VENDOR_ID_ADVANTECH, 0x1735, PCIDIO_MAINREG, - TYPE_PCI1735, - { {32, PCI1735_DI, 4, 0}, {0, 0, 0, 0} }, - { {32, PCI1735_DO, 4, 0}, {0, 0, 0, 0} }, - { {0, 0, 0, 0}, {0, 0, 0, 0} }, - { 4, PCI1735_BOARDID, 1, SDF_INTERNAL}, - { {3, PCI1735_C8254, 1, 0} }, - IO_8b}, - {"pci1736", PCI_VENDOR_ID_ADVANTECH, 0x1736, PCI1736_MAINREG, - TYPE_PCI1736, - { {0, 0, 0, 0}, {16, PCI1736_IDI, 2, 0} }, - { {0, 0, 0, 0}, {16, PCI1736_IDO, 2, 0} }, - { {0, 0, 0, 0}, {0, 0, 0, 0} }, - {4, PCI1736_BOARDID, 1, SDF_INTERNAL}, - { {0, 0, 0, 0} }, - IO_8b}, - {"pci1739", PCI_VENDOR_ID_ADVANTECH, 0x1739, PCIDIO_MAINREG, - TYPE_PCI1739, - { {0, 0, 0, 0}, {0, 0, 0, 0} }, - { {0, 0, 0, 0}, {0, 0, 0, 0} }, - { {48, PCI1739_DIO, 2, 0}, {0, 0, 0, 0} }, - {0, 0, 0, 0}, - { {0, 0, 0, 0} }, - IO_8b}, - {"pci1750", PCI_VENDOR_ID_ADVANTECH, 0x1750, PCIDIO_MAINREG, - TYPE_PCI1750, - { {0, 0, 0, 0}, {16, PCI1750_IDI, 2, 0} }, - { {0, 0, 0, 0}, {16, PCI1750_IDO, 2, 0} }, - { {0, 0, 0, 0}, {0, 0, 0, 0} }, - {0, 0, 0, 0}, - { {0, 0, 0, 0} }, - IO_8b}, - {"pci1751", PCI_VENDOR_ID_ADVANTECH, 0x1751, PCIDIO_MAINREG, - TYPE_PCI1751, - { {0, 0, 0, 0}, {0, 0, 0, 0} }, - { {0, 0, 0, 0}, {0, 0, 0, 0} }, - { {48, PCI1751_DIO, 2, 0}, {0, 0, 0, 0} }, - {0, 0, 0, 0}, - { {3, PCI1751_CNT, 1, 0} }, - IO_8b}, - {"pci1752", PCI_VENDOR_ID_ADVANTECH, 0x1752, PCIDIO_MAINREG, - TYPE_PCI1752, - { {0, 0, 0, 0}, {0, 0, 0, 0} }, - { {32, PCI1752_IDO, 2, 0}, {32, PCI1752_IDO2, 2, 0} }, - { {0, 0, 0, 0}, {0, 0, 0, 0} }, - {4, PCI175x_BOARDID, 1, SDF_INTERNAL}, - { {0, 0, 0, 0} }, - IO_16b}, - {"pci1753", PCI_VENDOR_ID_ADVANTECH, 0x1753, PCIDIO_MAINREG, - TYPE_PCI1753, - { {0, 0, 0, 0}, {0, 0, 0, 0} }, - { {0, 0, 0, 0}, {0, 0, 0, 0} }, - { {96, PCI1753_DIO, 4, 0}, {0, 0, 0, 0} }, - {0, 0, 0, 0}, - { {0, 0, 0, 0} }, - IO_8b}, - {"pci1753e", PCI_VENDOR_ID_ADVANTECH, 0x1753, PCIDIO_MAINREG, - TYPE_PCI1753E, - { {0, 0, 0, 0}, {0, 0, 0, 0} }, - { {0, 0, 0, 0}, {0, 0, 0, 0} }, - { {96, PCI1753_DIO, 4, 0}, {96, PCI1753E_DIO, 4, 0} }, - {0, 0, 0, 0}, - { {0, 0, 0, 0} }, - IO_8b}, - {"pci1754", PCI_VENDOR_ID_ADVANTECH, 0x1754, PCIDIO_MAINREG, - TYPE_PCI1754, - { {32, PCI1754_IDI, 2, 0}, {32, PCI1754_IDI2, 2, 0} }, - { {0, 0, 0, 0}, {0, 0, 0, 0} }, - { {0, 0, 0, 0}, {0, 0, 0, 0} }, - {4, PCI175x_BOARDID, 1, SDF_INTERNAL}, - { {0, 0, 0, 0} }, - IO_16b}, - {"pci1756", PCI_VENDOR_ID_ADVANTECH, 0x1756, PCIDIO_MAINREG, - TYPE_PCI1756, - { {0, 0, 0, 0}, {32, PCI1756_IDI, 2, 0} }, - { {0, 0, 0, 0}, {32, PCI1756_IDO, 2, 0} }, - { {0, 0, 0, 0}, {0, 0, 0, 0} }, - {4, PCI175x_BOARDID, 1, SDF_INTERNAL}, - { {0, 0, 0, 0} }, - IO_16b}, - {"pci1760", PCI_VENDOR_ID_ADVANTECH, 0x1760, 0, - TYPE_PCI1760, - { {0, 0, 0, 0}, {0, 0, 0, 0} }, /* This card have own setup work */ - { {0, 0, 0, 0}, {0, 0, 0, 0} }, - { {0, 0, 0, 0}, {0, 0, 0, 0} }, - {0, 0, 0, 0}, - { {0, 0, 0, 0} }, - IO_8b}, - {"pci1762", PCI_VENDOR_ID_ADVANTECH, 0x1762, PCIDIO_MAINREG, - TYPE_PCI1762, - { {0, 0, 0, 0}, {16, PCI1762_IDI, 1, 0} }, - { {0, 0, 0, 0}, {16, PCI1762_RO, 1, 0} }, - { {0, 0, 0, 0}, {0, 0, 0, 0} }, - {4, PCI1762_BOARDID, 1, SDF_INTERNAL}, - { {0, 0, 0, 0} }, - IO_16b} + { + .name = "pci1730", + .vendor_id = PCI_VENDOR_ID_ADVANTECH, + .device_id = 0x1730, + .main_pci_region = PCIDIO_MAINREG, + .cardtype = TYPE_PCI1730, + .sdi[0] = { 16, PCI1730_DI, 2, 0, }, + .sdi[1] = { 16, PCI1730_IDI, 2, 0, }, + .sdo[0] = { 16, PCI1730_DO, 2, 0, }, + .sdo[1] = { 16, PCI1730_IDO, 2, 0, }, + .sdio[0] = { 0, 0, 0, 0, }, + .sdio[1] = { 0, 0, 0, 0, }, + .boardid = { 4, PCI173x_BOARDID, 1, SDF_INTERNAL, }, + .s8254[0] = { 0, 0, 0, 0, }, + .io_access = IO_8b, + }, { + .name = "pci1733", + .vendor_id = PCI_VENDOR_ID_ADVANTECH, + .device_id = 0x1733, + .main_pci_region = PCIDIO_MAINREG, + .cardtype = TYPE_PCI1733, + .sdi[0] = { 0, 0, 0, 0, }, + .sdi[1] = { 32, PCI1733_IDI, 4, 0, }, + .sdo[0] = { 0, 0, 0, 0, }, + .sdo[1] = { 0, 0, 0, 0, }, + .sdio[0] = { 0, 0, 0, 0, }, + .sdio[1] = { 0, 0, 0, 0, }, + .boardid = { 4, PCI173x_BOARDID, 1, SDF_INTERNAL, }, + .s8254[0] = { 0, 0, 0, 0, }, + .io_access = IO_8b, + }, { + .name = "pci1734", + .vendor_id = PCI_VENDOR_ID_ADVANTECH, + .device_id = 0x1734, + .main_pci_region = PCIDIO_MAINREG, + .cardtype = TYPE_PCI1734, + .sdi[0] = { 0, 0, 0, 0, }, + .sdi[1] = { 0, 0, 0, 0, }, + .sdo[0] = { 0, 0, 0, 0, }, + .sdo[1] = { 32, PCI1734_IDO, 4, 0, }, + .sdio[0] = { 0, 0, 0, 0 }, + .sdio[1] = { 0, 0, 0, 0 }, + .boardid = { 4, PCI173x_BOARDID, 1, SDF_INTERNAL, }, + .s8254[0] = { 0, 0, 0, 0, }, + .io_access = IO_8b, + }, { + .name = "pci1735", + .vendor_id = PCI_VENDOR_ID_ADVANTECH, + .device_id = 0x1735, + .main_pci_region = PCIDIO_MAINREG, + .cardtype = TYPE_PCI1735, + .sdi[0] = { 32, PCI1735_DI, 4, 0, }, + .sdi[1] = { 0, 0, 0, 0, }, + .sdo[0] = { 32, PCI1735_DO, 4, 0, }, + .sdo[1] = { 0, 0, 0, 0, }, + .sdio[0] = { 0, 0, 0, 0, }, + .sdio[1] = { 0, 0, 0, 0, }, + .boardid = { 4, PCI1735_BOARDID, 1, SDF_INTERNAL, }, + .s8254[0] = { 3, PCI1735_C8254, 1, 0, }, + .io_access = IO_8b, + }, { + .name = "pci1736", + .vendor_id = PCI_VENDOR_ID_ADVANTECH, + .device_id = 0x1736, + .main_pci_region = PCI1736_MAINREG, + .cardtype = TYPE_PCI1736, + .sdi[0] = { 0, 0, 0, 0, }, + .sdi[1] = { 16, PCI1736_IDI, 2, 0, }, + .sdo[0] = { 0, 0, 0, 0, }, + .sdo[1] = { 16, PCI1736_IDO, 2, 0, }, + .sdio[0] = { 0, 0, 0, 0, }, + .sdio[1] = { 0, 0, 0, 0, }, + .boardid = { 4, PCI1736_BOARDID, 1, SDF_INTERNAL, }, + .s8254[0] = { 0, 0, 0, 0, }, + .io_access = IO_8b, + }, { + .name = "pci1739", + .vendor_id = PCI_VENDOR_ID_ADVANTECH, + .device_id = 0x1739, + .main_pci_region = PCIDIO_MAINREG, + .cardtype = TYPE_PCI1739, + .sdi[0] = { 0, 0, 0, 0, }, + .sdi[1] = { 0, 0, 0, 0, }, + .sdo[0] = { 0, 0, 0, 0, }, + .sdo[1] = { 0, 0, 0, 0, }, + .sdio[0] = { 48, PCI1739_DIO, 2, 0, }, + .sdio[1] = { 0, 0, 0, 0, }, + .boardid = { 0, 0, 0, 0, }, + .s8254[0] = { 0, 0, 0, 0, }, + .io_access = IO_8b, + }, { + .name = "pci1750", + .vendor_id = PCI_VENDOR_ID_ADVANTECH, + .device_id = 0x1750, + .main_pci_region = PCIDIO_MAINREG, + .cardtype = TYPE_PCI1750, + .sdi[0] = { 0, 0, 0, 0,}, + .sdi[1] = { 16, PCI1750_IDI, 2, 0, }, + .sdo[0] = { 0, 0, 0, 0, }, + .sdo[1] = { 16, PCI1750_IDO, 2, 0, }, + .sdio[0] = { 0, 0, 0, 0, }, + .sdio[1] = { 0, 0, 0, 0, }, + .boardid = { 0, 0, 0, 0, }, + .s8254[0] = { 0, 0, 0, 0, }, + .io_access = IO_8b, + }, { + .name = "pci1751", + .vendor_id = PCI_VENDOR_ID_ADVANTECH, + .device_id = 0x1751, + .main_pci_region = PCIDIO_MAINREG, + .cardtype = TYPE_PCI1751, + .sdi[0] = { 0, 0, 0, 0, }, + .sdi[1] = { 0, 0, 0, 0, }, + .sdo[0] = { 0, 0, 0, 0, }, + .sdo[1] = { 0, 0, 0, 0, }, + .sdio[0] = { 48, PCI1751_DIO, 2, 0, }, + .sdio[1] = { 0, 0, 0, 0, }, + .boardid = { 0, 0, 0, 0, }, + .s8254[0] = { 3, PCI1751_CNT, 1, 0, }, + .io_access = IO_8b, + }, { + .name = "pci1752", + .vendor_id = PCI_VENDOR_ID_ADVANTECH, + .device_id = 0x1752, + .main_pci_region = PCIDIO_MAINREG, + .cardtype = TYPE_PCI1752, + .sdi[0] = { 0, 0, 0, 0, }, + .sdi[1] = { 0, 0, 0, 0, }, + .sdo[0] = { 32, PCI1752_IDO, 2, 0, }, + .sdo[1] = { 32, PCI1752_IDO2, 2, 0, }, + .sdio[0] = { 0, 0, 0, 0, }, + .sdio[1] = { 0, 0, 0, 0, }, + .boardid = { 4, PCI175x_BOARDID, 1, SDF_INTERNAL, }, + .s8254[0] = { 0, 0, 0, 0, }, + .io_access = IO_16b, + }, { + .name = "pci1753", + .vendor_id = PCI_VENDOR_ID_ADVANTECH, + .device_id = 0x1753, + .main_pci_region = PCIDIO_MAINREG, + .cardtype = TYPE_PCI1753, + .sdi[0] = { 0, 0, 0, 0, }, + .sdi[1] = { 0, 0, 0, 0, }, + .sdo[0] = { 0, 0, 0, 0, }, + .sdo[1] = { 0, 0, 0, 0, }, + .sdio[0] = { 96, PCI1753_DIO, 4, 0, }, + .sdio[1] = { 0, 0, 0, 0, }, + .boardid = { 0, 0, 0, 0, }, + .s8254[0] = { 0, 0, 0, 0, }, + .io_access = IO_8b, + }, { + .name = "pci1753e", + .vendor_id = PCI_VENDOR_ID_ADVANTECH, + .device_id = 0x1753, + .main_pci_region = PCIDIO_MAINREG, + .cardtype = TYPE_PCI1753E, + .sdi[0] = { 0, 0, 0, 0, }, + .sdi[1] = { 0, 0, 0, 0, }, + .sdo[0] = { 0, 0, 0, 0, }, + .sdo[1] = { 0, 0, 0, 0, }, + .sdio[0] = { 96, PCI1753_DIO, 4, 0, }, + .sdio[1] = { 96, PCI1753E_DIO, 4, 0, }, + .boardid = { 0, 0, 0, 0, }, + .s8254[0] = { 0, 0, 0, 0, }, + .io_access = IO_8b, + }, { + .name = "pci1754", + .vendor_id = PCI_VENDOR_ID_ADVANTECH, + .device_id = 0x1754, + .main_pci_region = PCIDIO_MAINREG, + .cardtype = TYPE_PCI1754, + .sdi[0] = { 32, PCI1754_IDI, 2, 0, }, + .sdi[1] = { 32, PCI1754_IDI2, 2, 0, }, + .sdo[0] = { 0, 0, 0, 0, }, + .sdo[1] = { 0, 0, 0, 0, }, + .sdio[0] = { 0, 0, 0, 0, }, + .sdio[1] = { 0, 0, 0, 0, }, + .boardid = { 4, PCI175x_BOARDID, 1, SDF_INTERNAL, }, + .s8254[0] = { 0, 0, 0, 0, }, + .io_access = IO_16b, + }, { + .name = "pci1756", + .vendor_id = PCI_VENDOR_ID_ADVANTECH, + .device_id = 0x1756, + .main_pci_region = PCIDIO_MAINREG, + .cardtype = TYPE_PCI1756, + .sdi[0] = { 0, 0, 0, 0,}, + .sdi[1] = { 32, PCI1756_IDI, 2, 0, }, + .sdo[0] = { 0, 0, 0, 0, }, + .sdo[1] = { 32, PCI1756_IDO, 2, 0, }, + .sdio[0] = { 0, 0, 0, 0, }, + .sdio[1] = { 0, 0, 0, 0, }, + .boardid = { 4, PCI175x_BOARDID, 1, SDF_INTERNAL, }, + .s8254[0] = { 0, 0, 0, 0, }, + .io_access = IO_16b, + }, { + /* This card has its own 'attach' */ + .name = "pci1760", + .vendor_id = PCI_VENDOR_ID_ADVANTECH, + .device_id = 0x1760, + .main_pci_region = 0, + .cardtype = TYPE_PCI1760, + .sdi[0] = { 0, 0, 0, 0, }, + .sdi[1] = { 0, 0, 0, 0, }, + .sdo[0] = { 0, 0, 0, 0, }, + .sdo[1] = { 0, 0, 0, 0, }, + .sdio[0] = { 0, 0, 0, 0, }, + .sdio[1] = { 0, 0, 0, 0, }, + .boardid = { 0, 0, 0, 0, }, + .s8254[0] = { 0, 0, 0, 0, }, + .io_access = IO_8b, + }, { + .name = "pci1762", + .vendor_id = PCI_VENDOR_ID_ADVANTECH, + .device_id = 0x1762, + .main_pci_region = PCIDIO_MAINREG, + .cardtype = TYPE_PCI1762, + .sdi[0] = { 0, 0, 0, 0,}, + .sdi[1] = { 16, PCI1762_IDI, 1, 0, }, + .sdo[0] = { 0, 0, 0, 0, }, + .sdo[1] = { 16, PCI1762_RO, 1, 0, }, + .sdio[0] = { 0, 0, 0, 0, }, + .sdio[1] = { 0, 0, 0, 0, }, + .boardid = { 4, PCI1762_BOARDID, 1, SDF_INTERNAL, }, + .s8254[0] = { 0, 0, 0, 0, }, + .io_access = IO_16b, + }, }; struct pci_dio_private { -- cgit v0.10.2 From 79d3a1ddce4e85fd01665dc283459ea3d387b464 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 17 Aug 2012 18:20:14 -0700 Subject: staging: comedi: adv_pci_dio: remove '0' boardinfo data Remove all the boardinfo data that is simply '0'. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 0d1b441..e535d31 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -260,10 +260,7 @@ static const struct dio_boardtype boardtypes[] = { .sdi[1] = { 16, PCI1730_IDI, 2, 0, }, .sdo[0] = { 16, PCI1730_DO, 2, 0, }, .sdo[1] = { 16, PCI1730_IDO, 2, 0, }, - .sdio[0] = { 0, 0, 0, 0, }, - .sdio[1] = { 0, 0, 0, 0, }, .boardid = { 4, PCI173x_BOARDID, 1, SDF_INTERNAL, }, - .s8254[0] = { 0, 0, 0, 0, }, .io_access = IO_8b, }, { .name = "pci1733", @@ -271,14 +268,8 @@ static const struct dio_boardtype boardtypes[] = { .device_id = 0x1733, .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1733, - .sdi[0] = { 0, 0, 0, 0, }, .sdi[1] = { 32, PCI1733_IDI, 4, 0, }, - .sdo[0] = { 0, 0, 0, 0, }, - .sdo[1] = { 0, 0, 0, 0, }, - .sdio[0] = { 0, 0, 0, 0, }, - .sdio[1] = { 0, 0, 0, 0, }, .boardid = { 4, PCI173x_BOARDID, 1, SDF_INTERNAL, }, - .s8254[0] = { 0, 0, 0, 0, }, .io_access = IO_8b, }, { .name = "pci1734", @@ -286,14 +277,8 @@ static const struct dio_boardtype boardtypes[] = { .device_id = 0x1734, .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1734, - .sdi[0] = { 0, 0, 0, 0, }, - .sdi[1] = { 0, 0, 0, 0, }, - .sdo[0] = { 0, 0, 0, 0, }, .sdo[1] = { 32, PCI1734_IDO, 4, 0, }, - .sdio[0] = { 0, 0, 0, 0 }, - .sdio[1] = { 0, 0, 0, 0 }, .boardid = { 4, PCI173x_BOARDID, 1, SDF_INTERNAL, }, - .s8254[0] = { 0, 0, 0, 0, }, .io_access = IO_8b, }, { .name = "pci1735", @@ -302,11 +287,7 @@ static const struct dio_boardtype boardtypes[] = { .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1735, .sdi[0] = { 32, PCI1735_DI, 4, 0, }, - .sdi[1] = { 0, 0, 0, 0, }, .sdo[0] = { 32, PCI1735_DO, 4, 0, }, - .sdo[1] = { 0, 0, 0, 0, }, - .sdio[0] = { 0, 0, 0, 0, }, - .sdio[1] = { 0, 0, 0, 0, }, .boardid = { 4, PCI1735_BOARDID, 1, SDF_INTERNAL, }, .s8254[0] = { 3, PCI1735_C8254, 1, 0, }, .io_access = IO_8b, @@ -316,14 +297,9 @@ static const struct dio_boardtype boardtypes[] = { .device_id = 0x1736, .main_pci_region = PCI1736_MAINREG, .cardtype = TYPE_PCI1736, - .sdi[0] = { 0, 0, 0, 0, }, .sdi[1] = { 16, PCI1736_IDI, 2, 0, }, - .sdo[0] = { 0, 0, 0, 0, }, .sdo[1] = { 16, PCI1736_IDO, 2, 0, }, - .sdio[0] = { 0, 0, 0, 0, }, - .sdio[1] = { 0, 0, 0, 0, }, .boardid = { 4, PCI1736_BOARDID, 1, SDF_INTERNAL, }, - .s8254[0] = { 0, 0, 0, 0, }, .io_access = IO_8b, }, { .name = "pci1739", @@ -331,14 +307,7 @@ static const struct dio_boardtype boardtypes[] = { .device_id = 0x1739, .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1739, - .sdi[0] = { 0, 0, 0, 0, }, - .sdi[1] = { 0, 0, 0, 0, }, - .sdo[0] = { 0, 0, 0, 0, }, - .sdo[1] = { 0, 0, 0, 0, }, .sdio[0] = { 48, PCI1739_DIO, 2, 0, }, - .sdio[1] = { 0, 0, 0, 0, }, - .boardid = { 0, 0, 0, 0, }, - .s8254[0] = { 0, 0, 0, 0, }, .io_access = IO_8b, }, { .name = "pci1750", @@ -346,14 +315,8 @@ static const struct dio_boardtype boardtypes[] = { .device_id = 0x1750, .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1750, - .sdi[0] = { 0, 0, 0, 0,}, .sdi[1] = { 16, PCI1750_IDI, 2, 0, }, - .sdo[0] = { 0, 0, 0, 0, }, .sdo[1] = { 16, PCI1750_IDO, 2, 0, }, - .sdio[0] = { 0, 0, 0, 0, }, - .sdio[1] = { 0, 0, 0, 0, }, - .boardid = { 0, 0, 0, 0, }, - .s8254[0] = { 0, 0, 0, 0, }, .io_access = IO_8b, }, { .name = "pci1751", @@ -361,13 +324,7 @@ static const struct dio_boardtype boardtypes[] = { .device_id = 0x1751, .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1751, - .sdi[0] = { 0, 0, 0, 0, }, - .sdi[1] = { 0, 0, 0, 0, }, - .sdo[0] = { 0, 0, 0, 0, }, - .sdo[1] = { 0, 0, 0, 0, }, .sdio[0] = { 48, PCI1751_DIO, 2, 0, }, - .sdio[1] = { 0, 0, 0, 0, }, - .boardid = { 0, 0, 0, 0, }, .s8254[0] = { 3, PCI1751_CNT, 1, 0, }, .io_access = IO_8b, }, { @@ -376,14 +333,9 @@ static const struct dio_boardtype boardtypes[] = { .device_id = 0x1752, .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1752, - .sdi[0] = { 0, 0, 0, 0, }, - .sdi[1] = { 0, 0, 0, 0, }, .sdo[0] = { 32, PCI1752_IDO, 2, 0, }, .sdo[1] = { 32, PCI1752_IDO2, 2, 0, }, - .sdio[0] = { 0, 0, 0, 0, }, - .sdio[1] = { 0, 0, 0, 0, }, .boardid = { 4, PCI175x_BOARDID, 1, SDF_INTERNAL, }, - .s8254[0] = { 0, 0, 0, 0, }, .io_access = IO_16b, }, { .name = "pci1753", @@ -391,14 +343,7 @@ static const struct dio_boardtype boardtypes[] = { .device_id = 0x1753, .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1753, - .sdi[0] = { 0, 0, 0, 0, }, - .sdi[1] = { 0, 0, 0, 0, }, - .sdo[0] = { 0, 0, 0, 0, }, - .sdo[1] = { 0, 0, 0, 0, }, .sdio[0] = { 96, PCI1753_DIO, 4, 0, }, - .sdio[1] = { 0, 0, 0, 0, }, - .boardid = { 0, 0, 0, 0, }, - .s8254[0] = { 0, 0, 0, 0, }, .io_access = IO_8b, }, { .name = "pci1753e", @@ -406,14 +351,8 @@ static const struct dio_boardtype boardtypes[] = { .device_id = 0x1753, .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1753E, - .sdi[0] = { 0, 0, 0, 0, }, - .sdi[1] = { 0, 0, 0, 0, }, - .sdo[0] = { 0, 0, 0, 0, }, - .sdo[1] = { 0, 0, 0, 0, }, .sdio[0] = { 96, PCI1753_DIO, 4, 0, }, .sdio[1] = { 96, PCI1753E_DIO, 4, 0, }, - .boardid = { 0, 0, 0, 0, }, - .s8254[0] = { 0, 0, 0, 0, }, .io_access = IO_8b, }, { .name = "pci1754", @@ -423,12 +362,7 @@ static const struct dio_boardtype boardtypes[] = { .cardtype = TYPE_PCI1754, .sdi[0] = { 32, PCI1754_IDI, 2, 0, }, .sdi[1] = { 32, PCI1754_IDI2, 2, 0, }, - .sdo[0] = { 0, 0, 0, 0, }, - .sdo[1] = { 0, 0, 0, 0, }, - .sdio[0] = { 0, 0, 0, 0, }, - .sdio[1] = { 0, 0, 0, 0, }, .boardid = { 4, PCI175x_BOARDID, 1, SDF_INTERNAL, }, - .s8254[0] = { 0, 0, 0, 0, }, .io_access = IO_16b, }, { .name = "pci1756", @@ -436,14 +370,9 @@ static const struct dio_boardtype boardtypes[] = { .device_id = 0x1756, .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1756, - .sdi[0] = { 0, 0, 0, 0,}, .sdi[1] = { 32, PCI1756_IDI, 2, 0, }, - .sdo[0] = { 0, 0, 0, 0, }, .sdo[1] = { 32, PCI1756_IDO, 2, 0, }, - .sdio[0] = { 0, 0, 0, 0, }, - .sdio[1] = { 0, 0, 0, 0, }, .boardid = { 4, PCI175x_BOARDID, 1, SDF_INTERNAL, }, - .s8254[0] = { 0, 0, 0, 0, }, .io_access = IO_16b, }, { /* This card has its own 'attach' */ @@ -452,14 +381,6 @@ static const struct dio_boardtype boardtypes[] = { .device_id = 0x1760, .main_pci_region = 0, .cardtype = TYPE_PCI1760, - .sdi[0] = { 0, 0, 0, 0, }, - .sdi[1] = { 0, 0, 0, 0, }, - .sdo[0] = { 0, 0, 0, 0, }, - .sdo[1] = { 0, 0, 0, 0, }, - .sdio[0] = { 0, 0, 0, 0, }, - .sdio[1] = { 0, 0, 0, 0, }, - .boardid = { 0, 0, 0, 0, }, - .s8254[0] = { 0, 0, 0, 0, }, .io_access = IO_8b, }, { .name = "pci1762", @@ -467,14 +388,9 @@ static const struct dio_boardtype boardtypes[] = { .device_id = 0x1762, .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1762, - .sdi[0] = { 0, 0, 0, 0,}, .sdi[1] = { 16, PCI1762_IDI, 1, 0, }, - .sdo[0] = { 0, 0, 0, 0, }, .sdo[1] = { 16, PCI1762_RO, 1, 0, }, - .sdio[0] = { 0, 0, 0, 0, }, - .sdio[1] = { 0, 0, 0, 0, }, .boardid = { 4, PCI1762_BOARDID, 1, SDF_INTERNAL, }, - .s8254[0] = { 0, 0, 0, 0, }, .io_access = IO_16b, }, }; -- cgit v0.10.2 From 4bf75257ff84a57d2e878f149514e4fcd23a93bd Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 17 Aug 2012 18:20:34 -0700 Subject: staging: comedi: adv_pci_dio: add the number of subdevices to the boardinfo Instead of calculating the number of subdevices in the 'attach' simply add the number to the boardinfo. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index e535d31..2c3dbf0 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -241,6 +241,7 @@ struct dio_boardtype { int device_id; int main_pci_region; /* main I/O PCI region */ enum hw_cards_id cardtype; + int nsubdevs; struct diosubd_data sdi[MAX_DI_SUBDEVS]; /* DI chans */ struct diosubd_data sdo[MAX_DO_SUBDEVS]; /* DO chans */ struct diosubd_data sdio[MAX_DIO_SUBDEVG]; /* DIO 8255 chans */ @@ -256,6 +257,7 @@ static const struct dio_boardtype boardtypes[] = { .device_id = 0x1730, .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1730, + .nsubdevs = 5, .sdi[0] = { 16, PCI1730_DI, 2, 0, }, .sdi[1] = { 16, PCI1730_IDI, 2, 0, }, .sdo[0] = { 16, PCI1730_DO, 2, 0, }, @@ -268,6 +270,7 @@ static const struct dio_boardtype boardtypes[] = { .device_id = 0x1733, .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1733, + .nsubdevs = 2, .sdi[1] = { 32, PCI1733_IDI, 4, 0, }, .boardid = { 4, PCI173x_BOARDID, 1, SDF_INTERNAL, }, .io_access = IO_8b, @@ -277,6 +280,7 @@ static const struct dio_boardtype boardtypes[] = { .device_id = 0x1734, .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1734, + .nsubdevs = 2, .sdo[1] = { 32, PCI1734_IDO, 4, 0, }, .boardid = { 4, PCI173x_BOARDID, 1, SDF_INTERNAL, }, .io_access = IO_8b, @@ -286,6 +290,7 @@ static const struct dio_boardtype boardtypes[] = { .device_id = 0x1735, .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1735, + .nsubdevs = 4, .sdi[0] = { 32, PCI1735_DI, 4, 0, }, .sdo[0] = { 32, PCI1735_DO, 4, 0, }, .boardid = { 4, PCI1735_BOARDID, 1, SDF_INTERNAL, }, @@ -297,6 +302,7 @@ static const struct dio_boardtype boardtypes[] = { .device_id = 0x1736, .main_pci_region = PCI1736_MAINREG, .cardtype = TYPE_PCI1736, + .nsubdevs = 3, .sdi[1] = { 16, PCI1736_IDI, 2, 0, }, .sdo[1] = { 16, PCI1736_IDO, 2, 0, }, .boardid = { 4, PCI1736_BOARDID, 1, SDF_INTERNAL, }, @@ -307,6 +313,7 @@ static const struct dio_boardtype boardtypes[] = { .device_id = 0x1739, .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1739, + .nsubdevs = 2, .sdio[0] = { 48, PCI1739_DIO, 2, 0, }, .io_access = IO_8b, }, { @@ -315,6 +322,7 @@ static const struct dio_boardtype boardtypes[] = { .device_id = 0x1750, .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1750, + .nsubdevs = 2, .sdi[1] = { 16, PCI1750_IDI, 2, 0, }, .sdo[1] = { 16, PCI1750_IDO, 2, 0, }, .io_access = IO_8b, @@ -324,6 +332,7 @@ static const struct dio_boardtype boardtypes[] = { .device_id = 0x1751, .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1751, + .nsubdevs = 3, .sdio[0] = { 48, PCI1751_DIO, 2, 0, }, .s8254[0] = { 3, PCI1751_CNT, 1, 0, }, .io_access = IO_8b, @@ -333,6 +342,7 @@ static const struct dio_boardtype boardtypes[] = { .device_id = 0x1752, .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1752, + .nsubdevs = 3, .sdo[0] = { 32, PCI1752_IDO, 2, 0, }, .sdo[1] = { 32, PCI1752_IDO2, 2, 0, }, .boardid = { 4, PCI175x_BOARDID, 1, SDF_INTERNAL, }, @@ -343,6 +353,7 @@ static const struct dio_boardtype boardtypes[] = { .device_id = 0x1753, .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1753, + .nsubdevs = 4, .sdio[0] = { 96, PCI1753_DIO, 4, 0, }, .io_access = IO_8b, }, { @@ -351,6 +362,7 @@ static const struct dio_boardtype boardtypes[] = { .device_id = 0x1753, .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1753E, + .nsubdevs = 8, .sdio[0] = { 96, PCI1753_DIO, 4, 0, }, .sdio[1] = { 96, PCI1753E_DIO, 4, 0, }, .io_access = IO_8b, @@ -360,6 +372,7 @@ static const struct dio_boardtype boardtypes[] = { .device_id = 0x1754, .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1754, + .nsubdevs = 3, .sdi[0] = { 32, PCI1754_IDI, 2, 0, }, .sdi[1] = { 32, PCI1754_IDI2, 2, 0, }, .boardid = { 4, PCI175x_BOARDID, 1, SDF_INTERNAL, }, @@ -370,6 +383,7 @@ static const struct dio_boardtype boardtypes[] = { .device_id = 0x1756, .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1756, + .nsubdevs = 3, .sdi[1] = { 32, PCI1756_IDI, 2, 0, }, .sdo[1] = { 32, PCI1756_IDO, 2, 0, }, .boardid = { 4, PCI175x_BOARDID, 1, SDF_INTERNAL, }, @@ -381,6 +395,7 @@ static const struct dio_boardtype boardtypes[] = { .device_id = 0x1760, .main_pci_region = 0, .cardtype = TYPE_PCI1760, + .nsubdevs = 4, .io_access = IO_8b, }, { .name = "pci1762", @@ -388,6 +403,7 @@ static const struct dio_boardtype boardtypes[] = { .device_id = 0x1762, .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1762, + .nsubdevs = 3, .sdi[1] = { 16, PCI1762_IDI, 1, 0, }, .sdo[1] = { 16, PCI1762_RO, 1, 0, }, .boardid = { 4, PCI1762_BOARDID, 1, SDF_INTERNAL, }, @@ -1085,7 +1101,7 @@ static int pci_dio_attach_pci(struct comedi_device *dev, const struct dio_boardtype *this_board; struct pci_dio_private *devpriv; struct comedi_subdevice *s; - int ret, subdev, n_subdevices, i, j; + int ret, subdev, i, j; comedi_set_hw_dev(dev, &pcidev->dev); @@ -1105,26 +1121,7 @@ static int pci_dio_attach_pci(struct comedi_device *dev, return ret; dev->iobase = pci_resource_start(pcidev, this_board->main_pci_region); - if (this_board->cardtype == TYPE_PCI1760) { - n_subdevices = 4; /* 8 IDI, 8 IDO, 2 PWM, 8 CNT */ - } else { - n_subdevices = 0; - for (i = 0; i < MAX_DI_SUBDEVS; i++) - if (this_board->sdi[i].chans) - n_subdevices++; - for (i = 0; i < MAX_DO_SUBDEVS; i++) - if (this_board->sdo[i].chans) - n_subdevices++; - for (i = 0; i < MAX_DIO_SUBDEVG; i++) - n_subdevices += this_board->sdio[i].regs; - if (this_board->boardid.chans) - n_subdevices++; - for (i = 0; i < MAX_8254_SUBDEVS; i++) - if (this_board->s8254[i].chans) - n_subdevices++; - } - - ret = comedi_alloc_subdevices(dev, n_subdevices); + ret = comedi_alloc_subdevices(dev, this_board->nsubdevs); if (ret) return ret; -- cgit v0.10.2 From cb448d6572219efa4a6eb0c98f37125079b78549 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 17 Aug 2012 18:20:51 -0700 Subject: staging: comedi: adv_pci_dio: simplify the 'detach' Currently the 'detach' function in this driver walks thru the boardinfo in order to find the subdevice index for any sdio subdevices in order to call the subdev_8255_cleanup(). Then it goes thru all the subdevices to clean the s->private pointer. All the sdio subdevices are unique in that the s->type is COMEDI_SUBD_DIO. Use that to know when to call the cleanup for the 8255 subdevice. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 2c3dbf0..4da0e7b 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -1176,39 +1176,18 @@ static int pci_dio_attach_pci(struct comedi_device *dev, static void pci_dio_detach(struct comedi_device *dev) { - const struct dio_boardtype *this_board = comedi_board(dev); struct pci_dio_private *devpriv = dev->private; struct pci_dev *pcidev = comedi_to_pci_dev(dev); - int i, j; struct comedi_subdevice *s; - int subdev; + int i; if (devpriv) { if (devpriv->valid) pci_dio_reset(dev); - subdev = 0; - for (i = 0; i < MAX_DI_SUBDEVS; i++) { - if (this_board->sdi[i].chans) - subdev++; - } - for (i = 0; i < MAX_DO_SUBDEVS; i++) { - if (this_board->sdo[i].chans) - subdev++; - } - for (i = 0; i < MAX_DIO_SUBDEVG; i++) { - for (j = 0; j < this_board->sdio[i].regs; j++) { - s = dev->subdevices + subdev; - subdev_8255_cleanup(dev, s); - subdev++; - } - } - if (this_board->boardid.chans) - subdev++; - for (i = 0; i < MAX_8254_SUBDEVS; i++) - if (this_board->s8254[i].chans) - subdev++; for (i = 0; i < dev->n_subdevices; i++) { s = dev->subdevices + i; + if (s->type == COMEDI_SUBD_DIO) + subdev_8255_cleanup(dev, s); s->private = NULL; } } -- cgit v0.10.2 From f853d9ddf4867a4629753be4af7c5b98f7b7edd0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 17 Aug 2012 18:21:12 -0700 Subject: staging: comedi: adv_pci_dio: fix bug in 'detach' The 'attach' function can fail between when the devpriv and the comedi subdevices are allocated. If it does the 'detach' will try to access unallocated memory when it goes thru the subdevices. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 4da0e7b..a4c1b13 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -1184,6 +1184,8 @@ static void pci_dio_detach(struct comedi_device *dev) if (devpriv) { if (devpriv->valid) pci_dio_reset(dev); + } + if (dev->subdevices) { for (i = 0; i < dev->n_subdevices; i++) { s = dev->subdevices + i; if (s->type == COMEDI_SUBD_DIO) -- cgit v0.10.2 From 062bc6fe6e47d995a95b810319b34db3e149dd0e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Aug 2012 11:28:07 -0700 Subject: staging: comedi: aio_aio12_8: remove devpriv macro This macro relies on a local variable having a specific name. Remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/aio_aio12_8.c b/drivers/staging/comedi/drivers/aio_aio12_8.c index f7d453f..71364c6 100644 --- a/drivers/staging/comedi/drivers/aio_aio12_8.c +++ b/drivers/staging/comedi/drivers/aio_aio12_8.c @@ -84,8 +84,6 @@ struct aio12_8_private { unsigned int ao_readback[4]; }; -#define devpriv ((struct aio12_8_private *) dev->private) - static int aio_aio12_8_ai_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -125,6 +123,7 @@ static int aio_aio12_8_ao_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct aio12_8_private *devpriv = dev->private; int i; int val = devpriv->ao_readback[CR_CHAN(insn->chanspec)]; @@ -137,6 +136,7 @@ static int aio_aio12_8_ao_write(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct aio12_8_private *devpriv = dev->private; int i; int chan = CR_CHAN(insn->chanspec); unsigned long port = dev->iobase + AIO12_8_DAC_0 + (2 * chan); @@ -166,6 +166,7 @@ static int aio_aio12_8_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct aio12_8_boardtype *board = comedi_board(dev); + struct aio12_8_private *devpriv; int iobase; struct comedi_subdevice *s; int ret; @@ -180,8 +181,10 @@ static int aio_aio12_8_attach(struct comedi_device *dev, dev->iobase = iobase; - if (alloc_private(dev, sizeof(struct aio12_8_private)) < 0) - return -ENOMEM; + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; + devpriv = dev->private; ret = comedi_alloc_subdevices(dev, 3); if (ret) -- cgit v0.10.2 From 862edd6be5bad0b05f5166ccef38cc2062405cf1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Aug 2012 11:28:28 -0700 Subject: staging: comedi: aio_aio12_8: add ai and ao only card versions Add the analog input and analog output only versions of the card to the boardinfo. These cards all share the same i/o map. Cleanup the attach so that the unsupported subdevices are not initialized. All of these boards also have an 8254 counter/timer. The 8254 device is not currently supported but stub in the subdevice information so it can easily be added. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/aio_aio12_8.c b/drivers/staging/comedi/drivers/aio_aio12_8.c index 71364c6..c06f5cb 100644 --- a/drivers/staging/comedi/drivers/aio_aio12_8.c +++ b/drivers/staging/comedi/drivers/aio_aio12_8.c @@ -25,8 +25,9 @@ Driver: aio_aio12_8 Description: Access I/O Products PC-104 AIO12-8 Analog I/O Board Author: Pablo Mejia -Devices: - [Access I/O] PC-104 AIO12-8 +Devices: [Access I/O] PC-104 AIO12-8 (aio_aio12_8) + [Access I/O] PC-104 AI12-8 (aio_ai12_8) + [Access I/O] PC-104 AO12-8 (aio_ao12_8) Status: experimental Configuration Options: @@ -73,11 +74,22 @@ Notes: struct aio12_8_boardtype { const char *name; + int ai_nchan; + int ao_nchan; }; static const struct aio12_8_boardtype board_types[] = { { - .name = "aio_aio12_8"}, + .name = "aio_aio12_8", + .ai_nchan = 8, + .ao_nchan = 4, + }, { + .name = "aio_ai12_8", + .ai_nchan = 8, + }, { + .name = "aio_ao12_8", + .ao_nchan = 4, + }, }; struct aio12_8_private { @@ -167,18 +179,17 @@ static int aio_aio12_8_attach(struct comedi_device *dev, { const struct aio12_8_boardtype *board = comedi_board(dev); struct aio12_8_private *devpriv; - int iobase; struct comedi_subdevice *s; + int iobase; int ret; + dev->board_name = board->name; + iobase = it->options[0]; - if (!request_region(iobase, 24, "aio_aio12_8")) { + if (!request_region(iobase, 24, dev->board_name)) { printk(KERN_ERR "I/O port conflict"); return -EIO; } - - dev->board_name = board->name; - dev->iobase = iobase; ret = alloc_private(dev, sizeof(*devpriv)); @@ -186,36 +197,57 @@ static int aio_aio12_8_attach(struct comedi_device *dev, return ret; devpriv = dev->private; - ret = comedi_alloc_subdevices(dev, 3); + ret = comedi_alloc_subdevices(dev, 4); if (ret) return ret; - s = &dev->subdevices[0]; - s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; - s->n_chan = 8; - s->maxdata = (1 << 12) - 1; - s->range_table = &range_aio_aio12_8; - s->insn_read = aio_aio12_8_ai_read; - - s = &dev->subdevices[1]; - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_DIFF; - s->n_chan = 4; - s->maxdata = (1 << 12) - 1; - s->range_table = &range_aio_aio12_8; - s->insn_read = aio_aio12_8_ao_read; - s->insn_write = aio_aio12_8_ao_write; - - s = &dev->subdevices[2]; - subdev_8255_init(dev, s, NULL, dev->iobase + AIO12_8_DIO_0); + s = dev->subdevices + 0; + if (board->ai_nchan) { + /* Analog input subdevice */ + s->type = COMEDI_SUBD_AI; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; + s->n_chan = board->ai_nchan; + s->maxdata = 0x0fff; + s->range_table = &range_aio_aio12_8; + s->insn_read = aio_aio12_8_ai_read; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + s = dev->subdevices + 1; + if (board->ao_nchan) { + /* Analog output subdevice */ + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_DIFF; + s->n_chan = 4; + s->maxdata = 0x0fff; + s->range_table = &range_aio_aio12_8; + s->insn_read = aio_aio12_8_ao_read; + s->insn_write = aio_aio12_8_ao_write; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + s = dev->subdevices + 2; + /* 8255 Digital i/o subdevice */ + ret = subdev_8255_init(dev, s, NULL, dev->iobase + AIO12_8_DIO_0); + if (ret) + return ret; + + s = dev->subdevices + 3; + /* 8254 counter/timer subdevice */ + s->type = COMEDI_SUBD_UNUSED; + + dev_info(dev->class_dev, "%s: %s attached\n", + dev->driver->driver_name, dev->board_name); return 0; } static void aio_aio12_8_detach(struct comedi_device *dev) { - subdev_8255_cleanup(dev, &dev->subdevices[2]); + if (dev->subdevices) + subdev_8255_cleanup(dev, dev->subdevices + 2); if (dev->iobase) release_region(dev->iobase, 24); } -- cgit v0.10.2 From d4fec101b628164c2a731d97fb874309b21abf67 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Aug 2012 11:28:52 -0700 Subject: staging: comedi: aio_aio12_8: document the register map Fully document the register map and add namespace to all the defines. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/aio_aio12_8.c b/drivers/staging/comedi/drivers/aio_aio12_8.c index c06f5cb..46ef41a 100644 --- a/drivers/staging/comedi/drivers/aio_aio12_8.c +++ b/drivers/staging/comedi/drivers/aio_aio12_8.c @@ -43,34 +43,43 @@ Notes: #include #include "8255.h" -#define AIO12_8_STATUS 0x00 -#define AIO12_8_INTERRUPT 0x01 -#define AIO12_8_ADC 0x02 -#define AIO12_8_DAC_0 0x04 -#define AIO12_8_DAC_1 0x06 -#define AIO12_8_DAC_2 0x08 -#define AIO12_8_DAC_3 0x0A -#define AIO12_8_COUNTER_0 0x0C -#define AIO12_8_COUNTER_1 0x0D -#define AIO12_8_COUNTER_2 0x0E -#define AIO12_8_COUNTER_CONTROL 0x0F -#define AIO12_8_DIO_0 0x10 -#define AIO12_8_DIO_1 0x11 -#define AIO12_8_DIO_2 0x12 -#define AIO12_8_DIO_STATUS 0x13 -#define AIO12_8_DIO_CONTROL 0x14 -#define AIO12_8_ADC_TRIGGER_CONTROL 0x15 -#define AIO12_8_TRIGGER 0x16 -#define AIO12_8_POWER 0x17 - -#define STATUS_ADC_EOC 0x80 - -#define ADC_MODE_NORMAL 0x00 -#define ADC_MODE_INTERNAL_CLOCK 0x40 -#define ADC_MODE_STANDBY 0x80 -#define ADC_MODE_POWERDOWN 0xC0 - -#define DAC_ENABLE 0x18 +/* + * Register map + */ +#define AIO12_8_STATUS_REG 0x00 +#define AIO12_8_STATUS_ADC_EOC (1 << 7) +#define AIO12_8_STATUS_PORT_C_COS (1 << 6) +#define AIO12_8_STATUS_IRQ_ENA (1 << 2) +#define AIO12_8_INTERRUPT_REG 0x01 +#define AIO12_8_INTERRUPT_ADC (1 << 7) +#define AIO12_8_INTERRUPT_COS (1 << 6) +#define AIO12_8_INTERRUPT_COUNTER1 (1 << 5) +#define AIO12_8_INTERRUPT_PORT_C3 (1 << 4) +#define AIO12_8_INTERRUPT_PORT_C0 (1 << 3) +#define AIO12_8_INTERRUPT_ENA (1 << 2) +#define AIO12_8_ADC_REG 0x02 +#define AIO12_8_ADC_MODE_NORMAL (0 << 6) +#define AIO12_8_ADC_MODE_INT_CLK (1 << 6) +#define AIO12_8_ADC_MODE_STANDBY (2 << 6) +#define AIO12_8_ADC_MODE_POWERDOWN (3 << 6) +#define AIO12_8_ADC_ACQ_3USEC (0 << 5) +#define AIO12_8_ADC_ACQ_PROGRAM (1 << 5) +#define AIO12_8_ADC_RANGE(x) ((x) << 3) +#define AIO12_8_ADC_CHAN(x) ((x) << 0) +#define AIO12_8_DAC_REG(x) (0x04 + (x) * 2) +#define AIO12_8_8254_BASE_REG 0x0c +#define AIO12_8_8255_BASE_REG 0x10 +#define AIO12_8_DIO_CONTROL_REG 0x14 +#define AIO12_8_DIO_CONTROL_TST (1 << 0) +#define AIO12_8_ADC_TRIGGER_REG 0x15 +#define AIO12_8_ADC_TRIGGER_RANGE(x) ((x) << 3) +#define AIO12_8_ADC_TRIGGER_CHAN(x) ((x) << 0) +#define AIO12_8_TRIGGER_REG 0x16 +#define AIO12_8_TRIGGER_ADTRIG (1 << 1) +#define AIO12_8_TRIGGER_DACTRIG (1 << 0) +#define AIO12_8_COS_REG 0x17 +#define AIO12_8_DAC_ENABLE_REG 0x18 +#define AIO12_8_DAC_ENABLE_REF_ENA (1 << 0) struct aio12_8_boardtype { const char *name; @@ -100,35 +109,42 @@ static int aio_aio12_8_ai_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + unsigned int chan = CR_CHAN(insn->chanspec); + unsigned int range = CR_RANGE(insn->chanspec); + unsigned int val; + unsigned char control; int n; - unsigned char control = - ADC_MODE_NORMAL | - (CR_RANGE(insn->chanspec) << 3) | CR_CHAN(insn->chanspec); - /* read status to clear EOC latch */ - inb(dev->iobase + AIO12_8_STATUS); + /* + * Setup the control byte for internal 2MHz clock, 3uS conversion, + * at the desired range of the requested channel. + */ + control = AIO12_8_ADC_MODE_NORMAL | AIO12_8_ADC_ACQ_3USEC | + AIO12_8_ADC_RANGE(range) | AIO12_8_ADC_CHAN(chan); + + /* Read status to clear EOC latch */ + inb(dev->iobase + AIO12_8_STATUS_REG); for (n = 0; n < insn->n; n++) { int timeout = 5; /* Setup and start conversion */ - outb(control, dev->iobase + AIO12_8_ADC); + outb(control, dev->iobase + AIO12_8_ADC_REG); /* Wait for conversion to complete */ - while (timeout && - !(inb(dev->iobase + AIO12_8_STATUS) & STATUS_ADC_EOC)) { + do { + val = inb(dev->iobase + AIO12_8_STATUS_REG); timeout--; - printk(KERN_ERR "timeout %d\n", timeout); - udelay(1); - } - if (timeout == 0) { - comedi_error(dev, "ADC timeout"); - return -EIO; - } - - data[n] = inw(dev->iobase + AIO12_8_ADC) & 0x0FFF; + if (timeout == 0) { + dev_err(dev->class_dev, "ADC timeout\n"); + return -ETIMEDOUT; + } + } while (!(val & AIO12_8_STATUS_ADC_EOC)); + + data[n] = inw(dev->iobase + AIO12_8_ADC_REG) & s->maxdata; } - return n; + + return insn->n; } static int aio_aio12_8_ao_read(struct comedi_device *dev, @@ -136,8 +152,9 @@ static int aio_aio12_8_ao_read(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { struct aio12_8_private *devpriv = dev->private; + unsigned int chan = CR_CHAN(insn->chanspec); + int val = devpriv->ao_readback[chan]; int i; - int val = devpriv->ao_readback[CR_CHAN(insn->chanspec)]; for (i = 0; i < insn->n; i++) data[i] = val; @@ -149,18 +166,21 @@ static int aio_aio12_8_ao_write(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { struct aio12_8_private *devpriv = dev->private; + unsigned int chan = CR_CHAN(insn->chanspec); + unsigned long port = dev->iobase + AIO12_8_DAC_REG(chan); + unsigned int val = 0; int i; - int chan = CR_CHAN(insn->chanspec); - unsigned long port = dev->iobase + AIO12_8_DAC_0 + (2 * chan); /* enable DACs */ - outb(0x01, dev->iobase + DAC_ENABLE); + outb(AIO12_8_DAC_ENABLE_REF_ENA, dev->iobase + AIO12_8_DAC_ENABLE_REG); for (i = 0; i < insn->n; i++) { - outb(data[i] & 0xFF, port); /* LSB */ - outb((data[i] >> 8) & 0x0F, port + 1); /* MSB */ - devpriv->ao_readback[chan] = data[i]; + val = data[i]; + outw(val, port); } + + devpriv->ao_readback[chan] = val; + return insn->n; } @@ -230,7 +250,8 @@ static int aio_aio12_8_attach(struct comedi_device *dev, s = dev->subdevices + 2; /* 8255 Digital i/o subdevice */ - ret = subdev_8255_init(dev, s, NULL, dev->iobase + AIO12_8_DIO_0); + iobase = dev->iobase + AIO12_8_8255_BASE_REG; + ret = subdev_8255_init(dev, s, NULL, iobase); if (ret) return ret; -- cgit v0.10.2 From f2c8042276338f1f40ccb9e5bef77887cdb626f4 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Aug 2012 11:29:16 -0700 Subject: staging: comedi: aio_aio12_8: fix i/o region size This board has jumpers to set the board base address. These jumpers are marked A5 through A9 and A5 is the least significant bit of the address. This makes the address reqion for the board 32 bytes not 24. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/aio_aio12_8.c b/drivers/staging/comedi/drivers/aio_aio12_8.c index 46ef41a..c07de3e 100644 --- a/drivers/staging/comedi/drivers/aio_aio12_8.c +++ b/drivers/staging/comedi/drivers/aio_aio12_8.c @@ -206,7 +206,7 @@ static int aio_aio12_8_attach(struct comedi_device *dev, dev->board_name = board->name; iobase = it->options[0]; - if (!request_region(iobase, 24, dev->board_name)) { + if (!request_region(iobase, 32, dev->board_name)) { printk(KERN_ERR "I/O port conflict"); return -EIO; } -- cgit v0.10.2 From 90db97d5d9ce05c12f6cd2565b696a53a245e0ca Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Aug 2012 12:52:41 -0700 Subject: staging: comedi: comedi_bond: remove boardinfo The only field in the boardinfo for this driver is a pointer to the board 'name'. This field is used by the comedi core to match against the driver when doing a legacy attach. If a driver does not have any boardinfo, the comedi core matches against the driver name. Since the boardinfo name and driver name are identical we can simplify this driver a bit bu just removing the boardinfo completely. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/comedi_bond.c b/drivers/staging/comedi/drivers/comedi_bond.c index 5ed324c..6918439 100644 --- a/drivers/staging/comedi/drivers/comedi_bond.c +++ b/drivers/staging/comedi/drivers/comedi_bond.c @@ -79,20 +79,6 @@ MODULE_PARM_DESC(debug, "If true, print extra cryptic debugging output useful" #define WARNING(x...) printk(KERN_WARNING MODULE_NAME ": WARNING: "x) #define ERROR(x...) printk(KERN_ERR MODULE_NAME ": INTERNAL ERROR: "x) -/* - * Board descriptions for two imaginary boards. Describing the - * boards in this way is optional, and completely driver-dependent. - * Some drivers use arrays such as this, other do not. - */ -struct BondingBoard { - const char *name; -}; - -/* - * Useful for shorthand access to the particular board structure - */ -#define thisboard ((const struct BondingBoard *)dev->board_ptr) - struct BondedDevice { struct comedi_device *dev; unsigned minor; @@ -351,10 +337,6 @@ static int bonding_attach(struct comedi_device *dev, if (!doDevConfig(dev, it)) return -EINVAL; - /* - * Initialize dev->board_name. Note that we can use the "thisboard" - * macro now, since we just initialized it in the last line. - */ dev->board_name = devpriv->name; ret = comedi_alloc_subdevices(dev, 1); @@ -402,20 +384,11 @@ static void bonding_detach(struct comedi_device *dev) } } -static const struct BondingBoard bondingBoards[] = { - { - .name = "comedi_bond", - }, -}; - static struct comedi_driver bonding_driver = { .driver_name = "comedi_bond", .module = THIS_MODULE, .attach = bonding_attach, .detach = bonding_detach, - .board_name = &bondingBoards[0].name, - .offset = sizeof(struct BondingBoard), - .num_names = ARRAY_SIZE(bondingBoards), }; module_comedi_driver(bonding_driver); -- cgit v0.10.2 From a62a176402dbf01286c815493af3dead836e5bfa Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Aug 2012 12:52:58 -0700 Subject: staging: comedi: comedi_bond: remove devpriv macro This macro relies on a local variable having a specific name. Remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/comedi_bond.c b/drivers/staging/comedi/drivers/comedi_bond.c index 6918439..6829910 100644 --- a/drivers/staging/comedi/drivers/comedi_bond.c +++ b/drivers/staging/comedi/drivers/comedi_bond.c @@ -93,7 +93,7 @@ struct BondedDevice { /* this structure is for data unique to this hardware driver. If several hardware drivers keep similar information in this structure, feel free to suggest moving the variable to the struct comedi_device struct. */ -struct Private { +struct comedi_bond_private { # define MAX_BOARD_NAME 256 char name[MAX_BOARD_NAME]; struct BondedDevice **devs; @@ -102,12 +102,6 @@ struct Private { unsigned nchans; }; -/* - * most drivers define the following macro to make it easy to - * access the private structure. - */ -#define devpriv ((struct Private *)dev->private) - /* DIO devices are slightly special. Although it is possible to * implement the insn_read/insn_write interface, it is much more * useful to applications if you implement the insn_bits interface. @@ -117,6 +111,7 @@ static int bonding_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct comedi_bond_private *devpriv = dev->private; #define LSAMPL_BITS (sizeof(unsigned int)*8) unsigned nchans = LSAMPL_BITS, num_done = 0, i; @@ -163,6 +158,7 @@ static int bonding_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct comedi_bond_private *devpriv = dev->private; int chan = CR_CHAN(insn->chanspec), ret, io_bits = s->io_bits; unsigned int io; struct BondedDevice *bdev; @@ -216,6 +212,7 @@ static void *Realloc(const void *oldmem, size_t newlen, size_t oldlen) static int doDevConfig(struct comedi_device *dev, struct comedi_devconfig *it) { + struct comedi_bond_private *devpriv = dev->private; int i; struct comedi_device *devs_opened[COMEDI_NUM_BOARD_MINORS]; @@ -319,20 +316,19 @@ static int doDevConfig(struct comedi_device *dev, struct comedi_devconfig *it) static int bonding_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct comedi_bond_private *devpriv; struct comedi_subdevice *s; int ret; LOG_MSG("comedi%d\n", dev->minor); - /* - * Allocate the private structure area. alloc_private() is a - * convenient macro defined in comedidev.h. - */ - if (alloc_private(dev, sizeof(struct Private)) < 0) - return -ENOMEM; + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; + devpriv = dev->private; /* - * Setup our bonding from config params.. sets up our Private struct.. + * Setup our bonding from config params.. sets up our private struct.. */ if (!doDevConfig(dev, it)) return -EINVAL; @@ -362,6 +358,7 @@ static int bonding_attach(struct comedi_device *dev, static void bonding_detach(struct comedi_device *dev) { + struct comedi_bond_private *devpriv = dev->private; unsigned long devs_closed = 0; if (devpriv) { -- cgit v0.10.2 From fdb2a66ff03bff35e960a3a3303562751373418a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Aug 2012 12:53:20 -0700 Subject: staging: comedi: comedi_bond: remove private printk macros Remove the macros LOG_MSG, DEBUG, WARNING, and ERROR. Convert the printk's into dev_printk format. The DEBUG macro is not being used in the file so the module parameter 'debug' can also be removed. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/comedi_bond.c b/drivers/staging/comedi/drivers/comedi_bond.c index 6829910..1ca939c 100644 --- a/drivers/staging/comedi/drivers/comedi_bond.c +++ b/drivers/staging/comedi/drivers/comedi_bond.c @@ -65,20 +65,6 @@ Configuration Options: # define STR(x) STR1(x) #endif -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "If true, print extra cryptic debugging output useful" - "only to developers."); - -#define LOG_MSG(x...) printk(KERN_INFO MODULE_NAME": "x) -#define DEBUG(x...) \ - do { \ - if (debug) \ - printk(KERN_DEBUG MODULE_NAME": DEBUG: "x); \ - } while (0) -#define WARNING(x...) printk(KERN_WARNING MODULE_NAME ": WARNING: "x) -#define ERROR(x...) printk(KERN_ERR MODULE_NAME ": INTERNAL ERROR: "x) - struct BondedDevice { struct comedi_device *dev; unsigned minor; @@ -228,15 +214,18 @@ static int doDevConfig(struct comedi_device *dev, struct comedi_devconfig *it) struct BondedDevice *bdev = NULL; if (minor < 0 || minor >= COMEDI_NUM_BOARD_MINORS) { - ERROR("Minor %d is invalid!\n", minor); + dev_err(dev->class_dev, + "Minor %d is invalid!\n", minor); return 0; } if (minor == dev->minor) { - ERROR("Cannot bond this driver to itself!\n"); + dev_err(dev->class_dev, + "Cannot bond this driver to itself!\n"); return 0; } if (devs_opened[minor]) { - ERROR("Minor %d specified more than once!\n", minor); + dev_err(dev->class_dev, + "Minor %d specified more than once!\n", minor); return 0; } @@ -246,7 +235,8 @@ static int doDevConfig(struct comedi_device *dev, struct comedi_devconfig *it) d = devs_opened[minor] = comedi_open(file); if (!d) { - ERROR("Minor %u could not be opened\n", minor); + dev_err(dev->class_dev, + "Minor %u could not be opened\n", minor); return 0; } @@ -255,14 +245,14 @@ static int doDevConfig(struct comedi_device *dev, struct comedi_devconfig *it) sdev + 1)) > -1) { nchans = comedi_get_n_channels(d, sdev); if (nchans <= 0) { - ERROR("comedi_get_n_channels() returned %d " - "on minor %u subdev %d!\n", - nchans, minor, sdev); + dev_err(dev->class_dev, + "comedi_get_n_channels() returned %d on minor %u subdev %d!\n", + nchans, minor, sdev); return 0; } bdev = kmalloc(sizeof(*bdev), GFP_KERNEL); if (!bdev) { - ERROR("Out of memory.\n"); + dev_err(dev->class_dev, "Out of memory\n"); return 0; } bdev->dev = d; @@ -285,8 +275,8 @@ static int doDevConfig(struct comedi_device *dev, struct comedi_devconfig *it) Realloc(devpriv->devs, ++devpriv->ndevs * sizeof(bdev), tmp); if (!devpriv->devs) { - ERROR("Could not allocate memory. " - "Out of memory?"); + dev_err(dev->class_dev, + "Could not allocate memory. Out of memory?\n"); return 0; } @@ -306,7 +296,7 @@ static int doDevConfig(struct comedi_device *dev, struct comedi_devconfig *it) } if (!devpriv->nchans) { - ERROR("No channels found!\n"); + dev_err(dev->class_dev, "No channels found!\n"); return 0; } @@ -320,8 +310,6 @@ static int bonding_attach(struct comedi_device *dev, struct comedi_subdevice *s; int ret; - LOG_MSG("comedi%d\n", dev->minor); - ret = alloc_private(dev, sizeof(*devpriv)); if (ret) return ret; @@ -348,9 +336,9 @@ static int bonding_attach(struct comedi_device *dev, s->insn_bits = bonding_dio_insn_bits; s->insn_config = bonding_dio_insn_config; - LOG_MSG("attached with %u DIO channels coming from %u different " - "subdevices all bonded together. " - "John Lennon would be proud!\n", + dev_info(dev->class_dev, + "%s: %s attached, %u channels from %u devices\n", + dev->driver->driver_name, dev->board_name, devpriv->nchans, devpriv->ndevs); return 1; -- cgit v0.10.2 From c8e2c83769000e00287c0e6fabd51dc695b23af5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Aug 2012 12:53:36 -0700 Subject: staging: comedi: comedi_bond: remove the STR macro This macro is not used in the file. Remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/comedi_bond.c b/drivers/staging/comedi/drivers/comedi_bond.c index 1ca939c..e6ac27d 100644 --- a/drivers/staging/comedi/drivers/comedi_bond.c +++ b/drivers/staging/comedi/drivers/comedi_bond.c @@ -60,10 +60,6 @@ Configuration Options: #define MAX_CHANS 256 #define MODULE_NAME "comedi_bond" -#ifndef STR -# define STR1(x) #x -# define STR(x) STR1(x) -#endif struct BondedDevice { struct comedi_device *dev; -- cgit v0.10.2 From fa38126b51d05ebaeeb14e6724c86d4fb08a52a5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Aug 2012 12:53:56 -0700 Subject: staging: comedi: comedi_bond: remove MODULE_NAME macro This macro is only used in the MODULE_DESCRIPTION. Just remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/comedi_bond.c b/drivers/staging/comedi/drivers/comedi_bond.c index e6ac27d..6b516ed 100644 --- a/drivers/staging/comedi/drivers/comedi_bond.c +++ b/drivers/staging/comedi/drivers/comedi_bond.c @@ -59,8 +59,6 @@ Configuration Options: /* The maxiumum number of channels per subdevice. */ #define MAX_CHANS 256 -#define MODULE_NAME "comedi_bond" - struct BondedDevice { struct comedi_device *dev; unsigned minor; @@ -374,7 +372,7 @@ static struct comedi_driver bonding_driver = { module_comedi_driver(bonding_driver); MODULE_AUTHOR("Calin A. Culianu"); -MODULE_DESCRIPTION(MODULE_NAME "A driver for COMEDI to bond multiple COMEDI " +MODULE_DESCRIPTION("comedi_bond: A driver for COMEDI to bond multiple COMEDI " "devices together as one. In the words of John Lennon: " "'And the world will live as one...'"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From d3bcf099dee9b7eff642890612da1f1a13bb3255 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Aug 2012 14:30:08 -0700 Subject: staging: comedi: comedi_parport: remove devpriv macro This macro relies on a local variable having a specific name, Remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/comedi_parport.c b/drivers/staging/comedi/drivers/comedi_parport.c index 9a63cac..fcad423 100644 --- a/drivers/staging/comedi/drivers/comedi_parport.c +++ b/drivers/staging/comedi/drivers/comedi_parport.c @@ -96,11 +96,12 @@ struct parport_private { unsigned int c_data; int enable_irq; }; -#define devpriv ((struct parport_private *)(dev->private)) static int parport_insn_a(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct parport_private *devpriv = dev->private; + if (data[0]) { devpriv->a_data &= ~data[0]; devpriv->a_data |= (data[0] & data[1]); @@ -117,6 +118,8 @@ static int parport_insn_config_a(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct parport_private *devpriv = dev->private; + if (data[0]) { s->io_bits = 0xff; devpriv->c_data &= ~(1 << 5); @@ -145,6 +148,8 @@ static int parport_insn_b(struct comedi_device *dev, struct comedi_subdevice *s, static int parport_insn_c(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct parport_private *devpriv = dev->private; + data[0] &= 0x0f; if (data[0]) { devpriv->c_data &= ~data[0]; @@ -245,6 +250,8 @@ static int parport_intr_cmdtest(struct comedi_device *dev, static int parport_intr_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct parport_private *devpriv = dev->private; + devpriv->c_data |= 0x10; outb(devpriv->c_data, dev->iobase + PARPORT_C); @@ -256,6 +263,8 @@ static int parport_intr_cmd(struct comedi_device *dev, static int parport_intr_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct parport_private *devpriv = dev->private; + printk(KERN_DEBUG "parport_intr_cancel()\n"); devpriv->c_data &= ~0x10; @@ -269,6 +278,7 @@ static int parport_intr_cancel(struct comedi_device *dev, static irqreturn_t parport_interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct parport_private *devpriv = dev->private; struct comedi_subdevice *s = dev->subdevices + 3; if (!devpriv->enable_irq) { @@ -286,6 +296,7 @@ static irqreturn_t parport_interrupt(int irq, void *d) static int parport_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct parport_private *devpriv; int ret; unsigned int irq; unsigned long iobase; @@ -316,9 +327,10 @@ static int parport_attach(struct comedi_device *dev, if (ret) return ret; - ret = alloc_private(dev, sizeof(struct parport_private)); + ret = alloc_private(dev, sizeof(*devpriv)); if (ret < 0) return ret; + devpriv = dev->private; s = dev->subdevices + 0; s->type = COMEDI_SUBD_DIO; -- cgit v0.10.2 From 45d637000d818a9061b3a52e8aa09f58719ae01e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Aug 2012 14:30:27 -0700 Subject: staging: comedi: comedi_parport: cleanup dev->board_name Use the 'dev->driver->driver_name' for the 'dev->board_name'. And use the 'dev->board_name' for the resource name passed to request_region and request_irq. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/comedi_parport.c b/drivers/staging/comedi/drivers/comedi_parport.c index fcad423..fc59cb2 100644 --- a/drivers/staging/comedi/drivers/comedi_parport.c +++ b/drivers/staging/comedi/drivers/comedi_parport.c @@ -302,9 +302,11 @@ static int parport_attach(struct comedi_device *dev, unsigned long iobase; struct comedi_subdevice *s; + dev->board_name = dev->driver->driver_name; + iobase = it->options[0]; printk(KERN_INFO "comedi%d: parport: 0x%04lx ", dev->minor, iobase); - if (!request_region(iobase, PARPORT_SIZE, "parport (comedi)")) { + if (!request_region(iobase, PARPORT_SIZE, dev->board_name)) { printk(KERN_ERR "I/O port conflict\n"); return -EIO; } @@ -313,7 +315,7 @@ static int parport_attach(struct comedi_device *dev, irq = it->options[1]; if (irq) { printk(KERN_INFO " irq=%u", irq); - ret = request_irq(irq, parport_interrupt, 0, "comedi_parport", + ret = request_irq(irq, parport_interrupt, 0, dev->board_name, dev); if (ret < 0) { printk(KERN_ERR " irq not available\n"); @@ -321,7 +323,6 @@ static int parport_attach(struct comedi_device *dev, } dev->irq = irq; } - dev->board_name = "parport"; ret = comedi_alloc_subdevices(dev, 4); if (ret) -- cgit v0.10.2 From b8d0f3ae8c9945b740983991009513df74dbc949 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Aug 2012 14:30:53 -0700 Subject: staging: comedi: comedi_parport: cleanup 'attach' printk's Convert the printk messages in the 'attach' to dev_printk messages. Consolidate the attach message into one message after the device is attached. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/comedi_parport.c b/drivers/staging/comedi/drivers/comedi_parport.c index fc59cb2..48d529e 100644 --- a/drivers/staging/comedi/drivers/comedi_parport.c +++ b/drivers/staging/comedi/drivers/comedi_parport.c @@ -305,20 +305,18 @@ static int parport_attach(struct comedi_device *dev, dev->board_name = dev->driver->driver_name; iobase = it->options[0]; - printk(KERN_INFO "comedi%d: parport: 0x%04lx ", dev->minor, iobase); if (!request_region(iobase, PARPORT_SIZE, dev->board_name)) { - printk(KERN_ERR "I/O port conflict\n"); + dev_err(dev->class_dev, "I/O port conflict\n"); return -EIO; } dev->iobase = iobase; irq = it->options[1]; if (irq) { - printk(KERN_INFO " irq=%u", irq); ret = request_irq(irq, parport_interrupt, 0, dev->board_name, dev); if (ret < 0) { - printk(KERN_ERR " irq not available\n"); + dev_err(dev->class_dev, "irq not available\n"); return -EINVAL; } dev->irq = irq; @@ -379,8 +377,10 @@ static int parport_attach(struct comedi_device *dev, devpriv->c_data = 0; outb(devpriv->c_data, dev->iobase + PARPORT_C); - printk(KERN_INFO "\n"); - return 1; + dev_info(dev->class_dev, "%s: iobase=0x%04lx, irq %sabled", + dev->board_name, dev->iobase, dev->irq ? "en" : "dis"); + + return 0; } static void parport_detach(struct comedi_device *dev) -- cgit v0.10.2 From 06331fb0901519b846ebae347f9eeb65860361c7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Aug 2012 14:31:10 -0700 Subject: staging: comedi: comedi_parport: remove the printk noise Remove the function trace message in parport_intr_cancel() and the "bogus irq..." message is parport_interrupt(). They are just added noise. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/comedi_parport.c b/drivers/staging/comedi/drivers/comedi_parport.c index 48d529e..2dce9df 100644 --- a/drivers/staging/comedi/drivers/comedi_parport.c +++ b/drivers/staging/comedi/drivers/comedi_parport.c @@ -265,8 +265,6 @@ static int parport_intr_cancel(struct comedi_device *dev, { struct parport_private *devpriv = dev->private; - printk(KERN_DEBUG "parport_intr_cancel()\n"); - devpriv->c_data &= ~0x10; outb(devpriv->c_data, dev->iobase + PARPORT_C); @@ -281,10 +279,8 @@ static irqreturn_t parport_interrupt(int irq, void *d) struct parport_private *devpriv = dev->private; struct comedi_subdevice *s = dev->subdevices + 3; - if (!devpriv->enable_irq) { - printk(KERN_ERR "comedi_parport: bogus irq, ignored\n"); + if (!devpriv->enable_irq) return IRQ_NONE; - } comedi_buf_put(s->async, 0); s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; -- cgit v0.10.2 From f1e5aa75e72a301be2c0e3da448c970bca368225 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Aug 2012 15:04:24 -0700 Subject: staging: comedi: comedi_test: remove devpriv macro This macro relies on a local variable having a specific name. Remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c index 523a809..c77ce75 100644 --- a/drivers/staging/comedi/drivers/comedi_test.c +++ b/drivers/staging/comedi/drivers/comedi_test.c @@ -81,7 +81,6 @@ struct waveform_private { unsigned timer_running:1; unsigned int ao_loopbacks[N_CHANS]; }; -#define devpriv ((struct waveform_private *)dev->private) /* 1000 nanosec in a microsec */ static const int nano_per_micro = 1000; @@ -98,6 +97,7 @@ static const struct comedi_lrange waveform_ai_ranges = { static short fake_sawtooth(struct comedi_device *dev, unsigned int range_index, unsigned long current_time) { + struct waveform_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; unsigned int offset = s->maxdata / 2; u64 value; @@ -122,6 +122,7 @@ static short fake_squarewave(struct comedi_device *dev, unsigned int range_index, unsigned long current_time) { + struct waveform_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; unsigned int offset = s->maxdata / 2; u64 value; @@ -175,6 +176,7 @@ static short fake_waveform(struct comedi_device *dev, unsigned int channel, static void waveform_ai_interrupt(unsigned long arg) { struct comedi_device *dev = (struct comedi_device *)arg; + struct waveform_private *devpriv = dev->private; struct comedi_async *async = dev->read_subdev->async; struct comedi_cmd *cmd = &async->cmd; unsigned int i, j; @@ -362,6 +364,7 @@ static int waveform_ai_cmdtest(struct comedi_device *dev, static int waveform_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct waveform_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; if (cmd->flags & TRIG_RT) { @@ -395,6 +398,8 @@ static int waveform_ai_cmd(struct comedi_device *dev, static int waveform_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct waveform_private *devpriv = dev->private; + devpriv->timer_running = 0; del_timer(&devpriv->timer); return 0; @@ -404,6 +409,7 @@ static int waveform_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct waveform_private *devpriv = dev->private; int i, chan = CR_CHAN(insn->chanspec); for (i = 0; i < insn->n; i++) @@ -416,6 +422,7 @@ static int waveform_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct waveform_private *devpriv = dev->private; int i, chan = CR_CHAN(insn->chanspec); for (i = 0; i < insn->n; i++) @@ -428,6 +435,7 @@ static int waveform_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct waveform_board *board = comedi_board(dev); + struct waveform_private *devpriv; struct comedi_subdevice *s; int amplitude = it->options[0]; int period = it->options[1]; @@ -436,8 +444,10 @@ static int waveform_attach(struct comedi_device *dev, dev->board_name = board->name; - if (alloc_private(dev, sizeof(struct waveform_private)) < 0) - return -ENOMEM; + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret < 0) + return ret; + devpriv = dev->private; /* set default amplitude and period */ if (amplitude <= 0) @@ -496,7 +506,9 @@ static int waveform_attach(struct comedi_device *dev, static void waveform_detach(struct comedi_device *dev) { - if (dev->private) + struct waveform_private *devpriv = dev->private; + + if (devpriv) waveform_ai_cancel(dev, dev->read_subdev); } -- cgit v0.10.2 From b1da49430bb2e78616769623638f869c513e6ec1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Aug 2012 15:05:02 -0700 Subject: staging: comedi: comedi_test: remove boardinfo This boardinfo for this driver is unneccesary. This driver is only for testing the comedi subsystem. It defines two dummy subdevices, an 8 channel analog input subdevice and an 8 channel analog output subdevice. There is no "board" associated with it. Remove the boardinfo to keep the driver simple. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c index c77ce75..6864716 100644 --- a/drivers/staging/comedi/drivers/comedi_test.c +++ b/drivers/staging/comedi/drivers/comedi_test.c @@ -57,14 +57,6 @@ zero volts). #include "comedi_fc.h" #include -/* Board descriptions */ -struct waveform_board { - const char *name; - int ai_chans; - int ai_bits; - int have_dio; -}; - #define N_CHANS 8 /* Data unique to this driver */ @@ -434,7 +426,6 @@ static int waveform_ao_insn_write(struct comedi_device *dev, static int waveform_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - const struct waveform_board *board = comedi_board(dev); struct waveform_private *devpriv; struct comedi_subdevice *s; int amplitude = it->options[0]; @@ -442,7 +433,7 @@ static int waveform_attach(struct comedi_device *dev, int i; int ret; - dev->board_name = board->name; + dev->board_name = dev->driver->driver_name; ret = alloc_private(dev, sizeof(*devpriv)); if (ret < 0) @@ -467,8 +458,8 @@ static int waveform_attach(struct comedi_device *dev, /* analog input subdevice */ s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ; - s->n_chan = board->ai_chans; - s->maxdata = (1 << board->ai_bits) - 1; + s->n_chan = N_CHANS; + s->maxdata = 0xffff; s->range_table = &waveform_ai_ranges; s->len_chanlist = s->n_chan * 2; s->insn_read = waveform_ai_insn_read; @@ -481,8 +472,8 @@ static int waveform_attach(struct comedi_device *dev, /* analog output subdevice (loopback) */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITEABLE | SDF_GROUND; - s->n_chan = board->ai_chans; - s->maxdata = (1 << board->ai_bits) - 1; + s->n_chan = N_CHANS; + s->maxdata = 0xffff; s->range_table = &waveform_ai_ranges; s->len_chanlist = s->n_chan * 2; s->insn_write = waveform_ao_insn_write; @@ -512,23 +503,11 @@ static void waveform_detach(struct comedi_device *dev) waveform_ai_cancel(dev, dev->read_subdev); } -static const struct waveform_board waveform_boards[] = { - { - .name = "comedi_test", - .ai_chans = N_CHANS, - .ai_bits = 16, - .have_dio = 0, - }, -}; - static struct comedi_driver waveform_driver = { .driver_name = "comedi_test", .module = THIS_MODULE, .attach = waveform_attach, .detach = waveform_detach, - .board_name = &waveform_boards[0].name, - .offset = sizeof(struct waveform_board), - .num_names = ARRAY_SIZE(waveform_boards), }; module_comedi_driver(waveform_driver); -- cgit v0.10.2 From 9ac6eb40510bf9e6e82435f78f5c1cb92ee3f97a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Aug 2012 15:05:23 -0700 Subject: staging: comedi: comedi_test: convert attach message to dev_info Convert the 'attach' message from a printk to a dev_info. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c index 6864716..8ea9202 100644 --- a/drivers/staging/comedi/drivers/comedi_test.c +++ b/drivers/staging/comedi/drivers/comedi_test.c @@ -489,10 +489,12 @@ static int waveform_attach(struct comedi_device *dev, devpriv->timer.function = waveform_ai_interrupt; devpriv->timer.data = (unsigned long)dev; - printk(KERN_INFO "comedi%d: comedi_test: " - "%i microvolt, %li microsecond waveform attached\n", dev->minor, - devpriv->uvolt_amplitude, devpriv->usec_period); - return 1; + dev_info(dev->class_dev, + "%s: %i microvolt, %li microsecond waveform attached\n", + dev->board_name, + devpriv->uvolt_amplitude, devpriv->usec_period); + + return 0; } static void waveform_detach(struct comedi_device *dev) -- cgit v0.10.2 From 0edc7d8381b1d9f9c15d1590b057e9160032603b Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 24 Aug 2012 17:26:26 +0100 Subject: staging: comedi: serial2002: Set range for digital inputs and outputs I got an update from the original author of this driver (Anders Blomdell) to set the range table for digital input and digital output subdevices. Apply it. Cc: Anders Blomdell Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c index c18314b..0b58eec 100644 --- a/drivers/staging/comedi/drivers/serial2002.c +++ b/drivers/staging/comedi/drivers/serial2002.c @@ -588,7 +588,9 @@ static int serial_2002_open(struct comedi_device *dev) kfree(s->range_table_list); s->range_table = NULL; s->range_table_list = NULL; - if (range) { + if (kind == 1 || kind == 2) { + s->range_table = &range_digital; + } else if (range) { s->range_table_list = range_table_list = kmalloc(sizeof (struct -- cgit v0.10.2 From 4865a47fc3f460c3be52e83a8c85af1381aec19f Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 31 Aug 2012 20:41:31 +0100 Subject: staging: comedi: das08: Remove pc104 bustype value Remove the `pc104` value from `enum das08_bustype` and replace occurrences of it in the code and data with the `isa` value. The code treats them as equivalent anyway with expressions like `(thisboard->bustype == isa || thisboard->bustype == pc104)`. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 67a914a..33279dc 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -635,7 +635,7 @@ static const struct das08_board_struct das08_boards[] = { }, { .name = "pc104-das08", - .bustype = pc104, + .bustype = isa, .ai = das08_ai_rinsn, .ai_nbits = 12, .ai_pg = das08_pg_none, @@ -1004,7 +1004,7 @@ das08_attach(struct comedi_device *dev, struct comedi_devconfig *it) return -EIO; return das08_pci_attach_common(dev, pdev); } else if (IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) && - (thisboard->bustype == isa || thisboard->bustype == pc104)) { + thisboard->bustype == isa) { iobase = it->options[0]; dev_info(dev->class_dev, "iobase 0x%lx\n", iobase); if (!request_region(iobase, thisboard->iosize, DRV_NAME)) { @@ -1029,8 +1029,7 @@ static void __maybe_unused das08_detach(struct comedi_device *dev) struct das08_private_struct *devpriv = dev->private; das08_common_detach(dev); - if (IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) && - (thisboard->bustype == isa || thisboard->bustype == pc104)) { + if (IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) && thisboard->bustype == isa) { if (dev->iobase) release_region(dev->iobase, thisboard->iosize); } else if (IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) && diff --git a/drivers/staging/comedi/drivers/das08.h b/drivers/staging/comedi/drivers/das08.h index 27b6d4e..f80913e 100644 --- a/drivers/staging/comedi/drivers/das08.h +++ b/drivers/staging/comedi/drivers/das08.h @@ -24,7 +24,7 @@ #ifndef _DAS08_H #define _DAS08_H -enum das08_bustype { isa, pci, pcmcia, pc104 }; +enum das08_bustype { isa, pci, pcmcia }; /* different ways ai data is encoded in first two registers */ enum das08_ai_encoding { das08_encode12, das08_encode16, das08_pcm_encode12 }; enum das08_lrange { das08_pg_none, das08_bipolar5, das08_pgh, das08_pgl, -- cgit v0.10.2 From ffd76b327a19b49696635cd6891b9d279a73623e Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 31 Aug 2012 20:41:32 +0100 Subject: staging: comedi: das08: Add number of DI channels in board structure Add member `di_nchan` to `struct das08_board_struct` to set the number of digital input channels explicitly. Currently, the code determines the number of channels to 3 or 8 depending on what function the `di` member points to, which is not very elegant. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 33279dc..d176b3b 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -502,6 +502,7 @@ static const struct das08_board_struct das08_boards[] = { .ao = NULL, .ao_nbits = 12, .di = das08_di_rbits, + .di_nchan = 3, .do_ = das08_do_wbits, .do_nchan = 4, .i8255_offset = 8, @@ -517,6 +518,7 @@ static const struct das08_board_struct das08_boards[] = { .ai_encoding = das08_encode12, .ao = NULL, .di = das08_di_rbits, + .di_nchan = 3, .do_ = das08_do_wbits, .do_nchan = 4, .i8255_offset = 0, @@ -532,6 +534,7 @@ static const struct das08_board_struct das08_boards[] = { .ai_encoding = das08_encode12, .ao = NULL, .di = das08_di_rbits, + .di_nchan = 3, .do_ = das08_do_wbits, .do_nchan = 4, .i8255_offset = 0, @@ -547,6 +550,7 @@ static const struct das08_board_struct das08_boards[] = { .ai_encoding = das08_encode12, .ao = NULL, .di = das08_di_rbits, + .di_nchan = 3, .do_ = das08_do_wbits, .do_nchan = 4, .i8255_offset = 0, @@ -563,6 +567,7 @@ static const struct das08_board_struct das08_boards[] = { .ao = das08ao_ao_winsn, /* 8 */ .ao_nbits = 12, .di = das08_di_rbits, + .di_nchan = 3, .do_ = das08_do_wbits, .do_nchan = 4, .i8255_offset = 0x0c, @@ -579,6 +584,7 @@ static const struct das08_board_struct das08_boards[] = { .ao = das08ao_ao_winsn, /* 8 */ .ao_nbits = 12, .di = das08_di_rbits, + .di_nchan = 3, .do_ = das08_do_wbits, .do_nchan = 4, .i8255_offset = 0x0c, @@ -595,6 +601,7 @@ static const struct das08_board_struct das08_boards[] = { .ao = das08ao_ao_winsn, /* 8 */ .ao_nbits = 12, .di = das08_di_rbits, + .di_nchan = 3, .do_ = das08_do_wbits, .do_nchan = 4, .i8255_offset = 0x0c, @@ -611,6 +618,7 @@ static const struct das08_board_struct das08_boards[] = { .ao = das08jr_ao_winsn, .ao_nbits = 12, .di = das08jr_di_rbits, + .di_nchan = 8, .do_ = das08jr_do_wbits, .do_nchan = 8, .i8255_offset = 0, @@ -627,6 +635,7 @@ static const struct das08_board_struct das08_boards[] = { .ao = das08jr_ao_winsn, .ao_nbits = 16, .di = das08jr_di_rbits, + .di_nchan = 8, .do_ = das08jr_do_wbits, .do_nchan = 8, .i8255_offset = 0, @@ -643,6 +652,7 @@ static const struct das08_board_struct das08_boards[] = { .ao = NULL, .ao_nbits = 0, .di = das08_di_rbits, + .di_nchan = 3, .do_ = das08_do_wbits, .do_nchan = 4, .i8255_offset = 0, @@ -667,6 +677,7 @@ static const struct das08_board_struct das08_boards[] = { .ao = NULL, .ao_nbits = 0, .di = das08jr_di_rbits, + .di_nchan = 8, .do_ = das08jr_do_wbits, .do_nchan = 8, .i8255_offset = 0, @@ -694,6 +705,7 @@ static const struct das08_board_struct das08_boards[] = { .ao = NULL, .ao_nbits = 0, .di = das08_di_rbits, + .di_nchan = 3, .do_ = das08_do_wbits, .do_nchan = 4, .i8255_offset = 0, @@ -722,6 +734,7 @@ struct das08_board_struct das08_cs_boards[NUM_DAS08_CS_BOARDS] = { .ao = NULL, .ao_nbits = 0, .di = das08_di_rbits, + .di_nchan = 3, .do_ = das08_do_wbits, .do_nchan = 3, .i8255_offset = 0, @@ -740,6 +753,7 @@ struct das08_board_struct das08_cs_boards[NUM_DAS08_CS_BOARDS] = { .ao = NULL, .ao_nbits = 0, .di = das08_di_rbits, + .di_nchan = 3, .do_ = das08_do_wbits, .do_nchan = 3, .i8255_offset = 0, @@ -803,7 +817,7 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase) if (thisboard->di) { s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; - s->n_chan = (thisboard->di == das08_di_rbits) ? 3 : 8; + s->n_chan = thisboard->di_nchan; s->maxdata = 1; s->range_table = &range_digital; s->insn_bits = thisboard->di; diff --git a/drivers/staging/comedi/drivers/das08.h b/drivers/staging/comedi/drivers/das08.h index f80913e..320f56a 100644 --- a/drivers/staging/comedi/drivers/das08.h +++ b/drivers/staging/comedi/drivers/das08.h @@ -42,6 +42,7 @@ struct das08_board_struct { void *ao; unsigned int ao_nbits; void *di; + unsigned int di_nchan; void *do_; unsigned int do_nchan; unsigned int i8255_offset; -- cgit v0.10.2 From 1effe42da1ee4b424ccd2f8abaea5f838ef6ac93 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 31 Aug 2012 20:41:33 +0100 Subject: staging: comedi: das08: Mark 'JR' boards in board data Add a bool member `is_jr` to `struct das08_board_struct` and initialize it to `true` in those elements of `das08_boards[]` corresponding to the 'JR' board models. This will be used by a following patch that removes the `ai`, `ao`, `di` and `do` members from `struct das08_board_struct`. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index d176b3b..e17a71e 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -611,6 +611,7 @@ static const struct das08_board_struct das08_boards[] = { { .name = "das08/jr-ao", /* cio-das08-jr-ao.pdf */ .bustype = isa, + .is_jr = true, .ai = das08_ai_rinsn, .ai_nbits = 12, .ai_pg = das08_pg_none, @@ -628,6 +629,7 @@ static const struct das08_board_struct das08_boards[] = { { .name = "das08jr-16-ao", /* cio-das08jr-16-ao.pdf */ .bustype = isa, + .is_jr = true, .ai = das08_ai_rinsn, .ai_nbits = 16, .ai_pg = das08_pg_none, @@ -670,6 +672,7 @@ static const struct das08_board_struct das08_boards[] = { { .name = "das08jr/16", .bustype = isa, + .is_jr = true, .ai = das08_ai_rinsn, .ai_nbits = 16, .ai_pg = das08_pg_none, diff --git a/drivers/staging/comedi/drivers/das08.h b/drivers/staging/comedi/drivers/das08.h index 320f56a..5e00530 100644 --- a/drivers/staging/comedi/drivers/das08.h +++ b/drivers/staging/comedi/drivers/das08.h @@ -35,6 +35,7 @@ struct das08_board_struct { const char *name; unsigned int id; /* id for pci/pcmcia boards */ enum das08_bustype bustype; + bool is_jr; /* true for 'JR' boards */ void *ai; unsigned int ai_nbits; enum das08_lrange ai_pg; -- cgit v0.10.2 From dd2ac5d4b7ea7025e6f6e3975bc581944412a7fe Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 31 Aug 2012 20:41:34 +0100 Subject: staging: comedi: das08: Remove function pointers from board structure Remove the `ai`, `ao`, `di` and `do` pointers from `struct das08_board_struct`. These were initialized in `das08_boards[]` and `das08_cs_boards[]` to point to comedi instruction handler functions for the subdevice, but there are only two sets of functions depending on whether the `is_jr` member is true or false, and some of the functions will be NULL if the corresponding `ai_nbits`, `ao_nbits`, `di_nchan` and `do_nchan` members are zero. Determine which handler functions to use in das08_common_attach(). One element of `das08_boards[]` had `ao` set to NULL and `ao_nbits` set to 12. Set `ao_nbits` to 0 in this case to let das08_common_attach() know this board has no AO subdevice. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index e17a71e..8ba8369 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -495,15 +495,10 @@ static const struct das08_board_struct das08_boards[] = { { .name = "isa-das08", /* cio-das08.pdf */ .bustype = isa, - .ai = das08_ai_rinsn, .ai_nbits = 12, .ai_pg = das08_pg_none, .ai_encoding = das08_encode12, - .ao = NULL, - .ao_nbits = 12, - .di = das08_di_rbits, .di_nchan = 3, - .do_ = das08_do_wbits, .do_nchan = 4, .i8255_offset = 8, .i8254_offset = 4, @@ -512,14 +507,10 @@ static const struct das08_board_struct das08_boards[] = { { .name = "das08-pgm", /* cio-das08pgx.pdf */ .bustype = isa, - .ai = das08_ai_rinsn, .ai_nbits = 12, .ai_pg = das08_pgm, .ai_encoding = das08_encode12, - .ao = NULL, - .di = das08_di_rbits, .di_nchan = 3, - .do_ = das08_do_wbits, .do_nchan = 4, .i8255_offset = 0, .i8254_offset = 0x04, @@ -528,14 +519,10 @@ static const struct das08_board_struct das08_boards[] = { { .name = "das08-pgh", /* cio-das08pgx.pdf */ .bustype = isa, - .ai = das08_ai_rinsn, .ai_nbits = 12, .ai_pg = das08_pgh, .ai_encoding = das08_encode12, - .ao = NULL, - .di = das08_di_rbits, .di_nchan = 3, - .do_ = das08_do_wbits, .do_nchan = 4, .i8255_offset = 0, .i8254_offset = 0x04, @@ -544,14 +531,10 @@ static const struct das08_board_struct das08_boards[] = { { .name = "das08-pgl", /* cio-das08pgx.pdf */ .bustype = isa, - .ai = das08_ai_rinsn, .ai_nbits = 12, .ai_pg = das08_pgl, .ai_encoding = das08_encode12, - .ao = NULL, - .di = das08_di_rbits, .di_nchan = 3, - .do_ = das08_do_wbits, .do_nchan = 4, .i8255_offset = 0, .i8254_offset = 0x04, @@ -560,15 +543,11 @@ static const struct das08_board_struct das08_boards[] = { { .name = "das08-aoh", /* cio-das08_aox.pdf */ .bustype = isa, - .ai = das08_ai_rinsn, .ai_nbits = 12, .ai_pg = das08_pgh, .ai_encoding = das08_encode12, - .ao = das08ao_ao_winsn, /* 8 */ .ao_nbits = 12, - .di = das08_di_rbits, .di_nchan = 3, - .do_ = das08_do_wbits, .do_nchan = 4, .i8255_offset = 0x0c, .i8254_offset = 0x04, @@ -577,15 +556,11 @@ static const struct das08_board_struct das08_boards[] = { { .name = "das08-aol", /* cio-das08_aox.pdf */ .bustype = isa, - .ai = das08_ai_rinsn, .ai_nbits = 12, .ai_pg = das08_pgl, .ai_encoding = das08_encode12, - .ao = das08ao_ao_winsn, /* 8 */ .ao_nbits = 12, - .di = das08_di_rbits, .di_nchan = 3, - .do_ = das08_do_wbits, .do_nchan = 4, .i8255_offset = 0x0c, .i8254_offset = 0x04, @@ -594,15 +569,11 @@ static const struct das08_board_struct das08_boards[] = { { .name = "das08-aom", /* cio-das08_aox.pdf */ .bustype = isa, - .ai = das08_ai_rinsn, .ai_nbits = 12, .ai_pg = das08_pgm, .ai_encoding = das08_encode12, - .ao = das08ao_ao_winsn, /* 8 */ .ao_nbits = 12, - .di = das08_di_rbits, .di_nchan = 3, - .do_ = das08_do_wbits, .do_nchan = 4, .i8255_offset = 0x0c, .i8254_offset = 0x04, @@ -612,15 +583,11 @@ static const struct das08_board_struct das08_boards[] = { .name = "das08/jr-ao", /* cio-das08-jr-ao.pdf */ .bustype = isa, .is_jr = true, - .ai = das08_ai_rinsn, .ai_nbits = 12, .ai_pg = das08_pg_none, .ai_encoding = das08_encode12, - .ao = das08jr_ao_winsn, .ao_nbits = 12, - .di = das08jr_di_rbits, .di_nchan = 8, - .do_ = das08jr_do_wbits, .do_nchan = 8, .i8255_offset = 0, .i8254_offset = 0, @@ -630,15 +597,11 @@ static const struct das08_board_struct das08_boards[] = { .name = "das08jr-16-ao", /* cio-das08jr-16-ao.pdf */ .bustype = isa, .is_jr = true, - .ai = das08_ai_rinsn, .ai_nbits = 16, .ai_pg = das08_pg_none, .ai_encoding = das08_encode16, - .ao = das08jr_ao_winsn, .ao_nbits = 16, - .di = das08jr_di_rbits, .di_nchan = 8, - .do_ = das08jr_do_wbits, .do_nchan = 8, .i8255_offset = 0, .i8254_offset = 0x04, @@ -647,15 +610,10 @@ static const struct das08_board_struct das08_boards[] = { { .name = "pc104-das08", .bustype = isa, - .ai = das08_ai_rinsn, .ai_nbits = 12, .ai_pg = das08_pg_none, .ai_encoding = das08_encode12, - .ao = NULL, - .ao_nbits = 0, - .di = das08_di_rbits, .di_nchan = 3, - .do_ = das08_do_wbits, .do_nchan = 4, .i8255_offset = 0, .i8254_offset = 4, @@ -673,15 +631,10 @@ static const struct das08_board_struct das08_boards[] = { .name = "das08jr/16", .bustype = isa, .is_jr = true, - .ai = das08_ai_rinsn, .ai_nbits = 16, .ai_pg = das08_pg_none, .ai_encoding = das08_encode16, - .ao = NULL, - .ao_nbits = 0, - .di = das08jr_di_rbits, .di_nchan = 8, - .do_ = das08jr_do_wbits, .do_nchan = 8, .i8255_offset = 0, .i8254_offset = 0, @@ -701,15 +654,10 @@ static const struct das08_board_struct das08_boards[] = { .name = "pci-das08", /* pci-das08 */ .id = PCI_DEVICE_ID_PCIDAS08, .bustype = pci, - .ai = das08_ai_rinsn, .ai_nbits = 12, .ai_pg = das08_bipolar5, .ai_encoding = das08_encode12, - .ao = NULL, - .ao_nbits = 0, - .di = das08_di_rbits, .di_nchan = 3, - .do_ = das08_do_wbits, .do_nchan = 4, .i8255_offset = 0, .i8254_offset = 4, @@ -730,15 +678,10 @@ struct das08_board_struct das08_cs_boards[NUM_DAS08_CS_BOARDS] = { .name = "pcm-das08", .id = 0x0, /* XXX */ .bustype = pcmcia, - .ai = das08_ai_rinsn, .ai_nbits = 12, .ai_pg = das08_bipolar5, .ai_encoding = das08_pcm_encode12, - .ao = NULL, - .ao_nbits = 0, - .di = das08_di_rbits, .di_nchan = 3, - .do_ = das08_do_wbits, .do_nchan = 3, .i8255_offset = 0, .i8254_offset = 0, @@ -749,15 +692,10 @@ struct das08_board_struct das08_cs_boards[NUM_DAS08_CS_BOARDS] = { .name = "das08_cs", .id = 0x0, /* XXX */ .bustype = pcmcia, - .ai = das08_ai_rinsn, .ai_nbits = 12, .ai_pg = das08_bipolar5, .ai_encoding = das08_pcm_encode12, - .ao = NULL, - .ao_nbits = 0, - .di = das08_di_rbits, .di_nchan = 3, - .do_ = das08_do_wbits, .do_nchan = 3, .i8255_offset = 0, .i8254_offset = 0, @@ -784,7 +722,7 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase) s = dev->subdevices + 0; /* ai */ - if (thisboard->ai) { + if (thisboard->ai_nbits) { s->type = COMEDI_SUBD_AI; /* XXX some boards actually have differential * inputs instead of single ended. @@ -795,7 +733,7 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase) s->n_chan = 8; s->maxdata = (1 << thisboard->ai_nbits) - 1; s->range_table = das08_ai_lranges[thisboard->ai_pg]; - s->insn_read = thisboard->ai; + s->insn_read = das08_ai_rinsn; devpriv->pg_gainlist = das08_gainlists[thisboard->ai_pg]; } else { s->type = COMEDI_SUBD_UNUSED; @@ -803,40 +741,43 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase) s = dev->subdevices + 1; /* ao */ - if (thisboard->ao) { + if (thisboard->ao_nbits) { s->type = COMEDI_SUBD_AO; /* XXX lacks read-back insn */ s->subdev_flags = SDF_WRITABLE; s->n_chan = 2; s->maxdata = (1 << thisboard->ao_nbits) - 1; s->range_table = &range_bipolar5; - s->insn_write = thisboard->ao; + s->insn_write = + thisboard->is_jr ? das08jr_ao_winsn : das08ao_ao_winsn; } else { s->type = COMEDI_SUBD_UNUSED; } s = dev->subdevices + 2; /* di */ - if (thisboard->di) { + if (thisboard->di_nchan) { s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; s->n_chan = thisboard->di_nchan; s->maxdata = 1; s->range_table = &range_digital; - s->insn_bits = thisboard->di; + s->insn_bits = + thisboard->is_jr ? das08jr_di_rbits : das08_di_rbits; } else { s->type = COMEDI_SUBD_UNUSED; } s = dev->subdevices + 3; /* do */ - if (thisboard->do_) { + if (thisboard->do_nchan) { s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE | SDF_READABLE; s->n_chan = thisboard->do_nchan; s->maxdata = 1; s->range_table = &range_digital; - s->insn_bits = thisboard->do_; + s->insn_bits = + thisboard->is_jr ? das08jr_do_wbits : das08_do_wbits; } else { s->type = COMEDI_SUBD_UNUSED; } diff --git a/drivers/staging/comedi/drivers/das08.h b/drivers/staging/comedi/drivers/das08.h index 5e00530..d70d319 100644 --- a/drivers/staging/comedi/drivers/das08.h +++ b/drivers/staging/comedi/drivers/das08.h @@ -36,15 +36,11 @@ struct das08_board_struct { unsigned int id; /* id for pci/pcmcia boards */ enum das08_bustype bustype; bool is_jr; /* true for 'JR' boards */ - void *ai; unsigned int ai_nbits; enum das08_lrange ai_pg; enum das08_ai_encoding ai_encoding; - void *ao; unsigned int ao_nbits; - void *di; unsigned int di_nchan; - void *do_; unsigned int do_nchan; unsigned int i8255_offset; unsigned int i8254_offset; -- cgit v0.10.2 From 5bacadc84bc6dc217e3b5eb2efa14902df78a143 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 31 Aug 2012 20:41:35 +0100 Subject: staging: comedi: das08: Avoid zero initializers in board structure Don't bother initializing the `i8255_offset` and/or `i8254_offset` members of `struct das08_board_struct` in `das08_boards[]` and `das08_cs_boards[]` if they are zero as they are implicitly initialized to zero anyway, and zero means the corresponding subdevices are absent. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 8ba8369..78ee0be 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -524,7 +524,6 @@ static const struct das08_board_struct das08_boards[] = { .ai_encoding = das08_encode12, .di_nchan = 3, .do_nchan = 4, - .i8255_offset = 0, .i8254_offset = 0x04, .iosize = 16, /* unchecked */ }, @@ -536,7 +535,6 @@ static const struct das08_board_struct das08_boards[] = { .ai_encoding = das08_encode12, .di_nchan = 3, .do_nchan = 4, - .i8255_offset = 0, .i8254_offset = 0x04, .iosize = 16, /* unchecked */ }, @@ -589,8 +587,6 @@ static const struct das08_board_struct das08_boards[] = { .ao_nbits = 12, .di_nchan = 8, .do_nchan = 8, - .i8255_offset = 0, - .i8254_offset = 0, .iosize = 16, /* unchecked */ }, { @@ -603,7 +599,6 @@ static const struct das08_board_struct das08_boards[] = { .ao_nbits = 16, .di_nchan = 8, .do_nchan = 8, - .i8255_offset = 0, .i8254_offset = 0x04, .iosize = 16, /* unchecked */ }, @@ -615,7 +610,6 @@ static const struct das08_board_struct das08_boards[] = { .ai_encoding = das08_encode12, .di_nchan = 3, .do_nchan = 4, - .i8255_offset = 0, .i8254_offset = 4, .iosize = 16, /* unchecked */ }, @@ -636,8 +630,6 @@ static const struct das08_board_struct das08_boards[] = { .ai_encoding = das08_encode16, .di_nchan = 8, .do_nchan = 8, - .i8255_offset = 0, - .i8254_offset = 0, .iosize = 16, /* unchecked */ }, #if 0 @@ -659,7 +651,6 @@ static const struct das08_board_struct das08_boards[] = { .ai_encoding = das08_encode12, .di_nchan = 3, .do_nchan = 4, - .i8255_offset = 0, .i8254_offset = 4, .iosize = 8, }, @@ -683,8 +674,6 @@ struct das08_board_struct das08_cs_boards[NUM_DAS08_CS_BOARDS] = { .ai_encoding = das08_pcm_encode12, .di_nchan = 3, .do_nchan = 3, - .i8255_offset = 0, - .i8254_offset = 0, .iosize = 16, }, /* duplicate so driver name can be used also */ @@ -697,8 +686,6 @@ struct das08_board_struct das08_cs_boards[NUM_DAS08_CS_BOARDS] = { .ai_encoding = das08_pcm_encode12, .di_nchan = 3, .do_nchan = 3, - .i8255_offset = 0, - .i8254_offset = 0, .iosize = 16, }, }; -- cgit v0.10.2 From 383ecb88c1ec2b9875d4ab2d7dc1a818bce5a693 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 31 Aug 2012 20:41:36 +0100 Subject: staging: comedi: das08,das08_cs: Move das08_cs_boards[] Move `das08_cs_boards[]` from "das08.c" to "das08_cs.c" and make it static const. It no longer refers to anything in "das08.c" and no longer needs to be exported. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 78ee0be..1db86c8 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -663,35 +663,6 @@ static const struct das08_board_struct das08_boards[] = { }; #endif /* DO_COMEDI_DRIVER_REGISTER */ -#if IS_ENABLED(CONFIG_COMEDI_DAS08_CS) -struct das08_board_struct das08_cs_boards[NUM_DAS08_CS_BOARDS] = { - { - .name = "pcm-das08", - .id = 0x0, /* XXX */ - .bustype = pcmcia, - .ai_nbits = 12, - .ai_pg = das08_bipolar5, - .ai_encoding = das08_pcm_encode12, - .di_nchan = 3, - .do_nchan = 3, - .iosize = 16, - }, - /* duplicate so driver name can be used also */ - { - .name = "das08_cs", - .id = 0x0, /* XXX */ - .bustype = pcmcia, - .ai_nbits = 12, - .ai_pg = das08_bipolar5, - .ai_encoding = das08_pcm_encode12, - .di_nchan = 3, - .do_nchan = 3, - .iosize = 16, - }, -}; -EXPORT_SYMBOL_GPL(das08_cs_boards); -#endif - int das08_common_attach(struct comedi_device *dev, unsigned long iobase) { const struct das08_board_struct *thisboard = comedi_board(dev); diff --git a/drivers/staging/comedi/drivers/das08.h b/drivers/staging/comedi/drivers/das08.h index d70d319..48fa183 100644 --- a/drivers/staging/comedi/drivers/das08.h +++ b/drivers/staging/comedi/drivers/das08.h @@ -56,9 +56,6 @@ struct das08_private_struct { unsigned int i8254_iobase; }; -#define NUM_DAS08_CS_BOARDS 2 -extern struct das08_board_struct das08_cs_boards[NUM_DAS08_CS_BOARDS]; - int das08_common_attach(struct comedi_device *dev, unsigned long iobase); void das08_common_detach(struct comedi_device *dev); diff --git a/drivers/staging/comedi/drivers/das08_cs.c b/drivers/staging/comedi/drivers/das08_cs.c index f5700de..e4c91e6 100644 --- a/drivers/staging/comedi/drivers/das08_cs.c +++ b/drivers/staging/comedi/drivers/das08_cs.c @@ -58,6 +58,32 @@ Command support does not exist, but could be added for this board. #include #include +static const struct das08_board_struct das08_cs_boards[] = { + { + .name = "pcm-das08", + .id = 0x0, /* XXX */ + .bustype = pcmcia, + .ai_nbits = 12, + .ai_pg = das08_bipolar5, + .ai_encoding = das08_pcm_encode12, + .di_nchan = 3, + .do_nchan = 3, + .iosize = 16, + }, + /* duplicate so driver name can be used also */ + { + .name = "das08_cs", + .id = 0x0, /* XXX */ + .bustype = pcmcia, + .ai_nbits = 12, + .ai_pg = das08_bipolar5, + .ai_encoding = das08_pcm_encode12, + .di_nchan = 3, + .do_nchan = 3, + .iosize = 16, + }, +}; + static struct pcmcia_device *cur_dev; static int das08_cs_attach(struct comedi_device *dev, -- cgit v0.10.2 From 9fcd4853f7c642cda6d5d84ba2236d0af7c38336 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 31 Aug 2012 20:41:37 +0100 Subject: staging: comedi: das08: Remove dead code Remove the code that has been in `#if 0` for a long time. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 1db86c8..7f1b247 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -383,13 +383,8 @@ das08jr_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, chan = CR_CHAN(insn->chanspec); for (n = 0; n < insn->n; n++) { -#if 0 - outb(lsb, dev->iobase + devpriv->ao_offset_lsb[chan]); - outb(msb, dev->iobase + devpriv->ao_offset_msb[chan]); -#else outb(lsb, dev->iobase + DAS08JR_AO_LSB(chan)); outb(msb, dev->iobase + DAS08JR_AO_MSB(chan)); -#endif /* load DACs */ inb(dev->iobase + DAS08JR_DIO); @@ -418,13 +413,8 @@ das08ao_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, chan = CR_CHAN(insn->chanspec); for (n = 0; n < insn->n; n++) { -#if 0 - outb(lsb, dev->iobase + devpriv->ao_offset_lsb[chan]); - outb(msb, dev->iobase + devpriv->ao_offset_msb[chan]); -#else outb(lsb, dev->iobase + DAS08AO_AO_LSB(chan)); outb(msb, dev->iobase + DAS08AO_AO_MSB(chan)); -#endif /* load DACs */ inb(dev->iobase + DAS08AO_AO_UPDATE); @@ -613,14 +603,6 @@ static const struct das08_board_struct das08_boards[] = { .i8254_offset = 4, .iosize = 16, /* unchecked */ }, -#if 0 - { - .name = "das08/f", - }, - { - .name = "das08jr", - }, -#endif { .name = "das08jr/16", .bustype = isa, @@ -632,14 +614,6 @@ static const struct das08_board_struct das08_boards[] = { .do_nchan = 8, .iosize = 16, /* unchecked */ }, -#if 0 - { - .name = "das48-pga", /* cio-das48-pga.pdf */ - }, - { - .name = "das08-pga-g2", /* a KM board */ - }, -#endif #endif /* IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) */ #if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) { @@ -794,17 +768,6 @@ static int das08_pci_attach_common(struct comedi_device *dev, dev_info(dev->class_dev, "pcibase 0x%lx iobase 0x%lx\n", pci_iobase, iobase); devpriv->pci_iobase = pci_iobase; -#if 0 - /* We could enable pci-das08's interrupt here to make it possible - * to do timed input in this driver, but there is little point since - * conversions would have to be started by the interrupt handler - * so you might as well use comedi_rt_timer to emulate commands - */ - /* set source of interrupt trigger to counter2 output */ - outb(CNTRL_INTR | CNTRL_DIR, pci_iobase + CNTRL); - /* Enable local interrupt 1 and pci interrupt */ - outw(INTR1_ENABLE | PCI_INTR_ENABLE, pci_iobase + INTCSR); -#endif return das08_common_attach(dev, iobase); } -- cgit v0.10.2 From fb8ff5d501e8b461d604db941673efbc7dc9d347 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 31 Aug 2012 20:41:38 +0100 Subject: staging: comedi: das08: Remove pci_iobase from private data The `pci_iobase` I/O port registers from PCI BAR 1 are never accessed, so don't bother storing this base address in `struct das08_private_struct`. The `pci_iobase` member was checked for non-zero in `das08_detach()` but we can check `dev->iobase` is non-zero instead. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 7f1b247..9d33b5a 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -749,7 +749,6 @@ static int das08_pci_attach_common(struct comedi_device *dev, struct pci_dev *pdev) { unsigned long iobase; - unsigned long pci_iobase; struct das08_private_struct *devpriv = dev->private; if (!IS_ENABLED(CONFIG_COMEDI_DAS08_PCI)) @@ -763,11 +762,8 @@ static int das08_pci_attach_common(struct comedi_device *dev, return -EIO; } /* read base addresses */ - pci_iobase = pci_resource_start(pdev, 1); iobase = pci_resource_start(pdev, 2); - dev_info(dev->class_dev, "pcibase 0x%lx iobase 0x%lx\n", - pci_iobase, iobase); - devpriv->pci_iobase = pci_iobase; + dev_info(dev->class_dev, "iobase 0x%lx\n", iobase); return das08_common_attach(dev, iobase); } @@ -914,7 +910,7 @@ static void __maybe_unused das08_detach(struct comedi_device *dev) } else if (IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) && thisboard->bustype == pci) { if (devpriv && devpriv->pdev) { - if (devpriv->pci_iobase) + if (dev->iobase) comedi_pci_disable(devpriv->pdev); pci_dev_put(devpriv->pdev); } diff --git a/drivers/staging/comedi/drivers/das08.h b/drivers/staging/comedi/drivers/das08.h index 48fa183..af3024e 100644 --- a/drivers/staging/comedi/drivers/das08.h +++ b/drivers/staging/comedi/drivers/das08.h @@ -52,7 +52,6 @@ struct das08_private_struct { unsigned int do_bits; /* bits for do register on boards with register dedicated to digital out only */ const unsigned int *pg_gainlist; struct pci_dev *pdev; /* struct for pci-das08 */ - unsigned int pci_iobase; /* additional base address for pci-das08 */ unsigned int i8254_iobase; }; -- cgit v0.10.2 From 4d31848a737206fc2d309aa4f37c4f390182fda2 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 31 Aug 2012 20:41:39 +0100 Subject: staging: comedi: das08: Remove i8254_iobase from private data The I/O port base address for the counter subdevice doesn't need to be stored in the private data. It can be calculated on the fly using the offset in the static board data. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 9d33b5a..9a97bc2 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -425,22 +425,24 @@ das08ao_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, static void i8254_initialize(struct comedi_device *dev) { - struct das08_private_struct *devpriv = dev->private; + const struct das08_board_struct *thisboard = comedi_board(dev); + unsigned long i8254_iobase = dev->iobase + thisboard->i8254_offset; unsigned int mode = I8254_MODE0 | I8254_BINARY; int i; for (i = 0; i < 3; ++i) - i8254_set_mode(devpriv->i8254_iobase, 0, i, mode); + i8254_set_mode(i8254_iobase, 0, i, mode); } static int das08_counter_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - struct das08_private_struct *devpriv = dev->private; + const struct das08_board_struct *thisboard = comedi_board(dev); + unsigned long i8254_iobase = dev->iobase + thisboard->i8254_offset; int chan = insn->chanspec; - data[0] = i8254_read(devpriv->i8254_iobase, 0, chan); + data[0] = i8254_read(i8254_iobase, 0, chan); return 1; } @@ -448,10 +450,11 @@ static int das08_counter_write(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - struct das08_private_struct *devpriv = dev->private; + const struct das08_board_struct *thisboard = comedi_board(dev); + unsigned long i8254_iobase = dev->iobase + thisboard->i8254_offset; int chan = insn->chanspec; - i8254_write(devpriv->i8254_iobase, 0, chan, data[0]); + i8254_write(i8254_iobase, 0, chan, data[0]); return 1; } @@ -459,7 +462,8 @@ static int das08_counter_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - struct das08_private_struct *devpriv = dev->private; + const struct das08_board_struct *thisboard = comedi_board(dev); + unsigned long i8254_iobase = dev->iobase + thisboard->i8254_offset; int chan = insn->chanspec; if (insn->n != 2) @@ -467,10 +471,10 @@ static int das08_counter_config(struct comedi_device *dev, switch (data[0]) { case INSN_CONFIG_SET_COUNTER_MODE: - i8254_set_mode(devpriv->i8254_iobase, 0, chan, data[1]); + i8254_set_mode(i8254_iobase, 0, chan, data[1]); break; case INSN_CONFIG_8254_READ_STATUS: - data[1] = i8254_status(devpriv->i8254_iobase, 0, chan); + data[1] = i8254_status(i8254_iobase, 0, chan); break; default: return -EINVAL; @@ -734,8 +738,6 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase) s->insn_read = das08_counter_read; s->insn_write = das08_counter_write; s->insn_config = das08_counter_config; - - devpriv->i8254_iobase = iobase + thisboard->i8254_offset; i8254_initialize(dev); } else { s->type = COMEDI_SUBD_UNUSED; diff --git a/drivers/staging/comedi/drivers/das08.h b/drivers/staging/comedi/drivers/das08.h index af3024e..5a33993 100644 --- a/drivers/staging/comedi/drivers/das08.h +++ b/drivers/staging/comedi/drivers/das08.h @@ -52,7 +52,6 @@ struct das08_private_struct { unsigned int do_bits; /* bits for do register on boards with register dedicated to digital out only */ const unsigned int *pg_gainlist; struct pci_dev *pdev; /* struct for pci-das08 */ - unsigned int i8254_iobase; }; int das08_common_attach(struct comedi_device *dev, unsigned long iobase); -- cgit v0.10.2 From f8165b7d49e4dc4c47cf944f136a9c9967beb24e Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 31 Aug 2012 20:41:40 +0100 Subject: staging: comedi: das08: No need to check insn->n for counter config There is no need to check the value of `insn->n` is correct in `das08_counter_config()` as the core comedi module will have already checked it. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 9a97bc2..4d1d882 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -466,9 +466,6 @@ static int das08_counter_config(struct comedi_device *dev, unsigned long i8254_iobase = dev->iobase + thisboard->i8254_offset; int chan = insn->chanspec; - if (insn->n != 2) - return -EINVAL; - switch (data[0]) { case INSN_CONFIG_SET_COUNTER_MODE: i8254_set_mode(i8254_iobase, 0, chan, data[1]); -- cgit v0.10.2 From 624fcb2661e8139fbea5a097ef341cab623be591 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 31 Aug 2012 20:41:41 +0100 Subject: staging: comedi: das08: Unmark some __maybe_unused functions The `das08jr_di_rbits()`, `das08jr_do_wbits()`, `das08jr_ao_winsn()` and `das08ao_ao_winsn()` static functions are currently marked as `__maybe_unused` as they were formerly only referred to by possibly conditionally compiled out code. This is no longer the case (they are referred to by `das08_common_attach()`) so their `__maybe_unused` tags can be removed. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 4d1d882..6aa8064 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -342,9 +342,9 @@ static int das08_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, return insn->n; } -static int __maybe_unused -das08jr_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int das08jr_di_rbits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) { data[0] = 0; data[1] = inb(dev->iobase + DAS08JR_DIO); @@ -352,9 +352,9 @@ das08jr_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s, return insn->n; } -static int __maybe_unused -das08jr_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int das08jr_do_wbits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) { struct das08_private_struct *devpriv = dev->private; @@ -369,9 +369,9 @@ das08jr_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, return insn->n; } -static int __maybe_unused -das08jr_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int das08jr_ao_winsn(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) { int n; int lsb, msb; @@ -399,9 +399,9 @@ das08jr_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, * a different method to force an update. * */ -static int __maybe_unused -das08ao_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int das08ao_ao_winsn(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) { int n; int lsb, msb; -- cgit v0.10.2 From 3b85aa6378b2a978f7bf38096c6309e771b218b0 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 31 Aug 2012 20:41:42 +0100 Subject: staging: comedi: das08: Rearrange AO write functions Combine the AO write functions for 'JR' boards and other boards into a single function and factor out the data writing from the comedi instruction handling so it can be called from elsewhere in a later patch. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 6aa8064..13e6ac7 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -369,56 +369,39 @@ static int das08jr_do_wbits(struct comedi_device *dev, return insn->n; } -static int das08jr_ao_winsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static void das08_ao_set_data(struct comedi_device *dev, + unsigned int chan, unsigned int data) { - int n; - int lsb, msb; - int chan; - - lsb = data[0] & 0xff; - msb = (data[0] >> 8) & 0xff; - - chan = CR_CHAN(insn->chanspec); + const struct das08_board_struct *thisboard = comedi_board(dev); + unsigned char lsb; + unsigned char msb; - for (n = 0; n < insn->n; n++) { + lsb = data & 0xff; + msb = (data >> 8) & 0xff; + if (thisboard->is_jr) { outb(lsb, dev->iobase + DAS08JR_AO_LSB(chan)); outb(msb, dev->iobase + DAS08JR_AO_MSB(chan)); - /* load DACs */ inb(dev->iobase + DAS08JR_DIO); + } else { + outb(lsb, dev->iobase + DAS08AO_AO_LSB(chan)); + outb(msb, dev->iobase + DAS08AO_AO_MSB(chan)); + /* load DACs */ + inb(dev->iobase + DAS08AO_AO_UPDATE); } - - return n; } -/* - * - * The -aox boards have the DACs at a different offset and use - * a different method to force an update. - * - */ -static int das08ao_ao_winsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int das08_ao_winsn(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) { - int n; - int lsb, msb; - int chan; - - lsb = data[0] & 0xff; - msb = (data[0] >> 8) & 0xf; + unsigned int n; + unsigned int chan; chan = CR_CHAN(insn->chanspec); - for (n = 0; n < insn->n; n++) { - outb(lsb, dev->iobase + DAS08AO_AO_LSB(chan)); - outb(msb, dev->iobase + DAS08AO_AO_MSB(chan)); - - /* load DACs */ - inb(dev->iobase + DAS08AO_AO_UPDATE); - } + for (n = 0; n < insn->n; n++) + das08_ao_set_data(dev, chan, *data); return n; } @@ -681,8 +664,7 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase) s->n_chan = 2; s->maxdata = (1 << thisboard->ao_nbits) - 1; s->range_table = &range_bipolar5; - s->insn_write = - thisboard->is_jr ? das08jr_ao_winsn : das08ao_ao_winsn; + s->insn_write = das08_ao_winsn; } else { s->type = COMEDI_SUBD_UNUSED; } -- cgit v0.10.2 From 8432eb35a924440e21bccd965009b101a37a3aad Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 31 Aug 2012 20:41:43 +0100 Subject: staging: comedi: das08: Initialize AO channels Initialize the AO subdevice channels to mid-range data value so they are in a known state. This allows us to support reading back the current value in a later patch. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 13e6ac7..0457b9b 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -391,6 +391,17 @@ static void das08_ao_set_data(struct comedi_device *dev, } } +static void das08_ao_initialize(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + int n; + unsigned int data; + + data = s->maxdata / 2; /* should be about 0 volts */ + for (n = 0; n < s->n_chan; n++) + das08_ao_set_data(dev, n, data); +} + static int das08_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -665,6 +676,7 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase) s->maxdata = (1 << thisboard->ao_nbits) - 1; s->range_table = &range_bipolar5; s->insn_write = das08_ao_winsn; + das08_ao_initialize(dev, s); } else { s->type = COMEDI_SUBD_UNUSED; } -- cgit v0.10.2 From f0ba1d6e19c5e7f91005eaa4d9c14851e217feea Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 31 Aug 2012 20:41:44 +0100 Subject: staging: comedi: das08: Support read-back of AO subdevice Stash the last value written to each AO channel in private data and support the INSN_READ instruction to read it back. Don't bother setting the SDF_READABLE subdevice flag though as the hardware isn't really readable - we're just faking it. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 0457b9b..623e77e 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -373,6 +373,7 @@ static void das08_ao_set_data(struct comedi_device *dev, unsigned int chan, unsigned int data) { const struct das08_board_struct *thisboard = comedi_board(dev); + struct das08_private_struct *devpriv = dev->private; unsigned char lsb; unsigned char msb; @@ -389,6 +390,7 @@ static void das08_ao_set_data(struct comedi_device *dev, /* load DACs */ inb(dev->iobase + DAS08AO_AO_UPDATE); } + devpriv->ao_readback[chan] = data; } static void das08_ao_initialize(struct comedi_device *dev, @@ -417,6 +419,22 @@ static int das08_ao_winsn(struct comedi_device *dev, return n; } +static int das08_ao_rinsn(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + struct das08_private_struct *devpriv = dev->private; + unsigned int n; + unsigned int chan; + + chan = CR_CHAN(insn->chanspec); + + for (n = 0; n < insn->n; n++) + data[n] = devpriv->ao_readback[chan]; + + return n; +} + static void i8254_initialize(struct comedi_device *dev) { const struct das08_board_struct *thisboard = comedi_board(dev); @@ -670,12 +688,12 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase) /* ao */ if (thisboard->ao_nbits) { s->type = COMEDI_SUBD_AO; -/* XXX lacks read-back insn */ s->subdev_flags = SDF_WRITABLE; s->n_chan = 2; s->maxdata = (1 << thisboard->ao_nbits) - 1; s->range_table = &range_bipolar5; s->insn_write = das08_ao_winsn; + s->insn_read = das08_ao_rinsn; das08_ao_initialize(dev, s); } else { s->type = COMEDI_SUBD_UNUSED; diff --git a/drivers/staging/comedi/drivers/das08.h b/drivers/staging/comedi/drivers/das08.h index 5a33993..4231be5 100644 --- a/drivers/staging/comedi/drivers/das08.h +++ b/drivers/staging/comedi/drivers/das08.h @@ -52,6 +52,7 @@ struct das08_private_struct { unsigned int do_bits; /* bits for do register on boards with register dedicated to digital out only */ const unsigned int *pg_gainlist; struct pci_dev *pdev; /* struct for pci-das08 */ + unsigned int ao_readback[2]; /* assume 2 AO channels */ }; int das08_common_attach(struct comedi_device *dev, unsigned long iobase); -- cgit v0.10.2 From b1128a6bdaba01b4d15b9b1ead20c10b753ca135 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 31 Aug 2012 20:41:45 +0100 Subject: staging: comedi: das08: Remove manual configuration of PCI boards Remove the code that allows PCI boards to be manually attached by the `COMEDI_DEVCONFIG` ioctl (or the `comedi_config` application). Supported PCI boards will be attached automatically at probe time via `comedi_pci_auto_config()` and the `attach_pci` hook in the `struct comedi_driver`. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 623e77e..0b9ded3 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -32,8 +32,9 @@ * [ComputerBoards] DAS08 (isa-das08), DAS08-PGM (das08-pgm), * DAS08-PGH (das08-pgh), DAS08-PGL (das08-pgl), DAS08-AOH (das08-aoh), * DAS08-AOL (das08-aol), DAS08-AOM (das08-aom), DAS08/JR-AO (das08/jr-ao), - * DAS08/JR-16-AO (das08jr-16-ao), PCI-DAS08 (pci-das08 or das08), + * DAS08/JR-16-AO (das08jr-16-ao), PCI-DAS08 (pci-das08), * PC104-DAS08 (pc104-das08), DAS08/JR/16 (das08jr/16) + * Updated: Fri, 31 Aug 2012 19:19:06 +0100 * Status: works * * This is a rewrite of the das08 and das08jr drivers. @@ -41,9 +42,8 @@ * Options (for ISA cards): * [0] - base io address * - * Options (for pci-das08): - * [0] - bus (optional) - * [1] = slot (optional) + * Manual configuration of PCI cards is not supported; they are + * configured automatically. * * The das08 driver doesn't support asynchronous commands, since * the cheap das08 hardware doesn't really support them. The @@ -641,11 +641,6 @@ static const struct das08_board_struct das08_boards[] = { .i8254_offset = 4, .iosize = 8, }, - { /* wildcard entry matches any supported PCI device */ - .name = DRV_NAME, - .id = PCI_ANY_ID, - .bustype = pci, - }, #endif /* IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) */ }; #endif /* DO_COMEDI_DRIVER_REGISTER */ @@ -818,57 +813,6 @@ das08_attach_pci(struct comedi_device *dev, struct pci_dev *pdev) return das08_pci_attach_common(dev, pdev); } -static struct pci_dev *das08_find_pci(struct comedi_device *dev, - int bus, int slot) -{ - const struct das08_board_struct *thisboard = comedi_board(dev); - struct pci_dev *pdev; - unsigned int matchid; - - if (bus || slot) - dev_dbg(dev->class_dev, "Looking for %s at PCI %02X:%02X\n", - thisboard->name, bus, slot); - else - dev_dbg(dev->class_dev, "Looking for %s on PCI buses\n", - thisboard->name); - - matchid = thisboard->id; - pdev = NULL; - for_each_pci_dev(pdev) { - if ((bus || slot) && - (bus != pdev->bus->number || slot != PCI_SLOT(pdev->devfn))) - continue; - if (pdev->vendor != PCI_VENDOR_ID_COMPUTERBOARDS) - continue; - if (matchid == PCI_ANY_ID) { - /* wildcard board matches any supported PCI board */ - const struct das08_board_struct *foundboard; - foundboard = das08_find_pci_board(pdev); - if (foundboard == NULL) - continue; - /* replace wildcard board_ptr */ - dev->board_ptr = thisboard = foundboard; - } else { - /* match specific PCI board */ - if (pdev->device != matchid) - continue; - } - /* found a match */ - dev_info(dev->class_dev, "Found %s at PCI %s\n", - thisboard->name, pci_name(pdev)); - return pdev; - } - /* no match found */ - if (bus || slot) - dev_err(dev->class_dev, - "No %s cards found at PCI %02X:%02X\n", - thisboard->name, bus, slot); - else - dev_err(dev->class_dev, "No %s cards found on PCI buses\n", - thisboard->name); - return NULL; -} - static int __maybe_unused das08_attach(struct comedi_device *dev, struct comedi_devconfig *it) { @@ -884,11 +828,10 @@ das08_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev_info(dev->class_dev, "attach\n"); if (IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) && thisboard->bustype == pci) { - struct pci_dev *pdev; - pdev = das08_find_pci(dev, it->options[0], it->options[1]); - if (pdev == NULL) - return -EIO; - return das08_pci_attach_common(dev, pdev); + dev_err(dev->class_dev, + "Manual configuration of PCI board '%s' is not supported\n", + thisboard->name); + return -EIO; } else if (IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) && thisboard->bustype == isa) { iobase = it->options[0]; -- cgit v0.10.2 From c6e37f4f227e63320ba8dc080e9a7f4e173bd103 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 3 Sep 2012 17:42:18 +0100 Subject: staging: comedi: das08: absorb das08_pci_attach_common() Absorb `das08_pci_attach_common()` into `das08_attach_pci()` since that's the only place it was called from. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 0b9ded3..5a7c7da 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -751,28 +751,6 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase) } EXPORT_SYMBOL_GPL(das08_common_attach); -static int das08_pci_attach_common(struct comedi_device *dev, - struct pci_dev *pdev) -{ - unsigned long iobase; - struct das08_private_struct *devpriv = dev->private; - - if (!IS_ENABLED(CONFIG_COMEDI_DAS08_PCI)) - return -EINVAL; - - devpriv->pdev = pdev; - /* enable PCI device and reserve I/O spaces */ - if (comedi_pci_enable(pdev, dev->driver->driver_name)) { - dev_err(dev->class_dev, - "Error enabling PCI device and requesting regions\n"); - return -EIO; - } - /* read base addresses */ - iobase = pci_resource_start(pdev, 2); - dev_info(dev->class_dev, "iobase 0x%lx\n", iobase); - return das08_common_attach(dev, iobase); -} - static const struct das08_board_struct * das08_find_pci_board(struct pci_dev *pdev) { @@ -790,6 +768,8 @@ das08_find_pci_board(struct pci_dev *pdev) static int __devinit __maybe_unused das08_attach_pci(struct comedi_device *dev, struct pci_dev *pdev) { + struct das08_private_struct *devpriv; + unsigned long iobase; int ret; if (!IS_ENABLED(CONFIG_COMEDI_DAS08_PCI)) @@ -810,7 +790,18 @@ das08_attach_pci(struct comedi_device *dev, struct pci_dev *pdev) * has been removed. */ pci_dev_get(pdev); - return das08_pci_attach_common(dev, pdev); + devpriv = dev->private; + devpriv->pdev = pdev; + /* enable PCI device and reserve I/O spaces */ + if (comedi_pci_enable(pdev, dev->driver->driver_name)) { + dev_err(dev->class_dev, + "Error enabling PCI device and requesting regions\n"); + return -EIO; + } + /* read base addresses */ + iobase = pci_resource_start(pdev, 2); + dev_info(dev->class_dev, "iobase 0x%lx\n", iobase); + return das08_common_attach(dev, iobase); } static int __maybe_unused -- cgit v0.10.2 From 7c2b231520836df359f83e819ffeba4f5e0e23ad Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 31 Aug 2012 20:41:47 +0100 Subject: staging: comedi: das08: Don't report iobase for PCI device Don't bother reporting the I/O base address for PCI devices as it's not very interesting. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 5a7c7da..82f003f 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -800,7 +800,6 @@ das08_attach_pci(struct comedi_device *dev, struct pci_dev *pdev) } /* read base addresses */ iobase = pci_resource_start(pdev, 2); - dev_info(dev->class_dev, "iobase 0x%lx\n", iobase); return das08_common_attach(dev, iobase); } -- cgit v0.10.2 From 9bfdd96262335949d08507f97e7d10f60314c26e Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 31 Aug 2012 20:41:48 +0100 Subject: staging: comedi: das08: Add helper functions to check bus type Add inline helper function `is_isa_board(board)` to check if the driver supports ISA boards and this is an ISA board, and `is_pci_board(board)` to check if the driver supports PCI boards and this is a PCI board. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 82f003f..18f05b4 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -236,6 +236,16 @@ static const int *const das08_gainlists[] = { das08_pgm_gainlist, }; +static inline bool is_isa_board(const struct das08_board_struct *board) +{ + return IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) && board->bustype == isa; +} + +static inline bool is_pci_board(const struct das08_board_struct *board) +{ + return IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) && board->bustype == pci; +} + #define TIMEOUT 100000 static int das08_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, @@ -757,7 +767,7 @@ das08_find_pci_board(struct pci_dev *pdev) #if DO_COMEDI_DRIVER_REGISTER unsigned int i; for (i = 0; i < ARRAY_SIZE(das08_boards); i++) - if (das08_boards[i].bustype == pci && + if (is_pci_board(&das08_boards[i]) && pdev->device == das08_boards[i].id) return &das08_boards[i]; #endif @@ -817,13 +827,12 @@ das08_attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv = dev->private; dev_info(dev->class_dev, "attach\n"); - if (IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) && thisboard->bustype == pci) { + if (is_pci_board(thisboard)) { dev_err(dev->class_dev, "Manual configuration of PCI board '%s' is not supported\n", thisboard->name); return -EIO; - } else if (IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) && - thisboard->bustype == isa) { + } else if (is_isa_board(thisboard)) { iobase = it->options[0]; dev_info(dev->class_dev, "iobase 0x%lx\n", iobase); if (!request_region(iobase, thisboard->iosize, DRV_NAME)) { @@ -848,11 +857,10 @@ static void __maybe_unused das08_detach(struct comedi_device *dev) struct das08_private_struct *devpriv = dev->private; das08_common_detach(dev); - if (IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) && thisboard->bustype == isa) { + if (is_isa_board(thisboard)) { if (dev->iobase) release_region(dev->iobase, thisboard->iosize); - } else if (IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) && - thisboard->bustype == pci) { + } else if (is_pci_board(thisboard)) { if (devpriv && devpriv->pdev) { if (dev->iobase) comedi_pci_disable(devpriv->pdev); -- cgit v0.10.2 From c50141bf50fc268653ea0f9d5879a677309f2cc4 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 31 Aug 2012 20:41:49 +0100 Subject: staging: comedi: das08: abbreviate IS_ENABLED() The `IS_ENABLED(CONFIG_COMEDI_DAS08_ISA)` and `IS_ENABLED(CONFIG_COMEDI_DAS08_PCI)` macro calls are a bit long-winded. Define a couple of macros `DO_ISA` and `DO_PCI` as abbreviations for them. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 18f05b4..70ad8af 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -61,9 +61,9 @@ #define DRV_NAME "das08" -#define DO_COMEDI_DRIVER_REGISTER \ - (IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) || \ - IS_ENABLED(CONFIG_COMEDI_DAS08_PCI)) +#define DO_ISA IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) +#define DO_PCI IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) +#define DO_COMEDI_DRIVER_REGISTER (DO_ISA || DO_PCI) #define PCI_VENDOR_ID_COMPUTERBOARDS 0x1307 #define PCI_DEVICE_ID_PCIDAS08 0x29 @@ -238,12 +238,12 @@ static const int *const das08_gainlists[] = { static inline bool is_isa_board(const struct das08_board_struct *board) { - return IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) && board->bustype == isa; + return DO_ISA && board->bustype == isa; } static inline bool is_pci_board(const struct das08_board_struct *board) { - return IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) && board->bustype == pci; + return DO_PCI && board->bustype == pci; } #define TIMEOUT 100000 @@ -504,7 +504,7 @@ static int das08_counter_config(struct comedi_device *dev, #if DO_COMEDI_DRIVER_REGISTER static const struct das08_board_struct das08_boards[] = { -#if IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) +#if DO_ISA { .name = "isa-das08", /* cio-das08.pdf */ .bustype = isa, @@ -637,8 +637,8 @@ static const struct das08_board_struct das08_boards[] = { .do_nchan = 8, .iosize = 16, /* unchecked */ }, -#endif /* IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) */ -#if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) +#endif /* DO_ISA */ +#if DO_PCI { .name = "pci-das08", /* pci-das08 */ .id = PCI_DEVICE_ID_PCIDAS08, @@ -651,7 +651,7 @@ static const struct das08_board_struct das08_boards[] = { .i8254_offset = 4, .iosize = 8, }, -#endif /* IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) */ +#endif /* DO_PCI */ }; #endif /* DO_COMEDI_DRIVER_REGISTER */ @@ -782,7 +782,7 @@ das08_attach_pci(struct comedi_device *dev, struct pci_dev *pdev) unsigned long iobase; int ret; - if (!IS_ENABLED(CONFIG_COMEDI_DAS08_PCI)) + if (!DO_PCI) return -EINVAL; ret = alloc_private(dev, sizeof(struct das08_private_struct)); if (ret < 0) @@ -882,7 +882,7 @@ static struct comedi_driver das08_driver = { }; #endif -#if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) +#if DO_PCI static DEFINE_PCI_DEVICE_TABLE(das08_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, PCI_DEVICE_ID_PCIDAS08) }, {0} @@ -907,10 +907,10 @@ static struct pci_driver das08_pci_driver = { .probe = &das08_pci_probe, .remove = __devexit_p(&das08_pci_remove) }; -#endif /* CONFIG_COMEDI_DAS08_PCI */ +#endif /* DO_PCI */ #if DO_COMEDI_DRIVER_REGISTER -#if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) +#if DO_PCI module_comedi_pci_driver(das08_driver, das08_pci_driver); #else module_comedi_driver(das08_driver); -- cgit v0.10.2 From d4eb23a98f6c39ab0e5aa6abb67b615bb8973610 Mon Sep 17 00:00:00 2001 From: Emil Goode Date: Fri, 17 Aug 2012 18:53:26 +0200 Subject: staging: drm/omap: Add error handling This patch adds fail checks for kmalloc and kzalloc calls and also adds a error path that frees allocated pages by introducing a call to _drm_gem_put_pages. Signed-off-by: Emil Goode Signed-off-by: Rob Clark Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/omapdrm/omap_gem.c b/drivers/staging/omapdrm/omap_gem.c index 74082aa..c828743 100644 --- a/drivers/staging/omapdrm/omap_gem.c +++ b/drivers/staging/omapdrm/omap_gem.c @@ -226,7 +226,8 @@ static int omap_gem_attach_pages(struct drm_gem_object *obj) struct drm_device *dev = obj->dev; struct omap_gem_object *omap_obj = to_omap_bo(obj); struct page **pages; - int i, npages = obj->size >> PAGE_SHIFT; + int npages = obj->size >> PAGE_SHIFT; + int i, ret; dma_addr_t *addrs; WARN_ON(omap_obj->pages); @@ -246,18 +247,32 @@ static int omap_gem_attach_pages(struct drm_gem_object *obj) */ if (omap_obj->flags & (OMAP_BO_WC|OMAP_BO_UNCACHED)) { addrs = kmalloc(npages * sizeof(addrs), GFP_KERNEL); + if (!addrs) { + ret = -ENOMEM; + goto free_pages; + } + for (i = 0; i < npages; i++) { addrs[i] = dma_map_page(dev->dev, pages[i], 0, PAGE_SIZE, DMA_BIDIRECTIONAL); } } else { addrs = kzalloc(npages * sizeof(addrs), GFP_KERNEL); + if (!addrs) { + ret = -ENOMEM; + goto free_pages; + } } omap_obj->addrs = addrs; omap_obj->pages = pages; return 0; + +free_pages: + _drm_gem_put_pages(obj, pages, true, false); + + return ret; } /** release backing pages */ -- cgit v0.10.2 From 4619cdbc6b3fca9f07482095e338c16ee0c6d722 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 22 Aug 2012 16:49:44 -0700 Subject: staging: omapdrm: use alloc_ordered_workqueue() instead of UNBOUND w/ max_active = 1 This is an equivalent conversion and will ease scheduled removal of WQ_NON_REENTRANT. Only compile tested. Signed-off-by: Tejun Heo Signed-off-by: Rob Clark Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/omapdrm/omap_drv.c b/drivers/staging/omapdrm/omap_drv.c index b8e79eb..2ec5264 100644 --- a/drivers/staging/omapdrm/omap_drv.c +++ b/drivers/staging/omapdrm/omap_drv.c @@ -571,8 +571,7 @@ static int dev_load(struct drm_device *dev, unsigned long flags) dev->dev_private = priv; - priv->wq = alloc_workqueue("omapdrm", - WQ_UNBOUND | WQ_NON_REENTRANT, 1); + priv->wq = alloc_ordered_workqueue("omapdrm", 0); INIT_LIST_HEAD(&priv->obj_list); -- cgit v0.10.2 From 1e0fdfc2080015abf10a940de9a78a2748205f89 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Tue, 4 Sep 2012 11:36:20 -0500 Subject: staging: drm/omap: invert dimensions on crtc when rotated If rotated 90 or 270, we need to invert the dimensions used by drm core for calculating if the dimensions of an attached fb are correct. Signed-off-by: Rob Clark Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/omapdrm/omap_crtc.c b/drivers/staging/omapdrm/omap_crtc.c index 98a10bc..dade3de 100644 --- a/drivers/staging/omapdrm/omap_crtc.c +++ b/drivers/staging/omapdrm/omap_crtc.c @@ -195,6 +195,13 @@ static int omap_crtc_set_property(struct drm_crtc *crtc, struct drm_property *property, uint64_t val) { struct omap_crtc *omap_crtc = to_omap_crtc(crtc); + struct omap_drm_private *priv = crtc->dev->dev_private; + + if (property == priv->rotation_prop) { + crtc->invert_dimensions = + !!(val & ((1LL << DRM_ROTATE_90) | (1LL << DRM_ROTATE_270))); + } + return omap_plane_set_property(omap_crtc->plane, property, val); } -- cgit v0.10.2 From 0ff15d54161cc0e57fed79de1b5731c81225d668 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 4 Sep 2012 15:23:46 +0100 Subject: staging: rts_pstor: Fix invalid check As noted by David Binderman Resolves-bug: https://bugzilla.kernel.org/show_bug.cgi?id=46581 Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/rtsx_scsi.c b/drivers/staging/rts_pstor/rtsx_scsi.c index f2e5842..936b82d 100644 --- a/drivers/staging/rts_pstor/rtsx_scsi.c +++ b/drivers/staging/rts_pstor/rtsx_scsi.c @@ -2482,7 +2482,7 @@ static int spi_vendor_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip) unsigned int lun = SCSI_LUN(srb); u8 gpio_dir; - if (CHECK_PID(chip, 0x5208) && CHECK_PID(chip, 0x5288)) { + if (CHECK_PID(chip, 0x5208) || CHECK_PID(chip, 0x5288)) { set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); } -- cgit v0.10.2 From c0cdcb7ca853790f35f3eea8ec9853540a230f55 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 31 Aug 2012 21:23:29 +0900 Subject: staging/rts_pstor: remove braces {} in rtsx_card.c fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks -WARNING: braces {} are not necessary for any arm of this statement Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/rtsx_card.c b/drivers/staging/rts_pstor/rtsx_card.c index 4f971f2..539aa6a 100644 --- a/drivers/staging/rts_pstor/rtsx_card.c +++ b/drivers/staging/rts_pstor/rtsx_card.c @@ -309,11 +309,10 @@ static void release_sdio(struct rtsx_chip *chip) if (chip->chip_insert_with_sdio) { chip->chip_insert_with_sdio = 0; - if (CHECK_PID(chip, 0x5288)) { + if (CHECK_PID(chip, 0x5288)) rtsx_write_register(chip, 0xFE5A, 0x08, 0x00); - } else { + else rtsx_write_register(chip, 0xFE70, 0x80, 0x00); - } } rtsx_write_register(chip, SDIO_CTRL, SDIO_CD_CTRL, 0); @@ -379,11 +378,10 @@ void rtsx_reset_cards(struct rtsx_chip *chip) if (chip->need_reset & XD_CARD) { chip->card_exist |= XD_CARD; - if (chip->xd_show_cnt >= MAX_SHOW_CNT) { + if (chip->xd_show_cnt >= MAX_SHOW_CNT) do_reset_xd_card(chip); - } else { + else chip->xd_show_cnt++; - } } if (CHECK_PID(chip, 0x5288) && CHECK_BARO_PKG(chip, QFN)) { if (chip->card_exist & XD_CARD) { @@ -404,11 +402,10 @@ void rtsx_reset_cards(struct rtsx_chip *chip) if (chip->need_reset & MS_CARD) { chip->card_exist |= MS_CARD; - if (chip->ms_show_cnt >= MAX_SHOW_CNT) { + if (chip->ms_show_cnt >= MAX_SHOW_CNT) do_reset_ms_card(chip); - } else { + else chip->ms_show_cnt++; - } } } @@ -473,13 +470,12 @@ void card_cd_debounce(struct rtsx_chip *chip, unsigned long *need_reset, unsigne release_map |= MS_CARD; } } else { - if (chip->int_reg & XD_EXIST) { + if (chip->int_reg & XD_EXIST) reset_map |= XD_CARD; - } else if (chip->int_reg & SD_EXIST) { + else if (chip->int_reg & SD_EXIST) reset_map |= SD_CARD; - } else if (chip->int_reg & MS_EXIST) { + else if (chip->int_reg & MS_EXIST) reset_map |= MS_CARD; - } } if (reset_map) { @@ -489,21 +485,21 @@ void card_cd_debounce(struct rtsx_chip *chip, unsigned long *need_reset, unsigne for (i = 0; i < (DEBOUNCE_CNT); i++) { chip->int_reg = rtsx_readl(chip, RTSX_BIPR); - if (chip->int_reg & XD_EXIST) { + if (chip->int_reg & XD_EXIST) xd_cnt++; - } else { + else xd_cnt = 0; - } - if (chip->int_reg & SD_EXIST) { + + if (chip->int_reg & SD_EXIST) sd_cnt++; - } else { + else sd_cnt = 0; - } - if (chip->int_reg & MS_EXIST) { + + if (chip->int_reg & MS_EXIST) ms_cnt++; - } else { + else ms_cnt = 0; - } + wait_timeout(30); } @@ -677,9 +673,8 @@ int switch_ssc_clock(struct rtsx_chip *chip, int clk) RTSX_DEBUGP("Switch SSC clock to %dMHz (cur_clk = %d)\n", clk, chip->cur_clk); - if ((clk <= 2) || (N > max_N)) { + if ((clk <= 2) || (N > max_N)) TRACE_RET(chip, STATUS_FAIL); - } mcu_cnt = (u8)(125/clk + 3); if (CHECK_PID(chip, 0x5209)) { @@ -700,32 +695,29 @@ int switch_ssc_clock(struct rtsx_chip *chip, int clk) if (chip->ssc_en) { if (CHECK_PID(chip, 0x5209)) { if (chip->cur_card == SD_CARD) { - if (CHK_SD_SDR104(sd_card)) { + if (CHK_SD_SDR104(sd_card)) ssc_depth = chip->ssc_depth_sd_sdr104; - } else if (CHK_SD_SDR50(sd_card)) { + else if (CHK_SD_SDR50(sd_card)) ssc_depth = chip->ssc_depth_sd_sdr50; - } else if (CHK_SD_DDR50(sd_card)) { + else if (CHK_SD_DDR50(sd_card)) ssc_depth = double_depth(chip->ssc_depth_sd_ddr50); - } else if (CHK_SD_HS(sd_card)) { + else if (CHK_SD_HS(sd_card)) ssc_depth = double_depth(chip->ssc_depth_sd_hs); - } else if (CHK_MMC_52M(sd_card) || CHK_MMC_DDR52(sd_card)) { + else if (CHK_MMC_52M(sd_card) || CHK_MMC_DDR52(sd_card)) ssc_depth = double_depth(chip->ssc_depth_mmc_52m); - } else { + else ssc_depth = double_depth(chip->ssc_depth_low_speed); - } } else if (chip->cur_card == MS_CARD) { if (CHK_MSPRO(ms_card)) { - if (CHK_HG8BIT(ms_card)) { + if (CHK_HG8BIT(ms_card)) ssc_depth = double_depth(chip->ssc_depth_ms_hg); - } else { + else ssc_depth = double_depth(chip->ssc_depth_ms_4bit); - } } else { - if (CHK_MS4BIT(ms_card)) { + if (CHK_MS4BIT(ms_card)) ssc_depth = double_depth(chip->ssc_depth_ms_4bit); - } else { + else ssc_depth = double_depth(chip->ssc_depth_low_speed); - } } } else { ssc_depth = double_depth(chip->ssc_depth_low_speed); @@ -733,23 +725,23 @@ int switch_ssc_clock(struct rtsx_chip *chip, int clk) if (ssc_depth) { if (div == CLK_DIV_2) { - if (ssc_depth > 1) { + if (ssc_depth > 1) ssc_depth -= 1; - } else { + else ssc_depth = SSC_DEPTH_4M; - } + } else if (div == CLK_DIV_4) { - if (ssc_depth > 2) { + if (ssc_depth > 2) ssc_depth -= 2; - } else { + else ssc_depth = SSC_DEPTH_4M; - } + } else if (div == CLK_DIV_8) { - if (ssc_depth > 3) { + if (ssc_depth > 3) ssc_depth -= 3; - } else { + else ssc_depth = SSC_DEPTH_4M; - } + } } } else { @@ -760,11 +752,10 @@ int switch_ssc_clock(struct rtsx_chip *chip, int clk) ssc_depth = 0; } - if (CHECK_PID(chip, 0x5209)) { + if (CHECK_PID(chip, 0x5209)) ssc_depth_mask = SSC_DEPTH_MASK; - } else { + else ssc_depth_mask = 0x03; - } RTSX_DEBUGP("ssc_depth = %d\n", ssc_depth); @@ -781,9 +772,8 @@ int switch_ssc_clock(struct rtsx_chip *chip, int clk) } retval = rtsx_send_cmd(chip, 0, WAIT_TIME); - if (retval < 0) { + if (retval < 0) TRACE_RET(chip, STATUS_ERROR); - } udelay(10); RTSX_WRITE_REG(chip, CLK_CTL, CLK_LOW_FREQ, 0); @@ -976,25 +966,23 @@ int card_power_on(struct rtsx_chip *chip, u8 card) rtsx_init_cmd(chip); rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, mask, val1); - if (CHECK_PID(chip, 0x5209) && (card == SD_CARD)) { + if (CHECK_PID(chip, 0x5209) && (card == SD_CARD)) rtsx_add_cmd(chip, WRITE_REG_CMD, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_SUSPEND); - } + retval = rtsx_send_cmd(chip, 0, 100); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } udelay(chip->pmos_pwr_on_interval); rtsx_init_cmd(chip); rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, mask, val2); - if (CHECK_PID(chip, 0x5209) && (card == SD_CARD)) { + if (CHECK_PID(chip, 0x5209) && (card == SD_CARD)) rtsx_add_cmd(chip, WRITE_REG_CMD, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_ON); - } + retval = rtsx_send_cmd(chip, 0, 100); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } return STATUS_SUCCESS; } @@ -1016,9 +1004,8 @@ int card_power_off(struct rtsx_chip *chip, u8 card) } RTSX_WRITE_REG(chip, CARD_PWR_CTL, mask, val); - if (CHECK_PID(chip, 0x5209) && (card == SD_CARD)) { + if (CHECK_PID(chip, 0x5209) && (card == SD_CARD)) RTSX_WRITE_REG(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_OFF); - } return STATUS_SUCCESS; } @@ -1029,9 +1016,8 @@ int card_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 sec_addr, u16 sec unsigned int lun = SCSI_LUN(srb); int i; - if (chip->rw_card[lun] == NULL) { + if (chip->rw_card[lun] == NULL) TRACE_RET(chip, STATUS_FAIL); - } for (i = 0; i < 3; i++) { chip->rw_need_retry = 0; @@ -1042,9 +1028,9 @@ int card_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 sec_addr, u16 sec rtsx_release_chip(chip); TRACE_RET(chip, STATUS_FAIL); } - if (detect_card_cd(chip, chip->cur_card) != STATUS_SUCCESS) { + if (detect_card_cd(chip, chip->cur_card) != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + if (!chip->rw_need_retry) { RTSX_DEBUGP("RW fail, but no need to retry\n"); break; @@ -1066,26 +1052,26 @@ int card_share_mode(struct rtsx_chip *chip, int card) if (CHECK_PID(chip, 0x5209) || CHECK_PID(chip, 0x5208)) { mask = CARD_SHARE_MASK; - if (card == SD_CARD) { + if (card == SD_CARD) value = CARD_SHARE_48_SD; - } else if (card == MS_CARD) { + else if (card == MS_CARD) value = CARD_SHARE_48_MS; - } else if (card == XD_CARD) { + else if (card == XD_CARD) value = CARD_SHARE_48_XD; - } else { + else TRACE_RET(chip, STATUS_FAIL); - } + } else if (CHECK_PID(chip, 0x5288)) { mask = 0x03; - if (card == SD_CARD) { + if (card == SD_CARD) value = CARD_SHARE_BAROSSA_SD; - } else if (card == MS_CARD) { + else if (card == MS_CARD) value = CARD_SHARE_BAROSSA_MS; - } else if (card == XD_CARD) { + else if (card == XD_CARD) value = CARD_SHARE_BAROSSA_XD; - } else { + else TRACE_RET(chip, STATUS_FAIL); - } + } else { TRACE_RET(chip, STATUS_FAIL); } @@ -1103,24 +1089,23 @@ int select_card(struct rtsx_chip *chip, int card) if (chip->cur_card != card) { u8 mod; - if (card == SD_CARD) { + if (card == SD_CARD) mod = SD_MOD_SEL; - } else if (card == MS_CARD) { + else if (card == MS_CARD) mod = MS_MOD_SEL; - } else if (card == XD_CARD) { + else if (card == XD_CARD) mod = XD_MOD_SEL; - } else if (card == SPI_CARD) { + else if (card == SPI_CARD) mod = SPI_MOD_SEL; - } else { + else TRACE_RET(chip, STATUS_FAIL); - } + RTSX_WRITE_REG(chip, CARD_SELECT, 0x07, mod); chip->cur_card = card; retval = card_share_mode(chip, card); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } return STATUS_SUCCESS; @@ -1137,20 +1122,18 @@ void toggle_gpio(struct rtsx_chip *chip, u8 gpio) void turn_on_led(struct rtsx_chip *chip, u8 gpio) { - if (CHECK_PID(chip, 0x5288)) { + if (CHECK_PID(chip, 0x5288)) rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), (u8)(1 << gpio)); - } else { + else rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), 0); - } } void turn_off_led(struct rtsx_chip *chip, u8 gpio) { - if (CHECK_PID(chip, 0x5288)) { + if (CHECK_PID(chip, 0x5288)) rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), 0); - } else { + else rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), (u8)(1 << gpio)); - } } int detect_card_cd(struct rtsx_chip *chip, int card) @@ -1169,67 +1152,60 @@ int detect_card_cd(struct rtsx_chip *chip, int card) } status = rtsx_readl(chip, RTSX_BIPR); - if (!(status & card_cd)) { + if (!(status & card_cd)) TRACE_RET(chip, STATUS_FAIL); - } return STATUS_SUCCESS; } int check_card_exist(struct rtsx_chip *chip, unsigned int lun) { - if (chip->card_exist & chip->lun2card[lun]) { + if (chip->card_exist & chip->lun2card[lun]) return 1; - } return 0; } int check_card_ready(struct rtsx_chip *chip, unsigned int lun) { - if (chip->card_ready & chip->lun2card[lun]) { + if (chip->card_ready & chip->lun2card[lun]) return 1; - } return 0; } int check_card_wp(struct rtsx_chip *chip, unsigned int lun) { - if (chip->card_wp & chip->lun2card[lun]) { + if (chip->card_wp & chip->lun2card[lun]) return 1; - } return 0; } int check_card_fail(struct rtsx_chip *chip, unsigned int lun) { - if (chip->card_fail & chip->lun2card[lun]) { + if (chip->card_fail & chip->lun2card[lun]) return 1; - } return 0; } int check_card_ejected(struct rtsx_chip *chip, unsigned int lun) { - if (chip->card_ejected & chip->lun2card[lun]) { + if (chip->card_ejected & chip->lun2card[lun]) return 1; - } return 0; } u8 get_lun_card(struct rtsx_chip *chip, unsigned int lun) { - if ((chip->card_ready & chip->lun2card[lun]) == XD_CARD) { + if ((chip->card_ready & chip->lun2card[lun]) == XD_CARD) return (u8)XD_CARD; - } else if ((chip->card_ready & chip->lun2card[lun]) == SD_CARD) { + else if ((chip->card_ready & chip->lun2card[lun]) == SD_CARD) return (u8)SD_CARD; - } else if ((chip->card_ready & chip->lun2card[lun]) == MS_CARD) { + else if ((chip->card_ready & chip->lun2card[lun]) == MS_CARD) return (u8)MS_CARD; - } return 0; } -- cgit v0.10.2 From 8a16a5839a7755be28f6b22d3597892abf1e8ab6 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Thu, 30 Aug 2012 22:45:11 +0900 Subject: staging/rts_pstor: remove braces {} in rtsx_transport.c fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks -WARNING: braces {} are not necessary for any arm of this statement Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/rtsx_transport.c b/drivers/staging/rts_pstor/rtsx_transport.c index 54a4742..1f9a424 100644 --- a/drivers/staging/rts_pstor/rtsx_transport.c +++ b/drivers/staging/rts_pstor/rtsx_transport.c @@ -218,9 +218,9 @@ void rtsx_add_cmd(struct rtsx_chip *chip, val |= (u32)data; spin_lock_irq(&chip->rtsx->reg_lock); - if (chip->ci < (HOST_CMDS_BUF_LEN / 4)) { + if (chip->ci < (HOST_CMDS_BUF_LEN / 4)) cb[(chip->ci)++] = cpu_to_le32(val); - } + spin_unlock_irq(&chip->rtsx->reg_lock); } @@ -244,15 +244,14 @@ int rtsx_send_cmd(struct rtsx_chip *chip, u8 card, int timeout) long timeleft; int err = 0; - if (card == SD_CARD) { + if (card == SD_CARD) rtsx->check_card_cd = SD_EXIST; - } else if (card == MS_CARD) { + else if (card == MS_CARD) rtsx->check_card_cd = MS_EXIST; - } else if (card == XD_CARD) { + else if (card == XD_CARD) rtsx->check_card_cd = XD_EXIST; - } else { + else rtsx->check_card_cd = 0; - } spin_lock_irq(&rtsx->reg_lock); @@ -281,11 +280,11 @@ int rtsx_send_cmd(struct rtsx_chip *chip, u8 card, int timeout) } spin_lock_irq(&rtsx->reg_lock); - if (rtsx->trans_result == TRANS_RESULT_FAIL) { + if (rtsx->trans_result == TRANS_RESULT_FAIL) err = -EIO; - } else if (rtsx->trans_result == TRANS_RESULT_OK) { + else if (rtsx->trans_result == TRANS_RESULT_OK) err = 0; - } + spin_unlock_irq(&rtsx->reg_lock); finish_send_cmd: @@ -341,23 +340,21 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card, if ((sg == NULL) || (num_sg <= 0) || !offset || !index) return -EIO; - if (dma_dir == DMA_TO_DEVICE) { + if (dma_dir == DMA_TO_DEVICE) dir = HOST_TO_DEVICE; - } else if (dma_dir == DMA_FROM_DEVICE) { + else if (dma_dir == DMA_FROM_DEVICE) dir = DEVICE_TO_HOST; - } else { + else return -ENXIO; - } - if (card == SD_CARD) { + if (card == SD_CARD) rtsx->check_card_cd = SD_EXIST; - } else if (card == MS_CARD) { + else if (card == MS_CARD) rtsx->check_card_cd = MS_EXIST; - } else if (card == XD_CARD) { + else if (card == XD_CARD) rtsx->check_card_cd = XD_EXIST; - } else { + else rtsx->check_card_cd = 0; - } spin_lock_irq(&rtsx->reg_lock); @@ -405,11 +402,10 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card, *offset = 0; *index = *index + 1; } - if ((i == (sg_cnt - 1)) || !resid) { + if ((i == (sg_cnt - 1)) || !resid) option = SG_VALID | SG_END | SG_TRANS_DATA; - } else { + else option = SG_VALID | SG_TRANS_DATA; - } rtsx_add_sg_tbl(chip, (u32)addr, (u32)len, option); @@ -468,11 +464,11 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card, } spin_lock_irq(&rtsx->reg_lock); - if (rtsx->trans_result == TRANS_RESULT_FAIL) { + if (rtsx->trans_result == TRANS_RESULT_FAIL) err = -EIO; - } else if (rtsx->trans_result == TRANS_RESULT_OK) { + else if (rtsx->trans_result == TRANS_RESULT_OK) err = 0; - } + spin_unlock_irq(&rtsx->reg_lock); out: @@ -501,23 +497,21 @@ static int rtsx_transfer_sglist_adma(struct rtsx_chip *chip, u8 card, if ((sg == NULL) || (num_sg <= 0)) return -EIO; - if (dma_dir == DMA_TO_DEVICE) { + if (dma_dir == DMA_TO_DEVICE) dir = HOST_TO_DEVICE; - } else if (dma_dir == DMA_FROM_DEVICE) { + else if (dma_dir == DMA_FROM_DEVICE) dir = DEVICE_TO_HOST; - } else { + else return -ENXIO; - } - if (card == SD_CARD) { + if (card == SD_CARD) rtsx->check_card_cd = SD_EXIST; - } else if (card == MS_CARD) { + else if (card == MS_CARD) rtsx->check_card_cd = MS_EXIST; - } else if (card == XD_CARD) { + else if (card == XD_CARD) rtsx->check_card_cd = XD_EXIST; - } else { + else rtsx->check_card_cd = 0; - } spin_lock_irq(&rtsx->reg_lock); @@ -537,11 +531,10 @@ static int rtsx_transfer_sglist_adma(struct rtsx_chip *chip, u8 card, u32 val = TRIG_DMA; int sg_cnt, j; - if (i == buf_cnt / (HOST_SG_TBL_BUF_LEN / 8)) { + if (i == buf_cnt / (HOST_SG_TBL_BUF_LEN / 8)) sg_cnt = buf_cnt % (HOST_SG_TBL_BUF_LEN / 8); - } else { + else sg_cnt = (HOST_SG_TBL_BUF_LEN / 8); - } chip->sgi = 0; for (j = 0; j < sg_cnt; j++) { @@ -552,11 +545,10 @@ static int rtsx_transfer_sglist_adma(struct rtsx_chip *chip, u8 card, RTSX_DEBUGP("DMA addr: 0x%x, Len: 0x%x\n", (unsigned int)addr, len); - if (j == (sg_cnt - 1)) { + if (j == (sg_cnt - 1)) option = SG_VALID | SG_END | SG_TRANS_DATA; - } else { + else option = SG_VALID | SG_TRANS_DATA; - } rtsx_add_sg_tbl(chip, (u32)addr, (u32)len, option); @@ -615,11 +607,11 @@ static int rtsx_transfer_sglist_adma(struct rtsx_chip *chip, u8 card, } spin_lock_irq(&rtsx->reg_lock); - if (rtsx->trans_result == TRANS_RESULT_FAIL) { + if (rtsx->trans_result == TRANS_RESULT_FAIL) err = -EIO; - } else if (rtsx->trans_result == TRANS_RESULT_OK) { + else if (rtsx->trans_result == TRANS_RESULT_OK) err = 0; - } + spin_unlock_irq(&rtsx->reg_lock); out: @@ -647,27 +639,25 @@ static int rtsx_transfer_buf(struct rtsx_chip *chip, u8 card, void *buf, size_t if ((buf == NULL) || (len <= 0)) return -EIO; - if (dma_dir == DMA_TO_DEVICE) { + if (dma_dir == DMA_TO_DEVICE) dir = HOST_TO_DEVICE; - } else if (dma_dir == DMA_FROM_DEVICE) { + else if (dma_dir == DMA_FROM_DEVICE) dir = DEVICE_TO_HOST; - } else { + else return -ENXIO; - } addr = dma_map_single(&(rtsx->pci->dev), buf, len, dma_dir); if (!addr) return -ENOMEM; - if (card == SD_CARD) { + if (card == SD_CARD) rtsx->check_card_cd = SD_EXIST; - } else if (card == MS_CARD) { + else if (card == MS_CARD) rtsx->check_card_cd = MS_EXIST; - } else if (card == XD_CARD) { + else if (card == XD_CARD) rtsx->check_card_cd = XD_EXIST; - } else { + else rtsx->check_card_cd = 0; - } val |= (u32)(dir & 0x01) << 29; val |= (u32)(len & 0x00FFFFFF); @@ -698,11 +688,11 @@ static int rtsx_transfer_buf(struct rtsx_chip *chip, u8 card, void *buf, size_t } spin_lock_irq(&rtsx->reg_lock); - if (rtsx->trans_result == TRANS_RESULT_FAIL) { + if (rtsx->trans_result == TRANS_RESULT_FAIL) err = -EIO; - } else if (rtsx->trans_result == TRANS_RESULT_OK) { + else if (rtsx->trans_result == TRANS_RESULT_OK) err = 0; - } + spin_unlock_irq(&rtsx->reg_lock); out: -- cgit v0.10.2 From 411c076a2e8faad165f3504f4bad89cdfa5989cc Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Wed, 29 Aug 2012 22:45:15 +0900 Subject: staging/rts_pstor: remove braces {} in rtsx_chip.c fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks -WARNING: braces {} are not necessary for any arm of this statement Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/rtsx_chip.c b/drivers/staging/rts_pstor/rtsx_chip.c index 5452069..d8e691b 100644 --- a/drivers/staging/rts_pstor/rtsx_chip.c +++ b/drivers/staging/rts_pstor/rtsx_chip.c @@ -105,11 +105,10 @@ void rtsx_enable_bus_int(struct rtsx_chip *chip) reg |= DELINK_INT_EN; #ifdef SUPPORT_OCP if (CHECK_PID(chip, 0x5209)) { - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { + if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) reg |= MS_OC_INT_EN | SD_OC_INT_EN; - } else { + else reg |= SD_OC_INT_EN; - } } else { reg |= OC_INT_EN; } @@ -186,20 +185,20 @@ static int rtsx_pre_handle_sdio_new(struct rtsx_chip *chip) u8 cd_toggle_mask = 0; RTSX_READ_REG(chip, TLPTISTAT, &tmp); - if (CHECK_PID(chip, 0x5209)) { + if (CHECK_PID(chip, 0x5209)) cd_toggle_mask = 0x10; - } else { + else cd_toggle_mask = 0x08; - } + if (tmp & cd_toggle_mask) { /* Disable sdio_bus_auto_switch */ - if (CHECK_PID(chip, 0x5288)) { + if (CHECK_PID(chip, 0x5288)) RTSX_WRITE_REG(chip, 0xFE5A, 0x08, 0x00); - } else if (CHECK_PID(chip, 0x5208)) { + else if (CHECK_PID(chip, 0x5208)) RTSX_WRITE_REG(chip, 0xFE70, 0x80, 0x00); - } else { + else RTSX_WRITE_REG(chip, SDIO_CFG, SDIO_BUS_AUTO_SWITCH, 0); - } + RTSX_WRITE_REG(chip, TLPTISTAT, 0xFF, tmp); chip->need_reset |= SD_CARD; @@ -208,16 +207,14 @@ static int rtsx_pre_handle_sdio_new(struct rtsx_chip *chip) if (chip->asic_code) { retval = sd_pull_ctl_enable(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } else { RTSX_WRITE_REG(chip, FPGA_PULL_CTL, FPGA_SD_PULL_CTL_BIT | 0x20, 0); } retval = card_share_mode(chip, SD_CARD); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } /* Enable sdio_bus_auto_switch */ if (CHECK_PID(chip, 0x5288)) { @@ -232,11 +229,11 @@ static int rtsx_pre_handle_sdio_new(struct rtsx_chip *chip) chip->sd_io = 1; } } else { - if (CHECK_PID(chip, 0x5209)) { + if (CHECK_PID(chip, 0x5209)) RTSX_WRITE_REG(chip, TLPTISTAT, 0x10, 0x10); - } else { + else RTSX_WRITE_REG(chip, TLPTISTAT, 0x08, 0x08); - } + chip->need_reset |= SD_CARD; } @@ -257,48 +254,47 @@ int rtsx_reset_chip(struct rtsx_chip *chip) /* optimize PHY */ retval = rtsx_write_phy_register(chip, 0x00, 0xB966); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + retval = rtsx_write_phy_register(chip, 0x01, 0x713F); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + retval = rtsx_write_phy_register(chip, 0x03, 0xA549); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + retval = rtsx_write_phy_register(chip, 0x06, 0xB235); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + retval = rtsx_write_phy_register(chip, 0x07, 0xEF40); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + retval = rtsx_write_phy_register(chip, 0x1E, 0xF8EB); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + retval = rtsx_write_phy_register(chip, 0x19, 0xFE6C); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + wait_timeout(1); retval = rtsx_write_phy_register(chip, 0x0A, 0x05C0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + retval = rtsx_write_cfg_dw(chip, 1, 0x110, 0xFFFF, 0xFFFF); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = rtsx_read_phy_register(chip, 0x08, &val); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + RTSX_DEBUGP("Read from phy 0x08: 0x%04x\n", val); if (chip->phy_voltage) { @@ -308,9 +304,9 @@ int rtsx_reset_chip(struct rtsx_chip *chip) val |= chip->phy_voltage; RTSX_DEBUGP("Write to phy 0x08: 0x%04x\n", val); retval = rtsx_write_phy_register(chip, 0x08, val); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + } else { chip->phy_voltage = (u8)(val & 0x3F); RTSX_DEBUGP("Default, chip->phy_voltage = 0x%x\n", chip->phy_voltage); @@ -324,11 +320,11 @@ int rtsx_reset_chip(struct rtsx_chip *chip) #ifdef SUPPORT_OCP /* SSC power on, OCD power on */ - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { + if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) RTSX_WRITE_REG(chip, FPDCTL, OC_POWER_DOWN, 0); - } else { + else RTSX_WRITE_REG(chip, FPDCTL, OC_POWER_DOWN, MS_OC_POWER_DOWN); - } + if (CHECK_PID(chip, 0x5209)) { RTSX_WRITE_REG(chip, OCPPARA1, SD_OCP_TIME_MASK | MS_OCP_TIME_MASK, SD_OCP_TIME_800 | MS_OCP_TIME_800); @@ -352,9 +348,8 @@ int rtsx_reset_chip(struct rtsx_chip *chip) RTSX_WRITE_REG(chip, FPDCTL, OC_POWER_DOWN, OC_POWER_DOWN); #endif - if (!CHECK_PID(chip, 0x5288)) { + if (!CHECK_PID(chip, 0x5288)) RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0xFF, 0x03); - } /* Turn off LED */ RTSX_WRITE_REG(chip, CARD_GPIO, 0xFF, 0x03); @@ -364,9 +359,8 @@ int rtsx_reset_chip(struct rtsx_chip *chip) /* Card driving select */ RTSX_WRITE_REG(chip, CARD_DRIVE_SEL, 0xFF, chip->card_drive_sel); - if (CHECK_PID(chip, 0x5209)) { + if (CHECK_PID(chip, 0x5209)) RTSX_WRITE_REG(chip, SD30_DRIVE_SEL, 0x07, chip->sd30_drive_sel_3v3); - } #ifdef LED_AUTO_BLINK RTSX_WRITE_REG(chip, CARD_AUTO_BLINK, 0xFF, @@ -394,36 +388,34 @@ int rtsx_reset_chip(struct rtsx_chip *chip) if (CHK_SDIO_EXIST(chip)) { if (CHECK_PID(chip, 0x5209)) { retval = rtsx_write_cfg_dw(chip, 1, 0xC0, 0xFF, chip->aspm_l0s_l1_en); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + } else if (CHECK_PID(chip, 0x5288)) { retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF, chip->aspm_l0s_l1_en); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } } } else { - if (CHECK_PID(chip, 0x5208)) { + if (CHECK_PID(chip, 0x5208)) RTSX_WRITE_REG(chip, ASPM_FORCE_CTL, 0xFF, 0x3F); - } retval = rtsx_write_config_byte(chip, LCTLR, chip->aspm_l0s_l1_en); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + chip->aspm_level[0] = chip->aspm_l0s_l1_en; if (CHK_SDIO_EXIST(chip)) { chip->aspm_level[1] = chip->aspm_l0s_l1_en; - if (CHECK_PID(chip, 0x5288)) { + if (CHECK_PID(chip, 0x5288)) retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF, chip->aspm_l0s_l1_en); - } else { + else retval = rtsx_write_cfg_dw(chip, 1, 0xC0, 0xFF, chip->aspm_l0s_l1_en); - } - if (retval != STATUS_SUCCESS) { + + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + } chip->aspm_enabled = 1; @@ -431,49 +423,45 @@ int rtsx_reset_chip(struct rtsx_chip *chip) } else { if (chip->asic_code && CHECK_PID(chip, 0x5208)) { retval = rtsx_write_phy_register(chip, 0x07, 0x0129); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } retval = rtsx_write_config_byte(chip, LCTLR, chip->aspm_l0s_l1_en); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } retval = rtsx_write_config_byte(chip, 0x81, 1); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (CHK_SDIO_EXIST(chip)) { - if (CHECK_PID(chip, 0x5288)) { + if (CHECK_PID(chip, 0x5288)) retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF00, 0x0100); - } else { + else retval = rtsx_write_cfg_dw(chip, 1, 0xC0, 0xFF00, 0x0100); - } - if (retval != STATUS_SUCCESS) { + + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + } if (CHECK_PID(chip, 0x5209)) { retval = rtsx_write_cfg_dw(chip, 0, 0x70C, 0xFF000000, 0x5B); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } if (CHECK_PID(chip, 0x5288)) { if (!CHK_SDIO_EXIST(chip)) { retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFFFF, 0x0103); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + retval = rtsx_write_cfg_dw(chip, 2, 0x84, 0xFF, 0x03); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + } } @@ -499,29 +487,29 @@ int rtsx_reset_chip(struct rtsx_chip *chip) if (chip->ic_version >= IC_VER_D) { u16 reg; retval = rtsx_read_phy_register(chip, 0x00, ®); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + reg &= 0xFE7F; reg |= 0x80; retval = rtsx_write_phy_register(chip, 0x00, reg); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + retval = rtsx_read_phy_register(chip, 0x1C, ®); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + reg &= 0xFFF7; retval = rtsx_write_phy_register(chip, 0x1C, reg); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + } - if (chip->driver_first_load && (chip->ic_version < IC_VER_C)) { + if (chip->driver_first_load && (chip->ic_version < IC_VER_C)) rtsx_calibration(chip); - } + } else { rtsx_enable_bus_int(chip); } @@ -550,18 +538,18 @@ int rtsx_reset_chip(struct rtsx_chip *chip) RTSX_DEBUGP("In rtsx_reset_chip, chip->int_reg = 0x%x\n", chip->int_reg); if (chip->int_reg & SD_EXIST) { #ifdef HW_AUTO_SWITCH_SD_BUS - if (CHECK_PID(chip, 0x5208) && (chip->ic_version < IC_VER_C)) { + if (CHECK_PID(chip, 0x5208) && (chip->ic_version < IC_VER_C)) retval = rtsx_pre_handle_sdio_old(chip); - } else { + else retval = rtsx_pre_handle_sdio_new(chip); - } + RTSX_DEBUGP("chip->need_reset = 0x%x (rtsx_reset_chip)\n", (unsigned int)(chip->need_reset)); #else /* HW_AUTO_SWITCH_SD_BUS */ retval = rtsx_pre_handle_sdio_old(chip); #endif /* HW_AUTO_SWITCH_SD_BUS */ - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + } else { chip->sd_io = 0; RTSX_WRITE_REG(chip, SDIO_CTRL, SDIO_BUS_CTRL | SDIO_CD_CTRL, 0); @@ -572,9 +560,8 @@ NextCard: chip->need_reset |= XD_CARD; if (chip->int_reg & MS_EXIST) chip->need_reset |= MS_CARD; - if (chip->int_reg & CARD_EXIST) { + if (chip->int_reg & CARD_EXIST) RTSX_WRITE_REG(chip, SSC_CTL1, SSC_RSTB, SSC_RSTB); - } RTSX_DEBUGP("In rtsx_init_chip, chip->need_reset = 0x%x\n", (unsigned int)(chip->need_reset)); @@ -587,9 +574,8 @@ NextCard: if (chip->remote_wakeup_en && !chip->auto_delink_en) { RTSX_WRITE_REG(chip, WAKE_SEL_CTL, 0x07, 0x07); - if (chip->aux_pwr_exist) { + if (chip->aux_pwr_exist) RTSX_WRITE_REG(chip, PME_FORCE_CTL, 0xFF, 0x33); - } } else { RTSX_WRITE_REG(chip, WAKE_SEL_CTL, 0x07, 0x04); RTSX_WRITE_REG(chip, PME_FORCE_CTL, 0xFF, 0x30); @@ -598,18 +584,16 @@ NextCard: if (CHECK_PID(chip, 0x5208) && (chip->ic_version >= IC_VER_D)) { RTSX_WRITE_REG(chip, PETXCFG, 0x1C, 0x14); } else if (CHECK_PID(chip, 0x5209)) { - if (chip->force_clkreq_0) { + if (chip->force_clkreq_0) RTSX_WRITE_REG(chip, PETXCFG, 0x08, 0x08); - } else { + else RTSX_WRITE_REG(chip, PETXCFG, 0x08, 0x00); - } } if (chip->asic_code && CHECK_PID(chip, 0x5208)) { retval = rtsx_clr_phy_reg_bit(chip, 0x1C, 2); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } if (chip->ft2_fast_mode) { @@ -665,11 +649,10 @@ static int rts5209_init(struct rtsx_chip *chip) u8 val = 0; val = rtsx_readb(chip, 0x1C); - if ((val & 0x10) == 0) { + if ((val & 0x10) == 0) chip->asic_code = 1; - } else { + else chip->asic_code = 0; - } chip->ic_version = val & 0x0F; chip->phy_debug_mode = 0; @@ -679,9 +662,9 @@ static int rts5209_init(struct rtsx_chip *chip) chip->ms_power_class_en = 0x03; retval = rtsx_read_cfg_dw(chip, 0, 0x724, &lval); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + RTSX_DEBUGP("dw in 0x724: 0x%x\n", lval); val = (u8)lval; if (!(val & 0x80)) { @@ -690,17 +673,16 @@ static int rts5209_init(struct rtsx_chip *chip) else chip->lun_mode = SD_MS_2LUN; - if (val & 0x04) { + if (val & 0x04) SET_SDIO_EXIST(chip); - } else { + else CLR_SDIO_EXIST(chip); - } - if (val & 0x02) { + if (val & 0x02) chip->hw_bypass_sd = 0; - } else { + else chip->hw_bypass_sd = 1; - } + } else { SET_SDIO_EXIST(chip); chip->hw_bypass_sd = 0; @@ -714,24 +696,21 @@ static int rts5209_init(struct rtsx_chip *chip) val = (u8)(lval >> 8); clk = (val >> 5) & 0x07; - if (clk != 0x07) { + if (clk != 0x07) chip->asic_sd_sdr50_clk = 98 - clk * 2; - } - if (val & 0x10) { + if (val & 0x10) chip->auto_delink_en = 1; - } else { + else chip->auto_delink_en = 0; - } if (chip->ss_en == 2) { chip->ss_en = 0; } else { - if (val & 0x08) { + if (val & 0x08) chip->ss_en = 1; - } else { + else chip->ss_en = 0; - } } clk = val & 0x07; @@ -750,21 +729,21 @@ static int rts5209_init(struct rtsx_chip *chip) if (clk != 0x03) chip->asic_sd_ddr50_clk = (48 - clk * 2) * 2; - if (val & 0x01) { + if (val & 0x01) chip->sdr104_en = 1; - } else { + else chip->sdr104_en = 0; - } - if (val & 0x02) { + + if (val & 0x02) chip->ddr50_en = 1; - } else { + else chip->ddr50_en = 0; - } - if (val & 0x04) { + + if (val & 0x04) chip->sdr50_en = 1; - } else { + else chip->sdr50_en = 0; - } + val = (u8)(lval >> 24); @@ -772,11 +751,10 @@ static int rts5209_init(struct rtsx_chip *chip) if (clk != 0x07) chip->asic_sd_sdr104_clk = 206 - clk * 3; - if (val & 0x10) { + if (val & 0x10) chip->power_down_in_ss = 1; - } else { + else chip->power_down_in_ss = 0; - } chip->ms_power_class_en = val & 0x03; } @@ -786,20 +764,19 @@ static int rts5209_init(struct rtsx_chip *chip) retval = rtsx_read_pci_cfg_byte(0x00, 0x1C, 0x02, 0x58, ®58); - if (retval < 0) { + if (retval < 0) return STATUS_SUCCESS; - } + retval = rtsx_read_pci_cfg_byte(0x00, 0x1C, 0x02, 0x5B, ®5b); - if (retval < 0) { + if (retval < 0) return STATUS_SUCCESS; - } RTSX_DEBUGP("reg58 = 0x%x, reg5b = 0x%x\n", reg58, reg5b); - if ((reg58 == 0x00) && (reg5b == 0x01)) { + if ((reg58 == 0x00) && (reg5b == 0x01)) chip->auto_delink_en = 0; - } + } return STATUS_SUCCESS; @@ -813,24 +790,23 @@ static int rts5208_init(struct rtsx_chip *chip) RTSX_WRITE_REG(chip, CLK_SEL, 0x03, 0x03); RTSX_READ_REG(chip, CLK_SEL, &val); - if (val == 0) { + if (val == 0) chip->asic_code = 1; - } else { + else chip->asic_code = 0; - } if (chip->asic_code) { retval = rtsx_read_phy_register(chip, 0x1C, ®); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + RTSX_DEBUGP("Value of phy register 0x1C is 0x%x\n", reg); chip->ic_version = (reg >> 4) & 0x07; - if (reg & PHY_DEBUG_MODE) { + if (reg & PHY_DEBUG_MODE) chip->phy_debug_mode = 1; - } else { + else chip->phy_debug_mode = 0; - } + } else { RTSX_READ_REG(chip, 0xFE80, &val); chip->ic_version = val; @@ -839,33 +815,29 @@ static int rts5208_init(struct rtsx_chip *chip) RTSX_READ_REG(chip, PDINFO, &val); RTSX_DEBUGP("PDINFO: 0x%x\n", val); - if (val & AUX_PWR_DETECTED) { + if (val & AUX_PWR_DETECTED) chip->aux_pwr_exist = 1; - } else { + else chip->aux_pwr_exist = 0; - } RTSX_READ_REG(chip, 0xFE50, &val); - if (val & 0x01) { + if (val & 0x01) chip->hw_bypass_sd = 1; - } else { + else chip->hw_bypass_sd = 0; - } rtsx_read_config_byte(chip, 0x0E, &val); - if (val & 0x80) { + if (val & 0x80) SET_SDIO_EXIST(chip); - } else { + else CLR_SDIO_EXIST(chip); - } if (chip->use_hw_setting) { RTSX_READ_REG(chip, CHANGE_LINK_STATE, &val); - if (val & 0x80) { + if (val & 0x80) chip->auto_delink_en = 1; - } else { + else chip->auto_delink_en = 0; - } } return STATUS_SUCCESS; @@ -879,63 +851,57 @@ static int rts5288_init(struct rtsx_chip *chip) RTSX_WRITE_REG(chip, CLK_SEL, 0x03, 0x03); RTSX_READ_REG(chip, CLK_SEL, &val); - if (val == 0) { + if (val == 0) chip->asic_code = 1; - } else { + else chip->asic_code = 0; - } chip->ic_version = 0; chip->phy_debug_mode = 0; RTSX_READ_REG(chip, PDINFO, &val); RTSX_DEBUGP("PDINFO: 0x%x\n", val); - if (val & AUX_PWR_DETECTED) { + if (val & AUX_PWR_DETECTED) chip->aux_pwr_exist = 1; - } else { + else chip->aux_pwr_exist = 0; - } RTSX_READ_REG(chip, CARD_SHARE_MODE, &val); RTSX_DEBUGP("CARD_SHARE_MODE: 0x%x\n", val); - if (val & 0x04) { + if (val & 0x04) chip->baro_pkg = QFN; - } else { + else chip->baro_pkg = LQFP; - } RTSX_READ_REG(chip, 0xFE5A, &val); - if (val & 0x10) { + if (val & 0x10) chip->hw_bypass_sd = 1; - } else { + else chip->hw_bypass_sd = 0; - } retval = rtsx_read_cfg_dw(chip, 0, 0x718, &lval); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + max_func = (u8)((lval >> 29) & 0x07); RTSX_DEBUGP("Max function number: %d\n", max_func); - if (max_func == 0x02) { + if (max_func == 0x02) SET_SDIO_EXIST(chip); - } else { + else CLR_SDIO_EXIST(chip); - } if (chip->use_hw_setting) { RTSX_READ_REG(chip, CHANGE_LINK_STATE, &val); - if (val & 0x80) { + if (val & 0x80) chip->auto_delink_en = 1; - } else { + else chip->auto_delink_en = 0; - } - if (CHECK_BARO_PKG(chip, LQFP)) { + if (CHECK_BARO_PKG(chip, LQFP)) chip->lun_mode = SD_MS_1LUN; - } else { + else chip->lun_mode = DEFAULT_SINGLE; - } + } return STATUS_SUCCESS; @@ -990,22 +956,21 @@ int rtsx_init_chip(struct rtsx_chip *chip) chip->rw_fail_cnt[i] = 0; } - if (!check_sd_speed_prior(chip->sd_speed_prior)) { + if (!check_sd_speed_prior(chip->sd_speed_prior)) chip->sd_speed_prior = 0x01040203; - } + RTSX_DEBUGP("sd_speed_prior = 0x%08x\n", chip->sd_speed_prior); - if (!check_sd_current_prior(chip->sd_current_prior)) { + if (!check_sd_current_prior(chip->sd_current_prior)) chip->sd_current_prior = 0x00010203; - } + RTSX_DEBUGP("sd_current_prior = 0x%08x\n", chip->sd_current_prior); - if ((chip->sd_ddr_tx_phase > 31) || (chip->sd_ddr_tx_phase < 0)) { + if ((chip->sd_ddr_tx_phase > 31) || (chip->sd_ddr_tx_phase < 0)) chip->sd_ddr_tx_phase = 0; - } - if ((chip->mmc_ddr_tx_phase > 31) || (chip->mmc_ddr_tx_phase < 0)) { + + if ((chip->mmc_ddr_tx_phase > 31) || (chip->mmc_ddr_tx_phase < 0)) chip->mmc_ddr_tx_phase = 0; - } RTSX_WRITE_REG(chip, FPDCTL, SSC_POWER_DOWN, 0); wait_timeout(200); @@ -1014,24 +979,23 @@ int rtsx_init_chip(struct rtsx_chip *chip) if (CHECK_PID(chip, 0x5209)) { retval = rts5209_init(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + } else if (CHECK_PID(chip, 0x5208)) { retval = rts5208_init(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + } else if (CHECK_PID(chip, 0x5288)) { retval = rts5288_init(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + } - if (chip->ss_en == 2) { + if (chip->ss_en == 2) chip->ss_en = 0; - } RTSX_DEBUGP("chip->asic_code = %d\n", chip->asic_code); RTSX_DEBUGP("chip->ic_version = 0x%x\n", chip->ic_version); @@ -1068,9 +1032,8 @@ int rtsx_init_chip(struct rtsx_chip *chip) } retval = rtsx_reset_chip(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } return STATUS_SUCCESS; } @@ -1118,19 +1081,19 @@ static void rtsx_monitor_aspm_config(struct rtsx_chip *chip) chip->aspm_level[1] = reg1; } - if ((reg0 & 0x03) && (reg1 & 0x03)) { + if ((reg0 & 0x03) && (reg1 & 0x03)) maybe_support_aspm = 1; - } + } else { - if (reg0 & 0x03) { + if (reg0 & 0x03) maybe_support_aspm = 1; - } + } if (reg_changed) { - if (maybe_support_aspm) { + if (maybe_support_aspm) chip->aspm_l0s_l1_en = 0x03; - } + RTSX_DEBUGP("aspm_level[0] = 0x%02x, aspm_level[1] = 0x%02x\n", chip->aspm_level[0], chip->aspm_level[1]); @@ -1177,13 +1140,13 @@ void rtsx_polling_func(struct rtsx_chip *chip) if (chip->ocp_int & MS_OC_INT) ms_power_off_card3v3(chip); } else { - if (chip->card_exist & SD_CARD) { + if (chip->card_exist & SD_CARD) sd_power_off_card3v3(chip); - } else if (chip->card_exist & MS_CARD) { + else if (chip->card_exist & MS_CARD) ms_power_off_card3v3(chip); - } else if (chip->card_exist & XD_CARD) { + else if (chip->card_exist & XD_CARD) xd_power_off_card3v3(chip); - } + } chip->ocp_int = 0; @@ -1226,9 +1189,9 @@ void rtsx_polling_func(struct rtsx_chip *chip) if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) { u32 val; rtsx_read_cfg_dw(chip, 1, 0x04, &val); - if (val & 0x07) { + if (val & 0x07) ss_allowed = 0; - } + } } } else { @@ -1284,9 +1247,9 @@ void rtsx_polling_func(struct rtsx_chip *chip) turn_off_led(chip, LED_GPIO); - if (chip->auto_power_down && !chip->card_ready && !chip->sd_io) { + if (chip->auto_power_down && !chip->card_ready && !chip->sd_io) rtsx_force_power_down(chip, SSC_PDCTL | OC_PDCTL); - } + } } @@ -1299,9 +1262,9 @@ void rtsx_polling_func(struct rtsx_chip *chip) break; case RTSX_STAT_IDLE: - if (chip->sd_io && !chip->sd_int) { + if (chip->sd_io && !chip->sd_int) try_to_switch_sdio_ctrl(chip); - } + rtsx_enable_aspm(chip); break; @@ -1313,9 +1276,8 @@ void rtsx_polling_func(struct rtsx_chip *chip) #ifdef SUPPORT_OCP if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { #ifdef CONFIG_RTS_PSTOR_DEBUG - if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER | MS_OC_NOW | MS_OC_EVER)) { + if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER | MS_OC_NOW | MS_OC_EVER)) RTSX_DEBUGP("Over current, OCPSTAT is 0x%x\n", chip->ocp_stat); - } #endif if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) { @@ -1362,28 +1324,27 @@ Delink_Stage: if (chip->auto_delink_cnt == delink_stage1_cnt) { rtsx_set_stat(chip, RTSX_STAT_DELINK); - if (chip->asic_code && CHECK_PID(chip, 0x5208)) { + if (chip->asic_code && CHECK_PID(chip, 0x5208)) rtsx_set_phy_reg_bit(chip, 0x1C, 2); - } + if (chip->card_exist) { RTSX_DEBUGP("False card inserted, do force delink\n"); - if (enter_L1) { + if (enter_L1) rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, 1); - } + rtsx_write_register(chip, CHANGE_LINK_STATE, 0x0A, 0x0A); - if (enter_L1) { + if (enter_L1) rtsx_enter_L1(chip); - } chip->auto_delink_cnt = delink_stage3_cnt + 1; } else { RTSX_DEBUGP("No card inserted, do delink\n"); - if (enter_L1) { + if (enter_L1) rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, 1); - } + #ifdef HW_INT_WRITE_CLR if (CHECK_PID(chip, 0x5209)) { rtsx_writel(chip, RTSX_BIPR, 0xFFFFFFFF); @@ -1392,22 +1353,21 @@ Delink_Stage: #endif rtsx_write_register(chip, CHANGE_LINK_STATE, 0x02, 0x02); - if (enter_L1) { + if (enter_L1) rtsx_enter_L1(chip); - } + } } if (chip->auto_delink_cnt == delink_stage2_cnt) { RTSX_DEBUGP("Try to do force delink\n"); - if (enter_L1) { + if (enter_L1) rtsx_exit_L1(chip); - } - if (chip->asic_code && CHECK_PID(chip, 0x5208)) { + if (chip->asic_code && CHECK_PID(chip, 0x5208)) rtsx_set_phy_reg_bit(chip, 0x1C, 2); - } + rtsx_write_register(chip, CHANGE_LINK_STATE, 0x0A, 0x0A); } @@ -1472,9 +1432,9 @@ int rtsx_write_register(struct rtsx_chip *chip, u16 addr, u8 mask, u8 data) for (i = 0; i < MAX_RW_REG_CNT; i++) { val = rtsx_readl(chip, RTSX_HAIMR); if ((val & (1 << 31)) == 0) { - if (data != (u8)val) { + if (data != (u8)val) TRACE_RET(chip, STATUS_FAIL); - } + return STATUS_SUCCESS; } } @@ -1487,9 +1447,8 @@ int rtsx_read_register(struct rtsx_chip *chip, u16 addr, u8 *data) u32 val = 2 << 30; int i; - if (data) { + if (data) *data = 0; - } val |= (u32)(addr & 0x3FFF) << 16; @@ -1497,18 +1456,15 @@ int rtsx_read_register(struct rtsx_chip *chip, u16 addr, u8 *data) for (i = 0; i < MAX_RW_REG_CNT; i++) { val = rtsx_readl(chip, RTSX_HAIMR); - if ((val & (1 << 31)) == 0) { + if ((val & (1 << 31)) == 0) break; - } } - if (i >= MAX_RW_REG_CNT) { + if (i >= MAX_RW_REG_CNT) TRACE_RET(chip, STATUS_TIMEDOUT); - } - if (data) { + if (data) *data = (u8)(val & 0xFF); - } return STATUS_SUCCESS; } @@ -1537,9 +1493,8 @@ int rtsx_write_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 mask, u3 for (i = 0; i < MAX_RW_REG_CNT; i++) { RTSX_READ_REG(chip, CFGRWCTL, &tmp); - if ((tmp & 0x80) == 0) { + if ((tmp & 0x80) == 0) break; - } } } @@ -1558,9 +1513,8 @@ int rtsx_read_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 *val) for (i = 0; i < MAX_RW_REG_CNT; i++) { RTSX_READ_REG(chip, CFGRWCTL, &tmp); - if ((tmp & 0x80) == 0) { + if ((tmp & 0x80) == 0) break; - } } for (i = 0; i < 4; i++) { @@ -1568,9 +1522,8 @@ int rtsx_read_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 *val) data |= (u32)tmp << (i * 8); } - if (val) { + if (val) *val = data; - } return STATUS_SUCCESS; } @@ -1585,21 +1538,19 @@ int rtsx_write_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, int l RTSX_DEBUGP("%s\n", __func__); - if (!buf) { + if (!buf) TRACE_RET(chip, STATUS_NOMEM); - } - if ((len + offset) % 4) { + if ((len + offset) % 4) dw_len = (len + offset) / 4 + 1; - } else { + else dw_len = (len + offset) / 4; - } + RTSX_DEBUGP("dw_len = %d\n", dw_len); data = vzalloc(dw_len * 4); - if (!data) { + if (!data) TRACE_RET(chip, STATUS_NOMEM); - } mask = vzalloc(dw_len * 4); if (!mask) { @@ -1645,17 +1596,16 @@ int rtsx_read_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, int le RTSX_DEBUGP("%s\n", __func__); - if ((len + offset) % 4) { + if ((len + offset) % 4) dw_len = (len + offset) / 4 + 1; - } else { + else dw_len = (len + offset) / 4; - } + RTSX_DEBUGP("dw_len = %d\n", dw_len); data = (u32 *)vmalloc(dw_len * 4); - if (!data) { + if (!data) TRACE_RET(chip, STATUS_NOMEM); - } for (i = 0; i < dw_len; i++) { retval = rtsx_read_cfg_dw(chip, func, aligned_addr + i * 4, data + i); @@ -1700,9 +1650,8 @@ int rtsx_write_phy_register(struct rtsx_chip *chip, u8 addr, u16 val) } } - if (!finished) { + if (!finished) TRACE_RET(chip, STATUS_FAIL); - } return STATUS_SUCCESS; } @@ -1724,9 +1673,8 @@ int rtsx_read_phy_register(struct rtsx_chip *chip, u8 addr, u16 *val) } } - if (!finished) { + if (!finished) TRACE_RET(chip, STATUS_FAIL); - } RTSX_READ_REG(chip, PHYDATA0, &tmp); data = tmp; @@ -1753,9 +1701,8 @@ int rtsx_read_efuse(struct rtsx_chip *chip, u8 addr, u8 *val) udelay(1); } - if (data & 0x80) { + if (data & 0x80) TRACE_RET(chip, STATUS_TIMEDOUT); - } RTSX_READ_REG(chip, EFUSE_DATA, &data); if (val) @@ -1786,9 +1733,8 @@ int rtsx_write_efuse(struct rtsx_chip *chip, u8 addr, u8 val) wait_timeout(3); } - if (data & 0x80) { + if (data & 0x80) TRACE_RET(chip, STATUS_TIMEDOUT); - } wait_timeout(5); } @@ -1802,15 +1748,14 @@ int rtsx_clr_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit) u16 value; retval = rtsx_read_phy_register(chip, reg, &value); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + if (value & (1 << bit)) { value &= ~(1 << bit); retval = rtsx_write_phy_register(chip, reg, value); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } return STATUS_SUCCESS; @@ -1822,15 +1767,14 @@ int rtsx_set_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit) u16 value; retval = rtsx_read_phy_register(chip, reg, &value); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + if (0 == (value & (1 << bit))) { value |= (1 << bit); retval = rtsx_write_phy_register(chip, reg, value); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } return STATUS_SUCCESS; @@ -1861,11 +1805,11 @@ static void rtsx_handle_pm_dstate(struct rtsx_chip *chip, u8 dstate) if (CHK_SDIO_EXIST(chip)) { u8 func_no; - if (CHECK_PID(chip, 0x5288)) { + if (CHECK_PID(chip, 0x5288)) func_no = 2; - } else { + else func_no = 1; - } + rtsx_read_cfg_dw(chip, func_no, 0x84, &ultmp); RTSX_DEBUGP("pm_dstate of function %d: 0x%x\n", (int)func_no, ultmp); rtsx_write_cfg_dw(chip, func_no, 0x84, 0xFF, dstate); @@ -1898,11 +1842,10 @@ void rtsx_enter_ss(struct rtsx_chip *chip) } if (CHK_SDIO_EXIST(chip)) { - if (CHECK_PID(chip, 0x5288)) { + if (CHECK_PID(chip, 0x5288)) rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF00, 0x0100); - } else { + else rtsx_write_cfg_dw(chip, 1, 0xC0, 0xFF00, 0x0100); - } } if (chip->auto_delink_en) { @@ -1953,11 +1896,11 @@ int rtsx_pre_handle_interrupt(struct rtsx_chip *chip) u32 ocp_int = 0; if (CHECK_PID(chip, 0x5209)) { - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { + if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) ocp_int = MS_OC_INT | SD_OC_INT; - } else { + else ocp_int = SD_OC_INT; - } + } else { ocp_int = OC_INT; } @@ -1976,9 +1919,8 @@ int rtsx_pre_handle_interrupt(struct rtsx_chip *chip) chip->int_reg = rtsx_readl(chip, RTSX_BIPR); #ifdef HW_INT_WRITE_CLR - if (CHECK_PID(chip, 0x5209)) { + if (CHECK_PID(chip, 0x5209)) rtsx_writel(chip, RTSX_BIPR, chip->int_reg); - } #endif if (((chip->int_reg & int_enable) == 0) || (chip->int_reg == 0xFFFFFFFF)) @@ -1988,9 +1930,8 @@ int rtsx_pre_handle_interrupt(struct rtsx_chip *chip) if (CHECK_PID(chip, 0x5209)) { u8 val; rtsx_read_config_byte(chip, 0x05, &val); - if (val & 0x04) { + if (val & 0x04) return STATUS_FAIL; - } } } @@ -2107,16 +2048,15 @@ void rtsx_do_before_power_down(struct rtsx_chip *chip, int pm_stat) RTSX_DEBUGP("Host enter S1\n"); rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, HOST_ENTER_S1); } else if (pm_stat == PM_S3) { - if (chip->s3_pwr_off_delay > 0) { + if (chip->s3_pwr_off_delay > 0) wait_timeout(chip->s3_pwr_off_delay); - } + RTSX_DEBUGP("Host enter S3\n"); rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, HOST_ENTER_S3); } - if (chip->do_delink_before_power_down && chip->auto_delink_en) { + if (chip->do_delink_before_power_down && chip->auto_delink_en) rtsx_write_register(chip, CHANGE_LINK_STATE, 0x02, 2); - } rtsx_force_power_down(chip, SSC_PDCTL | OC_PDCTL); @@ -2143,11 +2083,10 @@ void rtsx_enable_aspm(struct rtsx_chip *chip) if (CHK_SDIO_EXIST(chip)) { u16 val = chip->aspm_l0s_l1_en | 0x0100; - if (CHECK_PID(chip, 0x5288)) { + if (CHECK_PID(chip, 0x5288)) rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFFFF, val); - } else { + else rtsx_write_cfg_dw(chip, 1, 0xC0, 0xFFFF, val); - } } } } @@ -2167,11 +2106,11 @@ void rtsx_disable_aspm(struct rtsx_chip *chip) if (chip->asic_code && CHECK_PID(chip, 0x5208)) rtsx_write_phy_register(chip, 0x07, 0x0129); - if (CHECK_PID(chip, 0x5208)) { + if (CHECK_PID(chip, 0x5208)) rtsx_write_register(chip, ASPM_FORCE_CTL, 0xF3, 0x30); - } else { + else rtsx_write_config_byte(chip, LCTLR, 0x00); - } + wait_timeout(1); } } @@ -2186,9 +2125,8 @@ int rtsx_read_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len) u16 reg_addr; u8 *ptr; - if (!buf) { + if (!buf) TRACE_RET(chip, STATUS_ERROR); - } ptr = buf; reg_addr = PPBUF_BASE2; @@ -2199,9 +2137,8 @@ int rtsx_read_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len) rtsx_add_cmd(chip, READ_REG_CMD, reg_addr++, 0, 0); retval = rtsx_send_cmd(chip, 0, 250); - if (retval < 0) { + if (retval < 0) TRACE_RET(chip, STATUS_FAIL); - } memcpy(ptr, rtsx_get_cmd_data(chip), 256); ptr += 256; @@ -2214,9 +2151,8 @@ int rtsx_read_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len) rtsx_add_cmd(chip, READ_REG_CMD, reg_addr++, 0, 0); retval = rtsx_send_cmd(chip, 0, 250); - if (retval < 0) { + if (retval < 0) TRACE_RET(chip, STATUS_FAIL); - } } memcpy(ptr, rtsx_get_cmd_data(chip), buf_len%256); @@ -2231,9 +2167,8 @@ int rtsx_write_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len) u16 reg_addr; u8 *ptr; - if (!buf) { + if (!buf) TRACE_RET(chip, STATUS_ERROR); - } ptr = buf; reg_addr = PPBUF_BASE2; @@ -2246,9 +2181,8 @@ int rtsx_write_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len) } retval = rtsx_send_cmd(chip, 0, 250); - if (retval < 0) { + if (retval < 0) TRACE_RET(chip, STATUS_FAIL); - } } if (buf_len%256) { @@ -2260,9 +2194,8 @@ int rtsx_write_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len) } retval = rtsx_send_cmd(chip, 0, 250); - if (retval < 0) { + if (retval < 0) TRACE_RET(chip, STATUS_FAIL); - } } return STATUS_SUCCESS; @@ -2270,9 +2203,8 @@ int rtsx_write_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len) int rtsx_check_chip_exist(struct rtsx_chip *chip) { - if (rtsx_readl(chip, 0) == 0xFFFFFFFF) { + if (rtsx_readl(chip, 0) == 0xFFFFFFFF) TRACE_RET(chip, STATUS_FAIL); - } return STATUS_SUCCESS; } @@ -2288,17 +2220,15 @@ int rtsx_force_power_on(struct rtsx_chip *chip, u8 ctl) #ifdef SUPPORT_OCP if (ctl & OC_PDCTL) { mask |= SD_OC_POWER_DOWN; - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { + if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) mask |= MS_OC_POWER_DOWN; - } } #endif if (mask) { retval = rtsx_write_register(chip, FPDCTL, mask, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (CHECK_PID(chip, 0x5288)) wait_timeout(200); @@ -2326,9 +2256,8 @@ int rtsx_force_power_down(struct rtsx_chip *chip, u8 ctl) if (mask) { val = mask; retval = rtsx_write_register(chip, FPDCTL, mask, val); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } return STATUS_SUCCESS; -- cgit v0.10.2 From 0e4da5cbaefa02ed408f8a78d759baef2905bf34 Mon Sep 17 00:00:00 2001 From: Jonathan Brett Date: Fri, 17 Aug 2012 21:13:18 +0100 Subject: Staging: asus_oled: Add suspend/resume callbacks - Add simple suspend/resume PM callbacks to disable oled display on suspend and return to previous state on resume Signed-off-by: Jonathan Brett Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/asus_oled/asus_oled.c b/drivers/staging/asus_oled/asus_oled.c index 42a5e7a..0018547 100644 --- a/drivers/staging/asus_oled/asus_oled.c +++ b/drivers/staging/asus_oled/asus_oled.c @@ -137,6 +137,7 @@ struct asus_oled_dev { size_t buf_size; char *buf; uint8_t enabled; + uint8_t enabled_post_resume; struct device *dev; }; @@ -765,11 +766,45 @@ static void asus_oled_disconnect(struct usb_interface *interface) dev_info(&interface->dev, "Disconnected Asus OLED device\n"); } +#ifdef CONFIG_PM +static int asus_oled_suspend(struct usb_interface *intf, pm_message_t message) +{ + struct asus_oled_dev *odev; + + odev = usb_get_intfdata(intf); + if (!odev) + return -ENODEV; + + odev->enabled_post_resume = odev->enabled; + enable_oled(odev, 0); + + return 0; +} + +static int asus_oled_resume(struct usb_interface *intf) +{ + struct asus_oled_dev *odev; + + odev = usb_get_intfdata(intf); + if (!odev) + return -ENODEV; + + enable_oled(odev, odev->enabled_post_resume); + + return 0; +} +#else +#define asus_oled_suspend NULL +#define asus_oled_resume NULL +#endif + static struct usb_driver oled_driver = { .name = ASUS_OLED_NAME, .probe = asus_oled_probe, .disconnect = asus_oled_disconnect, .id_table = id_table, + .suspend = asus_oled_suspend, + .resume = asus_oled_resume, }; static CLASS_ATTR_STRING(version, S_IRUGO, -- cgit v0.10.2 From ba07275faf0169820ff387c5f0d12a8a2e2165c8 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Thu, 23 Aug 2012 15:33:11 +0900 Subject: staging: ozwpan: Fix typo in staging/ozwpan Fix spelling typo in staging/ozwpan Signed-off-by: Masanari Iida Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ozwpan/ozevent.c b/drivers/staging/ozwpan/ozevent.c index 7f66b4f..a48498b 100644 --- a/drivers/staging/ozwpan/ozevent.c +++ b/drivers/staging/ozwpan/ozevent.c @@ -14,7 +14,7 @@ #include "ozappif.h" /*------------------------------------------------------------------------------ * Although the event mask is logically part of the oz_evtdev structure, it is - * needed outside of this file so define it seperately to avoid the need to + * needed outside of this file so define it separately to avoid the need to * export definition of struct oz_evtdev. */ u32 g_evt_mask; @@ -39,8 +39,8 @@ static struct oz_evtdev g_evtdev; */ void oz_event_init(void) { - /* Because g_evtdev is static external all fields initally zero so no - * need to reinitialised those. + /* Because g_evtdev is static external all fields initially zero so no + * need to reinitialized those. */ oz_trace("Event tracing initialized\n"); spin_lock_init(&g_evtdev.lock); -- cgit v0.10.2 From 0c925aa043640086ff928f45c89274965eace5a9 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 28 Aug 2012 21:11:00 +0800 Subject: staging: ozwpan: remove pointless conditional before kfree_skb() Remove pointless conditional before kfree_skb(). Signed-off-by: Wei Yongjun Acked-by: Rupesh Gujare Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ozwpan/ozpd.c b/drivers/staging/ozwpan/ozpd.c index f546b5a..0b3648c 100644 --- a/drivers/staging/ozwpan/ozpd.c +++ b/drivers/staging/ozwpan/ozpd.c @@ -746,8 +746,7 @@ int oz_isoc_stream_create(struct oz_pd *pd, u8 ep_num) */ static void oz_isoc_stream_free(struct oz_isoc_stream *st) { - if (st->skb) - kfree_skb(st->skb); + kfree_skb(st->skb); kfree(st); } /*------------------------------------------------------------------------------ -- cgit v0.10.2 From e31bbfcc44b5c8871c6633d0fe40723e4aefb222 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sun, 19 Aug 2012 00:24:07 +0530 Subject: staging: wlags49_h2: coding style fix at wl_wds_netif_carrier_off no braces needed for single statement if block Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlags49_h2/wl_netdev.c b/drivers/staging/wlags49_h2/wl_netdev.c index 824b852..680de2b 100644 --- a/drivers/staging/wlags49_h2/wl_netdev.c +++ b/drivers/staging/wlags49_h2/wl_netdev.c @@ -1768,9 +1768,8 @@ void wl_wds_netif_carrier_off( struct wl_private *lp ) if( lp != NULL ) { for( count = 0; count < NUM_WDS_PORTS; count++ ) { - if( lp->wds_port[count].is_registered ) { + if( lp->wds_port[count].is_registered ) netif_carrier_off( lp->wds_port[count].dev ); - } } } -- cgit v0.10.2 From 44e8482c77bdf35ba8d5fd8d8d8e56c11e1d39fa Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sun, 19 Aug 2012 00:24:08 +0530 Subject: staging: wlags49_h2: remove unneded return in wl_wds_netif_carrier_off the return is at the end of void function, which is not needed as this function returns void. Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlags49_h2/wl_netdev.c b/drivers/staging/wlags49_h2/wl_netdev.c index 680de2b..207933e 100644 --- a/drivers/staging/wlags49_h2/wl_netdev.c +++ b/drivers/staging/wlags49_h2/wl_netdev.c @@ -1773,7 +1773,6 @@ void wl_wds_netif_carrier_off( struct wl_private *lp ) } } - return; } // wl_wds_netif_carrier_off /*============================================================================*/ -- cgit v0.10.2 From a350d1fdfb6ed326493fe7e024acd8f65f7437c4 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sun, 19 Aug 2012 00:24:09 +0530 Subject: staging: wlags49_h2: style fix in w1_wds_netif_carrier_off whitespaces at beginning of the line are removed and are replaced with the tabs Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlags49_h2/wl_netdev.c b/drivers/staging/wlags49_h2/wl_netdev.c index 207933e..2259a5f 100644 --- a/drivers/staging/wlags49_h2/wl_netdev.c +++ b/drivers/staging/wlags49_h2/wl_netdev.c @@ -1763,15 +1763,14 @@ void wl_wds_netif_carrier_on( struct wl_private *lp ) ******************************************************************************/ void wl_wds_netif_carrier_off( struct wl_private *lp ) { - int count; - /*------------------------------------------------------------------------*/ + int count; - if( lp != NULL ) { - for( count = 0; count < NUM_WDS_PORTS; count++ ) { - if( lp->wds_port[count].is_registered ) - netif_carrier_off( lp->wds_port[count].dev ); - } - } + if( lp != NULL ) { + for( count = 0; count < NUM_WDS_PORTS; count++ ) { + if( lp->wds_port[count].is_registered ) + netif_carrier_off( lp->wds_port[count].dev ); + } + } } // wl_wds_netif_carrier_off /*============================================================================*/ -- cgit v0.10.2 From e4d653f3e280dc60e66a8bed98fef3c6ec4f1479 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sun, 19 Aug 2012 00:24:10 +0530 Subject: staging: wlagn49_h2: fix the checkpatch warning about the space after the open paranthesis the following fix is done in the wl_wds_netif_carrier_off function: wl_netdev.c:1764: ERROR: space prohibited after that open parenthesis '(' wl_netdev.c:1764: ERROR: space prohibited before that close parenthesis ')' wl_netdev.c:1768: ERROR: space prohibited after that open parenthesis '(' wl_netdev.c:1768: ERROR: space prohibited before that close parenthesis ')' wl_netdev.c:1768: ERROR: space required before the open parenthesis '(' wl_netdev.c:1769: ERROR: space prohibited after that open parenthesis '(' wl_netdev.c:1769: ERROR: space prohibited before that close parenthesis ')' wl_netdev.c:1769: ERROR: space required before the open parenthesis '(' wl_netdev.c:1770: ERROR: space prohibited after that open parenthesis '(' wl_netdev.c:1770: ERROR: space prohibited before that close parenthesis ')' wl_netdev.c:1770: ERROR: space required before the open parenthesis '(' wl_netdev.c:1771: ERROR: space prohibited after that open parenthesis '(' wl_netdev.c:1771: ERROR: space prohibited before that close parenthesis ')' Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlags49_h2/wl_netdev.c b/drivers/staging/wlags49_h2/wl_netdev.c index 2259a5f..5eda3c67 100644 --- a/drivers/staging/wlags49_h2/wl_netdev.c +++ b/drivers/staging/wlags49_h2/wl_netdev.c @@ -1765,10 +1765,10 @@ void wl_wds_netif_carrier_off( struct wl_private *lp ) { int count; - if( lp != NULL ) { - for( count = 0; count < NUM_WDS_PORTS; count++ ) { - if( lp->wds_port[count].is_registered ) - netif_carrier_off( lp->wds_port[count].dev ); + if(lp != NULL) { + for(count = 0; count < NUM_WDS_PORTS; count++) { + if(lp->wds_port[count].is_registered) + netif_carrier_off(lp->wds_port[count].dev); } } -- cgit v0.10.2 From 4b9645b711153e5e7bbbc9f15766190124b3fe7c Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sun, 19 Aug 2012 00:24:11 +0530 Subject: staging: wlags49_h2: remove return statements at the end of all void functions this patch removes the return statement at the end of all void functions, since the function returning void no need to have a return at the end of the function. Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlags49_h2/wl_netdev.c b/drivers/staging/wlags49_h2/wl_netdev.c index 5eda3c67..e6996c8 100644 --- a/drivers/staging/wlags49_h2/wl_netdev.c +++ b/drivers/staging/wlags49_h2/wl_netdev.c @@ -652,7 +652,6 @@ void wl_tx_timeout( struct net_device *dev ) wl_unlock( lp, &flags ); DBG_LEAVE( DbgInfo ); - return; } // wl_tx_timeout /*============================================================================*/ @@ -1292,7 +1291,6 @@ void wl_device_dealloc( struct net_device *dev ) free_netdev( dev ); DBG_LEAVE( DbgInfo ); - return; } // wl_device_dealloc /*============================================================================*/ @@ -1547,7 +1545,6 @@ void wl_wds_device_alloc( struct wl_private *lp ) WL_WDS_NETIF_STOP_QUEUE( lp ); DBG_LEAVE( DbgInfo ); - return; } // wl_wds_device_alloc /*============================================================================*/ @@ -1593,7 +1590,6 @@ void wl_wds_device_dealloc( struct wl_private *lp ) } DBG_LEAVE( DbgInfo ); - return; } // wl_wds_device_dealloc /*============================================================================*/ @@ -1629,8 +1625,6 @@ void wl_wds_netif_start_queue( struct wl_private *lp ) } } } - - return; } // wl_wds_netif_start_queue /*============================================================================*/ @@ -1666,8 +1660,6 @@ void wl_wds_netif_stop_queue( struct wl_private *lp ) } } } - - return; } // wl_wds_netif_stop_queue /*============================================================================*/ @@ -1703,8 +1695,6 @@ void wl_wds_netif_wake_queue( struct wl_private *lp ) } } } - - return; } // wl_wds_netif_wake_queue /*============================================================================*/ @@ -1738,8 +1728,6 @@ void wl_wds_netif_carrier_on( struct wl_private *lp ) } } } - - return; } // wl_wds_netif_carrier_on /*============================================================================*/ -- cgit v0.10.2 From 3cf7c7aaee1d97d39419fadc58110c1af552cefb Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sun, 19 Aug 2012 00:24:12 +0530 Subject: staging: wlagn49_h2: move open brace of if from below to beside of if statement the opening brace of the if statement should be beside to it, not below to it. Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlags49_h2/wl_netdev.c b/drivers/staging/wlags49_h2/wl_netdev.c index e6996c8..c936854 100644 --- a/drivers/staging/wlags49_h2/wl_netdev.c +++ b/drivers/staging/wlags49_h2/wl_netdev.c @@ -1795,22 +1795,19 @@ int wl_send_dma( struct wl_private *lp, struct sk_buff *skb, int port ) DBG_FUNC( "wl_send_dma" ); - if( lp == NULL ) - { + if( lp == NULL ) { DBG_ERROR( DbgInfo, "Private adapter struct is NULL\n" ); return FALSE; } - if( lp->dev == NULL ) - { + if( lp->dev == NULL ) { DBG_ERROR( DbgInfo, "net_device struct in wl_private is NULL\n" ); return FALSE; } /* AGAIN, ALL THE QUEUEING DONE HERE IN I/O MODE IS NOT PERFORMED */ - if( skb == NULL ) - { + if( skb == NULL ) { DBG_WARNING (DbgInfo, "Nothing to send.\n"); return FALSE; } @@ -1820,8 +1817,7 @@ int wl_send_dma( struct wl_private *lp, struct sk_buff *skb, int port ) /* Get a free descriptor */ desc = wl_pci_dma_get_tx_packet( lp ); - if( desc == NULL ) - { + if( desc == NULL ) { if( lp->netif_queue_on == TRUE ) { netif_stop_queue( lp->dev ); WL_WDS_NETIF_STOP_QUEUE( lp ); @@ -1837,8 +1833,7 @@ int wl_send_dma( struct wl_private *lp, struct sk_buff *skb, int port ) desc_next = desc->next_desc_addr; - if( desc_next->buf_addr == NULL ) - { + if( desc_next->buf_addr == NULL ) { DBG_ERROR( DbgInfo, "DMA descriptor buf_addr is NULL\n" ); return FALSE; } -- cgit v0.10.2 From cb154c18954e245c0d933e6b8302c381ffa13c67 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Mon, 27 Aug 2012 23:21:13 +0900 Subject: staging: wlags49_h2: Fix typo in staging/wlags49_h2 driver Correct spelling typo in staging/wlags49_h2 Signed-off-by: Masanari Iida Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlags49_h2/README.ubuntu b/drivers/staging/wlags49_h2/README.ubuntu index 5f1cfb8..f1483c4 100644 --- a/drivers/staging/wlags49_h2/README.ubuntu +++ b/drivers/staging/wlags49_h2/README.ubuntu @@ -81,7 +81,7 @@ The linux driver files (wl_xxxx.c) are changed in the following ways: - Addaptations of Andrey Borzenkov applied to 7.22 source - Alterations to avoid most HCF_ASSERTs -- Switching interrupts off and on in the HCF --- Bugfixes, things that were aparently wrong like reporting link status +-- Bugfixes, things that were apparently wrong like reporting link status change which checked a variable that was not changed in HCF anymore. -- Used on WEP but setting keys via SIOCSIWENCODEEXT was not supported -- Recovery actions added diff --git a/drivers/staging/wlags49_h2/hcfcfg.h b/drivers/staging/wlags49_h2/hcfcfg.h index 39fb4d3..869b5c3 100644 --- a/drivers/staging/wlags49_h2/hcfcfg.h +++ b/drivers/staging/wlags49_h2/hcfcfg.h @@ -21,7 +21,7 @@ * hcfcfg.tpl list all #defines which must be specified to: * adjust the HCF functions defined in HCF.C to the characteristics of a specific environment * o maximum sizes for messages -* o Endianess +* o Endianness * Compiler specific macros * o port I/O macros * o type definitions diff --git a/drivers/staging/wlags49_h2/hcfdef.h b/drivers/staging/wlags49_h2/hcfdef.h index 30744e1..74c0f71 100644 --- a/drivers/staging/wlags49_h2/hcfdef.h +++ b/drivers/staging/wlags49_h2/hcfdef.h @@ -652,15 +652,15 @@ err: you used an invalid bitmask; #if 0 //get compiler going #if HCF_EX_INT_TICK != HREG_EV_TICK ;? out dated checking -err: someone redefined these macros while the implemenation assumes they are equal; +err: someone redefined these macros while the implementation assumes they are equal; #endif #if HCF_EX_INT_TX_OK != HFS_TX_CNTL_TX_OK || HFS_TX_CNTL_TX_OK != HREG_EV_TX_OK ;? out dated checking -err: someone redefined these macros while the implemenation assumes they are equal; +err: someone redefined these macros while the implementation assumes they are equal; #endif #if HCF_EX_INT_TX_EX != HFS_TX_CNTL_TX_EX || HFS_TX_CNTL_TX_EX != HREG_EV_TX_EX ;? out dated checking -err: someone redefined these macros while the implemenation assumes they are equal; +err: someone redefined these macros while the implementation assumes they are equal; #endif #endif // 0 get compiler going diff --git a/drivers/staging/wlags49_h2/mdd.h b/drivers/staging/wlags49_h2/mdd.h index 5c3515f..48aa108 100644 --- a/drivers/staging/wlags49_h2/mdd.h +++ b/drivers/staging/wlags49_h2/mdd.h @@ -844,13 +844,13 @@ XX1( CFG_SCAN, SCAN_RS_STRCT, scan_result[32] ) /*Scan results * #define HCF_SUCCESS 0x00 // OK -#define HCF_ERR_TIME_OUT 0x04 // Expected Hermes event did not occure in expected time +#define HCF_ERR_TIME_OUT 0x04 // Expected Hermes event did not occur in expected time #define HCF_ERR_NO_NIC 0x05 /* card not found (usually yanked away during hcfio_in_string * Also: card is either absent or disabled while it should be neither */ #define HCF_ERR_LEN 0x08 /* buffer size insufficient * - IFB_ConfigTable too small * - hcf_get_info buffer has a size of 0 or 1 or less than needed - * to accomodate all data + * to accommodate all data * - hcf_put_info: CFG_DLNV_DATA exceeds intermediate * buffer size */ #define HCF_ERR_INCOMP_PRI 0x09 // primary functions are not compatible diff --git a/drivers/staging/wlags49_h2/wl_if.h b/drivers/staging/wlags49_h2/wl_if.h index 6a26130..6d66dabf 100644 --- a/drivers/staging/wlags49_h2/wl_if.h +++ b/drivers/staging/wlags49_h2/wl_if.h @@ -95,7 +95,7 @@ // Manufacture ID: 0156,0003 // Lowest measurment for noise floor seen is value 54 // Highest signal strength in close proximity to the AP seen is value 118 -// Very good must be arround 100 (otherwise its never "full scale" +// Very good must be around 100 (otherwise its never "full scale" // All other constants are derrived from these. This makes the signal gauge // work for me... #define HCF_MIN_SIGNAL_LEVEL 54 diff --git a/drivers/staging/wlags49_h2/wl_internal.h b/drivers/staging/wlags49_h2/wl_internal.h index 553601f..480814e 100644 --- a/drivers/staging/wlags49_h2/wl_internal.h +++ b/drivers/staging/wlags49_h2/wl_internal.h @@ -11,7 +11,7 @@ * *------------------------------------------------------------------------------ * - * Header for defintions and macros internal to the drvier. + * Header for definitions and macros internal to the drvier. * *------------------------------------------------------------------------------ * diff --git a/drivers/staging/wlags49_h2/wl_main.c b/drivers/staging/wlags49_h2/wl_main.c index 2041078..bb3733f 100644 --- a/drivers/staging/wlags49_h2/wl_main.c +++ b/drivers/staging/wlags49_h2/wl_main.c @@ -128,7 +128,7 @@ #include #endif /* BUS_PCI */ /******************************************************************************* - * macro defintions + * macro definitions ******************************************************************************/ #define VALID_PARAM(C) \ { \ @@ -1627,7 +1627,7 @@ int wl_put_ltv( struct wl_private *lp ) lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] ); #endif // WARP -//;?skip temporarily to see whether the RID or something else is the probelm hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord )); +//;?skip temporarily to see whether the RID or something else is the problem hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord )); DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL 2.4GHz : 0x%04x\n", lp->TxRateControl[0] ); diff --git a/drivers/staging/wlags49_h2/wl_netdev.c b/drivers/staging/wlags49_h2/wl_netdev.c index c936854..dde6327 100644 --- a/drivers/staging/wlags49_h2/wl_netdev.c +++ b/drivers/staging/wlags49_h2/wl_netdev.c @@ -1251,7 +1251,7 @@ struct net_device * wl_device_alloc( void ) netif_stop_queue( dev ); - /* Allocate virutal devices for WDS support if needed */ + /* Allocate virtual devices for WDS support if needed */ WL_WDS_DEVICE_ALLOC( lp ); DBG_LEAVE( DbgInfo ); diff --git a/drivers/staging/wlags49_h2/wl_pci.c b/drivers/staging/wlags49_h2/wl_pci.c index 0b31b01..457c7ed 100644 --- a/drivers/staging/wlags49_h2/wl_pci.c +++ b/drivers/staging/wlags49_h2/wl_pci.c @@ -385,7 +385,7 @@ int wl_adapter_is_open( struct net_device *dev ) * DESCRIPTION: * * Registered in the pci_driver structure, this function is called when the - * PCI subsystem finds a new PCI device which matches the infomation contained + * PCI subsystem finds a new PCI device which matches the information contained * in the pci_device_id table. * * PARAMETERS: @@ -424,7 +424,7 @@ int __devinit wl_pci_probe( struct pci_dev *pdev, * DESCRIPTION: * * Registered in the pci_driver structure, this function is called when the - * PCI subsystem detects that a PCI device which matches the infomation + * PCI subsystem detects that a PCI device which matches the information * contained in the pci_device_id table has been removed. * * PARAMETERS: diff --git a/drivers/staging/wlags49_h2/wl_priv.c b/drivers/staging/wlags49_h2/wl_priv.c index f30e5ee..87e1e41 100644 --- a/drivers/staging/wlags49_h2/wl_priv.c +++ b/drivers/staging/wlags49_h2/wl_priv.c @@ -225,7 +225,7 @@ int wvlan_uil_connect( struct uilreq *urq, struct wl_private *lp ) * * DESCRIPTION: * - * Disonnect from the UIL after a request has been completed. + * Disconnect from the UIL after a request has been completed. * * PARAMETERS: * diff --git a/drivers/staging/wlags49_h2/wl_profile.c b/drivers/staging/wlags49_h2/wl_profile.c index 0e49272..beabf59 100644 --- a/drivers/staging/wlags49_h2/wl_profile.c +++ b/drivers/staging/wlags49_h2/wl_profile.c @@ -910,7 +910,7 @@ int parse_mac_address(char *value, u_char *byte_array) memset(byte_field, '\0', 3); while (value[value_offset] != '\0') { - /* Skip over the colon chars seperating the bytes, if they exist */ + /* Skip over the colon chars separating the bytes, if they exist */ if (value[value_offset] == ':') { value_offset++; continue; diff --git a/drivers/staging/wlags49_h2/wl_version.h b/drivers/staging/wlags49_h2/wl_version.h index 3deacfa..037b526 100644 --- a/drivers/staging/wlags49_h2/wl_version.h +++ b/drivers/staging/wlags49_h2/wl_version.h @@ -152,7 +152,7 @@ err: define bus type; /******************************************************************************* - * bus architechture specific defines, includes, etc. + * bus architecture specific defines, includes, etc. ******************************************************************************/ /* * There doesn't seem to be a difference for PCMCIA and PCI anymore, at least diff --git a/drivers/staging/wlags49_h2/wl_wext.c b/drivers/staging/wlags49_h2/wl_wext.c index 7ff0a10..7e6bad9 100644 --- a/drivers/staging/wlags49_h2/wl_wext.c +++ b/drivers/staging/wlags49_h2/wl_wext.c @@ -2595,7 +2595,7 @@ static int wireless_set_scan(struct net_device *dev, struct iw_request_info *inf int retries = 0; /*------------------------------------------------------------------------*/ - //;? Note: shows results as trace, retruns always 0 unless BUSY + //;? Note: shows results as trace, returns always 0 unless BUSY DBG_FUNC( "wireless_set_scan" ); DBG_ENTER( DbgInfo ); -- cgit v0.10.2 From 4f19b38f135aaf3c71198bb55cb7a88693a4ba00 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Sun, 26 Aug 2012 08:52:48 +0800 Subject: staging: wlags49_h2: use is_broadcast_ether_addr() instead of memcmp() Using is_broadcast_ether_addr() instead of directly use memcmp() to determine if the ethernet address is broadcast address. Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlags49_h2/wl_wext.c b/drivers/staging/wlags49_h2/wl_wext.c index 7e6bad9..cef12f7 100644 --- a/drivers/staging/wlags49_h2/wl_wext.c +++ b/drivers/staging/wlags49_h2/wl_wext.c @@ -62,6 +62,7 @@ #include #include #include +#include #include #include @@ -173,7 +174,7 @@ static int hermes_clear_tkip_keys(ltv_t *ltv, u16 key_idx, u8 *addr) switch (key_idx) { case 0: - if (memcmp(addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) != 0) { + if (!is_broadcast_ether_addr(addr)) { ltv->len = 7; ltv->typ = CFG_REMOVE_TKIP_MAPPED_KEY; memcpy(<v->u.u8[0], addr, ETH_ALEN); -- cgit v0.10.2 From 4344379f63d3bf16d4f2cb3d6b3f3be12704173f Mon Sep 17 00:00:00 2001 From: Marc Dietrich Date: Sun, 19 Aug 2012 19:03:06 +0200 Subject: staging: nvec: fix clock setup commit 30b68231 "ARM: tegra: clock: add i2c fast clock entry in clock table" added a new clock for the i2c controllers, so clock requests are no longer conclusive. Fix this by specifying "div-clk" explicitly. Signed-off-by: Marc Dietrich Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index fb52fe0..3e090ec 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -770,7 +770,7 @@ static int __devinit tegra_nvec_probe(struct platform_device *pdev) return -ENODEV; } - i2c_clk = clk_get_sys("tegra-i2c.2", NULL); + i2c_clk = clk_get_sys("tegra-i2c.2", "div-clk"); if (IS_ERR(i2c_clk)) { dev_err(nvec->dev, "failed to get controller clock\n"); return -ENODEV; -- cgit v0.10.2 From 4b8bf03d7f775271c2016e76011b113bc5f83c14 Mon Sep 17 00:00:00 2001 From: Marc Dietrich Date: Sun, 19 Aug 2012 19:03:07 +0200 Subject: staging: nvec: release sync write lock in error case We forgot to release the sync write lock in case the async write fails. Found by rpiloose on IRC. Signed-off-by: Marc Dietrich Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index 3e090ec..fd84f8f 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -294,8 +294,10 @@ struct nvec_msg *nvec_write_sync(struct nvec_chip *nvec, nvec->sync_write_pending = (data[1] << 8) + data[0]; - if (nvec_write_async(nvec, data, size) < 0) + if (nvec_write_async(nvec, data, size) < 0) { + mutex_unlock(&nvec->sync_write_mutex); return NULL; + } dev_dbg(nvec->dev, "nvec_sync_write: 0x%04x\n", nvec->sync_write_pending); -- cgit v0.10.2 From 71d64ef2fa90aaf5425842b9bfef9e4b9e6ad0ff Mon Sep 17 00:00:00 2001 From: Marc Dietrich Date: Sun, 19 Aug 2012 19:03:08 +0200 Subject: staging: nvec: do not depend on MACH_PAZ00 With the removal of board files on the tegra arch, drivers can now only be instantiated via device tree. Consequently, all MACH_ config variables are removed. As a temporary solution always enable building for the (up to now) only supported paz00 board until nvec is full ported to device tree. Signed-off-by: Marc Dietrich Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/nvec/Kconfig b/drivers/staging/nvec/Kconfig index 43048e9..1235a78 100644 --- a/drivers/staging/nvec/Kconfig +++ b/drivers/staging/nvec/Kconfig @@ -28,7 +28,7 @@ config NVEC_POWER config NVEC_PAZ00 bool "Support for OEM specific functions on Compal PAZ00 based devices" - depends on MFD_NVEC && LEDS_CLASS && MACH_PAZ00 + depends on MFD_NVEC && LEDS_CLASS help Say Y to enable control of the yellow side leds on Compal PAZ00 based devices, e.g. Toshbia AC100 and Dynabooks AZ netbooks. -- cgit v0.10.2 From eb1e40a4dd0fb4095900e085fdd3ed259acbee29 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 22 Aug 2012 15:32:38 -0700 Subject: staging: nvec: use system_nrt_wq instead of custom one There isn't much reason to use custom workqueue in nvec. It can use system_nrt_wq instead and cancel the two work items on removal. Signed-off-by: Tejun Heo Signed-off-by: Marc Dietrich Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index fd84f8f..b0972d0 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -264,7 +264,7 @@ int nvec_write_async(struct nvec_chip *nvec, const unsigned char *data, list_add_tail(&msg->node, &nvec->tx_data); spin_unlock_irqrestore(&nvec->tx_lock, flags); - queue_work(nvec->wq, &nvec->tx_work); + queue_work(system_nrt_wq, &nvec->tx_work); return 0; } @@ -471,7 +471,7 @@ static void nvec_rx_completed(struct nvec_chip *nvec) if (!nvec_msg_is_event(nvec->rx)) complete(&nvec->ec_transfer); - queue_work(nvec->wq, &nvec->rx_work); + queue_work(system_nrt_wq, &nvec->rx_work); } /** @@ -794,13 +794,11 @@ static int __devinit tegra_nvec_probe(struct platform_device *pdev) INIT_LIST_HEAD(&nvec->tx_data); INIT_WORK(&nvec->rx_work, nvec_dispatch); INIT_WORK(&nvec->tx_work, nvec_request_master); - nvec->wq = alloc_workqueue("nvec", WQ_NON_REENTRANT, 2); err = devm_gpio_request_one(&pdev->dev, nvec->gpio, GPIOF_OUT_INIT_HIGH, "nvec gpio"); if (err < 0) { dev_err(nvec->dev, "couldn't request gpio\n"); - destroy_workqueue(nvec->wq); return -ENODEV; } @@ -808,7 +806,6 @@ static int __devinit tegra_nvec_probe(struct platform_device *pdev) "nvec", nvec); if (err) { dev_err(nvec->dev, "couldn't request irq\n"); - destroy_workqueue(nvec->wq); return -ENODEV; } disable_irq(nvec->irq); @@ -862,7 +859,8 @@ static int __devexit tegra_nvec_remove(struct platform_device *pdev) nvec_write_async(nvec, EC_DISABLE_EVENT_REPORTING, 3); mfd_remove_devices(nvec->dev); - destroy_workqueue(nvec->wq); + cancel_work_sync(&nvec->rx_work); + cancel_work_sync(&nvec->tx_work); return 0; } -- cgit v0.10.2 From 538a697ac8ca86b4507aaf81cfed5359aa11d606 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Tue, 21 Aug 2012 20:12:33 +0900 Subject: Staging: vme: Fix a white space issue The below checkpatch error was fixed. -ERROR: trailing whitespace Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c index 0170788..c3f94f3 100644 --- a/drivers/staging/vme/devices/vme_user.c +++ b/drivers/staging/vme/devices/vme_user.c @@ -396,7 +396,7 @@ static ssize_t vme_user_write(struct file *file, const char __user *buf, default: retval = -EINVAL; } - + mutex_unlock(&image[minor].mutex); if (retval > 0) -- cgit v0.10.2 From 736f5d0a0980a6bf71e5c0d30c2d35225fb3f583 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Tue, 21 Aug 2012 20:13:09 +0900 Subject: staging/vme: Use pr_ printks in vme_pio2_core.c The below checkpatch warnings was fixed, -WARNING: Prefer pr_err(... to printk(KERN_ERR, ... and added pr_fmt. Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/vme/devices/vme_pio2_core.c b/drivers/staging/vme/devices/vme_pio2_core.c index 4bf8e05..dad8281 100644 --- a/drivers/staging/vme/devices/vme_pio2_core.c +++ b/drivers/staging/vme/devices/vme_pio2_core.c @@ -10,6 +10,8 @@ * option) any later version. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -163,15 +165,13 @@ static int __init pio2_init(void) int retval = 0; if (bus_num == 0) { - printk(KERN_ERR "%s: No cards, skipping registration\n", - driver_name); + pr_err("No cards, skipping registration\n"); goto err_nocard; } if (bus_num > PIO2_CARDS_MAX) { - printk(KERN_ERR - "%s: Driver only able to handle %d PIO2 Cards\n", - driver_name, PIO2_CARDS_MAX); + pr_err("Driver only able to handle %d PIO2 Cards\n", + PIO2_CARDS_MAX); bus_num = PIO2_CARDS_MAX; } -- cgit v0.10.2 From 789d1aef176e720fce4a8a5a9ab07f093ddb9086 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 20 Aug 2012 08:43:13 -0700 Subject: staging: "vt6655" Fix typos in comments. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/vt6655/80211mgr.h b/drivers/staging/vt6655/80211mgr.h index 3bdab3f..65780f2 100644 --- a/drivers/staging/vt6655/80211mgr.h +++ b/drivers/staging/vt6655/80211mgr.h @@ -186,7 +186,7 @@ // -// Cipher Suite Selectors defiened in 802.11i +// Cipher Suite Selectors defined in 802.11i // #define WLAN_11i_CSS_USE_GROUP 0 #define WLAN_11i_CSS_WEP40 1 diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c index e7b93a2..6a06f64 100644 --- a/drivers/staging/vt6655/baseband.c +++ b/drivers/staging/vt6655/baseband.c @@ -28,8 +28,8 @@ * Functions: * BBuGetFrameTime - Calculate data frame transmitting time * BBvCaculateParameter - Caculate PhyLength, PhyService and Phy Signal parameter for baseband Tx - * BBbReadEmbeded - Embeded read baseband register via MAC - * BBbWriteEmbeded - Embeded write baseband register via MAC + * BBbReadEmbeded - Embedded read baseband register via MAC + * BBbWriteEmbeded - Embedded write baseband register via MAC * BBbIsRegBitsOn - Test if baseband register bits on * BBbIsRegBitsOff - Test if baseband register bits off * BBbVT3253Init - VIA VT3253 baseband chip init code @@ -2001,7 +2001,7 @@ BBvCaculateParameter ( } /* - * Description: Read a byte from BASEBAND, by embeded programming + * Description: Read a byte from BASEBAND, by embedded programming * * Parameters: * In: @@ -2043,7 +2043,7 @@ bool BBbReadEmbeded (unsigned long dwIoBase, unsigned char byBBAddr, unsigned ch /* - * Description: Write a Byte to BASEBAND, by embeded programming + * Description: Write a Byte to BASEBAND, by embedded programming * * Parameters: * In: diff --git a/drivers/staging/vt6655/bssdb.c b/drivers/staging/vt6655/bssdb.c index fcffa4f..fe57fb8 100644 --- a/drivers/staging/vt6655/bssdb.c +++ b/drivers/staging/vt6655/bssdb.c @@ -784,8 +784,8 @@ BSSDBbIsSTAInNodeDB(void *pMgmtObject, unsigned char *abyDstAddr, /*+ * * Routine Description: - * Find an empty node and allocated; if no empty found, - * instand used of most inactive one. + * Find an empty node and allocat it; if there is no empty node, + * then use the most inactive one. * * Return Value: * None diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index 2721e07..e2785c3 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -1354,7 +1354,8 @@ CARDbSetQuiet ( /* * * Description: - * Do Quiet, It will called by either ISR (after start) or VNTWIFI (before start) so do not need SPINLOCK + * Do Quiet, It will be called by either ISR(after start) + * or VNTWIFI(before start) so we do not need a SPINLOCK * * Parameters: * In: diff --git a/drivers/staging/vt6655/datarate.c b/drivers/staging/vt6655/datarate.c index efbb8f4..b86ec1b 100644 --- a/drivers/staging/vt6655/datarate.c +++ b/drivers/staging/vt6655/datarate.c @@ -126,7 +126,7 @@ DATARATEbyGetRateIdx ( /*+ * * Routine Description: - * Rate fallback Algorithm Implementaion + * Rate fallback Algorithm Implementation * * Parameters: * In: diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index c5e6b98..e54e00b 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -327,7 +327,7 @@ typedef struct tagSDeFragControlBlock //flags for driver status #define DEVICE_FLAGS_OPENED 0x00010000UL #define DEVICE_FLAGS_WOL_ENABLED 0x00080000UL -//flags for capbilities +//flags for capabilities #define DEVICE_FLAGS_TX_ALIGN 0x01000000UL #define DEVICE_FLAGS_HAVE_CAM 0x02000000UL #define DEVICE_FLAGS_FLOW_CTRL 0x04000000UL @@ -567,7 +567,7 @@ typedef struct __device_info { bool bPrvActive4RadioOFF; bool bGPIOBlockRead; - // Beacon releated + // Beacon related unsigned short wSeqCounter; unsigned short wBCNBufLen; bool bBeaconBufReady; diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 89d1c22..ee4fb16 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -518,7 +518,7 @@ static void s_vCompleteCurrentMeasure (PSDevice pDevice, unsigned char byResult) // -// Initialiation of MAC & BBP registers +// Initialisation of MAC & BBP registers // static void device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType) @@ -1064,7 +1064,7 @@ vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent) //Mask out the options cannot be set to the chip pDevice->sOpts.flags &= pChip_info->flags; - //Enable the chip specified capbilities + //Enable the chip specified capabilities pDevice->flags = pDevice->sOpts.flags | (pChip_info->flags & 0xFF000000UL); pDevice->tx_80211 = device_dma0_tx_80211; pDevice->sMgmtObj.pAdapter = (void *)pDevice; @@ -1678,7 +1678,7 @@ static int device_tx_srv(PSDevice pDevice, unsigned int uIdx) { uFrameSize = pTD->pTDInfo->dwReqCount - uFIFOHeaderSize; pTxBufHead = (PSTxBufHead) (pTD->pTDInfo->buf); // Update the statistics based on the Transmit status - // now, we DO'NT check TSR0_CDH + // now, we DONT check TSR0_CDH STAvUpdateTDStatCounter(&pDevice->scStatistic, byTsr0, byTsr1, diff --git a/drivers/staging/vt6655/dpc.c b/drivers/staging/vt6655/dpc.c index e8a71ba..373e9e4 100644 --- a/drivers/staging/vt6655/dpc.c +++ b/drivers/staging/vt6655/dpc.c @@ -718,7 +718,7 @@ device_receive_frame ( if ((*pbyRSSI != 0) && (pMgmt->pCurrBSS!=NULL)) { RFvRSSITodBm(pDevice, *pbyRSSI, &ldBm); - // Moniter if RSSI is too strong. + // Monitor if RSSI is too strong. pMgmt->pCurrBSS->byRSSIStatCnt++; pMgmt->pCurrBSS->byRSSIStatCnt %= RSSI_STAT_COUNT; pMgmt->pCurrBSS->ldBmAverage[pMgmt->pCurrBSS->byRSSIStatCnt] = ldBm; diff --git a/drivers/staging/vt6655/ioctl.c b/drivers/staging/vt6655/ioctl.c index ac15d38..afed6e3 100644 --- a/drivers/staging/vt6655/ioctl.c +++ b/drivers/staging/vt6655/ioctl.c @@ -111,7 +111,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) break; case WLAN_CMD_ZONETYPE_SET: - /* mike add :cann't support. */ + /* mike add :can't support. */ result = -EOPNOTSUPP; break; diff --git a/drivers/staging/vt6655/iwctl.c b/drivers/staging/vt6655/iwctl.c index 77aad7f..5cdda8d 100644 --- a/drivers/staging/vt6655/iwctl.c +++ b/drivers/staging/vt6655/iwctl.c @@ -358,7 +358,7 @@ int iwctl_giwscan(struct net_device *dev, /* - * Wireless Handler : set frequence or channel + * Wireless Handler : set frequency or channel */ int iwctl_siwfreq(struct net_device *dev, @@ -404,7 +404,7 @@ int iwctl_siwfreq(struct net_device *dev, } /* - * Wireless Handler : get frequence or channel + * Wireless Handler : get frequency or channel */ int iwctl_giwfreq(struct net_device *dev, @@ -1346,7 +1346,7 @@ if((wrq->flags & IW_ENCODE_DISABLED)==0){ }else if(index>0){ //when the length is 0 the request only changes the default transmit key index - //check the new key has a non zero lenget + //check the new key if it has a non zero length if(pDevice->bEncryptionEnable==false) { rc = -EINVAL; diff --git a/drivers/staging/vt6655/key.c b/drivers/staging/vt6655/key.c index 774b0d4..194fedc 100644 --- a/drivers/staging/vt6655/key.c +++ b/drivers/staging/vt6655/key.c @@ -372,7 +372,7 @@ bool KeybRemoveKey ( int i; if (is_broadcast_ether_addr(pbyBSSID)) { - // dealte all key + // delete all keys if ((dwKeyIndex & PAIRWISE_KEY) != 0) { for (i=0;iKeyTable[i].PairwiseKey.bKeyValid = false; diff --git a/drivers/staging/vt6655/mac.c b/drivers/staging/vt6655/mac.c index f8d1651..30c2615 100644 --- a/drivers/staging/vt6655/mac.c +++ b/drivers/staging/vt6655/mac.c @@ -56,9 +56,9 @@ * MACbSafeStop - Stop MAC function * MACbShutdown - Shut down MAC * MACvInitialize - Initialize MAC - * MACvSetCurrRxDescAddr - Set Rx Descriptos Address - * MACvSetCurrTx0DescAddr - Set Tx0 Descriptos Address - * MACvSetCurrTx1DescAddr - Set Tx1 Descriptos Address + * MACvSetCurrRxDescAddr - Set Rx Descriptors Address + * MACvSetCurrTx0DescAddr - Set Tx0 Descriptors Address + * MACvSetCurrTx1DescAddr - Set Tx1 Descriptors Address * MACvTimer0MicroSDelay - Micro Second Delay Loop by MAC * * Revision History: @@ -1498,7 +1498,7 @@ int ii; wOffset += (uKeyIdx * 4); for (ii=0;ii<4;ii++) { - // alway push 128 bits + // always push 128 bits DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"3.(%d) wOffset: %d, Data: %lX\n", ii, wOffset+ii, *pdwKey); VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+ii); VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, *pdwKey++); @@ -1567,7 +1567,7 @@ int ii; wOffset++; wOffset++; wOffset += (uKeyIdx * 4); - // alway push 128 bits + // always push 128 bits for (ii=0; ii<3; ii++) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"(%d) wOffset: %d, Data: %lX\n", ii, wOffset+ii, *pdwKey); VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+ii); @@ -1696,7 +1696,7 @@ int ii; wOffset += (uKeyIdx * 4); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"1. wOffset: %d, Data: %lX, idx:%d\n", wOffset, *pdwKey, uKeyIdx); - // alway push 128 bits + // always push 128 bits for (ii=0; ii<4; ii++) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"2.(%d) wOffset: %d, Data: %lX\n", ii, wOffset+ii, *pdwKey); VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+ii); diff --git a/drivers/staging/vt6655/mac.h b/drivers/staging/vt6655/mac.h index e3ccfee..adfb366 100644 --- a/drivers/staging/vt6655/mac.h +++ b/drivers/staging/vt6655/mac.h @@ -586,7 +586,7 @@ #define PKT_TYPE_NONE 0x00 // turn off receiver #define PKT_TYPE_ALL_MULTICAST 0x80 #define PKT_TYPE_PROMISCUOUS 0x40 -#define PKT_TYPE_DIRECTED 0x20 // obselete, directed address is always accepted +#define PKT_TYPE_DIRECTED 0x20 // obsolete, directed address is always accepted #define PKT_TYPE_BROADCAST 0x10 #define PKT_TYPE_MULTICAST 0x08 #define PKT_TYPE_ERROR_WPA 0x04 diff --git a/drivers/staging/vt6655/mib.c b/drivers/staging/vt6655/mib.c index 1b91a83..63ae4ad 100644 --- a/drivers/staging/vt6655/mib.c +++ b/drivers/staging/vt6655/mib.c @@ -191,7 +191,7 @@ void STAvUpdateRDStatCounter (PSStatCounter pStatistic, pStatistic->ullRsrOK++; if (cbFrameLength >= ETH_ALEN) { - // update counters in case that successful transmit + // update counters in case of successful transmit if (byRSR & RSR_ADDRBROAD) { pStatistic->ullRxBroadcastFrames++; pStatistic->ullRxBroadcastBytes += (unsigned long long) cbFrameLength; diff --git a/drivers/staging/vt6655/power.c b/drivers/staging/vt6655/power.c index 4c0b02e..661d534 100644 --- a/drivers/staging/vt6655/power.c +++ b/drivers/staging/vt6655/power.c @@ -207,7 +207,7 @@ PSbConsiderPowerDown( if (pDevice->bCmdRunning) return false; - // Froce PSEN on + // Force PSEN on MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PSEN); // check if all TD are empty, diff --git a/drivers/staging/vt6655/rf.c b/drivers/staging/vt6655/rf.c index aa69665..537a190 100644 --- a/drivers/staging/vt6655/rf.c +++ b/drivers/staging/vt6655/rf.c @@ -26,7 +26,7 @@ * Date: Feb. 19, 2004 * * Functions: - * IFRFbWriteEmbeded - Embeded write RF register via MAC + * IFRFbWriteEmbeded - Embedded write RF register via MAC * * Revision History: * @@ -460,11 +460,11 @@ bool s_bAL7230Init (unsigned long dwIoBase) //Calibration MACvTimer0MicroSDelay(dwIoBase, 150);//150us - bResult &= IFRFbWriteEmbeded(dwIoBase, (0x9ABA8F00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW)); //TXDCOC:active, RCK:diable + bResult &= IFRFbWriteEmbeded(dwIoBase, (0x9ABA8F00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW)); //TXDCOC:active, RCK:disable MACvTimer0MicroSDelay(dwIoBase, 30);//30us - bResult &= IFRFbWriteEmbeded(dwIoBase, (0x3ABA8F00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW)); //TXDCOC:diable, RCK:active + bResult &= IFRFbWriteEmbeded(dwIoBase, (0x3ABA8F00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW)); //TXDCOC:disable, RCK:active MACvTimer0MicroSDelay(dwIoBase, 30);//30us - bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL7230InitTable[CB_AL7230_INIT_SEQ-1]); //TXDCOC:diable, RCK:diable + bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL7230InitTable[CB_AL7230_INIT_SEQ-1]); //TXDCOC:disable, RCK:disable MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE3 | SOFTPWRCTL_SWPE2 | @@ -574,7 +574,7 @@ bool s_bAL7230SelectChannel (unsigned long dwIoBase, unsigned char byChannel) /*--------------------- Export Functions --------------------------*/ /* - * Description: Write to IF/RF, by embeded programming + * Description: Write to IF/RF, by embedded programming * * Parameters: * In: diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index 6935b37..c1e1f4f 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -2568,7 +2568,7 @@ CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) { if (bIsPSPOLL) { // The MAC will automatically replace the Duration-field of MAC header by Duration-field // of FIFO control header. - // This will cause AID-field of PS-POLL packet be incorrect (Because PS-POLL's AID field is + // This will cause AID-field of PS-POLL packet to be incorrect (Because PS-POLL's AID field is // in the same place of other packet's Duration-field). // And it will cause Cisco-AP to issue Disassociation-packet if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) { @@ -2860,7 +2860,7 @@ vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb, unsigned char *pbMPDU, un // SetPower will cause error power TX state for OFDM Date packet in TX buffer. // 2004.11.11 Kyle -- Using OFDM power to tx MngPkt will decrease the connection capability. - // And cmd timer will wait data pkt TX finish before scanning so it's OK + // And cmd timer will wait data pkt TX to finish before scanning so it's OK // to set power here. if (pDevice->pMgmt->eScanState != WMAC_NO_SCANNING) { RFbSetPower(pDevice, wCurrentRate, pDevice->byCurrentCh); @@ -2957,7 +2957,7 @@ vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb, unsigned char *pbMPDU, un pTxBufHead->wFragCtl |= cpu_to_le16((unsigned short)cbMacHdLen << 10); // Notes: - // Although spec says MMPDU can be fragmented; In most case, + // Although spec says MMPDU can be fragmented; In most casses, // no one will send a MMPDU under fragmentation. With RTS may occur. pDevice->bAES = false; //Set FRAGCTL_WEPTYP diff --git a/drivers/staging/vt6655/tcrc.c b/drivers/staging/vt6655/tcrc.c index f9c28bf..1313c4c 100644 --- a/drivers/staging/vt6655/tcrc.c +++ b/drivers/staging/vt6655/tcrc.c @@ -18,7 +18,7 @@ * * File: tcrc.c * - * Purpose: Implement functions to caculate CRC + * Purpose: Implement functions to calculate CRC * * Author: Tevin Chen * diff --git a/drivers/staging/vt6655/tcrc.h b/drivers/staging/vt6655/tcrc.h index d044985..a204421 100644 --- a/drivers/staging/vt6655/tcrc.h +++ b/drivers/staging/vt6655/tcrc.h @@ -18,7 +18,7 @@ * * File: tcrc.h * - * Purpose: Implement functions to caculate CRC + * Purpose: Implement functions to calculate CRC * * Author: Tevin Chen * diff --git a/drivers/staging/vt6655/vntwifi.c b/drivers/staging/vt6655/vntwifi.c index d645ecd..62c44b8 100644 --- a/drivers/staging/vt6655/vntwifi.c +++ b/drivers/staging/vt6655/vntwifi.c @@ -60,7 +60,7 @@ * Parameters: * In: * pMgmtHandle - pointer to management object - * eOPMode - Opreation Mode + * eOPMode - Operation Mode * Out: * none * diff --git a/drivers/staging/vt6655/wcmd.c b/drivers/staging/vt6655/wcmd.c index 7b5b99c..94bd1fc 100644 --- a/drivers/staging/vt6655/wcmd.c +++ b/drivers/staging/vt6655/wcmd.c @@ -121,7 +121,7 @@ vAdHocBeaconStop(PSDevice pDevice) /* * temporarily stop Beacon packet for AdHoc Server - * if all of the following coditions are met: + * if all of the following conditions are met: * (1) STA is in AdHoc mode * (2) VT3253 is programmed as automatic Beacon Transmitting * (3) One of the following conditions is met @@ -812,8 +812,8 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "sta ps tx fail \n"); } pMgmt->sNodeDBTable[ii].wEnQueueCnt--; - // check if sta ps enable, wait next pspoll - // if sta ps disable, send all pending buffers. + // check if sta ps enabled, and wait next pspoll. + // if sta ps disable, then send all pending buffers. if (pMgmt->sNodeDBTable[ii].bPSEnable) break; } diff --git a/drivers/staging/vt6655/wmgr.c b/drivers/staging/vt6655/wmgr.c index c46d519..b6f99ec 100644 --- a/drivers/staging/vt6655/wmgr.c +++ b/drivers/staging/vt6655/wmgr.c @@ -26,8 +26,8 @@ * Date: May 8, 2002 * * Functions: - * nsMgrObjectInitial - Initialize Management Objet data structure - * vMgrObjectReset - Reset Management Objet data structure + * nsMgrObjectInitial - Initialize Management Object data structure + * vMgrObjectReset - Reset Management Object data structure * vMgrAssocBeginSta - Start associate function * vMgrReAssocBeginSta - Start reassociate function * vMgrDisassocBeginSta - Start disassociate function @@ -54,7 +54,7 @@ * bMgrPrepareBeaconToSend - Prepare Beacon frame * s_vMgrLogStatus - Log 802.11 Status * vMgrRxManagePacket - Rcv management frame dispatch function - * s_vMgrFormatTIM- Assember TIM field of beacon + * s_vMgrFormatTIM- Assembler TIM field of beacon * vMgrTimerInit- Initial 1-sec and command call back funtions * * Revision History: @@ -425,7 +425,7 @@ vMgrTimerInit( /*+ * * Routine Description: - * Reset the management object structure. + * Reset the management object structure. * * Return Value: * None. @@ -1287,14 +1287,14 @@ s_vMgrRxAuthentication( vMgrDecodeAuthen(&sFrame); switch (cpu_to_le16((*(sFrame.pwAuthSequence )))){ case 1: - //AP funciton + //AP function s_vMgrRxAuthenSequence_1(pDevice,pMgmt, &sFrame); break; case 2: s_vMgrRxAuthenSequence_2(pDevice, pMgmt, &sFrame); break; case 3: - //AP funciton + //AP function s_vMgrRxAuthenSequence_3(pDevice, pMgmt, &sFrame); break; case 4: @@ -1923,7 +1923,7 @@ s_vMgrRxBeacon( byIEChannel = sFrame.pDSParms->byCurrChannel; } if (byCurrChannel != byIEChannel) { - // adjust channel info. bcs we rcv adjcent channel pakckets + // adjust channel info. bcs we rcv adjacent channel packets bChannelHit = false; byCurrChannel = byIEChannel; } @@ -2081,7 +2081,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==true) } } // - // Basic Rate Set may change dynamiclly + // Basic Rate Set may change dynamically // if (pBSSList->eNetworkTypeInUse == PHY_TYPE_11B) { uRateLen = WLAN_RATES_MAXLEN_11B; @@ -2134,7 +2134,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==true) } // DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Beacon 2 \n"); - // check if CF field exisit + // check if CF field exists if (WLAN_GET_CAP_INFO_ESS(*sFrame.pwCapInfo)) { if (sFrame.pCFParms->wCFPDurRemaining > 0) { // TODO: deal with CFP period to set NAV @@ -2244,7 +2244,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==true) if (pMgmt->sNodeDBTable[0].uInActiveCount != 0) pMgmt->sNodeDBTable[0].uInActiveCount = 0; - // adhoc mode:TSF updated only when beacon larger then local TSF + // adhoc mode:TSF updated only when beacon larger than local TSF if (bTSFLargeDiff && bTSFOffsetPostive && (pMgmt->eCurrState == WMAC_STATE_JOINTED)) bUpdateTSF = true; @@ -2252,7 +2252,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==true) // During dpc, already in spinlocked. if (BSSDBbIsSTAInNodeDB(pMgmt, sFrame.pHdr->sA3.abyAddr2, &uNodeIndex)) { - // Update the STA, (Techically the Beacons of all the IBSS nodes + // Update the STA, (Technically the Beacons of all the IBSS nodes // should be identical, but that's not happening in practice. pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, @@ -2305,7 +2305,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==true) */ } - // if other stations jointed, indicate connect to upper layer.. + // if other stations joined, indicate connection to upper layer.. if (pMgmt->eCurrState == WMAC_STATE_STARTED) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Current IBSS State: [Started]........to: [Jointed] \n"); pMgmt->eCurrState = WMAC_STATE_JOINTED; @@ -3081,8 +3081,8 @@ s_vMgrSynchBSS ( // } // } // if( uSameBssidNum>=2) { //we only check AP in hidden sssid mode - if ((pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) || //networkmanager 0.7.0 does not give the pairwise-key selsection, - (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) { // so we need re-selsect it according to real pairwise-key info. + if ((pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) || //networkmanager 0.7.0 does not give the pairwise-key selection, + (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) { // so we need re-select it according to real pairwise-key info. if(pCurr->bWPAValid == true) { //WPA-PSK pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK; if(pCurr->abyPKType[0] == WPA_TKIP) { @@ -3193,7 +3193,7 @@ s_vMgrFormatTIM( * * * Return Value: - * PTR to frame; or NULL on allocation failue + * PTR to frame; or NULL on allocation failure * -*/ @@ -3310,7 +3310,7 @@ s_MgrMakeBeacon( *((unsigned short *)(sFrame.pBuf + sFrame.len + sFrame.pRSNWPA->len))=0; sFrame.pRSNWPA->len +=2; - // RSN Capabilites + // RSN Capabilities *((unsigned short *)(sFrame.pBuf + sFrame.len + sFrame.pRSNWPA->len))=0; sFrame.pRSNWPA->len +=2; sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN; @@ -3420,7 +3420,7 @@ s_MgrMakeBeacon( * * * Return Value: - * PTR to frame; or NULL on allocation failue + * PTR to frame; or NULL on allocation failure * -*/ @@ -3611,7 +3611,7 @@ s_MgrMakeProbeResponse( * * * Return Value: - * A ptr to frame or NULL on allocation failue + * A ptr to frame or NULL on allocation failure * -*/ @@ -3652,7 +3652,7 @@ s_MgrMakeAssocRequest( memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - // Set the capibility and listen interval + // Set the capability and listen interval *(sFrame.pwCapInfo) = cpu_to_le16(wCurrCapInfo); *(sFrame.pwListenInterval) = cpu_to_le16(wListenInterval); @@ -3762,7 +3762,7 @@ s_MgrMakeAssocRequest( sFrame.pRSNWPA->len +=6; - // RSN Capabilites + // RSN Capabilities *pbyRSN++=0x00; *pbyRSN++=0x00; @@ -3831,7 +3831,7 @@ s_MgrMakeAssocRequest( } sFrame.pRSN->len +=6; - // RSN Capabilites + // RSN Capabilities if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist == true) { memcpy(&sFrame.pRSN->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2); } else { @@ -3886,7 +3886,7 @@ s_MgrMakeAssocRequest( * * * Return Value: - * A ptr to frame or NULL on allocation failue + * A ptr to frame or NULL on allocation failure * -*/ @@ -3929,7 +3929,7 @@ s_MgrMakeReAssocRequest( memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - /* Set the capibility and listen interval */ + /* Set the capability and listen interval */ *(sFrame.pwCapInfo) = cpu_to_le16(wCurrCapInfo); *(sFrame.pwListenInterval) = cpu_to_le16(wListenInterval); @@ -4019,7 +4019,7 @@ s_MgrMakeReAssocRequest( sFrame.pRSNWPA->len +=6; - // RSN Capabilites + // RSN Capabilities *pbyRSN++=0x00; *pbyRSN++=0x00; sFrame.pRSNWPA->len +=2; @@ -4087,7 +4087,7 @@ s_MgrMakeReAssocRequest( } sFrame.pRSN->len +=6; - // RSN Capabilites + // RSN Capabilities if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist == true) { memcpy(&sFrame.pRSN->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2); } else { @@ -4138,7 +4138,7 @@ s_MgrMakeReAssocRequest( * * * Return Value: - * PTR to frame; or NULL on allocation failue + * PTR to frame; or NULL on allocation failure * -*/ @@ -4212,7 +4212,7 @@ s_MgrMakeAssocResponse( * * * Return Value: - * PTR to frame; or NULL on allocation failue + * PTR to frame; or NULL on allocation failure * -*/ @@ -4333,7 +4333,7 @@ s_vMgrRxProbeResponse( byIEChannel = sFrame.pDSParms->byCurrChannel; } if (byCurrChannel != byIEChannel) { - // adjust channel info. bcs we rcv adjcent channel pakckets + // adjust channel info. bcs we rcv adjacent channel packets bChannelHit = false; byCurrChannel = byIEChannel; } diff --git a/drivers/staging/vt6655/wmgr.h b/drivers/staging/vt6655/wmgr.h index e3ae562..bfa67ae 100644 --- a/drivers/staging/vt6655/wmgr.h +++ b/drivers/staging/vt6655/wmgr.h @@ -286,7 +286,7 @@ typedef struct tagSMgmtObject CMD_STATE eCommandState; unsigned int uScanChannel; - // Desire joinning BSS vars + // Desire joining BSS vars unsigned char abyDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; unsigned char abyDesireBSSID[WLAN_BSSID_LEN]; @@ -310,7 +310,7 @@ typedef struct tagSMgmtObject unsigned int uScanEndCh; unsigned short wScanSteps; unsigned int uScanBSSType; - // Desire scannig vars + // Desire scanning vars unsigned char abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; unsigned char abyScanBSSID[WLAN_BSSID_LEN]; diff --git a/drivers/staging/vt6655/wpa.c b/drivers/staging/vt6655/wpa.c index 0afb9fe..4412fe9 100644 --- a/drivers/staging/vt6655/wpa.c +++ b/drivers/staging/vt6655/wpa.c @@ -229,7 +229,7 @@ WPA_ParseRSN ( * Parameters: * In: * byCmd - Search type - * byEncrypt- Encrcypt Type + * byEncrypt- Encrypt Type * pBSSList - BSS list * Out: * none diff --git a/drivers/staging/vt6655/wpa2.c b/drivers/staging/vt6655/wpa2.c index 744799c..884db1a 100644 --- a/drivers/staging/vt6655/wpa2.c +++ b/drivers/staging/vt6655/wpa2.c @@ -175,16 +175,16 @@ WPA2vParseRSN ( pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_USE_GROUP; bUseGK = true; } else if ( !memcmp(pbyOUI, abyOUIWEP40, 4)) { - // Invialid CSS, continue to parsing + // Invalid CSS, continue to parsing } else if ( !memcmp(pbyOUI, abyOUITKIP, 4)) { if (pBSSNode->byCSSGK != WLAN_11i_CSS_CCMP) pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_TKIP; else - ; // Invialid CSS, continue to parsing + ; // Invalid CSS, continue to parsing } else if ( !memcmp(pbyOUI, abyOUICCMP, 4)) { pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_CCMP; } else if ( !memcmp(pbyOUI, abyOUIWEP104, 4)) { - // Invialid CSS, continue to parsing + // Invalid CSS, continue to parsing } else { // any vendor checks here pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_UNKNOWN; @@ -329,7 +329,7 @@ WPA2uSetIEs( } pRSNIEs->len +=6; - // RSN Capabilites + // RSN Capabilities if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist == true) { memcpy(&pRSNIEs->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2); } else { diff --git a/drivers/staging/vt6655/wpactl.c b/drivers/staging/vt6655/wpactl.c index 732ba88..2b6ae1e 100644 --- a/drivers/staging/vt6655/wpactl.c +++ b/drivers/staging/vt6655/wpactl.c @@ -77,7 +77,7 @@ static void wpadev_setup(struct net_device *dev) /* * Description: - * register netdev for wpa supplicant deamon + * register netdev for wpa supplicant daemon * * Parameters: * In: @@ -164,7 +164,7 @@ static int wpa_release_wpadev(PSDevice pDevice) /* * Description: - * Set enable/disable dev for wpa supplicant deamon + * Set enable/disable dev for wpa supplicant daemon * * Parameters: * In: @@ -847,7 +847,7 @@ else if(!bWepEnabled) pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; else pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; //pMgmt->eAuthenMode = WMAC_AUTH_OPEN; - //pMgmt->bShareKeyAlgorithm = false; //20080717-06, by chester//Fix Open mode, WEP encrytion + //pMgmt->bShareKeyAlgorithm = false; //20080717-06, by chester//Fix Open mode, WEP encryption } //mike save old encryption status pDevice->eOldEncryptionStatus = pDevice->eEncryptionStatus; diff --git a/drivers/staging/vt6655/wroute.c b/drivers/staging/vt6655/wroute.c index 66e2eea..82e93cb 100644 --- a/drivers/staging/vt6655/wroute.c +++ b/drivers/staging/vt6655/wroute.c @@ -18,7 +18,7 @@ * * File: wroute.c * - * Purpose: handle WMAC frame relay & filterring + * Purpose: handle WMAC frame relay & filtering * * Author: Lyndon Chen * -- cgit v0.10.2 From 623b2b39c9ca172364d94baad650f735f497ca89 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 20 Aug 2012 08:43:14 -0700 Subject: staging: "vt6655" Typo change *Embeded to *Embedded. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c index 6a06f64..9a039ea 100644 --- a/drivers/staging/vt6655/baseband.c +++ b/drivers/staging/vt6655/baseband.c @@ -28,8 +28,8 @@ * Functions: * BBuGetFrameTime - Calculate data frame transmitting time * BBvCaculateParameter - Caculate PhyLength, PhyService and Phy Signal parameter for baseband Tx - * BBbReadEmbeded - Embedded read baseband register via MAC - * BBbWriteEmbeded - Embedded write baseband register via MAC + * BBbReadEmbedded - Embedded read baseband register via MAC + * BBbWriteEmbedded - Embedded write baseband register via MAC * BBbIsRegBitsOn - Test if baseband register bits on * BBbIsRegBitsOff - Test if baseband register bits off * BBbVT3253Init - VIA VT3253 baseband chip init code @@ -2013,7 +2013,7 @@ BBvCaculateParameter ( * Return Value: true if succeeded; false if failed. * */ -bool BBbReadEmbeded (unsigned long dwIoBase, unsigned char byBBAddr, unsigned char *pbyData) +bool BBbReadEmbedded (unsigned long dwIoBase, unsigned char byBBAddr, unsigned char *pbyData) { unsigned short ww; unsigned char byValue; @@ -2056,7 +2056,7 @@ bool BBbReadEmbeded (unsigned long dwIoBase, unsigned char byBBAddr, unsigned ch * Return Value: true if succeeded; false if failed. * */ -bool BBbWriteEmbeded (unsigned long dwIoBase, unsigned char byBBAddr, unsigned char byData) +bool BBbWriteEmbedded (unsigned long dwIoBase, unsigned char byBBAddr, unsigned char byData) { unsigned short ww; unsigned char byValue; @@ -2102,7 +2102,7 @@ bool BBbIsRegBitsOn (unsigned long dwIoBase, unsigned char byBBAddr, unsigned ch { unsigned char byOrgData; - BBbReadEmbeded(dwIoBase, byBBAddr, &byOrgData); + BBbReadEmbedded(dwIoBase, byBBAddr, &byOrgData); return (byOrgData & byTestBits) == byTestBits; } @@ -2125,7 +2125,7 @@ bool BBbIsRegBitsOff (unsigned long dwIoBase, unsigned char byBBAddr, unsigned c { unsigned char byOrgData; - BBbReadEmbeded(dwIoBase, byBBAddr, &byOrgData); + BBbReadEmbedded(dwIoBase, byBBAddr, &byOrgData); return (byOrgData & byTestBits) == 0; } @@ -2155,14 +2155,14 @@ bool BBbVT3253Init (PSDevice pDevice) if (byRFType == RF_RFMD2959) { if (byLocalID <= REV_ID_VT3253_A1) { for (ii = 0; ii < CB_VT3253_INIT_FOR_RFMD; ii++) { - bResult &= BBbWriteEmbeded(dwIoBase,byVT3253InitTab_RFMD[ii][0],byVT3253InitTab_RFMD[ii][1]); + bResult &= BBbWriteEmbedded(dwIoBase,byVT3253InitTab_RFMD[ii][0],byVT3253InitTab_RFMD[ii][1]); } } else { for (ii = 0; ii < CB_VT3253B0_INIT_FOR_RFMD; ii++) { - bResult &= BBbWriteEmbeded(dwIoBase,byVT3253B0_RFMD[ii][0],byVT3253B0_RFMD[ii][1]); + bResult &= BBbWriteEmbedded(dwIoBase,byVT3253B0_RFMD[ii][0],byVT3253B0_RFMD[ii][1]); } for (ii = 0; ii < CB_VT3253B0_AGC_FOR_RFMD2959; ii++) { - bResult &= BBbWriteEmbeded(dwIoBase,byVT3253B0_AGC4_RFMD2959[ii][0],byVT3253B0_AGC4_RFMD2959[ii][1]); + bResult &= BBbWriteEmbedded(dwIoBase,byVT3253B0_AGC4_RFMD2959[ii][0],byVT3253B0_AGC4_RFMD2959[ii][1]); } VNSvOutPortD(dwIoBase + MAC_REG_ITRTMSET, 0x23); MACvRegBitsOn(dwIoBase, MAC_REG_PAPEDELAY, BIT0); @@ -2177,10 +2177,10 @@ bool BBbVT3253Init (PSDevice pDevice) pDevice->ldBmThreshold[3] = 0; } else if ((byRFType == RF_AIROHA) || (byRFType == RF_AL2230S) ) { for (ii = 0; ii < CB_VT3253B0_INIT_FOR_AIROHA2230; ii++) { - bResult &= BBbWriteEmbeded(dwIoBase,byVT3253B0_AIROHA2230[ii][0],byVT3253B0_AIROHA2230[ii][1]); + bResult &= BBbWriteEmbedded(dwIoBase,byVT3253B0_AIROHA2230[ii][0],byVT3253B0_AIROHA2230[ii][1]); } for (ii = 0; ii < CB_VT3253B0_AGC; ii++) { - bResult &= BBbWriteEmbeded(dwIoBase,byVT3253B0_AGC[ii][0],byVT3253B0_AGC[ii][1]); + bResult &= BBbWriteEmbedded(dwIoBase,byVT3253B0_AGC[ii][0],byVT3253B0_AGC[ii][1]); } pDevice->abyBBVGA[0] = 0x1C; pDevice->abyBBVGA[1] = 0x10; @@ -2192,10 +2192,10 @@ bool BBbVT3253Init (PSDevice pDevice) pDevice->ldBmThreshold[3] = 0; } else if (byRFType == RF_UW2451) { for (ii = 0; ii < CB_VT3253B0_INIT_FOR_UW2451; ii++) { - bResult &= BBbWriteEmbeded(dwIoBase,byVT3253B0_UW2451[ii][0],byVT3253B0_UW2451[ii][1]); + bResult &= BBbWriteEmbedded(dwIoBase,byVT3253B0_UW2451[ii][0],byVT3253B0_UW2451[ii][1]); } for (ii = 0; ii < CB_VT3253B0_AGC; ii++) { - bResult &= BBbWriteEmbeded(dwIoBase,byVT3253B0_AGC[ii][0],byVT3253B0_AGC[ii][1]); + bResult &= BBbWriteEmbedded(dwIoBase,byVT3253B0_AGC[ii][0],byVT3253B0_AGC[ii][1]); } VNSvOutPortB(dwIoBase + MAC_REG_ITRTMSET, 0x23); MACvRegBitsOn(dwIoBase, MAC_REG_PAPEDELAY, BIT0); @@ -2210,28 +2210,28 @@ bool BBbVT3253Init (PSDevice pDevice) pDevice->ldBmThreshold[3] = 0; } else if (byRFType == RF_UW2452) { for (ii = 0; ii < CB_VT3253B0_INIT_FOR_UW2451; ii++) { - bResult &= BBbWriteEmbeded(dwIoBase,byVT3253B0_UW2451[ii][0],byVT3253B0_UW2451[ii][1]); + bResult &= BBbWriteEmbedded(dwIoBase,byVT3253B0_UW2451[ii][0],byVT3253B0_UW2451[ii][1]); } // Init ANT B select,TX Config CR09 = 0x61->0x45, 0x45->0x41(VC1/VC2 define, make the ANT_A, ANT_B inverted) - //bResult &= BBbWriteEmbeded(dwIoBase,0x09,0x41); + //bResult &= BBbWriteEmbedded(dwIoBase,0x09,0x41); // Init ANT B select,RX Config CR10 = 0x28->0x2A, 0x2A->0x28(VC1/VC2 define, make the ANT_A, ANT_B inverted) - //bResult &= BBbWriteEmbeded(dwIoBase,0x0a,0x28); + //bResult &= BBbWriteEmbedded(dwIoBase,0x0a,0x28); // Select VC1/VC2, CR215 = 0x02->0x06 - bResult &= BBbWriteEmbeded(dwIoBase,0xd7,0x06); + bResult &= BBbWriteEmbedded(dwIoBase,0xd7,0x06); //{{RobertYu:20050125, request by Jack - bResult &= BBbWriteEmbeded(dwIoBase,0x90,0x20); - bResult &= BBbWriteEmbeded(dwIoBase,0x97,0xeb); + bResult &= BBbWriteEmbedded(dwIoBase,0x90,0x20); + bResult &= BBbWriteEmbedded(dwIoBase,0x97,0xeb); //}} //{{RobertYu:20050221, request by Jack - bResult &= BBbWriteEmbeded(dwIoBase,0xa6,0x00); - bResult &= BBbWriteEmbeded(dwIoBase,0xa8,0x30); + bResult &= BBbWriteEmbedded(dwIoBase,0xa6,0x00); + bResult &= BBbWriteEmbedded(dwIoBase,0xa8,0x30); //}} - bResult &= BBbWriteEmbeded(dwIoBase,0xb0,0x58); + bResult &= BBbWriteEmbedded(dwIoBase,0xb0,0x58); for (ii = 0; ii < CB_VT3253B0_AGC; ii++) { - bResult &= BBbWriteEmbeded(dwIoBase,byVT3253B0_AGC[ii][0],byVT3253B0_AGC[ii][1]); + bResult &= BBbWriteEmbedded(dwIoBase,byVT3253B0_AGC[ii][0],byVT3253B0_AGC[ii][1]); } //VNSvOutPortB(dwIoBase + MAC_REG_ITRTMSET, 0x23); // RobertYu: 20050104, 20050131 disable PA_Delay //MACvRegBitsOn(dwIoBase, MAC_REG_PAPEDELAY, BIT0); // RobertYu: 20050104, 20050131 disable PA_Delay @@ -2248,10 +2248,10 @@ bool BBbVT3253Init (PSDevice pDevice) } else if (byRFType == RF_VT3226) { for (ii = 0; ii < CB_VT3253B0_INIT_FOR_AIROHA2230; ii++) { - bResult &= BBbWriteEmbeded(dwIoBase,byVT3253B0_AIROHA2230[ii][0],byVT3253B0_AIROHA2230[ii][1]); + bResult &= BBbWriteEmbedded(dwIoBase,byVT3253B0_AIROHA2230[ii][0],byVT3253B0_AIROHA2230[ii][1]); } for (ii = 0; ii < CB_VT3253B0_AGC; ii++) { - bResult &= BBbWriteEmbeded(dwIoBase,byVT3253B0_AGC[ii][0],byVT3253B0_AGC[ii][1]); + bResult &= BBbWriteEmbedded(dwIoBase,byVT3253B0_AGC[ii][0],byVT3253B0_AGC[ii][1]); } pDevice->abyBBVGA[0] = 0x1C; pDevice->abyBBVGA[1] = 0x10; @@ -2266,20 +2266,20 @@ bool BBbVT3253Init (PSDevice pDevice) //{{ RobertYu: 20050104 } else if (byRFType == RF_AIROHA7230) { for (ii = 0; ii < CB_VT3253B0_INIT_FOR_AIROHA2230; ii++) { - bResult &= BBbWriteEmbeded(dwIoBase,byVT3253B0_AIROHA2230[ii][0],byVT3253B0_AIROHA2230[ii][1]); + bResult &= BBbWriteEmbedded(dwIoBase,byVT3253B0_AIROHA2230[ii][0],byVT3253B0_AIROHA2230[ii][1]); } //{{ RobertYu:20050223, request by JerryChung // Init ANT B select,TX Config CR09 = 0x61->0x45, 0x45->0x41(VC1/VC2 define, make the ANT_A, ANT_B inverted) - //bResult &= BBbWriteEmbeded(dwIoBase,0x09,0x41); + //bResult &= BBbWriteEmbedded(dwIoBase,0x09,0x41); // Init ANT B select,RX Config CR10 = 0x28->0x2A, 0x2A->0x28(VC1/VC2 define, make the ANT_A, ANT_B inverted) - //bResult &= BBbWriteEmbeded(dwIoBase,0x0a,0x28); + //bResult &= BBbWriteEmbedded(dwIoBase,0x0a,0x28); // Select VC1/VC2, CR215 = 0x02->0x06 - bResult &= BBbWriteEmbeded(dwIoBase,0xd7,0x06); + bResult &= BBbWriteEmbedded(dwIoBase,0xd7,0x06); //}} for (ii = 0; ii < CB_VT3253B0_AGC; ii++) { - bResult &= BBbWriteEmbeded(dwIoBase,byVT3253B0_AGC[ii][0],byVT3253B0_AGC[ii][1]); + bResult &= BBbWriteEmbedded(dwIoBase,byVT3253B0_AGC[ii][0],byVT3253B0_AGC[ii][1]); } pDevice->abyBBVGA[0] = 0x1C; pDevice->abyBBVGA[1] = 0x10; @@ -2297,8 +2297,8 @@ bool BBbVT3253Init (PSDevice pDevice) } if (byLocalID > REV_ID_VT3253_A1) { - BBbWriteEmbeded(dwIoBase, 0x04, 0x7F); - BBbWriteEmbeded(dwIoBase, 0x0D, 0x01); + BBbWriteEmbedded(dwIoBase, 0x04, 0x7F); + BBbWriteEmbedded(dwIoBase, 0x0D, 0x01); } return bResult; @@ -2324,7 +2324,7 @@ void BBvReadAllRegs (unsigned long dwIoBase, unsigned char *pbyBBRegs) int ii; unsigned char byBase = 1; for (ii = 0; ii < BB_MAX_CONTEXT_SIZE; ii++) { - BBbReadEmbeded(dwIoBase, (unsigned char)(ii*byBase), pbyBBRegs); + BBbReadEmbedded(dwIoBase, (unsigned char)(ii*byBase), pbyBBRegs); pbyBBRegs += byBase; } } @@ -2350,39 +2350,39 @@ void BBvLoopbackOn (PSDevice pDevice) unsigned long dwIoBase = pDevice->PortOffset; //CR C9 = 0x00 - BBbReadEmbeded(dwIoBase, 0xC9, &pDevice->byBBCRc9);//CR201 - BBbWriteEmbeded(dwIoBase, 0xC9, 0); - BBbReadEmbeded(dwIoBase, 0x4D, &pDevice->byBBCR4d);//CR77 - BBbWriteEmbeded(dwIoBase, 0x4D, 0x90); + BBbReadEmbedded(dwIoBase, 0xC9, &pDevice->byBBCRc9);//CR201 + BBbWriteEmbedded(dwIoBase, 0xC9, 0); + BBbReadEmbedded(dwIoBase, 0x4D, &pDevice->byBBCR4d);//CR77 + BBbWriteEmbedded(dwIoBase, 0x4D, 0x90); //CR 88 = 0x02(CCK), 0x03(OFDM) - BBbReadEmbeded(dwIoBase, 0x88, &pDevice->byBBCR88);//CR136 + BBbReadEmbedded(dwIoBase, 0x88, &pDevice->byBBCR88);//CR136 if (pDevice->uConnectionRate <= RATE_11M) { //CCK // Enable internal digital loopback: CR33 |= 0000 0001 - BBbReadEmbeded(dwIoBase, 0x21, &byData);//CR33 - BBbWriteEmbeded(dwIoBase, 0x21, (unsigned char)(byData | 0x01));//CR33 + BBbReadEmbedded(dwIoBase, 0x21, &byData);//CR33 + BBbWriteEmbedded(dwIoBase, 0x21, (unsigned char)(byData | 0x01));//CR33 // CR154 = 0x00 - BBbWriteEmbeded(dwIoBase, 0x9A, 0); //CR154 + BBbWriteEmbedded(dwIoBase, 0x9A, 0); //CR154 - BBbWriteEmbeded(dwIoBase, 0x88, 0x02);//CR239 + BBbWriteEmbedded(dwIoBase, 0x88, 0x02);//CR239 } else { //OFDM // Enable internal digital loopback:CR154 |= 0000 0001 - BBbReadEmbeded(dwIoBase, 0x9A, &byData);//CR154 - BBbWriteEmbeded(dwIoBase, 0x9A, (unsigned char)(byData | 0x01));//CR154 + BBbReadEmbedded(dwIoBase, 0x9A, &byData);//CR154 + BBbWriteEmbedded(dwIoBase, 0x9A, (unsigned char)(byData | 0x01));//CR154 // CR33 = 0x00 - BBbWriteEmbeded(dwIoBase, 0x21, 0); //CR33 + BBbWriteEmbedded(dwIoBase, 0x21, 0); //CR33 - BBbWriteEmbeded(dwIoBase, 0x88, 0x03);//CR239 + BBbWriteEmbedded(dwIoBase, 0x88, 0x03);//CR239 } //CR14 = 0x00 - BBbWriteEmbeded(dwIoBase, 0x0E, 0);//CR14 + BBbWriteEmbedded(dwIoBase, 0x0E, 0);//CR14 // Disable TX_IQUN - BBbReadEmbeded(pDevice->PortOffset, 0x09, &pDevice->byBBCR09); - BBbWriteEmbeded(pDevice->PortOffset, 0x09, (unsigned char)(pDevice->byBBCR09 & 0xDE)); + BBbReadEmbedded(pDevice->PortOffset, 0x09, &pDevice->byBBCR09); + BBbWriteEmbedded(pDevice->PortOffset, 0x09, (unsigned char)(pDevice->byBBCR09 & 0xDE)); } /* @@ -2403,22 +2403,22 @@ void BBvLoopbackOff (PSDevice pDevice) unsigned char byData; unsigned long dwIoBase = pDevice->PortOffset; - BBbWriteEmbeded(dwIoBase, 0xC9, pDevice->byBBCRc9);//CR201 - BBbWriteEmbeded(dwIoBase, 0x88, pDevice->byBBCR88);//CR136 - BBbWriteEmbeded(dwIoBase, 0x09, pDevice->byBBCR09);//CR136 - BBbWriteEmbeded(dwIoBase, 0x4D, pDevice->byBBCR4d);//CR77 + BBbWriteEmbedded(dwIoBase, 0xC9, pDevice->byBBCRc9);//CR201 + BBbWriteEmbedded(dwIoBase, 0x88, pDevice->byBBCR88);//CR136 + BBbWriteEmbedded(dwIoBase, 0x09, pDevice->byBBCR09);//CR136 + BBbWriteEmbedded(dwIoBase, 0x4D, pDevice->byBBCR4d);//CR77 if (pDevice->uConnectionRate <= RATE_11M) { // CCK // Set the CR33 Bit2 to disable internal Loopback. - BBbReadEmbeded(dwIoBase, 0x21, &byData);//CR33 - BBbWriteEmbeded(dwIoBase, 0x21, (unsigned char)(byData & 0xFE));//CR33 + BBbReadEmbedded(dwIoBase, 0x21, &byData);//CR33 + BBbWriteEmbedded(dwIoBase, 0x21, (unsigned char)(byData & 0xFE));//CR33 } else { // OFDM - BBbReadEmbeded(dwIoBase, 0x9A, &byData);//CR154 - BBbWriteEmbeded(dwIoBase, 0x9A, (unsigned char)(byData & 0xFE));//CR154 + BBbReadEmbedded(dwIoBase, 0x9A, &byData);//CR154 + BBbWriteEmbedded(dwIoBase, 0x9A, (unsigned char)(byData & 0xFE));//CR154 } - BBbReadEmbeded(dwIoBase, 0x0E, &byData);//CR14 - BBbWriteEmbeded(dwIoBase, 0x0E, (unsigned char)(byData | 0x80));//CR14 + BBbReadEmbedded(dwIoBase, 0x0E, &byData);//CR14 + BBbWriteEmbedded(dwIoBase, 0x0E, (unsigned char)(byData | 0x80));//CR14 } @@ -2442,7 +2442,7 @@ BBvSetShortSlotTime (PSDevice pDevice) unsigned char byBBRxConf=0; unsigned char byBBVGA=0; - BBbReadEmbeded(pDevice->PortOffset, 0x0A, &byBBRxConf);//CR10 + BBbReadEmbedded(pDevice->PortOffset, 0x0A, &byBBRxConf);//CR10 if (pDevice->bShortSlotTime) { byBBRxConf &= 0xDF;//1101 1111 @@ -2451,12 +2451,12 @@ BBvSetShortSlotTime (PSDevice pDevice) } // patch for 3253B0 Baseband with Cardbus module - BBbReadEmbeded(pDevice->PortOffset, 0xE7, &byBBVGA); + BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byBBVGA); if (byBBVGA == pDevice->abyBBVGA[0]) { byBBRxConf |= 0x20;//0010 0000 } - BBbWriteEmbeded(pDevice->PortOffset, 0x0A, byBBRxConf);//CR10 + BBbWriteEmbedded(pDevice->PortOffset, 0x0A, byBBRxConf);//CR10 } @@ -2464,9 +2464,9 @@ void BBvSetVGAGainOffset(PSDevice pDevice, unsigned char byData) { unsigned char byBBRxConf=0; - BBbWriteEmbeded(pDevice->PortOffset, 0xE7, byData); + BBbWriteEmbedded(pDevice->PortOffset, 0xE7, byData); - BBbReadEmbeded(pDevice->PortOffset, 0x0A, &byBBRxConf);//CR10 + BBbReadEmbedded(pDevice->PortOffset, 0x0A, &byBBRxConf);//CR10 // patch for 3253B0 Baseband with Cardbus module if (byData == pDevice->abyBBVGA[0]) { byBBRxConf |= 0x20;//0010 0000 @@ -2476,7 +2476,7 @@ void BBvSetVGAGainOffset(PSDevice pDevice, unsigned char byData) byBBRxConf |= 0x20;//0010 0000 } pDevice->byBBVGACurrent = byData; - BBbWriteEmbeded(pDevice->PortOffset, 0x0A, byBBRxConf);//CR10 + BBbWriteEmbedded(pDevice->PortOffset, 0x0A, byBBRxConf);//CR10 } @@ -2495,10 +2495,10 @@ void BBvSetVGAGainOffset(PSDevice pDevice, unsigned char byData) void BBvSoftwareReset (unsigned long dwIoBase) { - BBbWriteEmbeded(dwIoBase, 0x50, 0x40); - BBbWriteEmbeded(dwIoBase, 0x50, 0); - BBbWriteEmbeded(dwIoBase, 0x9C, 0x01); - BBbWriteEmbeded(dwIoBase, 0x9C, 0); + BBbWriteEmbedded(dwIoBase, 0x50, 0x40); + BBbWriteEmbedded(dwIoBase, 0x50, 0); + BBbWriteEmbedded(dwIoBase, 0x9C, 0x01); + BBbWriteEmbedded(dwIoBase, 0x9C, 0); } /* @@ -2518,9 +2518,9 @@ BBvPowerSaveModeON (unsigned long dwIoBase) { unsigned char byOrgData; - BBbReadEmbeded(dwIoBase, 0x0D, &byOrgData); + BBbReadEmbedded(dwIoBase, 0x0D, &byOrgData); byOrgData |= BIT0; - BBbWriteEmbeded(dwIoBase, 0x0D, byOrgData); + BBbWriteEmbedded(dwIoBase, 0x0D, byOrgData); } /* @@ -2540,9 +2540,9 @@ BBvPowerSaveModeOFF (unsigned long dwIoBase) { unsigned char byOrgData; - BBbReadEmbeded(dwIoBase, 0x0D, &byOrgData); + BBbReadEmbedded(dwIoBase, 0x0D, &byOrgData); byOrgData &= ~(BIT0); - BBbWriteEmbeded(dwIoBase, 0x0D, byOrgData); + BBbWriteEmbedded(dwIoBase, 0x0D, byOrgData); } /* @@ -2567,7 +2567,7 @@ BBvSetTxAntennaMode (unsigned long dwIoBase, unsigned char byAntennaMode) #ifdef PLICE_DEBUG //printk("Enter BBvSetTxAntennaMode\n"); #endif - BBbReadEmbeded(dwIoBase, 0x09, &byBBTxConf);//CR09 + BBbReadEmbedded(dwIoBase, 0x09, &byBBTxConf);//CR09 if (byAntennaMode == ANT_DIVERSITY) { // bit 1 is diversity byBBTxConf |= 0x02; @@ -2581,7 +2581,7 @@ BBvSetTxAntennaMode (unsigned long dwIoBase, unsigned char byAntennaMode) byBBTxConf &= 0xFD; // 1111 1101 byBBTxConf |= 0x04; } - BBbWriteEmbeded(dwIoBase, 0x09, byBBTxConf);//CR09 + BBbWriteEmbedded(dwIoBase, 0x09, byBBTxConf);//CR09 } @@ -2606,7 +2606,7 @@ BBvSetRxAntennaMode (unsigned long dwIoBase, unsigned char byAntennaMode) { unsigned char byBBRxConf; - BBbReadEmbeded(dwIoBase, 0x0A, &byBBRxConf);//CR10 + BBbReadEmbedded(dwIoBase, 0x0A, &byBBRxConf);//CR10 if (byAntennaMode == ANT_DIVERSITY) { byBBRxConf |= 0x01; @@ -2616,7 +2616,7 @@ BBvSetRxAntennaMode (unsigned long dwIoBase, unsigned char byAntennaMode) byBBRxConf &= 0xFE; // 1111 1110 byBBRxConf |= 0x02; } - BBbWriteEmbeded(dwIoBase, 0x0A, byBBRxConf);//CR10 + BBbWriteEmbedded(dwIoBase, 0x0A, byBBRxConf);//CR10 } @@ -2635,15 +2635,15 @@ BBvSetRxAntennaMode (unsigned long dwIoBase, unsigned char byAntennaMode) void BBvSetDeepSleep (unsigned long dwIoBase, unsigned char byLocalID) { - BBbWriteEmbeded(dwIoBase, 0x0C, 0x17);//CR12 - BBbWriteEmbeded(dwIoBase, 0x0D, 0xB9);//CR13 + BBbWriteEmbedded(dwIoBase, 0x0C, 0x17);//CR12 + BBbWriteEmbedded(dwIoBase, 0x0D, 0xB9);//CR13 } void BBvExitDeepSleep (unsigned long dwIoBase, unsigned char byLocalID) { - BBbWriteEmbeded(dwIoBase, 0x0C, 0x00);//CR12 - BBbWriteEmbeded(dwIoBase, 0x0D, 0x01);//CR13 + BBbWriteEmbedded(dwIoBase, 0x0C, 0x00);//CR12 + BBbWriteEmbedded(dwIoBase, 0x0D, 0x01);//CR13 } diff --git a/drivers/staging/vt6655/baseband.h b/drivers/staging/vt6655/baseband.h index be2d689..c6909fa 100644 --- a/drivers/staging/vt6655/baseband.h +++ b/drivers/staging/vt6655/baseband.h @@ -73,12 +73,12 @@ #define BBvClearFOE(dwIoBase) \ { \ - BBbWriteEmbeded(dwIoBase, 0xB1, 0); \ + BBbWriteEmbedded(dwIoBase, 0xB1, 0); \ } #define BBvSetFOE(dwIoBase) \ { \ - BBbWriteEmbeded(dwIoBase, 0xB1, 0x0C); \ + BBbWriteEmbedded(dwIoBase, 0xB1, 0x0C); \ } @@ -107,8 +107,8 @@ BBvCaculateParameter ( unsigned char *pbyPhySgn ); -bool BBbReadEmbeded(unsigned long dwIoBase, unsigned char byBBAddr, unsigned char *pbyData); -bool BBbWriteEmbeded(unsigned long dwIoBase, unsigned char byBBAddr, unsigned char byData); +bool BBbReadEmbedded(unsigned long dwIoBase, unsigned char byBBAddr, unsigned char *pbyData); +bool BBbWriteEmbedded(unsigned long dwIoBase, unsigned char byBBAddr, unsigned char byData); void BBvReadAllRegs(unsigned long dwIoBase, unsigned char *pbyBBRegs); void BBvLoopbackOn(PSDevice pDevice); diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index e2785c3..b740cf2 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -461,22 +461,22 @@ bool CARDbSetPhyParameter (void *pDeviceHandler, CARD_PHY_TYPE ePHYType, unsigne pDevice->abyBBVGA[0] = 0x20; pDevice->abyBBVGA[2] = 0x10; pDevice->abyBBVGA[3] = 0x10; - BBbReadEmbeded(pDevice->PortOffset, 0xE7, &byData); + BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData); if (byData == 0x1C) { - BBbWriteEmbeded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]); + BBbWriteEmbedded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]); } } else if (pDevice->byRFType == RF_UW2452) { MACvSetBBType(pDevice->PortOffset, BB_TYPE_11A); pDevice->abyBBVGA[0] = 0x18; - BBbReadEmbeded(pDevice->PortOffset, 0xE7, &byData); + BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData); if (byData == 0x14) { - BBbWriteEmbeded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]); - BBbWriteEmbeded(pDevice->PortOffset, 0xE1, 0x57); + BBbWriteEmbedded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]); + BBbWriteEmbedded(pDevice->PortOffset, 0xE1, 0x57); } } else { MACvSetBBType(pDevice->PortOffset, BB_TYPE_11A); } - BBbWriteEmbeded(pDevice->PortOffset, 0x88, 0x03); + BBbWriteEmbedded(pDevice->PortOffset, 0x88, 0x03); bySlot = C_SLOT_SHORT; bySIFS = C_SIFS_A; byDIFS = C_SIFS_A + 2*C_SLOT_SHORT; @@ -490,19 +490,19 @@ bool CARDbSetPhyParameter (void *pDeviceHandler, CARD_PHY_TYPE ePHYType, unsigne pDevice->abyBBVGA[0] = 0x1C; pDevice->abyBBVGA[2] = 0x00; pDevice->abyBBVGA[3] = 0x00; - BBbReadEmbeded(pDevice->PortOffset, 0xE7, &byData); + BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData); if (byData == 0x20) { - BBbWriteEmbeded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]); + BBbWriteEmbedded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]); } } else if (pDevice->byRFType == RF_UW2452) { pDevice->abyBBVGA[0] = 0x14; - BBbReadEmbeded(pDevice->PortOffset, 0xE7, &byData); + BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData); if (byData == 0x18) { - BBbWriteEmbeded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]); - BBbWriteEmbeded(pDevice->PortOffset, 0xE1, 0xD3); + BBbWriteEmbedded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]); + BBbWriteEmbedded(pDevice->PortOffset, 0xE1, 0xD3); } } - BBbWriteEmbeded(pDevice->PortOffset, 0x88, 0x02); + BBbWriteEmbedded(pDevice->PortOffset, 0x88, 0x02); bySlot = C_SLOT_LONG; bySIFS = C_SIFS_BG; byDIFS = C_SIFS_BG + 2*C_SLOT_LONG; @@ -517,19 +517,19 @@ bool CARDbSetPhyParameter (void *pDeviceHandler, CARD_PHY_TYPE ePHYType, unsigne pDevice->abyBBVGA[0] = 0x1C; pDevice->abyBBVGA[2] = 0x00; pDevice->abyBBVGA[3] = 0x00; - BBbReadEmbeded(pDevice->PortOffset, 0xE7, &byData); + BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData); if (byData == 0x20) { - BBbWriteEmbeded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]); + BBbWriteEmbedded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]); } } else if (pDevice->byRFType == RF_UW2452) { pDevice->abyBBVGA[0] = 0x14; - BBbReadEmbeded(pDevice->PortOffset, 0xE7, &byData); + BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData); if (byData == 0x18) { - BBbWriteEmbeded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]); - BBbWriteEmbeded(pDevice->PortOffset, 0xE1, 0xD3); + BBbWriteEmbedded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]); + BBbWriteEmbedded(pDevice->PortOffset, 0xE1, 0xD3); } } - BBbWriteEmbeded(pDevice->PortOffset, 0x88, 0x08); + BBbWriteEmbedded(pDevice->PortOffset, 0x88, 0x08); bySIFS = C_SIFS_BG; if(VNTWIFIbIsShortSlotTime(wCapInfo)) { bySlot = C_SLOT_SHORT; diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index ee4fb16..697617f 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -2660,7 +2660,7 @@ static irqreturn_t device_intr(int irq, void *dev_instance) { (pDevice->byLocalID != REV_ID_VT3253_B0) && (pDevice->bBSSIDFilter == true)) { // update RSSI - //BBbReadEmbeded(pDevice->PortOffset, 0x3E, &byRSSI); + //BBbReadEmbedded(pDevice->PortOffset, 0x3E, &byRSSI); //pDevice->uCurrRSSI = byRSSI; } */ diff --git a/drivers/staging/vt6655/rf.c b/drivers/staging/vt6655/rf.c index 537a190..aaa231a 100644 --- a/drivers/staging/vt6655/rf.c +++ b/drivers/staging/vt6655/rf.c @@ -26,7 +26,7 @@ * Date: Feb. 19, 2004 * * Functions: - * IFRFbWriteEmbeded - Embedded write RF register via MAC + * IFRFbWriteEmbedded - Embedded write RF register via MAC * * Revision History: * @@ -453,18 +453,18 @@ bool s_bAL7230Init (unsigned long dwIoBase) BBvPowerSaveModeOFF(dwIoBase); //RobertYu:20050106, have DC value for Calibration for (ii = 0; ii < CB_AL7230_INIT_SEQ; ii++) - bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL7230InitTable[ii]); + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[ii]); // PLL On MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3); //Calibration MACvTimer0MicroSDelay(dwIoBase, 150);//150us - bResult &= IFRFbWriteEmbeded(dwIoBase, (0x9ABA8F00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW)); //TXDCOC:active, RCK:disable + bResult &= IFRFbWriteEmbedded(dwIoBase, (0x9ABA8F00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW)); //TXDCOC:active, RCK:disable MACvTimer0MicroSDelay(dwIoBase, 30);//30us - bResult &= IFRFbWriteEmbeded(dwIoBase, (0x3ABA8F00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW)); //TXDCOC:disable, RCK:active + bResult &= IFRFbWriteEmbedded(dwIoBase, (0x3ABA8F00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW)); //TXDCOC:disable, RCK:active MACvTimer0MicroSDelay(dwIoBase, 30);//30us - bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL7230InitTable[CB_AL7230_INIT_SEQ-1]); //TXDCOC:disable, RCK:disable + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[CB_AL7230_INIT_SEQ-1]); //TXDCOC:disable, RCK:disable MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE3 | SOFTPWRCTL_SWPE2 | @@ -490,9 +490,9 @@ bool s_bAL7230SelectChannel (unsigned long dwIoBase, unsigned char byChannel) // PLLON Off MACvWordRegBitsOff(dwIoBase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3); - bResult &= IFRFbWriteEmbeded (dwIoBase, dwAL7230ChannelTable0[byChannel-1]); //Reg0 - bResult &= IFRFbWriteEmbeded (dwIoBase, dwAL7230ChannelTable1[byChannel-1]); //Reg1 - bResult &= IFRFbWriteEmbeded (dwIoBase, dwAL7230ChannelTable2[byChannel-1]); //Reg4 + bResult &= IFRFbWriteEmbedded (dwIoBase, dwAL7230ChannelTable0[byChannel-1]); //Reg0 + bResult &= IFRFbWriteEmbedded (dwIoBase, dwAL7230ChannelTable1[byChannel-1]); //Reg1 + bResult &= IFRFbWriteEmbedded (dwIoBase, dwAL7230ChannelTable2[byChannel-1]); //Reg4 // PLLOn On MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3); @@ -586,7 +586,7 @@ bool s_bAL7230SelectChannel (unsigned long dwIoBase, unsigned char byChannel) * Return Value: true if succeeded; false if failed. * */ -bool IFRFbWriteEmbeded (unsigned long dwIoBase, unsigned long dwData) +bool IFRFbWriteEmbedded (unsigned long dwIoBase, unsigned long dwData) { unsigned short ww; unsigned long dwValue; @@ -669,11 +669,11 @@ bool RFbAL2230Init (unsigned long dwIoBase) //patch abnormal AL2230 frequency output //2008-8-21 chester - IFRFbWriteEmbeded(dwIoBase, (0x07168700+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW)); + IFRFbWriteEmbedded(dwIoBase, (0x07168700+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW)); for (ii = 0; ii < CB_AL2230_INIT_SEQ; ii++) - bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL2230InitTable[ii]); + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL2230InitTable[ii]); //2008-8-21 chester MACvTimer0MicroSDelay(dwIoBase, 30); //delay 30 us @@ -681,11 +681,11 @@ MACvTimer0MicroSDelay(dwIoBase, 30); //delay 30 us MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3); MACvTimer0MicroSDelay(dwIoBase, 150);//150us - bResult &= IFRFbWriteEmbeded(dwIoBase, (0x00d80f00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW)); + bResult &= IFRFbWriteEmbedded(dwIoBase, (0x00d80f00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW)); MACvTimer0MicroSDelay(dwIoBase, 30);//30us - bResult &= IFRFbWriteEmbeded(dwIoBase, (0x00780f00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW)); + bResult &= IFRFbWriteEmbedded(dwIoBase, (0x00780f00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW)); MACvTimer0MicroSDelay(dwIoBase, 30);//30us - bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL2230InitTable[CB_AL2230_INIT_SEQ-1]); + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL2230InitTable[CB_AL2230_INIT_SEQ-1]); MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE3 | SOFTPWRCTL_SWPE2 | @@ -704,8 +704,8 @@ bool RFbAL2230SelectChannel (unsigned long dwIoBase, unsigned char byChannel) bResult = true; - bResult &= IFRFbWriteEmbeded (dwIoBase, dwAL2230ChannelTable0[byChannel-1]); - bResult &= IFRFbWriteEmbeded (dwIoBase, dwAL2230ChannelTable1[byChannel-1]); + bResult &= IFRFbWriteEmbedded (dwIoBase, dwAL2230ChannelTable0[byChannel-1]); + bResult &= IFRFbWriteEmbedded (dwIoBase, dwAL2230ChannelTable1[byChannel-1]); // Set Channel[7] = 0 to tell H/W channel is changing now. VNSvOutPortB(dwIoBase + MAC_REG_CHANNEL, (byChannel & 0x7F)); @@ -817,7 +817,7 @@ bool bResult = true; switch (pDevice->byRFType) { case RF_AIROHA7230 : - bResult = IFRFbWriteEmbeded (pDevice->PortOffset, 0x1ABAEF00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW); + bResult = IFRFbWriteEmbedded (pDevice->PortOffset, 0x1ABAEF00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW); break; default : bResult = true; @@ -1072,23 +1072,23 @@ unsigned long dwMax7230Pwr = 0; switch (pDevice->byRFType) { case RF_AIROHA : - bResult &= IFRFbWriteEmbeded(pDevice->PortOffset, dwAL2230PowerTable[byPwr]); + bResult &= IFRFbWriteEmbedded(pDevice->PortOffset, dwAL2230PowerTable[byPwr]); if (uRATE <= RATE_11M) { - bResult &= IFRFbWriteEmbeded(pDevice->PortOffset, 0x0001B400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); + bResult &= IFRFbWriteEmbedded(pDevice->PortOffset, 0x0001B400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); } else { - bResult &= IFRFbWriteEmbeded(pDevice->PortOffset, 0x0005A400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); + bResult &= IFRFbWriteEmbedded(pDevice->PortOffset, 0x0005A400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); } break; case RF_AL2230S : - bResult &= IFRFbWriteEmbeded(pDevice->PortOffset, dwAL2230PowerTable[byPwr]); + bResult &= IFRFbWriteEmbedded(pDevice->PortOffset, dwAL2230PowerTable[byPwr]); if (uRATE <= RATE_11M) { - bResult &= IFRFbWriteEmbeded(pDevice->PortOffset, 0x040C1400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); - bResult &= IFRFbWriteEmbeded(pDevice->PortOffset, 0x00299B00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); + bResult &= IFRFbWriteEmbedded(pDevice->PortOffset, 0x040C1400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); + bResult &= IFRFbWriteEmbedded(pDevice->PortOffset, 0x00299B00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); }else { - bResult &= IFRFbWriteEmbeded(pDevice->PortOffset, 0x0005A400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); - bResult &= IFRFbWriteEmbeded(pDevice->PortOffset, 0x00099B00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); + bResult &= IFRFbWriteEmbedded(pDevice->PortOffset, 0x0005A400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); + bResult &= IFRFbWriteEmbedded(pDevice->PortOffset, 0x00099B00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); } break; @@ -1098,7 +1098,7 @@ unsigned long dwMax7230Pwr = 0; dwMax7230Pwr = 0x080C0B00 | ( (byPwr) << 12 ) | (BY_AL7230_REG_LEN << 3 ) | IFREGCTL_REGW; - bResult &= IFRFbWriteEmbeded(pDevice->PortOffset, dwMax7230Pwr); + bResult &= IFRFbWriteEmbedded(pDevice->PortOffset, dwMax7230Pwr); break; @@ -1166,24 +1166,24 @@ bool RFbAL7230SelectChannelPostProcess (unsigned long dwIoBase, unsigned char by if( (byOldChannel <= CB_MAX_CHANNEL_24G) && (byNewChannel > CB_MAX_CHANNEL_24G) ) { // Change from 2.4G to 5G - bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL7230InitTableAMode[2]); //Reg2 - bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL7230InitTableAMode[3]); //Reg3 - bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL7230InitTableAMode[5]); //Reg5 - bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL7230InitTableAMode[7]); //Reg7 - bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL7230InitTableAMode[10]);//Reg10 - bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL7230InitTableAMode[12]);//Reg12 - bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL7230InitTableAMode[15]);//Reg15 + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTableAMode[2]); //Reg2 + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTableAMode[3]); //Reg3 + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTableAMode[5]); //Reg5 + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTableAMode[7]); //Reg7 + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTableAMode[10]);//Reg10 + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTableAMode[12]);//Reg12 + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTableAMode[15]);//Reg15 } else if( (byOldChannel > CB_MAX_CHANNEL_24G) && (byNewChannel <= CB_MAX_CHANNEL_24G) ) { // change from 5G to 2.4G - bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL7230InitTable[2]); //Reg2 - bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL7230InitTable[3]); //Reg3 - bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL7230InitTable[5]); //Reg5 - bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL7230InitTable[7]); //Reg7 - bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL7230InitTable[10]);//Reg10 - bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL7230InitTable[12]);//Reg12 - bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL7230InitTable[15]);//Reg15 + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[2]); //Reg2 + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[3]); //Reg3 + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[5]); //Reg5 + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[7]); //Reg7 + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[10]);//Reg10 + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[12]);//Reg12 + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[15]);//Reg15 } return bResult; diff --git a/drivers/staging/vt6655/rf.h b/drivers/staging/vt6655/rf.h index 73f0969..1da0fde 100644 --- a/drivers/staging/vt6655/rf.h +++ b/drivers/staging/vt6655/rf.h @@ -75,7 +75,7 @@ /*--------------------- Export Functions --------------------------*/ -bool IFRFbWriteEmbeded(unsigned long dwIoBase, unsigned long dwData); +bool IFRFbWriteEmbedded(unsigned long dwIoBase, unsigned long dwData); bool RFbSelectChannel(unsigned long dwIoBase, unsigned char byRFType, unsigned char byChannel); bool RFbInit ( PSDevice pDevice -- cgit v0.10.2 From 7664ec86409e6326a1cb8e4f2a9a18dea978a630 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 20 Aug 2012 08:43:15 -0700 Subject: staging: "vt6655" Typo change *Caculate to *Calculate. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c index 9a039ea..8d2c6a7 100644 --- a/drivers/staging/vt6655/baseband.c +++ b/drivers/staging/vt6655/baseband.c @@ -40,7 +40,7 @@ * Revision History: * 06-10-2003 Bryan YC Fan: Re-write codes to support VT3253 spec. * 08-07-2003 Bryan YC Fan: Add MAXIM2827/2825 and RFMD2959 support. - * 08-26-2003 Kyle Hsu : Modify BBuGetFrameTime() and BBvCaculateParameter(). + * 08-26-2003 Kyle Hsu : Modify BBuGetFrameTime() and BBvCalculateParameter(). * cancel the setting of MAC_REG_SOFTPWRCTL on BBbVT3253Init(). * Add the comments. * 09-01-2003 Bryan YC Fan: RF & BB tables updated. @@ -1826,7 +1826,7 @@ BBuGetFrameTime ( } /* - * Description: Caculate Length, Service, and Signal fields of Phy for Tx + * Description: Calculate Length, Service, and Signal fields of Phy for Tx * * Parameters: * In: @@ -1842,7 +1842,7 @@ BBuGetFrameTime ( * */ void -BBvCaculateParameter ( +BBvCalculateParameter ( PSDevice pDevice, unsigned int cbFrameLength, unsigned short wRate, diff --git a/drivers/staging/vt6655/baseband.h b/drivers/staging/vt6655/baseband.h index c6909fa..9b5bc9c 100644 --- a/drivers/staging/vt6655/baseband.h +++ b/drivers/staging/vt6655/baseband.h @@ -97,7 +97,7 @@ BBuGetFrameTime( ); void -BBvCaculateParameter ( +BBvCalculateParameter ( PSDevice pDevice, unsigned int cbFrameLength, unsigned short wRate, diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index b740cf2..319ca48 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -28,9 +28,9 @@ * CARDbIsOFDMinBasicRate - Check if any OFDM rate is in BasicRateSet * CARDvSetLoopbackMode - Set Loopback mode * CARDbSoftwareReset - Sortware reset NIC - * CARDqGetTSFOffset - Caculate TSFOffset + * CARDqGetTSFOffset - Calculate TSFOffset * CARDbGetCurrentTSF - Read Current NIC TSF counter - * CARDqGetNextTBTT - Caculate Next Beacon TSF counter + * CARDqGetNextTBTT - Calculate Next Beacon TSF counter * CARDvSetFirstNextTBTT - Set NIC Beacon time * CARDvUpdateNextTBTT - Sync. NIC Beacon time * CARDbRadioPowerOff - Turn Off NIC Radio Power @@ -100,7 +100,7 @@ const unsigned short cwRXBCNTSFOff[MAX_RATE] = static void -s_vCaculateOFDMRParameter( +s_vCalculateOFDMRParameter( unsigned char byRate, CARD_PHY_TYPE ePHYType, unsigned char *pbyTxRate, @@ -111,7 +111,7 @@ s_vCaculateOFDMRParameter( /*--------------------- Export Functions --------------------------*/ /* - * Description: Caculate TxRate and RsvTime fields for RSPINF in OFDM mode. + * Description: Calculate TxRate and RsvTime fields for RSPINF in OFDM mode. * * Parameters: * In: @@ -126,7 +126,7 @@ s_vCaculateOFDMRParameter( */ static void -s_vCaculateOFDMRParameter ( +s_vCalculateOFDMRParameter ( unsigned char byRate, CARD_PHY_TYPE ePHYType, unsigned char *pbyTxRate, @@ -251,7 +251,7 @@ s_vSetRSPINF (PSDevice pDevice, CARD_PHY_TYPE ePHYType, void *pvSupportRateIEs, MACvSelectPage1(pDevice->PortOffset); //RSPINF_b_1 - BBvCaculateParameter(pDevice, + BBvCalculateParameter(pDevice, 14, VNTWIFIbyGetACKTxRate(RATE_1M, pvSupportRateIEs, pvExtSupportRateIEs), PK_TYPE_11B, @@ -262,7 +262,7 @@ s_vSetRSPINF (PSDevice pDevice, CARD_PHY_TYPE ePHYType, void *pvSupportRateIEs, VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_1, MAKEDWORD(wLen,MAKEWORD(bySignal,byServ))); ///RSPINF_b_2 - BBvCaculateParameter(pDevice, + BBvCalculateParameter(pDevice, 14, VNTWIFIbyGetACKTxRate(RATE_2M, pvSupportRateIEs, pvExtSupportRateIEs), PK_TYPE_11B, @@ -273,7 +273,7 @@ s_vSetRSPINF (PSDevice pDevice, CARD_PHY_TYPE ePHYType, void *pvSupportRateIEs, VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_2, MAKEDWORD(wLen,MAKEWORD(bySignal,byServ))); //RSPINF_b_5 - BBvCaculateParameter(pDevice, + BBvCalculateParameter(pDevice, 14, VNTWIFIbyGetACKTxRate(RATE_5M, pvSupportRateIEs, pvExtSupportRateIEs), PK_TYPE_11B, @@ -284,7 +284,7 @@ s_vSetRSPINF (PSDevice pDevice, CARD_PHY_TYPE ePHYType, void *pvSupportRateIEs, VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_5, MAKEDWORD(wLen,MAKEWORD(bySignal,byServ))); //RSPINF_b_11 - BBvCaculateParameter(pDevice, + BBvCalculateParameter(pDevice, 14, VNTWIFIbyGetACKTxRate(RATE_11M, pvSupportRateIEs, pvExtSupportRateIEs), PK_TYPE_11B, @@ -295,51 +295,51 @@ s_vSetRSPINF (PSDevice pDevice, CARD_PHY_TYPE ePHYType, void *pvSupportRateIEs, VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_11, MAKEDWORD(wLen,MAKEWORD(bySignal,byServ))); //RSPINF_a_6 - s_vCaculateOFDMRParameter(RATE_6M, + s_vCalculateOFDMRParameter(RATE_6M, ePHYType, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_6, MAKEWORD(byTxRate,byRsvTime)); //RSPINF_a_9 - s_vCaculateOFDMRParameter(RATE_9M, + s_vCalculateOFDMRParameter(RATE_9M, ePHYType, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_9, MAKEWORD(byTxRate,byRsvTime)); //RSPINF_a_12 - s_vCaculateOFDMRParameter(RATE_12M, + s_vCalculateOFDMRParameter(RATE_12M, ePHYType, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_12, MAKEWORD(byTxRate,byRsvTime)); //RSPINF_a_18 - s_vCaculateOFDMRParameter(RATE_18M, + s_vCalculateOFDMRParameter(RATE_18M, ePHYType, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_18, MAKEWORD(byTxRate,byRsvTime)); //RSPINF_a_24 - s_vCaculateOFDMRParameter(RATE_24M, + s_vCalculateOFDMRParameter(RATE_24M, ePHYType, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_24, MAKEWORD(byTxRate,byRsvTime)); //RSPINF_a_36 - s_vCaculateOFDMRParameter( + s_vCalculateOFDMRParameter( VNTWIFIbyGetACKTxRate(RATE_36M, pvSupportRateIEs, pvExtSupportRateIEs), ePHYType, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_36, MAKEWORD(byTxRate,byRsvTime)); //RSPINF_a_48 - s_vCaculateOFDMRParameter( + s_vCalculateOFDMRParameter( VNTWIFIbyGetACKTxRate(RATE_48M, pvSupportRateIEs, pvExtSupportRateIEs), ePHYType, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_48, MAKEWORD(byTxRate,byRsvTime)); //RSPINF_a_54 - s_vCaculateOFDMRParameter( + s_vCalculateOFDMRParameter( VNTWIFIbyGetACKTxRate(RATE_54M, pvSupportRateIEs, pvExtSupportRateIEs), ePHYType, &byTxRate, @@ -1739,7 +1739,7 @@ void CARDvSetRSPINF (void *pDeviceHandler, CARD_PHY_TYPE ePHYType) MACvSelectPage1(pDevice->PortOffset); //RSPINF_b_1 - BBvCaculateParameter(pDevice, + BBvCalculateParameter(pDevice, 14, CARDwGetCCKControlRate((void *)pDevice, RATE_1M), PK_TYPE_11B, @@ -1750,7 +1750,7 @@ void CARDvSetRSPINF (void *pDeviceHandler, CARD_PHY_TYPE ePHYType) VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_1, MAKEDWORD(wLen,MAKEWORD(bySignal,byServ))); ///RSPINF_b_2 - BBvCaculateParameter(pDevice, + BBvCalculateParameter(pDevice, 14, CARDwGetCCKControlRate((void *)pDevice, RATE_2M), PK_TYPE_11B, @@ -1761,7 +1761,7 @@ void CARDvSetRSPINF (void *pDeviceHandler, CARD_PHY_TYPE ePHYType) VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_2, MAKEDWORD(wLen,MAKEWORD(bySignal,byServ))); //RSPINF_b_5 - BBvCaculateParameter(pDevice, + BBvCalculateParameter(pDevice, 14, CARDwGetCCKControlRate((void *)pDevice, RATE_5M), PK_TYPE_11B, @@ -1772,7 +1772,7 @@ void CARDvSetRSPINF (void *pDeviceHandler, CARD_PHY_TYPE ePHYType) VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_5, MAKEDWORD(wLen,MAKEWORD(bySignal,byServ))); //RSPINF_b_11 - BBvCaculateParameter(pDevice, + BBvCalculateParameter(pDevice, 14, CARDwGetCCKControlRate((void *)pDevice, RATE_11M), PK_TYPE_11B, @@ -1783,56 +1783,56 @@ void CARDvSetRSPINF (void *pDeviceHandler, CARD_PHY_TYPE ePHYType) VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_11, MAKEDWORD(wLen,MAKEWORD(bySignal,byServ))); //RSPINF_a_6 - s_vCaculateOFDMRParameter(RATE_6M, + s_vCalculateOFDMRParameter(RATE_6M, ePHYType, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_6, MAKEWORD(byTxRate,byRsvTime)); //RSPINF_a_9 - s_vCaculateOFDMRParameter(RATE_9M, + s_vCalculateOFDMRParameter(RATE_9M, ePHYType, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_9, MAKEWORD(byTxRate,byRsvTime)); //RSPINF_a_12 - s_vCaculateOFDMRParameter(RATE_12M, + s_vCalculateOFDMRParameter(RATE_12M, ePHYType, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_12, MAKEWORD(byTxRate,byRsvTime)); //RSPINF_a_18 - s_vCaculateOFDMRParameter(RATE_18M, + s_vCalculateOFDMRParameter(RATE_18M, ePHYType, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_18, MAKEWORD(byTxRate,byRsvTime)); //RSPINF_a_24 - s_vCaculateOFDMRParameter(RATE_24M, + s_vCalculateOFDMRParameter(RATE_24M, ePHYType, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_24, MAKEWORD(byTxRate,byRsvTime)); //RSPINF_a_36 - s_vCaculateOFDMRParameter(CARDwGetOFDMControlRate((void *)pDevice, RATE_36M), + s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)pDevice, RATE_36M), ePHYType, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_36, MAKEWORD(byTxRate,byRsvTime)); //RSPINF_a_48 - s_vCaculateOFDMRParameter(CARDwGetOFDMControlRate((void *)pDevice, RATE_48M), + s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)pDevice, RATE_48M), ePHYType, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_48, MAKEWORD(byTxRate,byRsvTime)); //RSPINF_a_54 - s_vCaculateOFDMRParameter(CARDwGetOFDMControlRate((void *)pDevice, RATE_54M), + s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)pDevice, RATE_54M), ePHYType, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_54, MAKEWORD(byTxRate,byRsvTime)); //RSPINF_a_72 - s_vCaculateOFDMRParameter(CARDwGetOFDMControlRate((void *)pDevice, RATE_54M), + s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)pDevice, RATE_54M), ePHYType, &byTxRate, &byRsvTime); @@ -2042,7 +2042,7 @@ bool CARDbSoftwareReset (void *pDeviceHandler) /* - * Description: Caculate TSF offset of two TSF input + * Description: Calculate TSF offset of two TSF input * Get TSF Offset from RxBCN's TSF and local TSF * * Parameters: diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index c1e1f4f..4972e57 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -27,7 +27,7 @@ * Functions: * s_vGenerateTxParameter - Generate tx dma required parameter. * vGenerateMACHeader - Translate 802.3 to 802.11 header - * cbGetFragCount - Caculate fragment number count + * cbGetFragCount - Calculate fragment number count * csBeacon_xmit - beacon tx function * csMgmt_xmit - management tx function * s_cbFillTxBufHead - fulfill tx dma buffer header @@ -733,11 +733,11 @@ s_uFillDataHead ( if (byFBOption == AUTO_FB_NONE) { PSTxDataHead_g pBuf = (PSTxDataHead_g)pTxDataHead; //Get SignalField,ServiceField,Length - BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, + BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_a), (unsigned char *)&(pBuf->bySignalField_a) ); pBuf->wTransmitLength_a = cpu_to_le16(wLen); - BBvCaculateParameter(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B, + BBvCalculateParameter(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B, (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_b), (unsigned char *)&(pBuf->bySignalField_b) ); pBuf->wTransmitLength_b = cpu_to_le16(wLen); @@ -759,11 +759,11 @@ s_uFillDataHead ( // Auto Fallback PSTxDataHead_g_FB pBuf = (PSTxDataHead_g_FB)pTxDataHead; //Get SignalField,ServiceField,Length - BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, + BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_a), (unsigned char *)&(pBuf->bySignalField_a) ); pBuf->wTransmitLength_a = cpu_to_le16(wLen); - BBvCaculateParameter(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B, + BBvCalculateParameter(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B, (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_b), (unsigned char *)&(pBuf->bySignalField_b) ); pBuf->wTransmitLength_b = cpu_to_le16(wLen); @@ -788,7 +788,7 @@ s_uFillDataHead ( // Auto Fallback PSTxDataHead_a_FB pBuf = (PSTxDataHead_a_FB)pTxDataHead; //Get SignalField,ServiceField,Length - BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, + BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField), (unsigned char *)&(pBuf->bySignalField) ); pBuf->wTransmitLength = cpu_to_le16(wLen); @@ -805,7 +805,7 @@ s_uFillDataHead ( } else { PSTxDataHead_ab pBuf = (PSTxDataHead_ab)pTxDataHead; //Get SignalField,ServiceField,Length - BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, + BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField), (unsigned char *)&(pBuf->bySignalField) ); pBuf->wTransmitLength = cpu_to_le16(wLen); @@ -823,7 +823,7 @@ s_uFillDataHead ( else { PSTxDataHead_ab pBuf = (PSTxDataHead_ab)pTxDataHead; //Get SignalField,ServiceField,Length - BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, + BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField), (unsigned char *)&(pBuf->bySignalField) ); pBuf->wTransmitLength = cpu_to_le16(wLen); @@ -871,11 +871,11 @@ s_vFillRTSHead ( if (byFBOption == AUTO_FB_NONE) { PSRTS_g pBuf = (PSRTS_g)pvRTS; //Get SignalField,ServiceField,Length - BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, + BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_b), (unsigned char *)&(pBuf->bySignalField_b) ); pBuf->wTransmitLength_b = cpu_to_le16(wLen); - BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, + BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_a), (unsigned char *)&(pBuf->bySignalField_a) ); pBuf->wTransmitLength_a = cpu_to_le16(wLen); @@ -904,11 +904,11 @@ s_vFillRTSHead ( else { PSRTS_g_FB pBuf = (PSRTS_g_FB)pvRTS; //Get SignalField,ServiceField,Length - BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, + BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_b), (unsigned char *)&(pBuf->bySignalField_b) ); pBuf->wTransmitLength_b = cpu_to_le16(wLen); - BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, + BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_a), (unsigned char *)&(pBuf->bySignalField_a) ); pBuf->wTransmitLength_a = cpu_to_le16(wLen); @@ -946,7 +946,7 @@ s_vFillRTSHead ( if (byFBOption == AUTO_FB_NONE) { PSRTS_ab pBuf = (PSRTS_ab)pvRTS; //Get SignalField,ServiceField,Length - BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, + BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField), (unsigned char *)&(pBuf->bySignalField) ); pBuf->wTransmitLength = cpu_to_le16(wLen); @@ -975,7 +975,7 @@ s_vFillRTSHead ( else { PSRTS_a_FB pBuf = (PSRTS_a_FB)pvRTS; //Get SignalField,ServiceField,Length - BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, + BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField), (unsigned char *)&(pBuf->bySignalField) ); pBuf->wTransmitLength = cpu_to_le16(wLen); @@ -1005,7 +1005,7 @@ s_vFillRTSHead ( else if (byPktType == PK_TYPE_11B) { PSRTS_ab pBuf = (PSRTS_ab)pvRTS; //Get SignalField,ServiceField,Length - BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, + BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField), (unsigned char *)&(pBuf->bySignalField) ); pBuf->wTransmitLength = cpu_to_le16(wLen); @@ -1065,7 +1065,7 @@ s_vFillCTSHead ( // Auto Fall back PSCTS_FB pBuf = (PSCTS_FB)pvCTS; //Get SignalField,ServiceField,Length - BBvCaculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, + BBvCalculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_b), (unsigned char *)&(pBuf->bySignalField_b) ); @@ -1092,7 +1092,7 @@ s_vFillCTSHead ( } else { //if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) PSCTS pBuf = (PSCTS)pvCTS; //Get SignalField,ServiceField,Length - BBvCaculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, + BBvCalculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_b), (unsigned char *)&(pBuf->bySignalField_b) ); pBuf->wTransmitLength_b = cpu_to_le16(wLen); @@ -2664,7 +2664,7 @@ CMD_STATUS csBeacon_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) { wCurrentRate, false, 0, 0, 1, AUTO_FB_NONE)); } - BBvCaculateParameter(pDevice, cbFrameSize, wCurrentRate, byPktType, + BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate, byPktType, (unsigned short *)&(wLen), (unsigned char *)&(pTxDataHead->byServiceField), (unsigned char *)&(pTxDataHead->bySignalField) ); pTxDataHead->wTransmitLength = cpu_to_le16(wLen); diff --git a/drivers/staging/vt6655/tether.c b/drivers/staging/vt6655/tether.c index 1cf8508..28554bf 100644 --- a/drivers/staging/vt6655/tether.c +++ b/drivers/staging/vt6655/tether.c @@ -25,7 +25,7 @@ * Date: May 21, 1996 * * Functions: - * ETHbyGetHashIndexByCrc32 - Caculate multicast hash value by CRC32 + * ETHbyGetHashIndexByCrc32 - Calculate multicast hash value by CRC32 * ETHbIsBufferCrc32Ok - Check CRC value of the buffer if Ok or not * * Revision History: @@ -50,7 +50,7 @@ /* - * Description: Caculate multicast hash value by CRC32 + * Description: Calculate multicast hash value by CRC32 * * Parameters: * In: diff --git a/drivers/staging/vt6655/tkip.c b/drivers/staging/vt6655/tkip.c index ed3eac1..f141ba1 100644 --- a/drivers/staging/vt6655/tkip.c +++ b/drivers/staging/vt6655/tkip.c @@ -170,7 +170,7 @@ unsigned int rotr1(unsigned int a) /* - * Description: Caculate RC4Key fom TK, TA, and TSC + * Description: Calculate RC4Key fom TK, TA, and TSC * * Parameters: * In: -- cgit v0.10.2 From a0a1f61afa1ff8edda4ad69f37fdd69fdb7d0453 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Sun, 26 Aug 2012 08:16:43 -0700 Subject: staging "vt6656" Fix typos in comments, and in a printk message. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/vt6656/80211mgr.h b/drivers/staging/vt6656/80211mgr.h index 515b9c1..e5db73b 100644 --- a/drivers/staging/vt6656/80211mgr.h +++ b/drivers/staging/vt6656/80211mgr.h @@ -191,7 +191,7 @@ // -// Cipher Suite Selectors defiened in 802.11i +// Cipher Suite Selectors defined in 802.11i // #define WLAN_11i_CSS_USE_GROUP 0 #define WLAN_11i_CSS_WEP40 1 @@ -720,7 +720,7 @@ typedef struct tagWLAN_FR_AUTHEN { } WLAN_FR_AUTHEN, *PWLAN_FR_AUTHEN; -// Deauthenication +// Deauthentication typedef struct tagWLAN_FR_DEAUTHEN { unsigned int uType; diff --git a/drivers/staging/vt6656/baseband.c b/drivers/staging/vt6656/baseband.c index 06f27f6..b24605a 100644 --- a/drivers/staging/vt6656/baseband.c +++ b/drivers/staging/vt6656/baseband.c @@ -27,7 +27,7 @@ * * Functions: * BBuGetFrameTime - Calculate data frame transmitting time - * BBvCaculateParameter - Caculate PhyLength, PhyService and Phy Signal parameter for baseband Tx + * BBvCaculateParameter - Calculate PhyLength, PhyService and Phy Signal parameter for baseband Tx * BBbVT3184Init - VIA VT3184 baseband chip init code * BBvLoopbackOn - Turn on BaseBand Loopback mode * BBvLoopbackOff - Turn off BaseBand Loopback mode @@ -741,7 +741,7 @@ BBuGetFrameTime ( } /* - * Description: Caculate Length, Service, and Signal fields of Phy for Tx + * Description: Calculate Length, Service, and Signal fields of Phy for Tx * * Parameters: * In: diff --git a/drivers/staging/vt6656/bssdb.c b/drivers/staging/vt6656/bssdb.c index 0999367..2ac066d 100644 --- a/drivers/staging/vt6656/bssdb.c +++ b/drivers/staging/vt6656/bssdb.c @@ -226,7 +226,7 @@ PKnownBSS BSSpSearchBSSList(void *hDeviceContext, if (pSelect == NULL) { pSelect = pCurrBSS; } else { - // compare RSSI, select signal strong one + // compare RSSI, select the strongest signal if (pCurrBSS->uRSSI < pSelect->uRSSI) { pSelect = pCurrBSS; } @@ -274,9 +274,9 @@ void BSSvClearBSSList(void *hDeviceContext, BOOL bKeepCurrBSSID) if (pMgmt->sBSSList[ii].bActive && !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID, pMgmt->abyCurrBSSID)) { - //mike mark: there are two same BSSID in list if that AP is in hidden ssid mode,one 's SSID is null, - // but other's is obvious, so if it acssociate with your STA exactly,you must keep two - // of them!!!!!!!!! + //mike mark: there are two BSSID's in list. If that AP is in hidden ssid mode, one SSID is null, + // but other's might not be obvious, so if it associate's with your STA, + // you must keep the two of them!! // bKeepCurrBSSID = FALSE; continue; } @@ -489,7 +489,7 @@ BOOL BSSbInsertToBSSList(void *hDeviceContext, } if (pDevice->bUpdateBBVGA) { - // Moniter if RSSI is too strong. + // Monitor if RSSI is too strong. pBSSList->byRSSIStatCnt = 0; RFvRSSITodBm(pDevice, (BYTE)(pRxPacket->uRSSI), &pBSSList->ldBmMAX); pBSSList->ldBmAverage[0] = pBSSList->ldBmMAX; @@ -621,7 +621,7 @@ BOOL BSSbUpdateToBSSList(void *hDeviceContext, if (pRxPacket->uRSSI != 0) { RFvRSSITodBm(pDevice, (BYTE)(pRxPacket->uRSSI), &ldBm); - // Moniter if RSSI is too strong. + // Monitor if RSSI is too strong. pBSSList->byRSSIStatCnt++; pBSSList->byRSSIStatCnt %= RSSI_STAT_COUNT; pBSSList->ldBmAverage[pBSSList->byRSSIStatCnt] = ldBm; @@ -687,8 +687,8 @@ BOOL BSSbIsSTAInNodeDB(void *hDeviceContext, /*+ * * Routine Description: - * Find an empty node and allocated; if no empty found, - * instand used of most inactive one. + * Find an empty node and allocate it; if no empty node + * is found, then use the most inactive one. * * Return Value: * None @@ -718,7 +718,7 @@ void BSSvCreateOneNode(void *hDeviceContext, unsigned int *puNodeIndex) } } - // if not found replace uInActiveCount is largest one. + // if not found replace uInActiveCount with the largest one. if ( ii == (MAX_NODE_NUM + 1)) { *puNodeIndex = SelectIndex; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Replace inactive node = %d\n", SelectIndex); diff --git a/drivers/staging/vt6656/card.c b/drivers/staging/vt6656/card.c index e3ddc0b..694e648 100644 --- a/drivers/staging/vt6656/card.c +++ b/drivers/staging/vt6656/card.c @@ -28,9 +28,9 @@ * CARDbIsOFDMinBasicRate - Check if any OFDM rate is in BasicRateSet * CARDvSetLoopbackMode - Set Loopback mode * CARDbSoftwareReset - Sortware reset NIC - * CARDqGetTSFOffset - Caculate TSFOffset + * CARDqGetTSFOffset - Calculate TSFOffset * CARDbGetCurrentTSF - Read Current NIC TSF counter - * CARDqGetNextTBTT - Caculate Next Beacon TSF counter + * CARDqGetNextTBTT - Calculate Next Beacon TSF counter * CARDvSetFirstNextTBTT - Set NIC Beacon time * CARDvUpdateNextTBTT - Sync. NIC Beacon time * CARDbRadioPowerOff - Turn Off NIC Radio Power @@ -40,7 +40,7 @@ * * Revision History: * 06-10-2003 Bryan YC Fan: Re-write codes to support VT3253 spec. - * 08-26-2003 Kyle Hsu: Modify the defination type of dwIoBase. + * 08-26-2003 Kyle Hsu: Modify the definition type of dwIoBase. * 09-01-2003 Bryan YC Fan: Add vUpdateIFS(). * */ @@ -200,7 +200,7 @@ static WORD swGetOFDMControlRate(void *pDeviceHandler, WORD wRateIdx) } /* - * Description: Caculate TxRate and RsvTime fields for RSPINF in OFDM mode. + * Description: Calculate TxRate and RsvTime fields for RSPINF in OFDM mode. * * Parameters: * In: @@ -640,7 +640,7 @@ BYTE CARDbyGetPktType(void *pDeviceHandler) /* - * Description: Caculate TSF offset of two TSF input + * Description: Calculate TSF offset of two TSF input * Get TSF Offset from RxBCN's TSF and local TSF * * Parameters: diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h index 171dd68..6370d10 100644 --- a/drivers/staging/vt6656/device.h +++ b/drivers/staging/vt6656/device.h @@ -478,7 +478,7 @@ typedef struct __device_info { unsigned int cbTD; // - // Variables to track resources for the Interript In Pipe + // Variables to track resources for the Interrupt In Pipe // INT_BUFFER intBuf; BOOL fKillEventPollingThread; diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c index e4bdf2a..220bec8 100644 --- a/drivers/staging/vt6656/dpc.c +++ b/drivers/staging/vt6656/dpc.c @@ -748,7 +748,7 @@ RXbBulkInProcessData ( if ((*pbyRSSI != 0) && (pMgmt->pCurrBSS!=NULL)) { RFvRSSITodBm(pDevice, *pbyRSSI, &ldBm); - // Moniter if RSSI is too strong. + // Monitor if RSSI is too strong. pMgmt->pCurrBSS->byRSSIStatCnt++; pMgmt->pCurrBSS->byRSSIStatCnt %= RSSI_STAT_COUNT; pMgmt->pCurrBSS->ldBmAverage[pMgmt->pCurrBSS->byRSSIStatCnt] = ldBm; diff --git a/drivers/staging/vt6656/hostap.c b/drivers/staging/vt6656/hostap.c index 9f2ca17..6106040 100644 --- a/drivers/staging/vt6656/hostap.c +++ b/drivers/staging/vt6656/hostap.c @@ -18,7 +18,7 @@ * * File: hostap.c * - * Purpose: handle hostap deamon ioctl input/out functions + * Purpose: handle hostap daemon ioctl input/out functions * * Author: Lyndon Chen * @@ -48,7 +48,7 @@ static int msglevel =MSG_LEVEL_INFO; /* * Description: - * register net_device (AP) for hostap deamon + * register net_device (AP) for hostap daemon * * Parameters: * In: @@ -176,7 +176,7 @@ int vt6656_hostap_set_hostapd(PSDevice pDevice, int val, int rtnl_locked) /* * Description: - * remove station function supported for hostap deamon + * remove station function supported for hostap daemon * * Parameters: * In: @@ -204,7 +204,7 @@ static int hostap_remove_sta(PSDevice pDevice, /* * Description: - * add a station from hostap deamon + * add a station from hostap daemon * * Parameters: * In: @@ -686,7 +686,7 @@ static int hostap_get_encryption(PSDevice pDevice, /* * Description: - * vt6656_hostap_ioctl main function supported for hostap deamon. + * vt6656_hostap_ioctl main function supported for hostap daemon. * * Parameters: * In: diff --git a/drivers/staging/vt6656/int.c b/drivers/staging/vt6656/int.c index eba4b50..bba31ca 100644 --- a/drivers/staging/vt6656/int.c +++ b/drivers/staging/vt6656/int.c @@ -149,7 +149,7 @@ void INTnsProcessData(PSDevice pDevice) pMgmt->sNodeDBTable[0].bRxPSPoll = FALSE; } else if (pMgmt->byDTIMCount == 0) { - /* check if mutltcast tx bufferring */ + /* check if multicast tx buffering */ pMgmt->byDTIMCount = pMgmt->byDTIMPeriod-1; pMgmt->sNodeDBTable[0].bRxPSPoll = TRUE; diff --git a/drivers/staging/vt6656/ioctl.c b/drivers/staging/vt6656/ioctl.c index d67b29f..b6af5f6 100644 --- a/drivers/staging/vt6656/ioctl.c +++ b/drivers/staging/vt6656/ioctl.c @@ -617,7 +617,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) result = -EFAULT; break; } - /* for some AP maybe good authenticate */ + /* for some AP's maybe a good authentication */ if (wpa_Result.key_mgmt == 0x20) pMgmt->Cisco_cckm = 1; else @@ -641,7 +641,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) break; default: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Private command not support..\n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Private command not supported..\n"); } return result; diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c index 8b9894b..8f19874 100644 --- a/drivers/staging/vt6656/iwctl.c +++ b/drivers/staging/vt6656/iwctl.c @@ -674,7 +674,7 @@ int iwctl_giwaplist(struct net_device *dev, struct iw_request_info *info, jj++; } - wrq->flags = 1; // Should be define'd + wrq->flags = 1; // Should be defined wrq->length = jj; memcpy(extra, sock, sizeof(struct sockaddr) * jj); memcpy(extra + sizeof(struct sockaddr) * jj, qual, sizeof(struct iw_quality) * jj); diff --git a/drivers/staging/vt6656/key.c b/drivers/staging/vt6656/key.c index ee62a06..a61fcb9 100644 --- a/drivers/staging/vt6656/key.c +++ b/drivers/staging/vt6656/key.c @@ -403,7 +403,7 @@ BOOL KeybRemoveKey( BOOL bReturnValue = FALSE; if (is_broadcast_ether_addr(pbyBSSID)) { - // dealte all key + // delete all keys if ((dwKeyIndex & PAIRWISE_KEY) != 0) { for (i=0;iKeyTable[i].PairwiseKey.bKeyValid = FALSE; @@ -618,7 +618,7 @@ BOOL KeybGetTransmitKey(PSKeyManagement pTable, PBYTE pbyBSSID, DWORD dwKeyType, /* - * Description: Check Pairewise Key + * Description: Check Pairwise Key * * Parameters: * In: diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index d536756..ad422de 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -29,14 +29,14 @@ * vt6656_probe - module initial (insmod) driver entry * device_remove1 - module remove entry * device_open - allocate dma/descripter resource & initial mac/bbp function - * device_xmit - asynchrous data tx function + * device_xmit - asynchronous data tx function * device_set_multi - set mac filter * device_ioctl - ioctl entry - * device_close - shutdown mac/bbp & free dma/descripter resource + * device_close - shutdown mac/bbp & free dma/descriptor resource * device_alloc_frag_buf - rx fragement pre-allocated function * device_free_tx_bufs - free tx buffer function * device_dma0_tx_80211- tx 802.11 frame via dma0 - * device_dma0_xmit- tx PS bufferred frame via dma0 + * device_dma0_xmit- tx PS buffered frame via dma0 * device_init_registers- initial MAC & BBP & RF internal registers. * device_init_rings- initial tx/rx ring buffer * device_init_defrag_cb- initial & allocate de-fragement buffer. @@ -316,7 +316,7 @@ static void device_init_diversity_timer(PSDevice pDevice) // -// Initialiation of MAC & BBP registers +// Initialization of MAC & BBP registers // static BOOL device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType) @@ -639,7 +639,7 @@ static BOOL device_release_WPADEV(PSDevice pDevice) viawget_wpa_header *wpahdr; int ii=0; // wait_queue_head_t Set_wait; - //send device close to wpa_supplicnat layer + //send device close to wpa_supplicant layer if (pDevice->bWPADEVUp==TRUE) { wpahdr = (viawget_wpa_header *)pDevice->skb->data; wpahdr->type = VIAWGET_DEVICECLOSE_MSG; @@ -1010,7 +1010,7 @@ static int device_open(struct net_device *dev) { } if (device_init_defrag_cb(pDevice)== FALSE) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Initial defragement cb fail \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Initial defragment cb fail \n"); goto free_rx_tx; } @@ -1296,7 +1296,7 @@ static inline u32 ether_crc(int length, unsigned char *data) return crc; } -//find out the start position of str2 from str1 +//find out the start position of str2 from str1 static unsigned char *kstrstr(const unsigned char *str1, const unsigned char *str2) { int str1_len = strlen(str1); @@ -1345,7 +1345,7 @@ static int Config_FileGetParameter(unsigned char *string, } memset(buf2,0,100); - memcpy(buf2,start_p,end_p-start_p); //get the tartget line + memcpy(buf2,start_p,end_p-start_p); //get the target line buf2[end_p-start_p]='\0'; //find value @@ -1396,7 +1396,7 @@ static unsigned char *Config_FileOperation(PSDevice pDevice) } if(!(filp->f_op) || !(filp->f_op->read) ||!(filp->f_op->write)) { - printk("file %s cann't readable or writable?\n",config_path); + printk("file %s is not read or writeable?\n",config_path); result = -1; goto error1; } @@ -1969,7 +1969,7 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { default: rc = -EOPNOTSUPP; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Ioctl command not support..%x\n", cmd); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Ioctl command not supported..%x\n", cmd); } diff --git a/drivers/staging/vt6656/power.c b/drivers/staging/vt6656/power.c index b313677..ab3a554 100644 --- a/drivers/staging/vt6656/power.c +++ b/drivers/staging/vt6656/power.c @@ -19,7 +19,7 @@ * * File: power.c * - * Purpose: Handles 802.11 power management functions + * Purpose: Handles 802.11 power management functions * * Author: Lyndon Chen * diff --git a/drivers/staging/vt6656/rf.c b/drivers/staging/vt6656/rf.c index c82b3e6..6205e65 100644 --- a/drivers/staging/vt6656/rf.c +++ b/drivers/staging/vt6656/rf.c @@ -1048,7 +1048,7 @@ BYTE abyArray[256]; wLength1, abyArray ); - //Channle Table 0 + //Channel Table 0 wValue = 0; while ( wLength2 > 0 ) { @@ -1106,7 +1106,7 @@ BYTE abyArray[256]; wLength1, abyArray); - //Channle Table 0 + //Channel Table 0 wValue = 0; while ( wLength2 > 0 ) { diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index dd28b91..46e62f4 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -1827,7 +1827,7 @@ s_bPacketToWirelessUsb( * * Parameters: * In: - * pDevice - Pointer to adpater + * pDevice - Pointer to adapter * dwTxBufferAddr - Transmit Buffer * pPacket - Packet from upper layer * cbPacketSize - Transmit Data Length @@ -2198,7 +2198,7 @@ CMD_STATUS csMgmt_xmit( if (bIsPSPOLL) { // The MAC will automatically replace the Duration-field of MAC header by Duration-field - // of FIFO control header. + // of FIFO control header. // This will cause AID-field of PS-POLL packet be incorrect (Because PS-POLL's AID field is // in the same place of other packet's Duration-field). // And it will cause Cisco-AP to issue Disassociation-packet @@ -2473,7 +2473,7 @@ vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb) { cbMacHdLen = WLAN_HDR_ADDR3_LEN; } - // hostapd deamon ext support rate patch + // hostapd daemon ext support rate patch if (WLAN_GET_FC_FSTYPE(p80211Header->sA4.wFrameCtl) == WLAN_FSTYPE_ASSOCRESP) { if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len != 0) { @@ -2591,7 +2591,7 @@ vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb) { pMACHeader->wFrameCtl &= cpu_to_le16(0xfffc); memcpy(pbyPayloadHead, (skb->data + cbMacHdLen), cbFrameBodySize); - // replace support rate, patch for hostapd deamon( only support 11M) + // replace support rate, patch for hostapd daemon( only support 11M) if (WLAN_GET_FC_FSTYPE(p80211Header->sA4.wFrameCtl) == WLAN_FSTYPE_ASSOCRESP) { if (cbExtSuppRate != 0) { if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len != 0) @@ -2855,7 +2855,7 @@ int nsDMA_tx_packet(PSDevice pDevice, unsigned int uDMAIdx, struct sk_buff *skb) } PRINT_K("Authentication completed!!\n"); } - else if((Key_info & BIT3) && (Descriptor_type==2) && //RSN pairse-key challenge + else if((Key_info & BIT3) && (Descriptor_type==2) && //RSN pairwise-key challenge (Key_info & BIT8) && (Key_info & BIT9)) { pDevice->fWPA_Authened = TRUE; PRINT_K("WPA2 Authentication completed!!\n"); diff --git a/drivers/staging/vt6656/tcrc.c b/drivers/staging/vt6656/tcrc.c index e25021e..2237eeb 100644 --- a/drivers/staging/vt6656/tcrc.c +++ b/drivers/staging/vt6656/tcrc.c @@ -18,7 +18,7 @@ * * File: tcrc.c * - * Purpose: Implement functions to caculate CRC + * Purpose: Implement functions to calculate CRC * * Author: Tevin Chen * diff --git a/drivers/staging/vt6656/tcrc.h b/drivers/staging/vt6656/tcrc.h index 4dfd01e..dc54bd8 100644 --- a/drivers/staging/vt6656/tcrc.h +++ b/drivers/staging/vt6656/tcrc.h @@ -18,7 +18,7 @@ * * File: tcrc.h * - * Purpose: Implement functions to caculate CRC + * Purpose: Implement functions to calculate CRC * * Author: Tevin Chen * diff --git a/drivers/staging/vt6656/tether.c b/drivers/staging/vt6656/tether.c index 4f368f1..083b215 100644 --- a/drivers/staging/vt6656/tether.c +++ b/drivers/staging/vt6656/tether.c @@ -25,7 +25,7 @@ * Date: May 21, 1996 * * Functions: - * ETHbyGetHashIndexByCrc32 - Caculate multicast hash value by CRC32 + * ETHbyGetHashIndexByCrc32 - Calculate multicast hash value by CRC32 * ETHbIsBufferCrc32Ok - Check CRC value of the buffer if Ok or not * * Revision History: @@ -50,7 +50,7 @@ /* - * Description: Caculate multicast hash value by CRC32 + * Description: Calculate multicast hash value by CRC32 * * Parameters: * In: diff --git a/drivers/staging/vt6656/tkip.c b/drivers/staging/vt6656/tkip.c index 0715636..003123e 100644 --- a/drivers/staging/vt6656/tkip.c +++ b/drivers/staging/vt6656/tkip.c @@ -168,7 +168,7 @@ static unsigned int rotr1(unsigned int a) /* - * Description: Caculate RC4Key fom TK, TA, and TSC + * Description: Calculate RC4Key fom TK, TA, and TSC * * Parameters: * In: diff --git a/drivers/staging/vt6656/wcmd.c b/drivers/staging/vt6656/wcmd.c index 23ed03c..586fbe1 100644 --- a/drivers/staging/vt6656/wcmd.c +++ b/drivers/staging/vt6656/wcmd.c @@ -263,7 +263,7 @@ s_vProbeChannel( * * * Return Value: - * A ptr to Tx frame or NULL on allocation failue + * A ptr to Tx frame or NULL on allocation failure * -*/ @@ -794,7 +794,7 @@ void vRunCommand(void *hDeviceContext) DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "vMgrCreateOwnIBSS fail!\n"); } - // alway turn off unicast bit + // always turn off unicast bit MACvRegBitsOff(pDevice, MAC_REG_RCR, RCR_UNICAST); pDevice->byRxMode &= ~RCR_UNICAST; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wcmd: rx_mode = %x\n", pDevice->byRxMode ); @@ -946,7 +946,7 @@ void vRunCommand(void *hDeviceContext) pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; pItemSSID->len = 0; memset(pItemSSID->abySSID, 0, WLAN_SSID_MAXLEN); - //clear dessire SSID + //clear desired SSID pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; pItemSSID->len = 0; memset(pItemSSID->abySSID, 0, WLAN_SSID_MAXLEN); diff --git a/drivers/staging/vt6656/wctl.c b/drivers/staging/vt6656/wctl.c index c231ae7..9249263 100644 --- a/drivers/staging/vt6656/wctl.c +++ b/drivers/staging/vt6656/wctl.c @@ -89,7 +89,7 @@ BOOL WCTLbIsDuplicate (PSCache pCache, PS802_11Header pMACHeader) ADD_ONE_WITH_WRAP_AROUND(uIndex, DUPLICATE_RX_CACHE_LENGTH); } } - /* Not fount in cache - insert */ + /* Not found in cache - insert */ pCacheEntry = &pCache->asCacheEntry[pCache->uInPtr]; pCacheEntry->wFmSequence = pMACHeader->wSeqCtl; memcpy(&(pCacheEntry->abyAddr2[0]), &(pMACHeader->abyAddr2[0]), ETH_ALEN); diff --git a/drivers/staging/vt6656/wmgr.c b/drivers/staging/vt6656/wmgr.c index 9469c9e..7db6a8d 100644 --- a/drivers/staging/vt6656/wmgr.c +++ b/drivers/staging/vt6656/wmgr.c @@ -27,7 +27,7 @@ * * Functions: * nsMgrObjectInitial - Initialize Management Objet data structure - * vMgrObjectReset - Reset Management Objet data structure + * vMgrObjectReset - Reset Management Object data structure * vMgrAssocBeginSta - Start associate function * vMgrReAssocBeginSta - Start reassociate function * vMgrDisassocBeginSta - Start disassociate function @@ -2188,7 +2188,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE) // During dpc, already in spinlocked. if (BSSbIsSTAInNodeDB(pDevice, sFrame.pHdr->sA3.abyAddr2, &uNodeIndex)) { - // Update the STA, (Techically the Beacons of all the IBSS nodes + // Update the STA, (Technically the Beacons of all the IBSS nodes // should be identical, but that's not happening in practice. pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, @@ -2722,7 +2722,7 @@ void vMgrJoinBSSBegin(void *hDeviceContext, PCMD_STATUS pStatus) memcpy(pDevice->abyBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN); // Add current BSS to Candidate list - // This should only works for WPA2 BSS, and WPA2 BSS check must be done before. + // This should only work for WPA2 BSS, and WPA2 BSS check must be done before. if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) { BOOL bResult = bAdd_PMKID_Candidate((void *) pDevice, pMgmt->abyCurrBSSID, @@ -3181,7 +3181,7 @@ s_vMgrFormatTIM( * * * Return Value: - * PTR to frame; or NULL on allocation failue + * PTR to frame; or NULL on allocation failure * -*/ @@ -3353,7 +3353,7 @@ s_MgrMakeBeacon( * * * Return Value: - * PTR to frame; or NULL on allocation failue + * PTR to frame; or NULL on allocation failure * -*/ @@ -3528,7 +3528,7 @@ s_MgrMakeAssocRequest( memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - // Set the capibility and listen interval + // Set the capability and listen interval *(sFrame.pwCapInfo) = cpu_to_le16(wCurrCapInfo); *(sFrame.pwListenInterval) = cpu_to_le16(wListenInterval); @@ -3749,7 +3749,7 @@ s_MgrMakeAssocRequest( * * * Return Value: - * A ptr to frame or NULL on allocation failue + * A ptr to frame or NULL on allocation failure * -*/ @@ -3792,7 +3792,7 @@ s_MgrMakeReAssocRequest( memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - /* Set the capibility and listen interval */ + /* Set the capability and listen interval */ *(sFrame.pwCapInfo) = cpu_to_le16(wCurrCapInfo); *(sFrame.pwListenInterval) = cpu_to_le16(wListenInterval); @@ -4004,7 +4004,7 @@ s_MgrMakeReAssocRequest( * * * Return Value: - * PTR to frame; or NULL on allocation failue + * PTR to frame; or NULL on allocation failure * -*/ @@ -4077,7 +4077,7 @@ s_MgrMakeAssocResponse( * * * Return Value: - * PTR to frame; or NULL on allocation failue + * PTR to frame; or NULL on allocation failure * -*/ diff --git a/drivers/staging/vt6656/wpa.c b/drivers/staging/vt6656/wpa.c index b16d4dd..f6429a2 100644 --- a/drivers/staging/vt6656/wpa.c +++ b/drivers/staging/vt6656/wpa.c @@ -231,7 +231,7 @@ WPA_ParseRSN( * Parameters: * In: * byCmd - Search type - * byEncrypt- Encrcypt Type + * byEncrypt- Encrypt Type * pBSSList - BSS list * Out: * none diff --git a/drivers/staging/vt6656/wpa2.c b/drivers/staging/vt6656/wpa2.c index d4f3f75..c092697 100644 --- a/drivers/staging/vt6656/wpa2.c +++ b/drivers/staging/vt6656/wpa2.c @@ -174,16 +174,16 @@ WPA2vParseRSN ( pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_USE_GROUP; bUseGK = TRUE; } else if ( !memcmp(pbyOUI, abyOUIWEP40, 4)) { - // Invialid CSS, continue to parsing + // Invalid CSS, continue parsing } else if ( !memcmp(pbyOUI, abyOUITKIP, 4)) { if (pBSSNode->byCSSGK != WLAN_11i_CSS_CCMP) pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_TKIP; else - ; // Invialid CSS, continue to parsing + ; // Invalid CSS, continue parsing } else if ( !memcmp(pbyOUI, abyOUICCMP, 4)) { pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_CCMP; } else if ( !memcmp(pbyOUI, abyOUIWEP104, 4)) { - // Invialid CSS, continue to parsing + // Invalid CSS, continue parsing } else { // any vendor checks here pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_UNKNOWN; diff --git a/drivers/staging/vt6656/wpactl.c b/drivers/staging/vt6656/wpactl.c index 5435e82..3e65aa1 100644 --- a/drivers/staging/vt6656/wpactl.c +++ b/drivers/staging/vt6656/wpactl.c @@ -74,7 +74,7 @@ static void wpadev_setup(struct net_device *dev) /* * Description: - * register netdev for wpa supplicant deamon + * register netdev for wpa supplicant daemon * * Parameters: * In: @@ -154,7 +154,7 @@ static int wpa_release_wpadev(PSDevice pDevice) /* * Description: - * Set enable/disable dev for wpa supplicant deamon + * Set enable/disable dev for wpa supplicant daemon * * Parameters: * In: @@ -326,7 +326,7 @@ int wpa_set_wpadev(PSDevice pDevice, int val) if ((byKeyDecMode == KEY_CTL_TKIP) && (param->u.wpa_key.key_len != MAX_KEY_LEN)) { // TKIP Key must be 256 bits - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return- TKIP Key must be 256 bits!\n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return - TKIP Key must be 256 bits!\n"); return -EINVAL; } // Check AES key length -- cgit v0.10.2 From bda79783583290eee1d2b7ed96c506d57638ab00 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Sun, 26 Aug 2012 08:16:44 -0700 Subject: staging "vt6656" Typo rename Caculate to Calculate. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/vt6656/baseband.c b/drivers/staging/vt6656/baseband.c index b24605a..3855015 100644 --- a/drivers/staging/vt6656/baseband.c +++ b/drivers/staging/vt6656/baseband.c @@ -27,7 +27,7 @@ * * Functions: * BBuGetFrameTime - Calculate data frame transmitting time - * BBvCaculateParameter - Calculate PhyLength, PhyService and Phy Signal parameter for baseband Tx + * BBvCalculateParameter - Calculate PhyLength, PhyService and Phy Signal parameter for baseband Tx * BBbVT3184Init - VIA VT3184 baseband chip init code * BBvLoopbackOn - Turn on BaseBand Loopback mode * BBvLoopbackOff - Turn off BaseBand Loopback mode @@ -757,7 +757,7 @@ BBuGetFrameTime ( * */ void -BBvCaculateParameter ( +BBvCalculateParameter ( PSDevice pDevice, unsigned int cbFrameLength, WORD wRate, diff --git a/drivers/staging/vt6656/baseband.h b/drivers/staging/vt6656/baseband.h index 8db8cd0..844d5a8 100644 --- a/drivers/staging/vt6656/baseband.h +++ b/drivers/staging/vt6656/baseband.h @@ -104,7 +104,7 @@ BBuGetFrameTime( WORD wRate ); -void BBvCaculateParameter(PSDevice pDevice, +void BBvCalculateParameter(PSDevice pDevice, unsigned int cbFrameLength, WORD wRate, BYTE byPacketType, diff --git a/drivers/staging/vt6656/card.c b/drivers/staging/vt6656/card.c index 694e648..826520b 100644 --- a/drivers/staging/vt6656/card.c +++ b/drivers/staging/vt6656/card.c @@ -214,7 +214,7 @@ static WORD swGetOFDMControlRate(void *pDeviceHandler, WORD wRateIdx) * */ void -CARDvCaculateOFDMRParameter ( +CARDvCalculateOFDMRParameter ( WORD wRate, BYTE byBBType, PBYTE pbyTxRate, @@ -337,7 +337,7 @@ void CARDvSetRSPINF(void *pDeviceHandler, BYTE byBBType) int i; //RSPINF_b_1 - BBvCaculateParameter(pDevice, + BBvCalculateParameter(pDevice, 14, swGetCCKControlRate(pDevice, RATE_1M), PK_TYPE_11B, @@ -347,7 +347,7 @@ void CARDvSetRSPINF(void *pDeviceHandler, BYTE byBBType) ); ///RSPINF_b_2 - BBvCaculateParameter(pDevice, + BBvCalculateParameter(pDevice, 14, swGetCCKControlRate(pDevice, RATE_2M), PK_TYPE_11B, @@ -357,7 +357,7 @@ void CARDvSetRSPINF(void *pDeviceHandler, BYTE byBBType) ); //RSPINF_b_5 - BBvCaculateParameter(pDevice, + BBvCalculateParameter(pDevice, 14, swGetCCKControlRate(pDevice, RATE_5M), PK_TYPE_11B, @@ -367,7 +367,7 @@ void CARDvSetRSPINF(void *pDeviceHandler, BYTE byBBType) ); //RSPINF_b_11 - BBvCaculateParameter(pDevice, + BBvCalculateParameter(pDevice, 14, swGetCCKControlRate(pDevice, RATE_11M), PK_TYPE_11B, @@ -377,55 +377,55 @@ void CARDvSetRSPINF(void *pDeviceHandler, BYTE byBBType) ); //RSPINF_a_6 - CARDvCaculateOFDMRParameter (RATE_6M, + CARDvCalculateOFDMRParameter (RATE_6M, byBBType, &abyTxRate[0], &abyRsvTime[0]); //RSPINF_a_9 - CARDvCaculateOFDMRParameter (RATE_9M, + CARDvCalculateOFDMRParameter (RATE_9M, byBBType, &abyTxRate[1], &abyRsvTime[1]); //RSPINF_a_12 - CARDvCaculateOFDMRParameter (RATE_12M, + CARDvCalculateOFDMRParameter (RATE_12M, byBBType, &abyTxRate[2], &abyRsvTime[2]); //RSPINF_a_18 - CARDvCaculateOFDMRParameter (RATE_18M, + CARDvCalculateOFDMRParameter (RATE_18M, byBBType, &abyTxRate[3], &abyRsvTime[3]); //RSPINF_a_24 - CARDvCaculateOFDMRParameter (RATE_24M, + CARDvCalculateOFDMRParameter (RATE_24M, byBBType, &abyTxRate[4], &abyRsvTime[4]); //RSPINF_a_36 - CARDvCaculateOFDMRParameter (swGetOFDMControlRate(pDevice, RATE_36M), + CARDvCalculateOFDMRParameter (swGetOFDMControlRate(pDevice, RATE_36M), byBBType, &abyTxRate[5], &abyRsvTime[5]); //RSPINF_a_48 - CARDvCaculateOFDMRParameter (swGetOFDMControlRate(pDevice, RATE_48M), + CARDvCalculateOFDMRParameter (swGetOFDMControlRate(pDevice, RATE_48M), byBBType, &abyTxRate[6], &abyRsvTime[6]); //RSPINF_a_54 - CARDvCaculateOFDMRParameter (swGetOFDMControlRate(pDevice, RATE_54M), + CARDvCalculateOFDMRParameter (swGetOFDMControlRate(pDevice, RATE_54M), byBBType, &abyTxRate[7], &abyRsvTime[7]); //RSPINF_a_72 - CARDvCaculateOFDMRParameter (swGetOFDMControlRate(pDevice, RATE_54M), + CARDvCalculateOFDMRParameter (swGetOFDMControlRate(pDevice, RATE_54M), byBBType, &abyTxRate[8], &abyRsvTime[8]); diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index 46e62f4..c082b90 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -841,7 +841,7 @@ s_uFillDataHead ( if ((uDMAIdx == TYPE_ATIMDMA) || (uDMAIdx == TYPE_BEACONDMA)) { PSTxDataHead_ab pBuf = (PSTxDataHead_ab) pTxDataHead; //Get SignalField,ServiceField,Length - BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, + BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, (PWORD)&(pBuf->wTransmitLength), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField) ); //Get Duration and TimeStampOff @@ -858,10 +858,10 @@ s_uFillDataHead ( if (byFBOption == AUTO_FB_NONE) { PSTxDataHead_g pBuf = (PSTxDataHead_g)pTxDataHead; //Get SignalField,ServiceField,Length - BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, + BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, (PWORD)&(pBuf->wTransmitLength_a), (PBYTE)&(pBuf->byServiceField_a), (PBYTE)&(pBuf->bySignalField_a) ); - BBvCaculateParameter(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B, + BBvCalculateParameter(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B, (PWORD)&(pBuf->wTransmitLength_b), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b) ); //Get Duration and TimeStamp @@ -881,10 +881,10 @@ s_uFillDataHead ( // Auto Fallback PSTxDataHead_g_FB pBuf = (PSTxDataHead_g_FB)pTxDataHead; //Get SignalField,ServiceField,Length - BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, + BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, (PWORD)&(pBuf->wTransmitLength_a), (PBYTE)&(pBuf->byServiceField_a), (PBYTE)&(pBuf->bySignalField_a) ); - BBvCaculateParameter(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B, + BBvCalculateParameter(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B, (PWORD)&(pBuf->wTransmitLength_b), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b) ); //Get Duration and TimeStamp @@ -907,7 +907,7 @@ s_uFillDataHead ( // Auto Fallback PSTxDataHead_a_FB pBuf = (PSTxDataHead_a_FB)pTxDataHead; //Get SignalField,ServiceField,Length - BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, + BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, (PWORD)&(pBuf->wTransmitLength), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField) ); //Get Duration and TimeStampOff @@ -924,7 +924,7 @@ s_uFillDataHead ( } else { PSTxDataHead_ab pBuf = (PSTxDataHead_ab)pTxDataHead; //Get SignalField,ServiceField,Length - BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, + BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, (PWORD)&(pBuf->wTransmitLength), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField) ); //Get Duration and TimeStampOff @@ -942,7 +942,7 @@ s_uFillDataHead ( else if (byPktType == PK_TYPE_11B) { PSTxDataHead_ab pBuf = (PSTxDataHead_ab)pTxDataHead; //Get SignalField,ServiceField,Length - BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, + BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, (PWORD)&(pBuf->wTransmitLength), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField) ); //Get Duration and TimeStampOff @@ -993,11 +993,11 @@ s_vFillRTSHead ( if (byFBOption == AUTO_FB_NONE) { PSRTS_g pBuf = (PSRTS_g)pvRTS; //Get SignalField,ServiceField,Length - BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, + BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b) ); pBuf->wTransmitLength_b = cpu_to_le16(wLen); - BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, + BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_a), (PBYTE)&(pBuf->bySignalField_a) ); pBuf->wTransmitLength_a = cpu_to_le16(wLen); @@ -1035,11 +1035,11 @@ s_vFillRTSHead ( else { PSRTS_g_FB pBuf = (PSRTS_g_FB)pvRTS; //Get SignalField,ServiceField,Length - BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, + BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b) ); pBuf->wTransmitLength_b = cpu_to_le16(wLen); - BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, + BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_a), (PBYTE)&(pBuf->bySignalField_a) ); pBuf->wTransmitLength_a = cpu_to_le16(wLen); @@ -1084,7 +1084,7 @@ s_vFillRTSHead ( if (byFBOption == AUTO_FB_NONE) { PSRTS_ab pBuf = (PSRTS_ab)pvRTS; //Get SignalField,ServiceField,Length - BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, + BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField) ); pBuf->wTransmitLength = cpu_to_le16(wLen); @@ -1119,7 +1119,7 @@ s_vFillRTSHead ( else { PSRTS_a_FB pBuf = (PSRTS_a_FB)pvRTS; //Get SignalField,ServiceField,Length - BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, + BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField) ); pBuf->wTransmitLength = cpu_to_le16(wLen); @@ -1155,7 +1155,7 @@ s_vFillRTSHead ( else if (byPktType == PK_TYPE_11B) { PSRTS_ab pBuf = (PSRTS_ab)pvRTS; //Get SignalField,ServiceField,Length - BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, + BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField) ); pBuf->wTransmitLength = cpu_to_le16(wLen); @@ -1221,7 +1221,7 @@ s_vFillCTSHead ( // Auto Fall back PSCTS_FB pBuf = (PSCTS_FB)pvCTS; //Get SignalField,ServiceField,Length - BBvCaculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, + BBvCalculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b) ); pBuf->wTransmitLength_b = cpu_to_le16(wLen); @@ -1246,7 +1246,7 @@ s_vFillCTSHead ( } else { //if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) PSCTS pBuf = (PSCTS)pvCTS; //Get SignalField,ServiceField,Length - BBvCaculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, + BBvCalculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b) ); pBuf->wTransmitLength_b = cpu_to_le16(wLen); @@ -2272,7 +2272,7 @@ csBeacon_xmit( wCurrentRate = RATE_6M; pTxDataHead = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize); //Get SignalField,ServiceField,Length - BBvCaculateParameter(pDevice, cbFrameSize, wCurrentRate, PK_TYPE_11A, + BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate, PK_TYPE_11A, (PWORD)&(pTxDataHead->wTransmitLength), (PBYTE)&(pTxDataHead->byServiceField), (PBYTE)&(pTxDataHead->bySignalField) ); //Get Duration and TimeStampOff @@ -2285,7 +2285,7 @@ csBeacon_xmit( pTxBufHead->wFIFOCtl |= FIFOCTL_11B; pTxDataHead = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize); //Get SignalField,ServiceField,Length - BBvCaculateParameter(pDevice, cbFrameSize, wCurrentRate, PK_TYPE_11B, + BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate, PK_TYPE_11B, (PWORD)&(pTxDataHead->wTransmitLength), (PBYTE)&(pTxDataHead->byServiceField), (PBYTE)&(pTxDataHead->bySignalField) ); //Get Duration and TimeStampOff -- cgit v0.10.2 From 4148aa2ce73ed7bc7afe8dab8382f653f6bfecf2 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Sun, 26 Aug 2012 08:16:45 -0700 Subject: staging "vt6656" Typo rename Embeded to Embedded. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/vt6656/rf.c b/drivers/staging/vt6656/rf.c index 6205e65..593cdc7 100644 --- a/drivers/staging/vt6656/rf.c +++ b/drivers/staging/vt6656/rf.c @@ -26,7 +26,7 @@ * Date: Feb. 19, 2004 * * Functions: - * IFRFbWriteEmbeded - Embedded write RF register via MAC + * IFRFbWriteEmbedded - Embedded write RF register via MAC * * Revision History: * @@ -722,7 +722,7 @@ const BYTE RFaby11aChannelIndex[200] = { * Return Value: TRUE if succeeded; FALSE if failed. * */ -BOOL IFRFbWriteEmbeded (PSDevice pDevice, DWORD dwData) +BOOL IFRFbWriteEmbedded (PSDevice pDevice, DWORD dwData) { BYTE pbyData[4]; @@ -828,23 +828,23 @@ BOOL bResult = TRUE; case RF_AL2230 : if (pDevice->byCurPwr >= AL2230_PWR_IDX_LEN) return FALSE; - bResult &= IFRFbWriteEmbeded(pDevice, dwAL2230PowerTable[pDevice->byCurPwr]); + bResult &= IFRFbWriteEmbedded(pDevice, dwAL2230PowerTable[pDevice->byCurPwr]); if (uRATE <= RATE_11M) - bResult &= IFRFbWriteEmbeded(pDevice, 0x0001B400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); + bResult &= IFRFbWriteEmbedded(pDevice, 0x0001B400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); else - bResult &= IFRFbWriteEmbeded(pDevice, 0x0005A400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); + bResult &= IFRFbWriteEmbedded(pDevice, 0x0005A400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); break; case RF_AL2230S : if (pDevice->byCurPwr >= AL2230_PWR_IDX_LEN) return FALSE; - bResult &= IFRFbWriteEmbeded(pDevice, dwAL2230PowerTable[pDevice->byCurPwr]); + bResult &= IFRFbWriteEmbedded(pDevice, dwAL2230PowerTable[pDevice->byCurPwr]); if (uRATE <= RATE_11M) { - bResult &= IFRFbWriteEmbeded(pDevice, 0x040C1400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); - bResult &= IFRFbWriteEmbeded(pDevice, 0x00299B00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); + bResult &= IFRFbWriteEmbedded(pDevice, 0x040C1400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); + bResult &= IFRFbWriteEmbedded(pDevice, 0x00299B00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); }else { - bResult &= IFRFbWriteEmbeded(pDevice, 0x0005A400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); - bResult &= IFRFbWriteEmbeded(pDevice, 0x00099B00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); + bResult &= IFRFbWriteEmbedded(pDevice, 0x0005A400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); + bResult &= IFRFbWriteEmbedded(pDevice, 0x00099B00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); } break; @@ -854,10 +854,10 @@ BOOL bResult = TRUE; DWORD dwMax7230Pwr; if (uRATE <= RATE_11M) { //RobertYu:20060426, for better 11b mask - bResult &= IFRFbWriteEmbeded(pDevice, 0x111BB900+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW); + bResult &= IFRFbWriteEmbedded(pDevice, 0x111BB900+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW); } else { - bResult &= IFRFbWriteEmbeded(pDevice, 0x221BB900+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW); + bResult &= IFRFbWriteEmbedded(pDevice, 0x221BB900+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW); } if (pDevice->byCurPwr > AL7230_PWR_IDX_LEN) return FALSE; @@ -866,7 +866,7 @@ BOOL bResult = TRUE; dwMax7230Pwr = 0x080C0B00 | ( (pDevice->byCurPwr) << 12 ) | (BY_AL7230_REG_LEN << 3 ) | IFREGCTL_REGW; - bResult &= IFRFbWriteEmbeded(pDevice, dwMax7230Pwr); + bResult &= IFRFbWriteEmbedded(pDevice, dwMax7230Pwr); break; } break; @@ -879,7 +879,7 @@ BOOL bResult = TRUE; return FALSE; dwVT3226Pwr = ((0x3F-pDevice->byCurPwr) << 20 ) | ( 0x17 << 8 ) /* Reg7 */ | (BY_VT3226_REG_LEN << 3 ) | IFREGCTL_REGW; - bResult &= IFRFbWriteEmbeded(pDevice, dwVT3226Pwr); + bResult &= IFRFbWriteEmbedded(pDevice, dwVT3226Pwr); break; } @@ -894,27 +894,27 @@ BOOL bResult = TRUE; dwVT3226Pwr = ((0x3F-pDevice->byCurPwr) << 20 ) | ( 0xE07 << 8 ) /* Reg7 */ | //RobertYu:20060420, TWIF 1.10 (BY_VT3226_REG_LEN << 3 ) | IFREGCTL_REGW; - bResult &= IFRFbWriteEmbeded(pDevice, dwVT3226Pwr); + bResult &= IFRFbWriteEmbedded(pDevice, dwVT3226Pwr); - bResult &= IFRFbWriteEmbeded(pDevice, 0x03C6A200+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW); + bResult &= IFRFbWriteEmbedded(pDevice, 0x03C6A200+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW); if (pDevice->sMgmtObj.eScanState != WMAC_NO_SCANNING) { // scanning, the channel number is pDevice->uScanChannel DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"@@@@ RFbRawSetPower> 11B mode uCurrChannel[%d]\n", pDevice->sMgmtObj.uScanChannel); - bResult &= IFRFbWriteEmbeded(pDevice, dwVT3226D0LoCurrentTable[pDevice->sMgmtObj.uScanChannel-1]); //RobertYu:20060420, sometimes didn't change channel just set power with different rate + bResult &= IFRFbWriteEmbedded(pDevice, dwVT3226D0LoCurrentTable[pDevice->sMgmtObj.uScanChannel-1]); //RobertYu:20060420, sometimes didn't change channel just set power with different rate } else { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"@@@@ RFbRawSetPower> 11B mode uCurrChannel[%d]\n", pDevice->sMgmtObj.uCurrChannel); - bResult &= IFRFbWriteEmbeded(pDevice, dwVT3226D0LoCurrentTable[pDevice->sMgmtObj.uCurrChannel-1]); //RobertYu:20060420, sometimes didn't change channel just set power with different rate + bResult &= IFRFbWriteEmbedded(pDevice, dwVT3226D0LoCurrentTable[pDevice->sMgmtObj.uCurrChannel-1]); //RobertYu:20060420, sometimes didn't change channel just set power with different rate } - bResult &= IFRFbWriteEmbeded(pDevice, 0x015C0800+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW); //RobertYu:20060420, ok now, new switching power (mini-pci can have bigger power consumption) + bResult &= IFRFbWriteEmbedded(pDevice, 0x015C0800+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW); //RobertYu:20060420, ok now, new switching power (mini-pci can have bigger power consumption) } else { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"@@@@ RFbRawSetPower> 11G mode\n"); dwVT3226Pwr = ((0x3F-pDevice->byCurPwr) << 20 ) | ( 0x7 << 8 ) /* Reg7 */ | //RobertYu:20060420, TWIF 1.10 (BY_VT3226_REG_LEN << 3 ) | IFREGCTL_REGW; - bResult &= IFRFbWriteEmbeded(pDevice, dwVT3226Pwr); - bResult &= IFRFbWriteEmbeded(pDevice, 0x00C6A200+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW); //RobertYu:20060327 - bResult &= IFRFbWriteEmbeded(pDevice, 0x016BC600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW); //RobertYu:20060111 - bResult &= IFRFbWriteEmbeded(pDevice, 0x00900800+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW); //RobertYu:20060111 + bResult &= IFRFbWriteEmbedded(pDevice, dwVT3226Pwr); + bResult &= IFRFbWriteEmbedded(pDevice, 0x00C6A200+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW); //RobertYu:20060327 + bResult &= IFRFbWriteEmbedded(pDevice, 0x016BC600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW); //RobertYu:20060111 + bResult &= IFRFbWriteEmbedded(pDevice, 0x00900800+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW); //RobertYu:20060111 } break; } @@ -929,7 +929,7 @@ BOOL bResult = TRUE; dwVT3342Pwr = ((0x3F-pDevice->byCurPwr) << 20 ) | ( 0x27 << 8 ) /* Reg7 */ | (BY_VT3342_REG_LEN << 3 ) | IFREGCTL_REGW; - bResult &= IFRFbWriteEmbeded(pDevice, dwVT3342Pwr); + bResult &= IFRFbWriteEmbedded(pDevice, dwVT3342Pwr); break; } @@ -1141,9 +1141,9 @@ BOOL s_bVT3226D0_11bLoCurrentAdjust( bResult = TRUE; if( b11bMode ) - bResult &= IFRFbWriteEmbeded(pDevice, dwVT3226D0LoCurrentTable[byChannel-1]); + bResult &= IFRFbWriteEmbedded(pDevice, dwVT3226D0LoCurrentTable[byChannel-1]); else - bResult &= IFRFbWriteEmbeded(pDevice, 0x016BC600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW); //RobertYu:20060412 + bResult &= IFRFbWriteEmbedded(pDevice, 0x016BC600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW); //RobertYu:20060412 return bResult; } diff --git a/drivers/staging/vt6656/rf.h b/drivers/staging/vt6656/rf.h index f5ba8fd..72eb27a 100644 --- a/drivers/staging/vt6656/rf.h +++ b/drivers/staging/vt6656/rf.h @@ -63,7 +63,7 @@ extern const BYTE RFaby11aChannelIndex[200]; /*--------------------- Export Functions --------------------------*/ -BOOL IFRFbWriteEmbeded(PSDevice pDevice, DWORD dwData); +BOOL IFRFbWriteEmbedded(PSDevice pDevice, DWORD dwData); BOOL RFbSetPower(PSDevice pDevice, unsigned int uRATE, unsigned int uCH); BOOL RFbRawSetPower( -- cgit v0.10.2 From 70a1fb1933a3ecfc265444f954a8c0310cdf293a Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Sun, 26 Aug 2012 09:03:04 +0800 Subject: Staging: vt6656: using is_broadcast_ether_addr() to simplify the code Using is_broadcast_ether_addr() to simplify the code. Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/vt6656/hostap.c b/drivers/staging/vt6656/hostap.c index 6106040..0a73d40 100644 --- a/drivers/staging/vt6656/hostap.c +++ b/drivers/staging/vt6656/hostap.c @@ -439,9 +439,7 @@ static int hostap_set_encryption(PSDevice pDevice, return -EINVAL; } - if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && - param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && - param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { + if (is_broadcast_ether_addr(param->sta_addr)) { if (param->u.crypt.idx >= MAX_GROUP_KEY) return -EINVAL; iNodeIndex = 0; @@ -663,9 +661,7 @@ static int hostap_get_encryption(PSDevice pDevice, param->u.crypt.err = 0; - if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && - param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && - param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { + if (is_broadcast_ether_addr(param->sta_addr)) { iNodeIndex = 0; } else { if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &iNodeIndex) == FALSE) { -- cgit v0.10.2 From 78b311435195ea54c36973394dae7ff14712b1c7 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Sun, 26 Aug 2012 09:02:16 +0800 Subject: Staging: vt6655: using is_broadcast_ether_addr() to simplify the code Using is_broadcast_ether_addr() to simplify the code. Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/vt6655/hostap.c b/drivers/staging/vt6655/hostap.c index 6ac6f45..67b1b88 100644 --- a/drivers/staging/vt6655/hostap.c +++ b/drivers/staging/vt6655/hostap.c @@ -495,9 +495,7 @@ static int hostap_set_encryption(PSDevice pDevice, return -EINVAL; } - if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && - param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && - param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { + if (is_broadcast_ether_addr(param->sta_addr)) { if (param->u.crypt.idx >= MAX_GROUP_KEY) return -EINVAL; iNodeIndex = 0; @@ -716,9 +714,7 @@ static int hostap_get_encryption(PSDevice pDevice, param->u.crypt.err = 0; - if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && - param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && - param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { + if (is_broadcast_ether_addr(param->sta_addr)) { iNodeIndex = 0; } else { if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &iNodeIndex) == false) { -- cgit v0.10.2 From 0c43e56c3001fa4c55b01abf0d8a12bbc79aa148 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Sun, 26 Aug 2012 09:04:23 +0800 Subject: staging: rtl8192e: use is_broadcast_ether_addr() instead of memcmp() Using is_broadcast_ether_addr() instead of directly use memcmp() to determine if the ethernet address is broadcast address. spatch with a semantic match is used to found this problem. (http://coccinelle.lip6.fr/) Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c index 7c95518..22a2764 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac.c +++ b/drivers/staging/rtl8192e/rtllib_softmac.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "dot11d.h" short rtllib_is_54g(struct rtllib_network *net) @@ -1843,7 +1844,7 @@ static short probe_rq_parse(struct rtllib_device *ieee, struct sk_buff *skb, bssid_match = (memcmp(header->addr3, ieee->current_network.bssid, ETH_ALEN) != 0) && - (memcmp(header->addr3, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) != 0); + (!is_broadcast_ether_addr(header->addr3)); if (bssid_match) return -1; @@ -3361,9 +3362,7 @@ static int rtllib_wpa_set_encryption(struct rtllib_device *ieee, param->u.crypt.key_len); return -EINVAL; } - if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && - param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && - param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { + if (is_broadcast_ether_addr(param->sta_addr)) { if (param->u.crypt.idx >= NUM_WEP_KEYS) return -EINVAL; crypt = &ieee->crypt_info.crypt[param->u.crypt.idx]; -- cgit v0.10.2 From 8cfbc9dcde38c167b10c9c1b74f410f9a577b857 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Sun, 26 Aug 2012 09:00:30 +0800 Subject: Staging: rtl8192u: use is_broadcast_ether_addr() instead of memcmp() Using is_broadcast_ether_addr() instead of directly use memcmp() to determine if the ethernet address is broadcast address. spatch with a semantic match is used to found this problem. (http://coccinelle.lip6.fr/) Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c index a6adfc9..6721ed9 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c @@ -20,6 +20,8 @@ #include #include #include +#include + #include "dot11d.h" u8 rsn_authen_cipher_suite[16][4] = { @@ -2969,9 +2971,7 @@ static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee, param->u.crypt.key_len); return -EINVAL; } - if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && - param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && - param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { + if (is_broadcast_ether_addr(param->sta_addr)) { if (param->u.crypt.idx >= WEP_KEYS) return -EINVAL; crypt = &ieee->crypt[param->u.crypt.idx]; -- cgit v0.10.2 From 148d711654cf0387fda241df3b9716783a60f803 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Sun, 26 Aug 2012 08:59:58 +0800 Subject: staging: rtl8187se: use is_broadcast_ether_addr() instead of memcmp() Using is_broadcast_ether_addr() instead of directly use memcmp() to determine if the ethernet address is broadcast address. spatch with a semantic match is used to found this problem. (http://coccinelle.lip6.fr/) Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c index 8173240..7c669a2 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "dot11d.h" u8 rsn_authen_cipher_suite[16][4] = { @@ -2808,9 +2809,7 @@ static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee, param->u.crypt.key_len); return -EINVAL; } - if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && - param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && - param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { + if (is_broadcast_ether_addr(param->sta_addr)) { if (param->u.crypt.idx >= WEP_KEYS) return -EINVAL; crypt = &ieee->crypt[param->u.crypt.idx]; -- cgit v0.10.2 From 779477f29664e2e3f694339356f97a9e0eb30faa Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Sun, 26 Aug 2012 09:22:33 +0800 Subject: staging: r8712u: use is_broadcast_ether_addr() to simplify the code Using is_broadcast_ether_addr() to simplify the code. spatch with a semantic match is used to found this problem. (http://coccinelle.lip6.fr/) Signed-off-by: Wei Yongjun Acked-by: Larry Finger Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8712/ethernet.h b/drivers/staging/rtl8712/ethernet.h index 882d61b..9095420 100644 --- a/drivers/staging/rtl8712/ethernet.h +++ b/drivers/staging/rtl8712/ethernet.h @@ -35,14 +35,6 @@ /*!< Is Multicast Address? */ #define RT_ETH_IS_MULTICAST(_pAddr) ((((u8 *)(_pAddr))[0]&0x01) != 0) -/*!< Is Broadcast Address? */ -#define RT_ETH_IS_BROADCAST(_pAddr) ( \ - ((u8 *)(_pAddr))[0] == 0xff && \ - ((u8 *)(_pAddr))[1] == 0xff && \ - ((u8 *)(_pAddr))[2] == 0xff && \ - ((u8 *)(_pAddr))[3] == 0xff && \ - ((u8 *)(_pAddr))[4] == 0xff && \ - ((u8 *)(_pAddr))[5] == 0xff) #endif /* #ifndef __INC_ETHERNET_H */ diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c index 35e781f..c9a6a7f 100644 --- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c +++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c @@ -407,9 +407,7 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, if (param_len != (u32)((u8 *) param->u.crypt.key - (u8 *)param) + param->u.crypt.key_len) return -EINVAL; - if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && - param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && - param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { + if (is_broadcast_ether_addr(param->sta_addr)) { if (param->u.crypt.idx >= WEP_KEYS) { /* for large key indices, set the default (0) */ param->u.crypt.idx = 0; diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_set.c b/drivers/staging/rtl8712/rtl871x_ioctl_set.c index f352b32..d3ab24e 100644 --- a/drivers/staging/rtl8712/rtl871x_ioctl_set.c +++ b/drivers/staging/rtl8712/rtl871x_ioctl_set.c @@ -131,10 +131,7 @@ u8 r8712_set_802_11_bssid(struct _adapter *padapter, u8 *bssid) u8 status = true; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - if ((bssid[0] == 0x00 && bssid[1] == 0x00 && bssid[2] == 0x00 && - bssid[3] == 0x00 && bssid[4] == 0x00 && bssid[5] == 0x00) || - (bssid[0] == 0xFF && bssid[1] == 0xFF && bssid[2] == 0xFF && - bssid[3] == 0xFF && bssid[4] == 0xFF && bssid[5] == 0xFF)) { + if (is_zero_ether_addr(bssid) || is_broadcast_ether_addr(bssid)) { status = false; return status; } -- cgit v0.10.2 From cfd757010691eae4e17acc246f74e7622c3a2f05 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Sun, 26 Aug 2012 23:35:17 +0200 Subject: speakup: lower default software speech rate Speech synthesis beginners need a low speech rate, and trained people want a high speech rate. A medium speech rate is thus actually not a good default for neither. Since trained people will typically know how to change the rate, better default for a low speech rate, which beginners can grasp and learn how to increase it afterwards This was agreed with users on the speakup mailing list. Signed-off-by: Samuel Thibault Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/speakup/speakup_soft.c b/drivers/staging/speakup/speakup_soft.c index 42cdafe..2a67610 100644 --- a/drivers/staging/speakup/speakup_soft.c +++ b/drivers/staging/speakup/speakup_soft.c @@ -46,7 +46,7 @@ static int misc_registered; static struct var_t vars[] = { { CAPS_START, .u.s = {"\x01+3p" } }, { CAPS_STOP, .u.s = {"\x01-3p" } }, - { RATE, .u.n = {"\x01%ds", 5, 0, 9, 0, 0, NULL } }, + { RATE, .u.n = {"\x01%ds", 2, 0, 9, 0, 0, NULL } }, { PITCH, .u.n = {"\x01%dp", 5, 0, 9, 0, 0, NULL } }, { VOL, .u.n = {"\x01%dv", 5, 0, 9, 0, 0, NULL } }, { TONE, .u.n = {"\x01%dx", 1, 0, 2, 0, 0, NULL } }, -- cgit v0.10.2 From f69ba6abdae3fc5072175a74759f92af4c26b56f Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Thu, 23 Aug 2012 15:18:28 +0800 Subject: Staging: rtl8187se: use is_zero_ether_addr() instead of memcmp() Using is_zero_ether_addr() instead of directly use memcmp() to determine if the ethernet address is all zeros. spatch with a semantic match is used to found this problem. (http://coccinelle.lip6.fr/) Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c index 5d20490..1ef8fd6 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c @@ -14,6 +14,8 @@ */ +#include + #include "ieee80211.h" /* FIXME: add A freqs */ @@ -131,7 +133,6 @@ int ieee80211_wx_set_wap(struct ieee80211_device *ieee, { int ret = 0; - u8 zero[] = {0,0,0,0,0,0}; unsigned long flags; short ifup = ieee->proto_started;//dev->flags & IFF_UP; @@ -161,7 +162,7 @@ int ieee80211_wx_set_wap(struct ieee80211_device *ieee, spin_lock_irqsave(&ieee->lock, flags); memcpy(ieee->current_network.bssid, temp->sa_data, ETH_ALEN); - ieee->wap_set = memcmp(temp->sa_data, zero,ETH_ALEN)!=0; + ieee->wap_set = !is_zero_ether_addr(temp->sa_data); //printk(" %x:%x:%x:%x:%x:%x\n", ieee->current_network.bssid[0],ieee->current_network.bssid[1],ieee->current_network.bssid[2],ieee->current_network.bssid[3],ieee->current_network.bssid[4],ieee->current_network.bssid[5]); spin_unlock_irqrestore(&ieee->lock, flags); -- cgit v0.10.2 From f6aa782f255de96b89ff4fc98dad0d57a9691c8a Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Thu, 23 Aug 2012 15:19:37 +0800 Subject: Staging: rtl8192u: use is_zero_ether_addr() instead of memcmp() Using is_zero_ether_addr() instead of directly use memcmp() to determine if the ethernet address is all zeros. spatch with a semantic match is used to found this problem. (http://coccinelle.lip6.fr/) Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c index cb5a3c3..421da8a 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c @@ -14,6 +14,8 @@ */ +#include + #include "ieee80211.h" #include "dot11d.h" /* FIXME: add A freqs */ @@ -136,7 +138,6 @@ int ieee80211_wx_set_wap(struct ieee80211_device *ieee, { int ret = 0; - u8 zero[] = {0,0,0,0,0,0}; unsigned long flags; short ifup = ieee->proto_started;//dev->flags & IFF_UP; @@ -165,7 +166,7 @@ int ieee80211_wx_set_wap(struct ieee80211_device *ieee, spin_lock_irqsave(&ieee->lock, flags); memcpy(ieee->current_network.bssid, temp->sa_data, ETH_ALEN); - ieee->wap_set = memcmp(temp->sa_data, zero,ETH_ALEN)!=0; + ieee->wap_set = !is_zero_ether_addr(temp->sa_data); spin_unlock_irqrestore(&ieee->lock, flags); -- cgit v0.10.2 From efe13d868f3475ae7c296fff02f10c84dd80d45c Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Thu, 23 Aug 2012 16:50:12 +0800 Subject: staging: rtl8192e: use is_zero_ether_addr() instead of memcmp() Using is_zero_ether_addr() instead of directly use memcmp() to determine if the ethernet address is all zeros. spatch with a semantic match is used to found this problem. (http://coccinelle.lip6.fr/) Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8192e/rtllib_softmac_wx.c b/drivers/staging/rtl8192e/rtllib_softmac_wx.c index 1bb6b52e..740cf85 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac_wx.c +++ b/drivers/staging/rtl8192e/rtllib_softmac_wx.c @@ -14,6 +14,8 @@ */ +#include + #include "rtllib.h" #include "dot11d.h" /* FIXME: add A freqs */ @@ -137,7 +139,6 @@ int rtllib_wx_set_wap(struct rtllib_device *ieee, { int ret = 0; - u8 zero[] = {0, 0, 0, 0, 0, 0}; unsigned long flags; short ifup = ieee->proto_started; @@ -157,7 +158,7 @@ int rtllib_wx_set_wap(struct rtllib_device *ieee, goto out; } - if (memcmp(temp->sa_data, zero, ETH_ALEN) == 0) { + if (is_zero_ether_addr(temp->sa_data)) { spin_lock_irqsave(&ieee->lock, flags); memcpy(ieee->current_network.bssid, temp->sa_data, ETH_ALEN); ieee->wap_set = 0; @@ -177,7 +178,7 @@ int rtllib_wx_set_wap(struct rtllib_device *ieee, ieee->cannot_notify = false; memcpy(ieee->current_network.bssid, temp->sa_data, ETH_ALEN); - ieee->wap_set = (memcmp(temp->sa_data, zero, ETH_ALEN) != 0); + ieee->wap_set = !is_zero_ether_addr(temp->sa_data); spin_unlock_irqrestore(&ieee->lock, flags); -- cgit v0.10.2 From 3cd84fbd667d1dd01209b8c30a3a8525e8a99e63 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 24 Aug 2012 13:29:09 +0800 Subject: staging: r8712u: rtl871x_mlme.c: use is_zero_ether_addr() instead of memcmp() Using is_zero_ether_addr() instead of directly use memcmp() to determine if the ethernet address is all zeros. spatch with a semantic match is used to found this problem. (http://coccinelle.lip6.fr/) Signed-off-by: Wei Yongjun Acked-by: Larry Finger Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8712/rtl871x_mlme.c b/drivers/staging/rtl8712/rtl871x_mlme.c index dc7adc1..c51ad9e 100644 --- a/drivers/staging/rtl8712/rtl871x_mlme.c +++ b/drivers/staging/rtl8712/rtl871x_mlme.c @@ -28,6 +28,8 @@ #define _RTL871X_MLME_C_ +#include + #include "osdep_service.h" #include "drv_types.h" #include "recv_osdep.h" @@ -146,9 +148,8 @@ static struct wlan_network *_r8712_find_network(struct __queue *scanned_queue, unsigned long irqL; struct list_head *phead, *plist; struct wlan_network *pnetwork = NULL; - u8 zero_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; - if (!memcmp(zero_addr, addr, ETH_ALEN)) + if (is_zero_ether_addr(addr)) return NULL; spin_lock_irqsave(&scanned_queue->lock, irqL); phead = get_list_head(scanned_queue); -- cgit v0.10.2 From b7553423cde0cb49a35fabcb15f83688c01ce400 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sun, 26 Aug 2012 11:06:33 +0530 Subject: staging: rtl8192u: use kzalloc to allocate firmware pointer the firmware pointer is allocated with kmalloc and memset, instead we can just do a kzalloc which will return a memory that has been memset. Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index 5981d66..5c132ac 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -2808,9 +2808,7 @@ static void rtl8192_init_priv_variable(struct net_device* dev) (priv->EarlyRxThreshold == 7 ? RCR_ONLYERLPKT:0); priv->AcmControl = 0; - priv->pFirmware = kmalloc(sizeof(rt_firmware), GFP_KERNEL); - if (priv->pFirmware) - memset(priv->pFirmware, 0, sizeof(rt_firmware)); + priv->pFirmware = kzalloc(sizeof(rt_firmware), GFP_KERNEL); /* rx related queue */ skb_queue_head_init(&priv->rx_queue); -- cgit v0.10.2 From 085b50186dff9dc551b54d09be0c21ec925e7fc7 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 28 Aug 2012 21:10:35 +0800 Subject: staging: rtl8192e: remove pointless conditional before kfree_skb() Remove pointless conditional before kfree_skb(). Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 42e5c5c..81134d3 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -734,8 +734,7 @@ static void rtl8192_prepare_beacon(struct r8192_priv *priv) ring = &priv->tx_ring[BEACON_QUEUE]; pskb = __skb_dequeue(&ring->queue); - if (pskb) - kfree_skb(pskb); + kfree_skb(pskb); pnewskb = rtllib_get_beacon(priv->rtllib); if (!pnewskb) -- cgit v0.10.2 From b4797fef980664ea5923b24795ed365177d68525 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Wed, 5 Sep 2012 00:54:41 +0530 Subject: staging: rtl8192e: remove casting of returned pointer from kmalloc as per Documentation/CodingStyle we dont need to cast the return of kmalloc Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c index 22a2764..8027ceb 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac.c +++ b/drivers/staging/rtl8192e/rtllib_softmac.c @@ -3410,8 +3410,7 @@ static int rtllib_wpa_set_encryption(struct rtllib_device *ieee, lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt); - new_crypt = (struct lib80211_crypt_data *) - kmalloc(sizeof(*new_crypt), GFP_KERNEL); + new_crypt = kmalloc(sizeof(*new_crypt), GFP_KERNEL); if (new_crypt == NULL) { ret = -ENOMEM; goto done; -- cgit v0.10.2 From ceee26c0e09ee6df22563bf01aa6b29bd1e5c0de Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 21 Aug 2012 16:36:28 +0800 Subject: staging: rtl8187se: using random_ether_addr() to generate random MAC Using random_ether_addr() to generate a random Ethernet address (MAC) that is not multicast and has the local assigned bit set. Not need to duplicating its implementation. spatch with a semantic match is used to found this problem. (http://coccinelle.lip6.fr/) Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c index 7c669a2..00f9af0 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c @@ -2111,13 +2111,7 @@ void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee) inline void ieee80211_randomize_cell(struct ieee80211_device *ieee) { - get_random_bytes(ieee->current_network.bssid, ETH_ALEN); - - /* an IBSS cell address must have the two less significant - * bits of the first byte = 2 - */ - ieee->current_network.bssid[0] &= ~0x01; - ieee->current_network.bssid[0] |= 0x02; + random_ether_addr(ieee->current_network.bssid); } /* called in user context only */ -- cgit v0.10.2 From 71cd7913cb7b28aa6e7daee217339fc8c70f1a0b Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 21 Aug 2012 16:38:45 +0800 Subject: staging: rtl8192e: using random_ether_addr() to generate random MAC Using random_ether_addr() to generate a random Ethernet address (MAC) that is not multicast and has the local assigned bit set. Not need to duplicating its implementation. spatch with a semantic match is used to found this problem. (http://coccinelle.lip6.fr/) Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c index 8027ceb..99e907d 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac.c +++ b/drivers/staging/rtl8192e/rtllib_softmac.c @@ -2620,13 +2620,7 @@ void rtllib_wake_all_queues(struct rtllib_device *ieee) inline void rtllib_randomize_cell(struct rtllib_device *ieee) { - get_random_bytes(ieee->current_network.bssid, ETH_ALEN); - - /* an IBSS cell address must have the two less significant - * bits of the first byte = 2 - */ - ieee->current_network.bssid[0] &= ~0x01; - ieee->current_network.bssid[0] |= 0x02; + random_ether_addr(ieee->current_network.bssid); } /* called in user context only */ -- cgit v0.10.2 From 37905ae131a728d90515bb9258f195edb6c5d5a2 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 21 Aug 2012 16:39:04 +0800 Subject: Staging: rtl8192u: using random_ether_addr() to generate random MAC Using random_ether_addr() to generate a random Ethernet address (MAC) that is not multicast and has the local assigned bit set. Not need to duplicating its implementation. spatch with a semantic match is used to found this problem. (http://coccinelle.lip6.fr/) Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c index 6721ed9..9f625bc 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c @@ -2288,13 +2288,7 @@ void ieee80211_stop_queue(struct ieee80211_device *ieee) inline void ieee80211_randomize_cell(struct ieee80211_device *ieee) { - get_random_bytes(ieee->current_network.bssid, ETH_ALEN); - - /* an IBSS cell address must have the two less significant - * bits of the first byte = 2 - */ - ieee->current_network.bssid[0] &= ~0x01; - ieee->current_network.bssid[0] |= 0x02; + random_ether_addr(ieee->current_network.bssid); } /* called in user context only */ -- cgit v0.10.2 From c8be681fad93aac2121efcd1bcff54ffe53403eb Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Mon, 3 Sep 2012 18:15:26 +0800 Subject: staging: csr: fix possible memory leak in do_patch_convert_download() pfw has been allocated in function xbv_to_patch() and should be freed before leaving from the error handling cases. spatch with a semantic match is used to found this problem. (http://coccinelle.lip6.fr/) Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/csr/csr_wifi_hip_download.c b/drivers/staging/csr/csr_wifi_hip_download.c index 8e4a460..6db672c 100644 --- a/drivers/staging/csr/csr_wifi_hip_download.c +++ b/drivers/staging/csr/csr_wifi_hip_download.c @@ -250,6 +250,7 @@ static CsrResult do_patch_convert_download(card_t *card, void *dlpriv, xbv1_t *p if (r != CSR_RESULT_SUCCESS) { unifi_error(card->ospriv, "Failed to find BOOT_LOADER_CONTROL\n"); + kfree(pfw); return CSR_RESULT_FAILURE; } @@ -265,6 +266,7 @@ static CsrResult do_patch_convert_download(card_t *card, void *dlpriv, xbv1_t *p desc = unifi_fw_open_buffer(card->ospriv, pfw, psize); if (!desc) { + kfree(pfw); return CSR_WIFI_HIP_RESULT_NO_MEMORY; } -- cgit v0.10.2 From 6a5c23194e09103ed24301e098c03a7da382a656 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Sat, 25 Aug 2012 09:39:15 +0800 Subject: staging: csr: use is_zero_ether_addr() instead of memcmp() Using is_zero_ether_addr() instead of directly use memcmp() to determine if the ethernet address is all zeros. spatch with a semantic match is used to found this problem. (http://coccinelle.lip6.fr/) Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/csr/sme_wext.c b/drivers/staging/csr/sme_wext.c index 5689123..b58c0c6 100644 --- a/drivers/staging/csr/sme_wext.c +++ b/drivers/staging/csr/sme_wext.c @@ -1191,8 +1191,6 @@ unifi_siwap(struct net_device *dev, struct iw_request_info *info, netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); unifi_priv_t *priv = interfacePriv->privPtr; int err = 0; - const unsigned char zero_bssid[ETH_ALEN] = {0x00, 0x00, 0x00, - 0x00, 0x00, 0x00}; func_enter(); @@ -1213,7 +1211,7 @@ unifi_siwap(struct net_device *dev, struct iw_request_info *info, unifi_trace(priv, UDBG1, "unifi_siwap: asked for %pM\n", wrqu->ap_addr.sa_data); - if (!memcmp(wrqu->ap_addr.sa_data, zero_bssid, ETH_ALEN)) { + if (is_zero_ether_addr(wrqu->ap_addr.sa_data)) { priv->ignore_bssid_join = FALSE; err = sme_mgt_disconnect(priv); if (err) { -- cgit v0.10.2 From 5ca136a0cb96aabcb3c2158fb958677d55915f93 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Tue, 28 Aug 2012 11:59:04 -0500 Subject: staging: r8712u: Fix allocations not checked for failure The driver has a dev_alloc_skb() and an skb_clone() call that are not checked for failure. Signed-off-by: Larry Finger Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8712/rtl8712_recv.c b/drivers/staging/rtl8712/rtl8712_recv.c index 8e82ce2..4cd297a 100644 --- a/drivers/staging/rtl8712/rtl8712_recv.c +++ b/drivers/staging/rtl8712/rtl8712_recv.c @@ -374,6 +374,8 @@ static int amsdu_to_msdu(struct _adapter *padapter, union recv_frame *prframe) a_len -= ETH_HLEN; /* Allocate new skb for releasing to upper layer */ sub_skb = dev_alloc_skb(nSubframe_Length + 12); + if (!sub_skb) + break; skb_reserve(sub_skb, 12); data_ptr = (u8 *)skb_put(sub_skb, nSubframe_Length); memcpy(data_ptr, pdata, nSubframe_Length); @@ -1094,6 +1096,8 @@ static int recvbuf2recvframe(struct _adapter *padapter, struct sk_buff *pskb) precvframe->u.hdr.rx_end = pkt_copy->data + alloc_sz; } else { precvframe->u.hdr.pkt = skb_clone(pskb, GFP_ATOMIC); + if (!precvframe->u.hdr.pkt) + return _FAIL; precvframe->u.hdr.rx_head = pbuf; precvframe->u.hdr.rx_data = pbuf; precvframe->u.hdr.rx_tail = pbuf; -- cgit v0.10.2 From 73ee07faeec88b15ef4ffa412622fc2c021ca8ff Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Wed, 29 Aug 2012 15:59:59 -0500 Subject: staging: r8712u: Remove defines that are not used This driver has a number of defines, etc. that are not used. Signed-off-by: Larry Finger Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8712/drv_types.h b/drivers/staging/rtl8712/drv_types.h index 62b5566..a074fe8 100644 --- a/drivers/staging/rtl8712/drv_types.h +++ b/drivers/staging/rtl8712/drv_types.h @@ -70,9 +70,7 @@ struct qos_priv { #include "rtl871x_event.h" #include "rtl871x_led.h" -#define SPEC_DEV_ID_NONE BIT(0) #define SPEC_DEV_ID_DISABLE_HT BIT(1) -#define SPEC_DEV_ID_ENABLE_PS BIT(2) struct specific_device_id { u32 flags; @@ -127,13 +125,6 @@ struct registry_priv { u8 wifi_test; }; -/* For registry parameters */ -#define RGTRY_OFT(field) ((addr_t)FIELD_OFFSET(struct registry_priv, field)) -#define RGTRY_SZ(field) sizeof(((struct registry_priv *)0)->field) -#define BSSID_OFT(field) ((addr_t)FIELD_OFFSET(struct ndis_wlan_bssid_ex, \ - field)) -#define BSSID_SZ(field) sizeof(((struct ndis_wlan_bssid_ex *)0)->field) - struct dvobj_priv { struct _adapter *padapter; u32 nr_endpoint; diff --git a/drivers/staging/rtl8712/rtl871x_pwrctrl.h b/drivers/staging/rtl8712/rtl871x_pwrctrl.h index 6024c4f..70ff924f 100644 --- a/drivers/staging/rtl8712/rtl871x_pwrctrl.h +++ b/drivers/staging/rtl8712/rtl871x_pwrctrl.h @@ -30,26 +30,7 @@ #include "drv_types.h" -#define FW_PWR0 0 -#define FW_PWR1 1 -#define FW_PWR2 2 -#define FW_PWR3 3 - - -#define HW_PWR0 7 -#define HW_PWR1 6 -#define HW_PWR2 2 -#define HW_PWR3 0 -#define HW_PWR4 8 - -#define FW_PWRMSK 0x7 - - -#define XMIT_ALIVE BIT(0) -#define RECV_ALIVE BIT(1) #define CMD_ALIVE BIT(2) -#define EVT_ALIVE BIT(3) - enum Power_Mgnt { PS_MODE_ACTIVE = 0 , @@ -66,7 +47,6 @@ enum Power_Mgnt { PS_MODE_NUM }; - /* BIT[2:0] = HW state BIT[3] = Protocol PS state, 0: register active state, diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c index c758c40..6b73843 100644 --- a/drivers/staging/rtl8712/usb_intf.c +++ b/drivers/staging/rtl8712/usb_intf.c @@ -37,7 +37,6 @@ #include "recv_osdep.h" #include "xmit_osdep.h" #include "rtl8712_efuse.h" -#include "usb_vendor_req.h" #include "usb_ops.h" #include "usb_osintf.h" diff --git a/drivers/staging/rtl8712/usb_osintf.h b/drivers/staging/rtl8712/usb_osintf.h index d95797aa..609f921 100644 --- a/drivers/staging/rtl8712/usb_osintf.h +++ b/drivers/staging/rtl8712/usb_osintf.h @@ -28,9 +28,6 @@ #include "osdep_service.h" #include "drv_types.h" -#include "usb_vendor_req.h" - -#define USBD_HALTED(Status) ((u32)(Status) >> 30 == 3) extern char *r8712_initmac; diff --git a/drivers/staging/rtl8712/usb_vendor_req.h b/drivers/staging/rtl8712/usb_vendor_req.h deleted file mode 100644 index 82335a8..0000000 --- a/drivers/staging/rtl8712/usb_vendor_req.h +++ /dev/null @@ -1,58 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef _USB_VENDOR_REQUEST_H_ -#define _USB_VENDOR_REQUEST_H_ - -/*4 Set/Get Register related wIndex/Data */ -#define RT_USB_RESET_MASK_OFF 0 -#define RT_USB_RESET_MASK_ON 1 -#define RT_USB_SLEEP_MASK_OFF 0 -#define RT_USB_SLEEP_MASK_ON 1 -#define RT_USB_LDO_ON 1 -#define RT_USB_LDO_OFF 0 - -/*4 Set/Get SYSCLK related wValue or Data */ -#define RT_USB_SYSCLK_32KHZ 0 -#define RT_USB_SYSCLK_40MHZ 1 -#define RT_USB_SYSCLK_60MHZ 2 - -enum RT_USB_BREQUEST { - RT_USB_SET_REGISTER = 1, - RT_USB_SET_SYSCLK = 2, - RT_USB_GET_SYSCLK = 3, - RT_USB_GET_REGISTER = 4 -}; - -enum RT_USB_WVALUE { - RT_USB_RESET_MASK = 1, - RT_USB_SLEEP_MASK = 2, - RT_USB_USB_HRCPWM = 3, - RT_USB_LDO = 4, - RT_USB_BOOT_TYPE = 5 -}; - -#endif - -- cgit v0.10.2 From 1e9ee6f7b6ad68dc67444fff13bb7324087874e3 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Thu, 23 Aug 2012 14:40:28 +0800 Subject: staging: r8712u: use is_zero_ether_addr() instead of memcmp() Using is_zero_ether_addr() instead of directly use memcmp(addr, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) to determine if the ethernet address is all zeros. spatch with a semantic match is used to found this problem. (http://coccinelle.lip6.fr/) Signed-off-by: Wei Yongjun Acked-by: Larry Finger Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8712/rtl871x_recv.c b/drivers/staging/rtl8712/rtl871x_recv.c index c9d1743..23ec684 100644 --- a/drivers/staging/rtl8712/rtl871x_recv.c +++ b/drivers/staging/rtl8712/rtl871x_recv.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "osdep_service.h" #include "drv_types.h" @@ -331,8 +332,8 @@ static sint sta2sta_data_frame(struct _adapter *adapter, return _FAIL; if ((memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) return _FAIL; - if (!memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || - !memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || + if (is_zero_ether_addr(pattrib->bssid) || + is_zero_ether_addr(mybssid) || (memcmp(pattrib->bssid, mybssid, ETH_ALEN))) return _FAIL; sta_addr = pattrib->src; @@ -409,8 +410,8 @@ static sint ap2sta_data_frame(struct _adapter *adapter, if ((memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) return _FAIL; /* check BSSID */ - if (!memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || - !memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || + if (is_zero_ether_addr(pattrib->bssid) || + is_zero_ether_addr(mybssid) || (memcmp(pattrib->bssid, mybssid, ETH_ALEN))) return _FAIL; if (bmcast) -- cgit v0.10.2 From c14d01b8a159b9b6a337ccd91de2b89c8f37b3a4 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Sun, 26 Aug 2012 08:55:15 +0800 Subject: staging: et131x: using is_zero_ether_addr() to simplify the code Using is_zero_ether_addr() to simplify the code Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index 029725c..c13499d 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c @@ -3955,12 +3955,7 @@ static void et131x_hwaddr_init(struct et131x_adapter *adapter) * EEPROM then we need to generate the last octet and set it on the * device */ - if (adapter->rom_addr[0] == 0x00 && - adapter->rom_addr[1] == 0x00 && - adapter->rom_addr[2] == 0x00 && - adapter->rom_addr[3] == 0x00 && - adapter->rom_addr[4] == 0x00 && - adapter->rom_addr[5] == 0x00) { + if (is_zero_ether_addr(adapter->rom_addr)) { /* * We need to randomly generate the last octet so we * decrease our chances of setting the mac address to -- cgit v0.10.2 From dce15efebe76088dc381ab91156842ebf7c79aca Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Mon, 3 Sep 2012 18:02:23 +0800 Subject: staging: bcm: fix possible memory leak in bcm_char_ioctl() psFwInfo has been allocated in this function and should be freed before leaving from the error handling cases. spatch with a semantic match is used to found this problem. (http://coccinelle.lip6.fr/) Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index cf411d1..3d02c2e 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -820,6 +820,7 @@ cntrlEnd: if (copy_from_user(psFwInfo, IoBuffer.InputBuffer, IoBuffer.InputLength)) { up(&Adapter->fw_download_sema); + kfree(psFwInfo); return -EFAULT; } @@ -829,6 +830,7 @@ cntrlEnd: BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Something else is wrong %lu\n", psFwInfo->u32FirmwareLength); up(&Adapter->fw_download_sema); + kfree(psFwInfo); Status = -EINVAL; return Status; } -- cgit v0.10.2 From 45145f9ab143727335477570b436c464880714c8 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 25 Aug 2012 21:57:08 +0200 Subject: drivers/staging/crystalhd/crystalhd_lnx.c: adjust inconsistent IS_ERR and PTR_ERR Change the call to PTR_ERR to access the value just tested by IS_ERR. The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression e,e1; @@ ( if (IS_ERR(e)) { ... PTR_ERR(e) ... } | if (IS_ERR(e=e1)) { ... PTR_ERR(e) ... } | *if (IS_ERR(e)) { ... * PTR_ERR(e1) ... } ) // Signed-off-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/crystalhd/crystalhd_lnx.c b/drivers/staging/crystalhd/crystalhd_lnx.c index 5909d8d..166203a 100644 --- a/drivers/staging/crystalhd/crystalhd_lnx.c +++ b/drivers/staging/crystalhd/crystalhd_lnx.c @@ -381,7 +381,7 @@ static int __devinit chd_dec_init_chdev(struct crystalhd_adp *adp) dev = device_create(crystalhd_class, NULL, MKDEV(adp->chd_dec_major, 0), NULL, "crystalhd"); if (IS_ERR(dev)) { - rc = PTR_ERR(crystalhd_class); + rc = PTR_ERR(dev); BCMLOG_ERR("failed to create device\n"); goto device_create_fail; } -- cgit v0.10.2 From 03bbb232d6cd7083daedf0915ffb6cac26870e67 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sat, 25 Aug 2012 23:11:43 +0530 Subject: staging: sbe-2t3e3: fix sparse warnings warnings: drivers/staging/sbe-2t3e3/netdev.c:30:56: warning: incorrect type in initializer (different address spaces) drivers/staging/sbe-2t3e3/netdev.c:30:56: expected void *data drivers/staging/sbe-2t3e3/netdev.c:30:56: got void [noderef] * drivers/staging/sbe-2t3e3/netdev.c:48:44: warning: incorrect type in argument 2 (different address spaces) drivers/staging/sbe-2t3e3/netdev.c:48:44: expected void const [noderef] *from drivers/staging/sbe-2t3e3/netdev.c:48:44: got void *data drivers/staging/sbe-2t3e3/netdev.c:54:34: warning: incorrect type in argument 1 (different address spaces) drivers/staging/sbe-2t3e3/netdev.c:54:34: expected void [noderef] *dst drivers/staging/sbe-2t3e3/netdev.c:54:34: got void *data type must be __user. Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/sbe-2t3e3/netdev.c b/drivers/staging/sbe-2t3e3/netdev.c index c7b5e8b..b339c77 100644 --- a/drivers/staging/sbe-2t3e3/netdev.c +++ b/drivers/staging/sbe-2t3e3/netdev.c @@ -27,7 +27,7 @@ int t3e3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) int cmd_2t3e3, len, rlen; t3e3_param_t param; t3e3_resp_t resp; - void *data = ifr->ifr_data + sizeof(cmd_2t3e3) + sizeof(len); + void __user *data = ifr->ifr_data + sizeof(cmd_2t3e3) + sizeof(len); if (cmd == SIOCWANDEV) return hdlc_ioctl(dev, ifr, cmd); -- cgit v0.10.2 From 1228cd13f94cd6eb46904aa5a9883bdde843109a Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sat, 25 Aug 2012 23:10:47 +0530 Subject: staging: sbe-2t3e3: fix sparse warnings warnings: drivers/staging/sbe-2t3e3/netdev.c:24:5: warning: symbol 't3e3_ioctl' was not declared. Should it be static? drivers/staging/sbe-2t3e3/netdev.c:85:5: warning: symbol 't3e3_open' was not declared. Should it be static? drivers/staging/sbe-2t3e3/netdev.c:100:5: warning: symbol 't3e3_close' was not declared. Should it be static? Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/sbe-2t3e3/netdev.c b/drivers/staging/sbe-2t3e3/netdev.c index b339c77..180c963 100644 --- a/drivers/staging/sbe-2t3e3/netdev.c +++ b/drivers/staging/sbe-2t3e3/netdev.c @@ -21,7 +21,7 @@ #include #include "2t3e3.h" -int t3e3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +static int t3e3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct channel *sc = dev_to_priv(dev); int cmd_2t3e3, len, rlen; @@ -82,7 +82,7 @@ static struct net_device_stats* t3e3_get_stats(struct net_device *dev) return nstats; } -int t3e3_open(struct net_device *dev) +static int t3e3_open(struct net_device *dev) { struct channel *sc = dev_to_priv(dev); int ret = hdlc_open(dev); @@ -97,7 +97,7 @@ int t3e3_open(struct net_device *dev) return 0; } -int t3e3_close(struct net_device *dev) +static int t3e3_close(struct net_device *dev) { struct channel *sc = dev_to_priv(dev); hdlc_close(dev); -- cgit v0.10.2 From c993e432edc3b8ce8d3985d8dac3ecba82be86c0 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sun, 26 Aug 2012 02:35:47 +0530 Subject: staging: cptm1217: use module_i2c_driver macro use the module_i2c_driver and remove the reimplementation of module_i2c_driver Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/cptm1217/clearpad_tm1217.c b/drivers/staging/cptm1217/clearpad_tm1217.c index 0d924d3..a49b0da 100644 --- a/drivers/staging/cptm1217/clearpad_tm1217.c +++ b/drivers/staging/cptm1217/clearpad_tm1217.c @@ -658,18 +658,7 @@ static struct i2c_driver cp_tm1217_driver = { .resume = cp_tm1217_resume, }; -static int __init clearpad_tm1217_init(void) -{ - return i2c_add_driver(&cp_tm1217_driver); -} - -static void __exit clearpad_tm1217_exit(void) -{ - i2c_del_driver(&cp_tm1217_driver); -} - -module_init(clearpad_tm1217_init); -module_exit(clearpad_tm1217_exit); +module_i2c_driver(cp_tm1217_driver); MODULE_AUTHOR("Ramesh Agarwal "); MODULE_DESCRIPTION("Synaptics TM1217 TouchScreen Driver"); -- cgit v0.10.2 From 623c2bb2c59a6941c68e5d47d13e417f63535043 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sun, 26 Aug 2012 11:12:33 +0530 Subject: staging: serqt_usb2: fix dbg print when kzalloc failed to allocate qt_port the port was kzalloced but the print statement says that its kmalloc. Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c index 1b26023..c56609c 100644 --- a/drivers/staging/serqt_usb2/serqt_usb2.c +++ b/drivers/staging/serqt_usb2/serqt_usb2.c @@ -704,7 +704,7 @@ static int qt_startup(struct usb_serial *serial) port = serial->port[i]; qt_port = kzalloc(sizeof(*qt_port), GFP_KERNEL); if (!qt_port) { - dbg("%s: kmalloc for quatech_port (%d) failed!.", + dbg("%s: kzalloc for quatech_port (%d) failed!.", __func__, i); for (--i; i >= 0; i--) { port = serial->port[i]; -- cgit v0.10.2 From 651d4bc7ed85356efa16465073f13a24f040369e Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sun, 26 Aug 2012 12:36:56 +0530 Subject: staging: slicoss: return early before calling request_firmware with empty firmware filename when the device id doesn't match in slic_card_download_gbrcv the filename is "", i.e an empty name, and we try calling request_firmware with that name, actually we can just fail out at default case before even calling request_firmware Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c index 56829fc..eb498b8 100644 --- a/drivers/staging/slicoss/slicoss.c +++ b/drivers/staging/slicoss/slicoss.c @@ -514,8 +514,7 @@ static int slic_card_download_gbrcv(struct adapter *adapter) file = "slicoss/gbrcvucode.sys"; break; default: - ASSERT(0); - break; + return -ENOENT; } ret = request_firmware(&fw, file, &adapter->pcidev->dev); -- cgit v0.10.2 From 7ee34ab2b37a2a8191bb1b33eebd3ed8cfae0ce6 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sun, 26 Aug 2012 12:42:50 +0530 Subject: staging: slicoss: release firmware before returning we request_firmware in slic_card_download_gbrcv and we return out with out calling release_firmware, where we compare against a firmware lengths of certain device ids. Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c index eb498b8..170e0df 100644 --- a/drivers/staging/slicoss/slicoss.c +++ b/drivers/staging/slicoss/slicoss.c @@ -528,12 +528,16 @@ static int slic_card_download_gbrcv(struct adapter *adapter) index += 4; switch (adapter->devid) { case SLIC_2GB_DEVICE_ID: - if (rcvucodelen != OasisRcvUCodeLen) + if (rcvucodelen != OasisRcvUCodeLen) { + release_firmware(fw); return -EINVAL; + } break; case SLIC_1GB_DEVICE_ID: - if (rcvucodelen != GBRcvUCodeLen) + if (rcvucodelen != GBRcvUCodeLen) { + release_firmware(fw); return -EINVAL; + } break; default: ASSERT(0); -- cgit v0.10.2 From 147cd165757fc67fdf8ae58b015f39c8134970fb Mon Sep 17 00:00:00 2001 From: "Dae S. Kim" Date: Wed, 29 Aug 2012 17:08:33 +0200 Subject: Staging: android: Alarm driver cleanups Little cleanups. Enum value ANDROID_ALARM_TYPE_COUNT was treated as an alarm type within a switch statement. That condition was unreachable though. Signed-off-by: Dae S. Kim Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/android/alarm-dev.c b/drivers/staging/android/alarm-dev.c index 5b70640..a9b293f 100644 --- a/drivers/staging/android/alarm-dev.c +++ b/drivers/staging/android/alarm-dev.c @@ -67,10 +67,8 @@ static struct devalarm alarms[ANDROID_ALARM_TYPE_COUNT]; static int is_wakeup(enum android_alarm_type type) { - if (type == ANDROID_ALARM_RTC_WAKEUP || - type == ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP) - return 1; - return 0; + return (type == ANDROID_ALARM_RTC_WAKEUP || + type == ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP); } @@ -85,12 +83,9 @@ static void devalarm_start(struct devalarm *alrm, ktime_t exp) static int devalarm_try_to_cancel(struct devalarm *alrm) { - int ret; if (is_wakeup(alrm->type)) - ret = alarm_try_to_cancel(&alrm->u.alrm); - else - ret = hrtimer_try_to_cancel(&alrm->u.hrt); - return ret; + return alarm_try_to_cancel(&alrm->u.alrm); + return hrtimer_try_to_cancel(&alrm->u.hrt); } static void devalarm_cancel(struct devalarm *alrm) @@ -223,10 +218,12 @@ from_old_alarm_set: case ANDROID_ALARM_ELAPSED_REALTIME: get_monotonic_boottime(&tmp_time); break; - case ANDROID_ALARM_TYPE_COUNT: case ANDROID_ALARM_SYSTEMTIME: ktime_get_ts(&tmp_time); break; + default: + rv = -EINVAL; + goto err1; } if (copy_to_user((void __user *)arg, &tmp_time, sizeof(tmp_time))) { -- cgit v0.10.2 From d328ddd20e076e940f4931cd032aedf1ae2ced73 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sun, 26 Aug 2012 11:57:16 +0530 Subject: staging: sm7xxfb: copy device name before we pass to the smtc_alloc_fb_info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit the name is not initialised and passed to the function smtc_alloc_fb_info and copies the name into a member of fb structure. copy the name before calling alloc_fb_info. Signed-off-by: Devendra Naga Acked-by: Javier Muñoz Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/sm7xxfb/sm7xxfb.c b/drivers/staging/sm7xxfb/sm7xxfb.c index 1c1780c..d935c23 100644 --- a/drivers/staging/sm7xxfb/sm7xxfb.c +++ b/drivers/staging/sm7xxfb/sm7xxfb.c @@ -798,6 +798,8 @@ static int __devinit smtcfb_pci_probe(struct pci_dev *pdev, if (err) return err; + sprintf(name, "sm%Xfb", ent->device); + sfb = smtc_alloc_fb_info(pdev, name); if (!sfb) { @@ -806,7 +808,6 @@ static int __devinit smtcfb_pci_probe(struct pci_dev *pdev, } sfb->chip_id = ent->device; - sprintf(name, "sm%Xfb", sfb->chip_id); pci_set_drvdata(pdev, sfb); -- cgit v0.10.2 From 375d8886bc76871f012a337b4d6d753970d9fb36 Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Wed, 29 Aug 2012 18:48:30 -0400 Subject: Staging: sep: Correct misspelled "remap_page_range" -> "remap_pfn_range" Signed-off-by: Robert P. J. Day Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/sep/sep_main.c b/drivers/staging/sep/sep_main.c index ca8946a..a414e52 100644 --- a/drivers/staging/sep/sep_main.c +++ b/drivers/staging/sep/sep_main.c @@ -719,7 +719,7 @@ static int sep_mmap(struct file *filp, struct vm_area_struct *vma) if (remap_pfn_range(vma, vma->vm_start, bus_addr >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot)) { - dev_dbg(&sep->pdev->dev, "[PID%d] remap_page_range failed\n", + dev_dbg(&sep->pdev->dev, "[PID%d] remap_pfn_range failed\n", current->pid); error = -EAGAIN; goto end_function_with_error; -- cgit v0.10.2 From a47bf2452b05e6f7a3bbbe2433b0a7a6c1f4a5e4 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sun, 2 Sep 2012 02:29:50 +0530 Subject: staging: cxt1e1: use kernel's way of returning error codes The error codes the kernel functions return are -ve numbers, convert this function to follow the other kernel functions Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/cxt1e1/linux.c b/drivers/staging/cxt1e1/linux.c index 911c0e4..6452dc3 100644 --- a/drivers/staging/cxt1e1/linux.c +++ b/drivers/staging/cxt1e1/linux.c @@ -405,7 +405,7 @@ c4_linux_xmit (struct sk_buff * skb, struct net_device * ndev) priv = hdlc->priv; rval = musycc_start_xmit (priv->ci, priv->channum, skb); - return -rval; + return rval; } static const struct net_device_ops chan_ops = { diff --git a/drivers/staging/cxt1e1/musycc.c b/drivers/staging/cxt1e1/musycc.c index 90c0f1e..ba721c6 100644 --- a/drivers/staging/cxt1e1/musycc.c +++ b/drivers/staging/cxt1e1/musycc.c @@ -1761,15 +1761,15 @@ musycc_start_xmit (ci_t * ci, int channum, void *mem_token) u_int32_t len; if (!(ch = sd_find_chan (ci, channum))) - return ENOENT; + return -ENOENT; if (ci->state != C_RUNNING) /* full interrupt processing available */ - return EINVAL; + return -EINVAL; if (ch->state != UP) - return EINVAL; + return -EINVAL; if (!(ch->status & TX_ENABLED)) - return EROFS; /* how else to flag unwritable state ? */ + return -EROFS; /* how else to flag unwritable state ? */ #ifdef RLD_TRANS_DEBUGx if (1 || cxt1e1_log_level >= LOG_MONITOR2) @@ -1836,7 +1836,7 @@ musycc_start_xmit (ci_t * ci, int channum, void *mem_token) #if 0 spin_unlock_irqrestore (&ch->ch_txlock, flags); #endif - return EBUSY; /* tell user to try again later */ + return -EBUSY; /* tell user to try again later */ } /**************************************************/ /** Put the user data into MUSYCC data buffer(s) **/ -- cgit v0.10.2 From 21aac2c935178ef8594ad81a174319ece3139a0d Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sun, 2 Sep 2012 02:29:51 +0530 Subject: staging: cxt1e1: solve coding style problem remove the spaces and replace with tabs at the beginning of a line and also remove space between function call and its open paranthesis Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/cxt1e1/linux.c b/drivers/staging/cxt1e1/linux.c index 6452dc3..0ff2865 100644 --- a/drivers/staging/cxt1e1/linux.c +++ b/drivers/staging/cxt1e1/linux.c @@ -1169,11 +1169,11 @@ cleanup_hdlc (void) STATIC void __exit c4_mod_remove (void) { - cleanup_hdlc (); /* delete any missed channels */ - cleanup_devs (); - c4_cleanup (); - cleanup_ioremap (); - pr_info("SBE - driver removed.\n"); + cleanup_hdlc(); /* delete any missed channels */ + cleanup_devs(); + c4_cleanup(); + cleanup_ioremap(); + pr_info("SBE - driver removed.\n"); } module_init (c4_mod_init); -- cgit v0.10.2 From a31f7f5fca7f4f05577649aeeb7fbe91fd8732ae Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 3 Sep 2012 08:06:02 -0700 Subject: staging: "winbond" Fix typos. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/winbond/localpara.h b/drivers/staging/winbond/localpara.h index d798057..84effc4 100644 --- a/drivers/staging/winbond/localpara.h +++ b/drivers/staging/winbond/localpara.h @@ -137,7 +137,7 @@ struct wb_local_para { u8 iPowerSaveMode; /* 0 indicates on, 1 indicates off */ u8 ATIMmode; u8 ExcludeUnencrypted; - /* Unit ime count for the decision to enter PS mode */ + /* Unit time count for the decision to enter PS mode */ u16 CheckCountForPS; u8 boHasTxActivity;/* tx activity has occurred */ u8 boMacPsValid; /* Power save mode obtained from H/W is valid or not */ @@ -187,7 +187,7 @@ struct wb_local_para { u8 reserved7[3]; struct chan_info CurrentChan; /* Current channel no. and channel band. It may be changed by scanning. */ - u8 boHandover; /* Roaming, Hnadover to other AP. */ + u8 boHandover; /* Roaming, Handover to other AP. */ u8 boCCAbusy; u16 CWMax; /* It may not be the real value that H/W used */ diff --git a/drivers/staging/winbond/mds.c b/drivers/staging/winbond/mds.c index c9f0e8f..1b8b8ac 100644 --- a/drivers/staging/winbond/mds.c +++ b/drivers/staging/winbond/mds.c @@ -569,7 +569,7 @@ Mds_SendComplete(struct wbsoft_priv *adapter, struct T02_descriptor *pT02) unsigned char SendOK = true; u8 RetryCount, TxRate; - if (pT02->T02_IgnoreResult) /* Don't care the result */ + if (pT02->T02_IgnoreResult) /* Don't care about the result */ return; if (pT02->T02_IsLastMpdu) { /* TODO: DTO -- get the retry count and fragment count */ diff --git a/drivers/staging/winbond/mto.c b/drivers/staging/winbond/mto.c index 1b52ebd..560c0ab 100644 --- a/drivers/staging/winbond/mto.c +++ b/drivers/staging/winbond/mto.c @@ -23,7 +23,7 @@ #include "core.h" /* Declare SQ3 to rate and fragmentation threshold table */ -/* Declare fragmentation thresholds table */ +/* Declare fragmentation threshold table */ #define MTO_MAX_FRAG_TH_LEVELS 5 #define MTO_MAX_DATA_RATE_LEVELS 12 diff --git a/drivers/staging/winbond/phy_calibration.c b/drivers/staging/winbond/phy_calibration.c index 77a3fff..cabae34 100644 --- a/drivers/staging/winbond/phy_calibration.c +++ b/drivers/staging/winbond/phy_calibration.c @@ -399,7 +399,7 @@ void _rxadc_dc_offset_cancellation_winbond(struct hw_data *phw_data, u32 frequen val |= MASK_ADC_DC_CAL_STR; hw_set_dxx_reg(phw_data, REG_MODE_CTRL, val); - /* e. The result are shown in "adc_dc_cal_i[8:0] and adc_dc_cal_q[8:0]" */ + /* e. The results are shown in "adc_dc_cal_i[8:0] and adc_dc_cal_q[8:0]" */ #ifdef _DEBUG hw_get_dxx_reg(phw_data, REG_OFFSET_READ, &val); PHY_DEBUG(("[CAL] REG_OFFSET_READ = 0x%08X\n", val)); @@ -720,7 +720,7 @@ u8 _tx_iq_calibration_loop_winbond(struct hw_data *phw_data, for (capture_time = 0; capture_time < 10; capture_time++) { /* * a. Set iqcal_mode[1:0] to 0x2 and set "calib_start" to 0x1 to - * enable "IQ alibration Mode II" + * enable "IQ calibration Mode II" */ reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE); reg_mode_ctrl &= ~MASK_IQCAL_MODE; @@ -750,7 +750,7 @@ u8 _tx_iq_calibration_loop_winbond(struct hw_data *phw_data, /* * d. Set iqcal_mode[1:0] to 0x3 and set "calib_start" to 0x1 to - * enable "IQ alibration Mode II" + * enable "IQ calibration Mode II" */ /* hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &val); */ hw_get_dxx_reg(phw_data, REG_MODE_CTRL, ®_mode_ctrl); @@ -980,7 +980,7 @@ void _tx_iq_calibration_winbond(struct hw_data *phw_data) phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0); /* ; [BB-chip]: Calibration (6f).Send test pattern */ /* ; [BB-chip]: Calibration (6g). Search RXGCL optimal value */ - /* ; [BB-chip]: Calibration (6h). Caculate TX-path IQ imbalance and setting TX path IQ compensation table */ + /* ; [BB-chip]: Calibration (6h). Calculate TX-path IQ imbalance and setting TX path IQ compensation table */ /* phy_set_rf_data(phw_data, 3, (3<<24)|0x025586); */ msleep(30); /* 20060612.1.a 30ms delay. Add the follow 2 lines */ @@ -1373,7 +1373,7 @@ u8 _rx_iq_calibration_loop_winbond(struct hw_data *phw_data, u16 factor, u32 fre /***************************************************************/ void _rx_iq_calibration_winbond(struct hw_data *phw_data, u32 frequency) { -/* figo 20050523 marked this flag for can't compile for relesase */ +/* figo 20050523 marked this flag for can't compile for release */ #ifdef _DEBUG s32 rx_cal_reg[4]; u32 val; @@ -1397,7 +1397,7 @@ void _rx_iq_calibration_winbond(struct hw_data *phw_data, u32 frequency) /* ; [BB-chip]: Calibration (7f). Send test pattern */ /* ; [BB-chip]: Calibration (7g). Search RXGCL optimal value */ - /* ; [BB-chip]: Calibration (7h). Caculate RX-path IQ imbalance and setting RX path IQ compensation table */ + /* ; [BB-chip]: Calibration (7h). Calculate RX-path IQ imbalance and setting RX path IQ compensation table */ result = _rx_iq_calibration_loop_winbond(phw_data, 12589, frequency); @@ -1454,7 +1454,7 @@ void phy_calibration_winbond(struct hw_data *phw_data, u32 frequency) _rxadc_dc_offset_cancellation_winbond(phw_data, frequency); /* _txidac_dc_offset_cancellation_winbond(phw_data); */ - /* _txqdac_dc_offset_cacellation_winbond(phw_data); */ + /* _txqdac_dc_offset_cancellation_winbond(phw_data); */ _tx_iq_calibration_winbond(phw_data); _rx_iq_calibration_winbond(phw_data, frequency); diff --git a/drivers/staging/winbond/reg.c b/drivers/staging/winbond/reg.c index 1b38d6d..5ecf9a1 100644 --- a/drivers/staging/winbond/reg.c +++ b/drivers/staging/winbond/reg.c @@ -693,7 +693,7 @@ u32 w89rf242_rf_data[] = { (0x0E << 24) | 0x5557DC, /* 1555F ; IBSC (0x0E) -- IRLNA & IRLNB (PTAT & Const current)=01/01; FA5976B_1.3F */ (0x10 << 24) | 0x000C20, /* 00030 ; TMODA (0x10) -- LNA_gain_step=0011 ; LNA=15/16dB */ (0x11 << 24) | 0x0C0022, /* 03000 ; TMODB (0x11) -- Turn ON RX-Q path Test Switch; To improve IQ path group delay (FA5976A_1.3C) */ - (0x12 << 24) | 0x000024 /* TMODC (0x12) -- Turn OFF Tempearure sensor */ + (0x12 << 24) | 0x000024 /* TMODC (0x12) -- Turn OFF Temperature sensor */ }; u32 w89rf242_channel_data_24[][2] = { diff --git a/drivers/staging/winbond/sme_api.h b/drivers/staging/winbond/sme_api.h index 8f4596c..712331b 100644 --- a/drivers/staging/winbond/sme_api.h +++ b/drivers/staging/winbond/sme_api.h @@ -107,7 +107,7 @@ s8 sme_set_bssid_list_scan(void *pcore_data, void *pscan_para); s8 sme_set_reload_defaults(void *pcore_data, u8 reload_type); -/*------------------------- none-standard ----------------------------------*/ +/*------------------------- non-standard ----------------------------------*/ s8 sme_get_connect_status(void *pcore_data, u8 *pstatus); /*--------------------------------------------------------------------------*/ diff --git a/drivers/staging/winbond/wb35reg.c b/drivers/staging/winbond/wb35reg.c index da595f1..1bff7d1 100644 --- a/drivers/staging/winbond/wb35reg.c +++ b/drivers/staging/winbond/wb35reg.c @@ -217,7 +217,7 @@ unsigned char Wb35Reg_Write(struct hw_data *pHwData, u16 RegisterNo, u32 Registe * This command will be executed with a user defined value. When it completes, * this value is useful. For example, hal_set_current_channel will use it. * true : read command process successfully - * false : register not support + * false : register not supported */ unsigned char Wb35Reg_WriteWithCallbackValue(struct hw_data *pHwData, u16 RegisterNo, @@ -631,7 +631,7 @@ unsigned char Wb35Reg_initial(struct hw_data *pHwData) * CardComputeCrc -- * * Description: - * Runs the AUTODIN II CRC algorithm on buffer Buffer of length, Length. + * Runs the AUTODIN II CRC algorithm on the buffers Buffer length. * * Arguments: * Buffer - the input buffer diff --git a/drivers/staging/winbond/wb35tx.c b/drivers/staging/winbond/wb35tx.c index 5df39d4..0f870da 100644 --- a/drivers/staging/winbond/wb35tx.c +++ b/drivers/staging/winbond/wb35tx.c @@ -149,14 +149,14 @@ void Wb35Tx_stop(struct hw_data * pHwData) { struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx; - // Trying to canceling the Trp of EP2 + // Try to cancel the Trp of EP2 if (pWb35Tx->EP2vm_state == VM_RUNNING) - usb_unlink_urb( pWb35Tx->Tx2Urb ); // Only use unlink, let Wb35Tx_destrot to free them + usb_unlink_urb( pWb35Tx->Tx2Urb ); // Only use unlink, let Wb35Tx_destroy to free them pr_debug("EP2 Tx stop\n"); - // Trying to canceling the Irp of EP4 + // Try to cancel the Irp of EP4 if (pWb35Tx->EP4vm_state == VM_RUNNING) - usb_unlink_urb( pWb35Tx->Tx4Urb ); // Only use unlink, let Wb35Tx_destrot to free them + usb_unlink_urb( pWb35Tx->Tx4Urb ); // Only use unlink, let Wb35Tx_destroy to free them pr_debug("EP4 Tx stop\n"); } diff --git a/drivers/staging/winbond/wb35tx_s.h b/drivers/staging/winbond/wb35tx_s.h index f70f433..9186526 100644 --- a/drivers/staging/winbond/wb35tx_s.h +++ b/drivers/staging/winbond/wb35tx_s.h @@ -41,7 +41,7 @@ struct wb35_tx { int EP4VM_status; u32 TxFillCount; // 20060928 - u32 TxTimer; // 20060928 Add if sending packet not great than 13 + u32 TxTimer; // 20060928 Add if sending packet is greater than 13 }; #endif -- cgit v0.10.2 From da1e4faf4de7bd26bef9568bc3bc29781ddf6b47 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Sun, 2 Sep 2012 13:55:54 -0400 Subject: Staging: bcm: Fix white space issues in InterfaceInit.h This patch fixes white space issue in InterfaceInit.h as reported by checkpatch.pl. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/InterfaceInit.h b/drivers/staging/bcm/InterfaceInit.h index 058315a..44eaf97 100644 --- a/drivers/staging/bcm/InterfaceInit.h +++ b/drivers/staging/bcm/InterfaceInit.h @@ -1,21 +1,20 @@ #ifndef _INTERFACE_INIT_H #define _INTERFACE_INIT_H -#define BCM_USB_VENDOR_ID_T3 0x198f -#define BCM_USB_VENDOR_ID_FOXCONN 0x0489 -#define BCM_USB_VENDOR_ID_ZTE 0x19d2 +#define BCM_USB_VENDOR_ID_T3 0x198f +#define BCM_USB_VENDOR_ID_FOXCONN 0x0489 +#define BCM_USB_VENDOR_ID_ZTE 0x19d2 -#define BCM_USB_PRODUCT_ID_T3 0x0300 -#define BCM_USB_PRODUCT_ID_T3B 0x0210 -#define BCM_USB_PRODUCT_ID_T3L 0x0220 -#define BCM_USB_PRODUCT_ID_SM250 0xbccd -#define BCM_USB_PRODUCT_ID_SYM 0x15E -#define BCM_USB_PRODUCT_ID_1901 0xe017 -#define BCM_USB_PRODUCT_ID_226 0x0132 -#define BCM_USB_PRODUCT_ID_ZTE_TU25 0x0007 - -#define BCM_USB_MINOR_BASE 192 +#define BCM_USB_PRODUCT_ID_T3 0x0300 +#define BCM_USB_PRODUCT_ID_T3B 0x0210 +#define BCM_USB_PRODUCT_ID_T3L 0x0220 +#define BCM_USB_PRODUCT_ID_SM250 0xbccd +#define BCM_USB_PRODUCT_ID_SYM 0x15E +#define BCM_USB_PRODUCT_ID_1901 0xe017 +#define BCM_USB_PRODUCT_ID_226 0x0132 +#define BCM_USB_PRODUCT_ID_ZTE_TU25 0x0007 +#define BCM_USB_MINOR_BASE 192 INT InterfaceInitialize(void); @@ -24,4 +23,3 @@ INT InterfaceExit(void); INT usbbcm_worker_thread(PS_INTERFACE_ADAPTER psIntfAdapter); #endif - -- cgit v0.10.2 From 1d200e8d0a53f419e89097b0fc197941228191c3 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Sun, 2 Sep 2012 13:55:55 -0400 Subject: Staging: bcm: Convert INT to int in InterfaceInit.h This patch converts INT to int in InterfaceInit.h Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/InterfaceInit.h b/drivers/staging/bcm/InterfaceInit.h index 44eaf97..3b35832 100644 --- a/drivers/staging/bcm/InterfaceInit.h +++ b/drivers/staging/bcm/InterfaceInit.h @@ -16,10 +16,10 @@ #define BCM_USB_MINOR_BASE 192 -INT InterfaceInitialize(void); +int InterfaceInitialize(void); -INT InterfaceExit(void); +int InterfaceExit(void); -INT usbbcm_worker_thread(PS_INTERFACE_ADAPTER psIntfAdapter); +int usbbcm_worker_thread(PS_INTERFACE_ADAPTER psIntfAdapter); #endif -- cgit v0.10.2 From d7b990a035a86a07e81231caceb6e624056c258f Mon Sep 17 00:00:00 2001 From: Alexey Khoroshilov Date: Sun, 2 Sep 2012 23:30:13 +0400 Subject: staging: bcm: fix error handling in bcm_init() bcm_init() does not have proper error handling of usb_register(). The patch implements one. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov Acked-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c index 8f85de6..57452ef 100644 --- a/drivers/staging/bcm/InterfaceInit.c +++ b/drivers/staging/bcm/InterfaceInit.c @@ -669,6 +669,8 @@ struct class *bcm_class; static __init int bcm_init(void) { + int retval; + printk(KERN_INFO "%s: %s, %s\n", DRV_NAME, DRV_DESCRIPTION, DRV_VERSION); printk(KERN_INFO "%s\n", DRV_COPYRIGHT); @@ -678,7 +680,13 @@ static __init int bcm_init(void) return PTR_ERR(bcm_class); } - return usb_register(&usbbcm_driver); + retval = usb_register(&usbbcm_driver); + if (retval < 0) { + printk(KERN_ERR DRV_NAME ": could not register usb driver\n"); + class_destroy(bcm_class); + return retval; + } + return 0; } static __exit void bcm_exit(void) -- cgit v0.10.2 From c2e114db5a2c02b5b148cf8db88c4a0d7c8ffb56 Mon Sep 17 00:00:00 2001 From: Alexey Khoroshilov Date: Sun, 2 Sep 2012 23:30:14 +0400 Subject: staging: bcm: use pr_info and pr_err rather than printk Convert printk(KERN_INFO to pr_info( and printk(KERN_ERR to pr_err(. Signed-off-by: Alexey Khoroshilov Acked-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c index 57452ef..dfee0ce 100644 --- a/drivers/staging/bcm/InterfaceInit.c +++ b/drivers/staging/bcm/InterfaceInit.c @@ -671,18 +671,18 @@ static __init int bcm_init(void) { int retval; - printk(KERN_INFO "%s: %s, %s\n", DRV_NAME, DRV_DESCRIPTION, DRV_VERSION); - printk(KERN_INFO "%s\n", DRV_COPYRIGHT); + pr_info("%s: %s, %s\n", DRV_NAME, DRV_DESCRIPTION, DRV_VERSION); + pr_info("%s\n", DRV_COPYRIGHT); bcm_class = class_create(THIS_MODULE, DRV_NAME); if (IS_ERR(bcm_class)) { - printk(KERN_ERR DRV_NAME ": could not create class\n"); + pr_err(DRV_NAME ": could not create class\n"); return PTR_ERR(bcm_class); } retval = usb_register(&usbbcm_driver); if (retval < 0) { - printk(KERN_ERR DRV_NAME ": could not register usb driver\n"); + pr_err(DRV_NAME ": could not register usb driver\n"); class_destroy(bcm_class); return retval; } -- cgit v0.10.2 From 0505c63d3a70fd7ac3eabf2851e6415042faa098 Mon Sep 17 00:00:00 2001 From: Priit Laes Date: Sat, 1 Sep 2012 12:05:57 +0300 Subject: staging: csr: netdev.c: Clean up KERNEL_VERSION checks: <=2.6.25 Signed-off-by: Priit Laes Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/csr/netdev.c b/drivers/staging/csr/netdev.c index 0e34020..1d06241 100644 --- a/drivers/staging/csr/netdev.c +++ b/drivers/staging/csr/netdev.c @@ -52,9 +52,6 @@ #include "csr_wifi_hip_unifi.h" #include "csr_wifi_hip_conversions.h" #include "unifi_priv.h" -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) -#include -#endif #include @@ -188,13 +185,8 @@ static struct sk_buff *uf_qdiscop_dequeue(struct Qdisc* qd); static void uf_qdiscop_reset(struct Qdisc* qd); static void uf_qdiscop_destroy(struct Qdisc* qd); static int uf_qdiscop_dump(struct Qdisc *qd, struct sk_buff *skb); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25) static int uf_qdiscop_tune(struct Qdisc *qd, struct nlattr *opt); static int uf_qdiscop_init(struct Qdisc *qd, struct nlattr *opt); -#else -static int uf_qdiscop_tune(struct Qdisc *qd, struct rtattr *opt); -static int uf_qdiscop_init(struct Qdisc *qd, struct rtattr *opt); -#endif #endif @@ -226,9 +218,6 @@ static struct Qdisc_ops uf_qdisc_ops = #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) #define UF_QDISC_CREATE_DFLT(_dev, _ops, _root) \ qdisc_create_dflt(dev, netdev_get_tx_queue(_dev, 0), _ops, _root) -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -#define UF_QDISC_CREATE_DFLT(_dev, _ops, _root) \ - qdisc_create_dflt(dev, _ops, _root) #else #define UF_QDISC_CREATE_DFLT(_dev, _ops, _root) \ qdisc_create_dflt(dev, _ops) @@ -699,10 +688,8 @@ uf_free_netdevice(unifi_priv_t *priv) #ifdef CSR_SUPPORT_SME /* Cancel work items and destroy the workqueue */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) cancel_work_sync(&priv->multicast_list_task); #endif -#endif /* Destroy the workqueues. */ flush_workqueue(priv->unifi_workqueue); destroy_workqueue(priv->unifi_workqueue); @@ -3479,11 +3466,7 @@ static void uf_qdiscop_destroy(struct Qdisc* qd) /* called whenever parameters are updated on existing qdisc */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25) static int uf_qdiscop_tune(struct Qdisc *qd, struct nlattr *opt) -#else -static int uf_qdiscop_tune(struct Qdisc *qd, struct rtattr *opt) -#endif { func_enter(); func_exit(); @@ -3492,11 +3475,7 @@ static int uf_qdiscop_tune(struct Qdisc *qd, struct rtattr *opt) /* called during initial creation of qdisc on device */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25) static int uf_qdiscop_init(struct Qdisc *qd, struct nlattr *opt) -#else -static int uf_qdiscop_init(struct Qdisc *qd, struct rtattr *opt) -#endif { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) struct net_device *dev = qd->dev_queue->dev; -- cgit v0.10.2 From 58abe64fcfb2bc7b8d22792a6bf889e8d1d7ccb3 Mon Sep 17 00:00:00 2001 From: Priit Laes Date: Sat, 1 Sep 2012 12:05:58 +0300 Subject: staging: csr: netdev.c: Clean up KERNEL_VERSION checks: 2.6.27 Signed-off-by: Priit Laes Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/csr/netdev.c b/drivers/staging/csr/netdev.c index 1d06241..c8f6d8e 100644 --- a/drivers/staging/csr/netdev.c +++ b/drivers/staging/csr/netdev.c @@ -215,9 +215,6 @@ static struct Qdisc_ops uf_qdisc_ops = #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) #define UF_QDISC_CREATE_DFLT(_dev, _ops, _root) -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) -#define UF_QDISC_CREATE_DFLT(_dev, _ops, _root) \ - qdisc_create_dflt(dev, netdev_get_tx_queue(_dev, 0), _ops, _root) #else #define UF_QDISC_CREATE_DFLT(_dev, _ops, _root) \ qdisc_create_dflt(dev, _ops) @@ -2337,8 +2334,6 @@ uf_resume_data_plane(unifi_priv_t *priv, int queue, if (netif_running(priv->netdev[interfaceTag])) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) netif_tx_schedule_all(priv->netdev[interfaceTag]); -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) - netif_schedule_queue(netdev_get_tx_queue(priv->netdev[interfaceTag], 0)); #else netif_schedule(priv->netdev[interfaceTag]); #endif /* LINUX_VERSION_CODE */ @@ -3198,25 +3193,11 @@ void uf_net_get_name(struct net_device *dev, char *name, int len) int uf_install_qdisc(struct net_device *dev) { struct Qdisc *qdisc; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) struct netdev_queue *queue0; -#endif /* LINUX_VERSION_CODE */ func_enter(); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) - /* - * check that there is no qdisc currently attached to device - * this ensures that we will be the root qdisc. (I can't find a better - * way to test this explicitly) - */ - if (dev->qdisc_sleeping != &noop_qdisc) { - func_exit_r(-EFAULT); - return -EINVAL; - } -#endif /* LINUX_VERSION_CODE */ - qdisc = UF_QDISC_CREATE_DFLT(dev, &uf_qdisc_ops, TC_H_ROOT); if (!qdisc) { unifi_error(NULL, "%s: qdisc installation failed\n", dev->name); @@ -3229,7 +3210,6 @@ int uf_install_qdisc(struct net_device *dev) qdisc->handle = 0x80020000; qdisc->flags = 0x0; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) queue0 = netdev_get_tx_queue(dev, 0); if (queue0 == NULL) { unifi_error(NULL, "%s: netdev_get_tx_queue returned no queue\n", @@ -3239,12 +3219,6 @@ int uf_install_qdisc(struct net_device *dev) } queue0->qdisc = qdisc; queue0->qdisc_sleeping = qdisc; -#else - qdisc_lock_tree(dev); - list_add_tail(&qdisc->list, &dev->qdisc_list); - dev->qdisc_sleeping = qdisc; - qdisc_unlock_tree(dev); -#endif /* LINUX_VERSION_CODE */ func_exit_r(0); return 0; @@ -3253,11 +3227,7 @@ int uf_install_qdisc(struct net_device *dev) static int uf_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(qd->dev_queue->dev); -#else - netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(qd->dev); -#endif /* LINUX_VERSION_CODE */ unifi_priv_t *priv = interfacePriv->privPtr; struct uf_sched_data *q = qdisc_priv(qd); struct uf_tx_packet_data *pkt_data = (struct uf_tx_packet_data *) skb->cb; @@ -3304,11 +3274,7 @@ static int uf_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd) static int uf_qdiscop_requeue(struct sk_buff *skb, struct Qdisc* qd) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) netInterface_priv_t *interfacePriv = (netInterface_priv_t*)netdev_priv(qd->dev_queue->dev); -#else - netInterface_priv_t *interfacePriv = (netInterface_priv_t*)netdev_priv(qd->dev); -#endif /* LINUX_VERSION_CODE */ unifi_priv_t *priv = interfacePriv->privPtr; struct uf_sched_data *q = qdisc_priv(qd); struct uf_tx_packet_data *pkt_data = (struct uf_tx_packet_data *) skb->cb; @@ -3338,11 +3304,7 @@ static int uf_qdiscop_requeue(struct sk_buff *skb, struct Qdisc* qd) static struct sk_buff *uf_qdiscop_dequeue(struct Qdisc* qd) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(qd->dev_queue->dev); -#else - netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(qd->dev); -#endif /* LINUX_VERSION_CODE */ unifi_priv_t *priv = interfacePriv->privPtr; struct uf_sched_data *q = qdisc_priv(qd); struct sk_buff *skb; @@ -3477,11 +3439,7 @@ static int uf_qdiscop_tune(struct Qdisc *qd, struct nlattr *opt) /* called during initial creation of qdisc on device */ static int uf_qdiscop_init(struct Qdisc *qd, struct nlattr *opt) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) struct net_device *dev = qd->dev_queue->dev; -#else - struct net_device *dev = qd->dev; -#endif /* LINUX_VERSION_CODE */ netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); unifi_priv_t *priv = interfacePriv->privPtr; struct uf_sched_data *q = qdisc_priv(qd); -- cgit v0.10.2 From a1a18726f48f290f18608653b1babf2ab27bffd1 Mon Sep 17 00:00:00 2001 From: Priit Laes Date: Sat, 1 Sep 2012 12:05:59 +0300 Subject: staging: csr: netdev.c: Clean up KERNEL_VERSION checks: 2.6.28 Signed-off-by: Priit Laes Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/csr/netdev.c b/drivers/staging/csr/netdev.c index c8f6d8e..63de717 100644 --- a/drivers/staging/csr/netdev.c +++ b/drivers/staging/csr/netdev.c @@ -66,7 +66,6 @@ */ #define ALLOW_Q_PAUSE -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) #ifdef UNIFI_NET_NAME #define UF_ALLOC_NETDEV(_dev, _size, _name, _setup, _num_of_queues) \ do { \ @@ -80,21 +79,6 @@ _dev = alloc_etherdev_mq(_size, _num_of_queues); \ } while (0); #endif /* UNIFI_NET_NAME */ -#else -#ifdef UNIFI_NET_NAME -#define UF_ALLOC_NETDEV(_dev, _size, _name, _setup, _num_of_queues) \ - do { \ - static char name[8]; \ - sprintf(name, "%s%s", UNIFI_NET_NAME, _name); \ - _dev = alloc_netdev(_size, name, _setup); \ - } while (0); -#else -#define UF_ALLOC_NETDEV(_dev, _size, _name, _setup, _num_of_queues) \ - do { \ - _dev = alloc_etherdev(_size); \ - } while (0); -#endif /* UNIFI_NET_NAME */ -#endif /* LINUX_VERSION_CODE */ /* Wext handler is suported only if CSR_SUPPORT_WEXT is defined */ @@ -115,9 +99,7 @@ static int uf_net_open(struct net_device *dev); static int uf_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static int uf_net_stop(struct net_device *dev); static struct net_device_stats *uf_net_get_stats(struct net_device *dev); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) static u16 uf_net_select_queue(struct net_device *dev, struct sk_buff *skb); -#endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) static netdev_tx_t uf_net_xmit(struct sk_buff *skb, struct net_device *dev); #else @@ -178,48 +160,6 @@ struct uf_tx_packet_data { unsigned long host_tag; }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) -static int uf_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd); -static int uf_qdiscop_requeue(struct sk_buff *skb, struct Qdisc* qd); -static struct sk_buff *uf_qdiscop_dequeue(struct Qdisc* qd); -static void uf_qdiscop_reset(struct Qdisc* qd); -static void uf_qdiscop_destroy(struct Qdisc* qd); -static int uf_qdiscop_dump(struct Qdisc *qd, struct sk_buff *skb); -static int uf_qdiscop_tune(struct Qdisc *qd, struct nlattr *opt); -static int uf_qdiscop_init(struct Qdisc *qd, struct nlattr *opt); -#endif - - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) -/* queueing discipline operations */ -static struct Qdisc_ops uf_qdisc_ops = -{ - .next = NULL, - .cl_ops = NULL, - .id = "UniFi Qdisc", - .priv_size = sizeof(struct uf_sched_data), - - .enqueue = uf_qdiscop_enqueue, - .dequeue = uf_qdiscop_dequeue, - .requeue = uf_qdiscop_requeue, - .drop = NULL, /* drop not needed since we are always the root qdisc */ - - .init = uf_qdiscop_init, - .reset = uf_qdiscop_reset, - .destroy = uf_qdiscop_destroy, - .change = uf_qdiscop_tune, - - .dump = uf_qdiscop_dump, -}; -#endif /* LINUX_VERSION_CODE */ - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) -#define UF_QDISC_CREATE_DFLT(_dev, _ops, _root) -#else -#define UF_QDISC_CREATE_DFLT(_dev, _ops, _root) \ - qdisc_create_dflt(dev, _ops) -#endif /* LINUX_VERSION_CODE */ - #endif /* CONFIG_NET_SCHED */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) @@ -329,10 +269,8 @@ uf_alloc_netdevice(CsrSdioFunction *sdio_dev, int bus_id) dev->get_stats = uf_net_get_stats; dev->set_multicast_list = uf_set_multicast_list; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) dev->select_queue = uf_net_select_queue; #endif -#endif #ifdef CSR_SUPPORT_WEXT dev->wireless_handlers = &unifi_iw_handler_def; @@ -472,16 +410,8 @@ uf_alloc_netdevice(CsrSdioFunction *sdio_dev, int bus_id) #endif #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) -#ifdef CONFIG_NET_SCHED - /* Register the qdisc operations */ - register_qdisc(&uf_qdisc_ops); -#endif /* CONFIG_NET_SCHED */ -#endif /* LINUX_VERSION_CODE */ - priv->ref_count = 1; - priv->amp_client = NULL; priv->coredump_mode = 0; priv->ptest_mode = 0; @@ -671,13 +601,6 @@ uf_free_netdevice(unifi_priv_t *priv) spin_unlock_irqrestore(&priv->wapi_lock, flags); #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) -#ifdef CONFIG_NET_SCHED - /* Unregister the qdisc operations */ - unregister_qdisc(&uf_qdisc_ops); -#endif /* CONFIG_NET_SCHED */ -#endif /* LINUX_VERSION_CODE */ - #ifdef CSR_SUPPORT_WEXT /* Unregister callback for netdevice state changes */ unregister_netdevice_notifier(&uf_netdev_notifier); @@ -940,7 +863,6 @@ get_packet_priority(unifi_priv_t *priv, struct sk_buff *skb, const struct ethhdr return priority; } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) /* * --------------------------------------------------------------------------- * uf_net_select_queue @@ -988,7 +910,6 @@ uf_net_select_queue(struct net_device *dev, struct sk_buff *skb) func_exit(); return (u16)queue; } /* uf_net_select_queue() */ -#endif int skb_add_llc_snap(struct net_device *dev, struct sk_buff *skb, int proto) @@ -1912,9 +1833,7 @@ uf_net_xmit(struct sk_buff *skb, struct net_device *dev) int result; static tx_signal_handler tx_handler; CSR_PRIORITY priority; -#if !defined (CONFIG_NET_SCHED) || (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)) CsrWifiRouterCtrlPortAction port_action; -#endif /* CONFIG_NET_SCHED */ func_enter(); @@ -1939,11 +1858,6 @@ uf_net_xmit(struct sk_buff *skb, struct net_device *dev) port = UF_UNCONTROLLED_PORT_Q; } -#if defined (CONFIG_NET_SCHED) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)) - /* Remove the ethernet header */ - skb_pull(skb, ETH_HLEN); - result = tx_handler(priv, skb, &ehdr, priority); -#else /* Uncontrolled port rules apply */ port_action = verify_port(priv , (((CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode)||(CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI== interfacePriv->interfaceMode))? interfacePriv->bssid.a: ehdr.h_dest) @@ -1969,7 +1883,6 @@ uf_net_xmit(struct sk_buff *skb, struct net_device *dev) func_exit(); return NETDEV_TX_OK; } -#endif /* CONFIG_NET_SCHED */ if (result == NETDEV_TX_OK) { #if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION)) @@ -2042,7 +1955,6 @@ unifi_pause_xmit(void *ospriv, unifi_TrafficQueue queue) func_enter(); unifi_trace(priv, UDBG2, "Stopping queue %d\n", queue); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) for(i=0;inetdev[i])) @@ -2050,24 +1962,6 @@ unifi_pause_xmit(void *ospriv, unifi_TrafficQueue queue) netif_stop_subqueue(priv->netdev[i], (u16)queue); } } -#else -#ifdef ALLOW_Q_PAUSE - unifi_trace(priv, UDBG2, "Stopping netif\n"); - /* stop the traffic from all the interfaces. */ - for(i=0;inetdev[i])) { - UF_NETIF_TX_STOP_ALL_QUEUES(priv->netdev[i]); - } - } -#else - if (net_is_tx_q_paused(priv, queue)) { - unifi_trace(priv, UDBG2, "Queue already stopped\n"); - return; - } - net_tx_q_pause(priv, queue); -#endif -#endif #ifdef CSR_SUPPORT_SME if(queue<=3) { @@ -2091,7 +1985,6 @@ unifi_restart_xmit(void *ospriv, unifi_TrafficQueue queue) func_enter(); unifi_trace(priv, UDBG2, "Waking queue %d\n", queue); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) for(i=0;inetdev[i])) @@ -2099,25 +1992,6 @@ unifi_restart_xmit(void *ospriv, unifi_TrafficQueue queue) netif_wake_subqueue(priv->netdev[i], (u16)queue); } } -#else -#ifdef ALLOW_Q_PAUSE - /* Need to supply queue number depending on Kernel support */ - /* Resume the traffic from all the interfaces */ - for(i=0;inetdev[i])) { - UF_NETIF_TX_WAKE_ALL_QUEUES(priv->netdev[i]); - } - } -#else - if (!(net_is_tx_q_paused(priv, queue))) { - unifi_trace(priv, UDBG2, "Queue already running\n"); - func_exit(); - return; - } - net_tx_q_unpause(priv, queue); -#endif -#endif #ifdef CSR_SUPPORT_SME if(queue <=3) { @@ -2332,11 +2206,7 @@ uf_resume_data_plane(unifi_priv_t *priv, int queue, { #ifdef CONFIG_NET_SCHED if (netif_running(priv->netdev[interfaceTag])) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) netif_tx_schedule_all(priv->netdev[interfaceTag]); -#else - netif_schedule(priv->netdev[interfaceTag]); -#endif /* LINUX_VERSION_CODE */ } #endif uf_process_rx_pending_queue(priv, queue, peer_address, 1,interfaceTag); @@ -3162,330 +3032,6 @@ void uf_net_get_name(struct net_device *dev, char *name, int len) } /* uf_net_get_name */ - - - - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) -#ifdef CONFIG_NET_SCHED - -/* - * --------------------------------------------------------------------------- - * uf_install_qdisc - * - * Creates a root qdisc, registers our qdisc handlers and - * overrides the device's qdisc_sleeping to prevent the system - * from creating a new one for our network device. - * - * Arguments: - * dev Pointer to the network device. - * - * Returns: - * 0 on success, Linux error code otherwise. - * - * Notes: - * This function holds the qdisk lock so it needs to be called - * after registering the network device in uf_register_netdev(). - * Also, the qdisc_create_dflt() API has changed in 2.6.20 to - * include the parentid. - * --------------------------------------------------------------------------- - */ -int uf_install_qdisc(struct net_device *dev) -{ - struct Qdisc *qdisc; - struct netdev_queue *queue0; - - - func_enter(); - - qdisc = UF_QDISC_CREATE_DFLT(dev, &uf_qdisc_ops, TC_H_ROOT); - if (!qdisc) { - unifi_error(NULL, "%s: qdisc installation failed\n", dev->name); - func_exit_r(-EFAULT); - return -EFAULT; - } - unifi_trace(NULL, UDBG5, "%s: parent qdisc=0x%p\n", - dev->name, qdisc); - - qdisc->handle = 0x80020000; - qdisc->flags = 0x0; - - queue0 = netdev_get_tx_queue(dev, 0); - if (queue0 == NULL) { - unifi_error(NULL, "%s: netdev_get_tx_queue returned no queue\n", - dev->name); - func_exit_r(-EFAULT); - return -EFAULT; - } - queue0->qdisc = qdisc; - queue0->qdisc_sleeping = qdisc; - - func_exit_r(0); - return 0; - -} /* uf_install_qdisc() */ - -static int uf_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd) -{ - netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(qd->dev_queue->dev); - unifi_priv_t *priv = interfacePriv->privPtr; - struct uf_sched_data *q = qdisc_priv(qd); - struct uf_tx_packet_data *pkt_data = (struct uf_tx_packet_data *) skb->cb; - struct ethhdr ehdr; - struct Qdisc *qdisc; - int r, proto; - - func_enter(); - - memcpy(&ehdr, skb->data, ETH_HLEN); - proto = ntohs(ehdr.h_proto); - - /* 802.1x - apply controlled/uncontrolled port rules */ - if ((proto != ETH_P_PAE) -#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE - && (proto != ETH_P_WAI) -#endif - ) { - /* queues 0 - 3 */ - pkt_data->priority = get_packet_priority(priv, skb, &ehdr, interfacePriv); - pkt_data->queue = unifi_frame_priority_to_queue(pkt_data->priority); - } else { - pkt_data->queue = UNIFI_TRAFFIC_Q_EAPOL; - } - - qdisc = q->queues[pkt_data->queue]; - r = qdisc->enqueue(skb, qdisc); - if (r == NET_XMIT_SUCCESS) { - qd->q.qlen++; - qd->bstats.bytes += skb->len; - qd->bstats.packets++; - func_exit_r(NET_XMIT_SUCCESS); - return NET_XMIT_SUCCESS; - } - - unifi_error(priv, "uf_qdiscop_enqueue: dropped\n"); - qd->qstats.drops++; - - func_exit_r(r); - return r; - -} /* uf_qdiscop_enqueue() */ - - -static int uf_qdiscop_requeue(struct sk_buff *skb, struct Qdisc* qd) -{ - netInterface_priv_t *interfacePriv = (netInterface_priv_t*)netdev_priv(qd->dev_queue->dev); - unifi_priv_t *priv = interfacePriv->privPtr; - struct uf_sched_data *q = qdisc_priv(qd); - struct uf_tx_packet_data *pkt_data = (struct uf_tx_packet_data *) skb->cb; - struct Qdisc *qdisc; - int r; - - func_enter(); - - unifi_trace(priv, UDBG5, "uf_qdiscop_requeue: (q=%d), tag=%u\n", - pkt_data->queue, pkt_data->host_tag); - - /* we recorded which queue to use earlier! */ - qdisc = q->queues[pkt_data->queue]; - - if ((r = qdisc->ops->requeue(skb, qdisc)) == 0) { - qd->q.qlen++; - func_exit_r(0); - return 0; - } - - unifi_error(priv, "uf_qdiscop_requeue: dropped\n"); - qd->qstats.drops++; - - func_exit_r(r); - return r; -} /* uf_qdiscop_requeue() */ - -static struct sk_buff *uf_qdiscop_dequeue(struct Qdisc* qd) -{ - netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(qd->dev_queue->dev); - unifi_priv_t *priv = interfacePriv->privPtr; - struct uf_sched_data *q = qdisc_priv(qd); - struct sk_buff *skb; - struct Qdisc *qdisc; - int queue, i; - struct ethhdr ehdr; - struct uf_tx_packet_data *pkt_data; - CsrWifiRouterCtrlPortAction port_action; - - func_enter(); - - /* check all the queues */ - for (i = UNIFI_TRAFFIC_Q_MAX - 1; i >= 0; i--) { - - if (i != UNIFI_TRAFFIC_Q_EAPOL) { - queue = priv->prev_queue; - if (++priv->prev_queue >= UNIFI_TRAFFIC_Q_EAPOL) { - priv->prev_queue = 0; - } - } else { - queue = i; - } - -#ifndef ALLOW_Q_PAUSE - /* If queue is paused, do not dequeue */ - if (net_is_tx_q_paused(priv, queue)) { - unifi_trace(priv, UDBG5, - "uf_qdiscop_dequeue: tx queue paused (q=%d)\n", queue); - continue; - } -#endif - - qdisc = q->queues[queue]; - skb = qdisc->dequeue(qdisc); - if (skb) { - /* A packet has been dequeued, decrease the queued packets count */ - qd->q.qlen--; - - pkt_data = (struct uf_tx_packet_data *) skb->cb; - - /* Check the (un)controlled port status */ - memcpy(&ehdr, skb->data, ETH_HLEN); - - port_action = verify_port(priv - , (((CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) ||(CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI == interfacePriv->interfaceMode))? interfacePriv->bssid.a: ehdr.h_dest) - , (UNIFI_TRAFFIC_Q_EAPOL == queue? UF_UNCONTROLLED_PORT_Q: UF_CONTROLLED_PORT_Q) - , interfacePriv->InterfaceTag); - - /* Dequeue packet if port is open */ - if (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN) { - unifi_trace(priv, UDBG5, - "uf_qdiscop_dequeue: new (q=%d), tag=%u\n", - queue, pkt_data->host_tag); - - func_exit(); - return skb; - } - - /* Discard or block the packet if necessary */ - if (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD) { - unifi_trace(priv, UDBG5, - "uf_qdiscop_dequeue: drop (q=%d), tag=%u\n", - queue, pkt_data->host_tag); - kfree_skb(skb); - break; - } - - /* We can not send the packet now, put it back to the queue */ - if (qdisc->ops->requeue(skb, qdisc) != 0) { - unifi_error(priv, - "uf_qdiscop_dequeue: requeue (q=%d) failed, tag=%u, drop it\n", - queue, pkt_data->host_tag); - - /* Requeue failed, drop the packet */ - kfree_skb(skb); - break; - } - /* We requeued the packet, increase the queued packets count */ - qd->q.qlen++; - - unifi_trace(priv, UDBG5, - "uf_qdiscop_dequeue: skip (q=%d), tag=%u\n", - queue, pkt_data->host_tag); - } - } - - func_exit(); - return NULL; -} /* uf_qdiscop_dequeue() */ - - -static void uf_qdiscop_reset(struct Qdisc* qd) -{ - struct uf_sched_data *q = qdisc_priv(qd); - int queue; - func_enter(); - - for (queue = 0; queue < UNIFI_TRAFFIC_Q_MAX; queue++) { - qdisc_reset(q->queues[queue]); - } - qd->q.qlen = 0; - - func_exit(); -} /* uf_qdiscop_reset() */ - - -static void uf_qdiscop_destroy(struct Qdisc* qd) -{ - struct uf_sched_data *q = qdisc_priv(qd); - int queue; - - func_enter(); - - for (queue=0; queue < UNIFI_TRAFFIC_Q_MAX; queue++) { - qdisc_destroy(q->queues[queue]); - q->queues[queue] = &noop_qdisc; - } - - func_exit(); -} /* uf_qdiscop_destroy() */ - - -/* called whenever parameters are updated on existing qdisc */ -static int uf_qdiscop_tune(struct Qdisc *qd, struct nlattr *opt) -{ - func_enter(); - func_exit(); - return 0; -} /* uf_qdiscop_tune() */ - - -/* called during initial creation of qdisc on device */ -static int uf_qdiscop_init(struct Qdisc *qd, struct nlattr *opt) -{ - struct net_device *dev = qd->dev_queue->dev; - netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); - unifi_priv_t *priv = interfacePriv->privPtr; - struct uf_sched_data *q = qdisc_priv(qd); - int err = 0, i; - - func_enter(); - - /* make sure we do not mess with the ingress qdisc */ - if (qd->flags & TCQ_F_INGRESS) { - func_exit(); - return -EINVAL; - } - - /* if options were passed in, set them */ - if (opt) { - err = uf_qdiscop_tune(qd, opt); - } - - /* create child queues */ - for (i = 0; i < UNIFI_TRAFFIC_Q_MAX; i++) { - q->queues[i] = UF_QDISC_CREATE_DFLT(dev, &pfifo_qdisc_ops, - qd->handle); - if (!q->queues[i]) { - q->queues[i] = &noop_qdisc; - unifi_error(priv, "%s child qdisc %i creation failed\n"); - } - - unifi_trace(priv, UDBG5, "%s: child qdisc=0x%p\n", - dev->name, q->queues[i]); - } - - func_exit_r(err); - return err; -} /* uf_qdiscop_init() */ - - -static int uf_qdiscop_dump(struct Qdisc *qd, struct sk_buff *skb) -{ - func_enter(); - func_exit_r(skb->len); - return skb->len; -} /* uf_qdiscop_dump() */ - -#endif /* CONFIG_NET_SCHED */ -#endif /* LINUX_VERSION_CODE */ - #ifdef CSR_SUPPORT_WEXT /* -- cgit v0.10.2 From 96bc8c7ab85b0ed27190a66f05d1677953b8bfb3 Mon Sep 17 00:00:00 2001 From: Priit Laes Date: Sat, 1 Sep 2012 12:06:00 +0300 Subject: staging: csr: netdev.c: Clean up KERNEL_VERSION checks: 2.6.29 Signed-off-by: Priit Laes Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/csr/netdev.c b/drivers/staging/csr/netdev.c index 63de717..8b46280 100644 --- a/drivers/staging/csr/netdev.c +++ b/drivers/staging/csr/netdev.c @@ -162,7 +162,6 @@ struct uf_tx_packet_data { #endif /* CONFIG_NET_SCHED */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) static const struct net_device_ops uf_netdev_ops = { .ndo_open = uf_net_open, @@ -173,7 +172,6 @@ static const struct net_device_ops uf_netdev_ops = .ndo_set_rx_mode = uf_set_multicast_list, .ndo_select_queue = uf_net_select_queue, }; -#endif static u8 oui_rfc1042[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 }; static u8 oui_8021h[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 }; @@ -257,20 +255,7 @@ uf_alloc_netdevice(CsrSdioFunction *sdio_dev, int bus_id) priv->interfacePriv[0] = interfacePriv; /* Setup / override net_device fields */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) dev->netdev_ops = &uf_netdev_ops; -#else - dev->open = uf_net_open; - dev->stop = uf_net_stop; - dev->hard_start_xmit = uf_net_xmit; - dev->do_ioctl = uf_net_ioctl; - - /* called by /proc/net/dev */ - dev->get_stats = uf_net_get_stats; - - dev->set_multicast_list = uf_set_multicast_list; - dev->select_queue = uf_net_select_queue; -#endif #ifdef CSR_SUPPORT_WEXT dev->wireless_handlers = &unifi_iw_handler_def; @@ -504,19 +489,7 @@ uf_alloc_netdevice_for_other_interfaces(unifi_priv_t *priv, u16 interfaceTag) INIT_LIST_HEAD(&interfacePriv->rx_controlled_list); /* Setup / override net_device fields */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) dev->netdev_ops = &uf_netdev_ops; -#else - dev->open = uf_net_open; - dev->stop = uf_net_stop; - dev->hard_start_xmit = uf_net_xmit; - dev->do_ioctl = uf_net_ioctl; - - /* called by /proc/net/dev */ - dev->get_stats = uf_net_get_stats; - - dev->set_multicast_list = uf_set_multicast_list; -#endif #ifdef CSR_SUPPORT_WEXT dev->wireless_handlers = &unifi_iw_handler_def; -- cgit v0.10.2 From 99b2c9d77eaa1f9a52cad4432631c9e7a741ac6b Mon Sep 17 00:00:00 2001 From: Priit Laes Date: Sat, 1 Sep 2012 12:06:01 +0300 Subject: staging: csr: netdev.c: Clean up KERNEL_VERSION checks: 2.6.32 Signed-off-by: Priit Laes Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/csr/netdev.c b/drivers/staging/csr/netdev.c index 8b46280..371e0a0 100644 --- a/drivers/staging/csr/netdev.c +++ b/drivers/staging/csr/netdev.c @@ -100,17 +100,7 @@ static int uf_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static int uf_net_stop(struct net_device *dev); static struct net_device_stats *uf_net_get_stats(struct net_device *dev); static u16 uf_net_select_queue(struct net_device *dev, struct sk_buff *skb); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) static netdev_tx_t uf_net_xmit(struct sk_buff *skb, struct net_device *dev); -#else -static int uf_net_xmit(struct sk_buff *skb, struct net_device *dev); -#ifndef NETDEV_TX_OK -#define NETDEV_TX_OK 0 -#endif -#ifndef NETDEV_TX_BUSY -#define NETDEV_TX_BUSY 1 -#endif -#endif static void uf_set_multicast_list(struct net_device *dev); @@ -1792,11 +1782,7 @@ send_ma_pkt_request(unifi_priv_t *priv, struct sk_buff *skb, const struct ethhdr * The controlled port is handled in the qdisc dequeue handler. * --------------------------------------------------------------------------- */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) static netdev_tx_t -#else -static int -#endif uf_net_xmit(struct sk_buff *skb, struct net_device *dev) { netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); -- cgit v0.10.2 From 6d99c525a0a1e981d89cc8f42b721f5973e684dd Mon Sep 17 00:00:00 2001 From: Priit Laes Date: Sat, 1 Sep 2012 12:06:02 +0300 Subject: staging: csr: netdev.c: Clean up KERNEL_VERSION checks: 2.6.34 Signed-off-by: Priit Laes Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/csr/netdev.c b/drivers/staging/csr/netdev.c index 371e0a0..01ec08e 100644 --- a/drivers/staging/csr/netdev.c +++ b/drivers/staging/csr/netdev.c @@ -2808,19 +2808,13 @@ uf_set_multicast_list(struct net_device *dev) #else u8 *mc_list = interfacePriv->mc_list; -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,34) struct netdev_hw_addr *mc_addr; int mc_addr_count; -#else - struct dev_mc_list *p; /* Pointer to the addresses structure. */ - int i; -#endif if (priv->init_progress != UNIFI_INIT_COMPLETED) { return; } -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,34) mc_addr_count = netdev_mc_count(dev); unifi_trace(priv, UDBG3, @@ -2839,25 +2833,6 @@ uf_set_multicast_list(struct net_device *dev) mc_list += ETH_ALEN; } -#else - unifi_trace(priv, UDBG3, - "uf_set_multicast_list (count=%d)\n", dev->mc_count); - - /* Not enough space? */ - if (dev->mc_count > UNIFI_MAX_MULTICAST_ADDRESSES) { - return; - } - - /* Store the list to be processed by the work item. */ - interfacePriv->mc_list_count = dev->mc_count; - p = dev->mc_list; - for (i = 0; i < dev->mc_count; i++) { - memcpy(mc_list, p->dmi_addr, ETH_ALEN); - p = p->next; - mc_list += ETH_ALEN; - } -#endif - /* Send a message to the workqueue */ queue_work(priv->unifi_workqueue, &priv->multicast_list_task); #endif -- cgit v0.10.2 From 879a901f7eb6271d82da40cfb3c5bc3b6bb5c3fe Mon Sep 17 00:00:00 2001 From: Priit Laes Date: Sat, 1 Sep 2012 12:06:03 +0300 Subject: staging: csr: netdev.c: Clean up KERNEL_VERSION checks: 2.6.37 Signed-off-by: Priit Laes Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/csr/netdev.c b/drivers/staging/csr/netdev.c index 01ec08e..6fac068 100644 --- a/drivers/staging/csr/netdev.c +++ b/drivers/staging/csr/netdev.c @@ -338,21 +338,13 @@ uf_alloc_netdevice(CsrSdioFunction *sdio_dev, int bus_id) interfacePriv->connected = UnifiConnectedUnknown; /* -1 unknown, 0 no, 1 yes */ #ifdef USE_DRIVER_LOCK -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37) sema_init(&priv->lock, 1); -#else - init_MUTEX(&priv->lock); -#endif #endif /* USE_DRIVER_LOCK */ spin_lock_init(&priv->send_signal_lock); spin_lock_init(&priv->m4_lock); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37) sema_init(&priv->ba_mutex, 1); -#else - init_MUTEX(&priv->ba_mutex); -#endif #if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION)) spin_lock_init(&priv->wapi_lock); -- cgit v0.10.2 From 6e5e4043bc72a702fea3646793dcd3dda9258b87 Mon Sep 17 00:00:00 2001 From: Priit Laes Date: Sat, 1 Sep 2012 12:06:04 +0300 Subject: staging: csr: remove unused define ALLOW_Q_PAUSE Signed-off-by: Priit Laes Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/csr/netdev.c b/drivers/staging/csr/netdev.c index 6fac068..510dc51 100644 --- a/drivers/staging/csr/netdev.c +++ b/drivers/staging/csr/netdev.c @@ -55,17 +55,6 @@ #include -/* ALLOW_Q_PAUSE: Pre 2.6.28 kernels do not support multiple driver queues (required for QoS). - * In order to support QoS in these kernels, multiple queues are implemented in the driver. But since - * there is only a single queue in the kernel (leading to multiple queues in the driver) there is no possibility - * of stopping a particular queue in the kernel. Stopping the single kernel queue leads to undesirable starvation - * of driver queues. One of the proposals is to not stop the kernel queue but to prevent dequeuing from the - * 'stopped' driver queue. Allow q pause is an experimental implementation of this scheme for pre 2.6.28 kernels. - * When NOT defined, queues are paused locally in the driver and packets are dequeued for transmission only from the - * unpaused queues. When Allow q pause is defined the kernel queue is stopped whenever any driver queue is paused. - */ -#define ALLOW_Q_PAUSE - #ifdef UNIFI_NET_NAME #define UF_ALLOC_NETDEV(_dev, _size, _name, _setup, _num_of_queues) \ do { \ diff --git a/drivers/staging/csr/unifi_priv.h b/drivers/staging/csr/unifi_priv.h index 6d6b461..1dee840 100644 --- a/drivers/staging/csr/unifi_priv.h +++ b/drivers/staging/csr/unifi_priv.h @@ -634,12 +634,10 @@ struct unifi_priv { spinlock_t wapi_lock; #endif -#ifndef ALLOW_Q_PAUSE /* Array to indicate if a particular Tx queue is paused, this may not be * required in a multiqueue implementation since we can directly stop kernel * queues */ u8 tx_q_paused_flag[UNIFI_TRAFFIC_Q_MAX]; -#endif #ifdef CSR_WIFI_RX_PATH_SPLIT struct workqueue_struct *rx_workqueue; @@ -798,12 +796,6 @@ typedef struct netInterface_priv u8 bcTimSetReqQueued; } netInterface_priv_t; -#ifndef ALLOW_Q_PAUSE -#define net_is_tx_q_paused(priv, q) (priv->tx_q_paused_flag[q]) -#define net_tx_q_unpause(priv, q) (priv->tx_q_paused_flag[q] = 0) -#define net_tx_q_pause(priv, q) (priv->tx_q_paused_flag[q] = 1) -#endif - #ifdef CSR_SUPPORT_SME #define routerStartBuffering(priv,queue) priv->routerBufferEnable[(queue)] = TRUE; #define routerStopBuffering(priv,queue) priv->routerBufferEnable[(queue)] = FALSE; -- cgit v0.10.2 From 6e9950a62bfa4c9a286979f4b2067982f40bfb2f Mon Sep 17 00:00:00 2001 From: Priit Laes Date: Sat, 1 Sep 2012 12:06:05 +0300 Subject: staging: csr: Drop unused UNIFI_NET_NAME configuration option Signed-off-by: Priit Laes Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/csr/netdev.c b/drivers/staging/csr/netdev.c index 510dc51..31bd796 100644 --- a/drivers/staging/csr/netdev.c +++ b/drivers/staging/csr/netdev.c @@ -55,21 +55,6 @@ #include -#ifdef UNIFI_NET_NAME -#define UF_ALLOC_NETDEV(_dev, _size, _name, _setup, _num_of_queues) \ - do { \ - static char name[8]; \ - sprintf(name, "%s%s", UNIFI_NET_NAME, _name); \ - _dev = alloc_netdev_mq(_size, name, _setup, _num_of_queues); \ - } while (0); -#else -#define UF_ALLOC_NETDEV(_dev, _size, _name, _setup, _num_of_queues) \ - do { \ - _dev = alloc_etherdev_mq(_size, _num_of_queues); \ - } while (0); -#endif /* UNIFI_NET_NAME */ - - /* Wext handler is suported only if CSR_SUPPORT_WEXT is defined */ #ifdef CSR_SUPPORT_WEXT extern struct iw_handler_def unifi_iw_handler_def; @@ -212,7 +197,7 @@ uf_alloc_netdevice(CsrSdioFunction *sdio_dev, int bus_id) * The RedHat 9 redhat-config-network tool doesn't recognise wlan* devices, * so use "eth*" (like other wireless extns drivers). */ - UF_ALLOC_NETDEV(dev, sizeof(unifi_priv_t)+sizeof(netInterface_priv_t), "%d", ether_setup, UNIFI_TRAFFIC_Q_MAX); + dev = alloc_etherdev_mq(sizeof(unifi_priv_t) + sizeof(netInterface_priv_t), UNIFI_TRAFFIC_Q_MAX); if (dev == NULL) { return NULL; @@ -437,7 +422,7 @@ uf_alloc_netdevice_for_other_interfaces(unifi_priv_t *priv, u16 interfaceTag) * The RedHat 9 redhat-config-network tool doesn't recognise wlan* devices, * so use "eth*" (like other wireless extns drivers). */ - UF_ALLOC_NETDEV(dev, sizeof(netInterface_priv_t), "%d", ether_setup, 1); + dev = alloc_etherdev_mq(sizeof(netInterface_priv_t), 1); if (dev == NULL) { return FALSE; } -- cgit v0.10.2 From b5008ae2373223d7d6591098754f161594a505ee Mon Sep 17 00:00:00 2001 From: Priit Laes Date: Sat, 1 Sep 2012 12:06:06 +0300 Subject: staging: csr: drv.c: Remove KERNEL_VERSION checks and associated defines Signed-off-by: Priit Laes Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/csr/drv.c b/drivers/staging/csr/drv.c index 9834d92..2497580 100644 --- a/drivers/staging/csr/drv.c +++ b/drivers/staging/csr/drv.c @@ -123,11 +123,7 @@ static void udi_set_log_filter(ul_client_t *pcli, /* Mutex to protect access to priv->sme_cli */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37) DEFINE_SEMAPHORE(udi_mutex); -#else -DECLARE_MUTEX(udi_mutex); -#endif s32 CsrHipResultToStatus(CsrResult csrResult) { @@ -1979,18 +1975,6 @@ uf_sme_queue_message(unifi_priv_t *priv, u8 *buffer, int length) } /* uf_sme_queue_message() */ #endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) -#define UF_DEVICE_CREATE(_class, _parent, _devno, _priv, _fmt, _args) \ - device_create(_class, _parent, _devno, _priv, _fmt, _args) -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) -#define UF_DEVICE_CREATE(_class, _parent, _devno, _priv, _fmt, _args) \ - device_create_drvdata(_class, _parent, _devno, _priv, _fmt, _args) -#else -#define UF_DEVICE_CREATE(_class, _parent, _devno, _priv, _fmt, _args) \ - device_create(_class, _parent, _devno, _fmt, _args) -#endif - /* **************************************************************************** * @@ -2008,17 +1992,6 @@ static struct file_operations unifi_fops = { .poll = unifi_poll, }; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) -#define UF_DEVICE_CREATE(_class, _parent, _devno, _priv, _fmt, _args) \ - device_create(_class, _parent, _devno, _priv, _fmt, _args) -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) -#define UF_DEVICE_CREATE(_class, _parent, _devno, _priv, _fmt, _args) \ - device_create_drvdata(_class, _parent, _devno, _priv, _fmt, _args) -#else -#define UF_DEVICE_CREATE(_class, _parent, _devno, _priv, _fmt, _args) \ - device_create(_class, _parent, _devno, _fmt, _args) -#endif - static dev_t unifi_first_devno; static struct class *unifi_class; @@ -2041,11 +2014,11 @@ int uf_create_device_nodes(unifi_priv_t *priv, int bus_id) } #ifdef SDIO_EXPORTS_STRUCT_DEVICE - if (!UF_DEVICE_CREATE(unifi_class, priv->unifi_device, - devno, priv, "unifi%d", bus_id)) { + if (!device_create(unifi_class, priv->unifi_device, + devno, priv, "unifi%d", bus_id)) { #else - priv->unifi_device = UF_DEVICE_CREATE(unifi_class, NULL, - devno, priv, "unifi%d", bus_id); + priv->unifi_device = device_create(unifi_class, NULL, + devno, priv, "unifi%d", bus_id); if (priv->unifi_device == NULL) { #endif /* SDIO_EXPORTS_STRUCT_DEVICE */ @@ -2067,13 +2040,13 @@ int uf_create_device_nodes(unifi_priv_t *priv, int bus_id) return r; } - if (!UF_DEVICE_CREATE(unifi_class, + if (!device_create(unifi_class, #ifdef SDIO_EXPORTS_STRUCT_DEVICE - priv->unifi_device, + priv->unifi_device, #else - NULL, + NULL, #endif /* SDIO_EXPORTS_STRUCT_DEVICE */ - devno, priv, "unifiudi%d", bus_id)) { + devno, priv, "unifiudi%d", bus_id)) { device_destroy(unifi_class, priv->unifi_cdev.dev); cdev_del(&priv->unifiudi_cdev); cdev_del(&priv->unifi_cdev); -- cgit v0.10.2 From 457d404c0abbaf90543e6b8130b805bc824b030a Mon Sep 17 00:00:00 2001 From: Priit Laes Date: Sat, 1 Sep 2012 12:06:07 +0300 Subject: staging: csr: unifi_wext.h: Remove KERNEL_VERSION checks Signed-off-by: Priit Laes Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/csr/unifi_wext.h b/drivers/staging/csr/unifi_wext.h index fc0a06a..6834c43 100644 --- a/drivers/staging/csr/unifi_wext.h +++ b/drivers/staging/csr/unifi_wext.h @@ -71,15 +71,9 @@ uf_iwe_stream_add_point(struct iw_request_info *info, char *start, char *stop, { char *new_start; - new_start = iwe_stream_add_point( -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) || defined (IW_REQUEST_FLAG_COMPAT) - info, -#endif - start, stop, piwe, extra); + new_start = iwe_stream_add_point(info, start, stop, piwe, extra); if (unlikely(new_start == start)) - { return -E2BIG; - } return (new_start - start); } @@ -91,14 +85,9 @@ uf_iwe_stream_add_event(struct iw_request_info *info, char *start, char *stop, { char *new_start; - new_start = iwe_stream_add_event( -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) || defined(IW_REQUEST_FLAG_COMPAT) - info, -#endif - start, stop, piwe, len); - if (unlikely(new_start == start)) { + new_start = iwe_stream_add_event(info, start, stop, piwe, len); + if (unlikely(new_start == start)) return -E2BIG; - } return (new_start - start); } @@ -109,14 +98,9 @@ uf_iwe_stream_add_value(struct iw_request_info *info, char *stream, char *start, { char *new_start; - new_start = iwe_stream_add_value( -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) || defined(IW_REQUEST_FLAG_COMPAT) - info, -#endif - stream, start, stop, piwe, len); - if (unlikely(new_start == start)) { + new_start = iwe_stream_add_value(info, stream, start, stop, piwe, len); + if (unlikely(new_start == start)) return -E2BIG; - } return (new_start - start); } -- cgit v0.10.2 From 59e6201d383a15e152611d245a7bdc1585b8c59c Mon Sep 17 00:00:00 2001 From: Priit Laes Date: Sat, 1 Sep 2012 12:06:08 +0300 Subject: staging: csr: unifi_priv.h: Remove KERNEL_VERSION checks Signed-off-by: Priit Laes Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/csr/unifi_priv.h b/drivers/staging/csr/unifi_priv.h index 1dee840..f634b31 100644 --- a/drivers/staging/csr/unifi_priv.h +++ b/drivers/staging/csr/unifi_priv.h @@ -29,9 +29,7 @@ #include #include #include -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19) #include -#endif #ifdef CSR_WIFI_SUPPORT_MMC_DRIVER #include @@ -73,31 +71,9 @@ extern struct wake_lock unifi_sdio_wake_lock; #include "unifi_clients.h" - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) -#include - -#undef INIT_WORK -#define INIT_WORK(_work, _func) \ - do { \ - INIT_LIST_HEAD(&(_work)->entry); \ - (_work)->pending = 0; \ - PREPARE_WORK((_work), (_func), (_work)); \ - init_timer(&(_work)->timer); \ - } while(0) - -#endif /* Linux kernel < 2.6.20 */ - - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) #define UF_NETIF_TX_WAKE_ALL_QUEUES(_netdev) netif_tx_wake_all_queues(_netdev) #define UF_NETIF_TX_START_ALL_QUEUES(_netdev) netif_tx_start_all_queues(_netdev) #define UF_NETIF_TX_STOP_ALL_QUEUES(_netdev) netif_tx_stop_all_queues(_netdev) -#else -#define UF_NETIF_TX_WAKE_ALL_QUEUES(_netdev) netif_wake_queue(_netdev) -#define UF_NETIF_TX_START_ALL_QUEUES(_netdev) netif_start_queue(_netdev) -#define UF_NETIF_TX_STOP_ALL_QUEUES(_netdev) netif_stop_queue(_netdev) -#endif /* Linux kernel >= 2.6.27 */ #ifdef CSR_NATIVE_LINUX @@ -1080,9 +1056,6 @@ CsrWifiRouterCtrlStaInfo_t * CsrWifiRouterCtrlGetStationRecordFromHandle(unifi_p void uf_update_sta_activity(unifi_priv_t *priv, u16 interfaceTag, const u8 *peerMacAddress); void uf_process_ma_pkt_cfm_for_ap(unifi_priv_t *priv,u16 interfaceTag, const CSR_MA_PACKET_CONFIRM *pkt_cfm); #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) -int uf_install_qdisc(struct net_device *dev); -#endif void uf_resume_data_plane(unifi_priv_t *priv, int queue, CsrWifiMacAddress peer_address, -- cgit v0.10.2 From 4febd649bbaaff71dae4cb7bda5473e92c590e01 Mon Sep 17 00:00:00 2001 From: Priit Laes Date: Sat, 1 Sep 2012 12:06:09 +0300 Subject: staging: csr: Remove unneeded UF_NETIF_TX_* macros Signed-off-by: Priit Laes Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/csr/io.c b/drivers/staging/csr/io.c index 4774dc8..4c929b2 100644 --- a/drivers/staging/csr/io.c +++ b/drivers/staging/csr/io.c @@ -669,7 +669,7 @@ unregister_unifi_sdio(int bus_id) if(interfacePriv->netdev_registered) { netif_carrier_off(priv->netdev[interfaceTag]); - UF_NETIF_TX_STOP_ALL_QUEUES(priv->netdev[interfaceTag]); + netif_tx_stop_all_queues(priv->netdev[interfaceTag]); } } diff --git a/drivers/staging/csr/netdev.c b/drivers/staging/csr/netdev.c index 31bd796..9a52ab4 100644 --- a/drivers/staging/csr/netdev.c +++ b/drivers/staging/csr/netdev.c @@ -613,7 +613,7 @@ uf_net_open(struct net_device *dev) } #endif - UF_NETIF_TX_START_ALL_QUEUES(dev); + netif_tx_start_all_queues(dev); func_exit(); return 0; @@ -643,7 +643,7 @@ uf_net_stop(struct net_device *dev) func_enter(); #endif - UF_NETIF_TX_STOP_ALL_QUEUES(dev); + netif_tx_stop_all_queues(dev); func_exit(); return 0; @@ -2977,7 +2977,7 @@ uf_netdev_event(struct notifier_block *notif, unsigned long event, void* ptr) { interfacePriv->wait_netdev_change ? "" : "not"); if (interfacePriv->wait_netdev_change) { - UF_NETIF_TX_WAKE_ALL_QUEUES(priv->netdev[interfacePriv->InterfaceTag]); + netif_tx_wake_all_queues(priv->netdev[interfacePriv->InterfaceTag]); interfacePriv->connected = UnifiConnected; interfacePriv->wait_netdev_change = FALSE; /* Note: passing the broadcast address here will allow anyone to attempt to join our adhoc network */ diff --git a/drivers/staging/csr/sdio_events.c b/drivers/staging/csr/sdio_events.c index 6892c2e..2a80b9e 100644 --- a/drivers/staging/csr/sdio_events.c +++ b/drivers/staging/csr/sdio_events.c @@ -66,7 +66,7 @@ void unifi_suspend(void *ospriv) unifi_trace(priv, UDBG1, "unifi_suspend: netif_carrier_off"); netif_carrier_off(priv->netdev[interfaceTag]); } - UF_NETIF_TX_STOP_ALL_QUEUES(priv->netdev[interfaceTag]); + netif_tx_stop_all_queues(priv->netdev[interfaceTag]); } } @@ -119,7 +119,7 @@ void unifi_resume(void *ospriv) if (interfacePriv->netdev_registered == 1) { netif_carrier_on(priv->netdev[interfaceTag]); - UF_NETIF_TX_START_ALL_QUEUES(priv->netdev[interfaceTag]); + netif_tx_start_all_queues(priv->netdev[interfaceTag]); } } diff --git a/drivers/staging/csr/sme_sys.c b/drivers/staging/csr/sme_sys.c index 7ff3f43..0c61e75 100644 --- a/drivers/staging/csr/sme_sys.c +++ b/drivers/staging/csr/sme_sys.c @@ -192,7 +192,7 @@ void CsrWifiRouterCtrlMediaStatusReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) #endif unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlMediaStatusReqHandler: AP/P2PGO setting netif_carrier_on\n"); - UF_NETIF_TX_WAKE_ALL_QUEUES(priv->netdev[req->interfaceTag]); + netif_tx_wake_all_queues(priv->netdev[req->interfaceTag]); break; default: @@ -226,7 +226,7 @@ void CsrWifiRouterCtrlMediaStatusReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) unifi_trace(priv, UDBG1, "CsrWifiRouterMediaStatusReqHandler: UnifiConnected && netif_carrier_on\n"); netif_carrier_on(priv->netdev[req->interfaceTag]); - UF_NETIF_TX_WAKE_ALL_QUEUES(priv->netdev[req->interfaceTag]); + netif_tx_wake_all_queues(priv->netdev[req->interfaceTag]); uf_process_rx_pending_queue(priv, UF_UNCONTROLLED_PORT_Q, broadcast_address, 1, interfacePriv->InterfaceTag); uf_process_rx_pending_queue(priv, UF_CONTROLLED_PORT_Q, broadcast_address, 1, interfacePriv->InterfaceTag); } @@ -955,7 +955,7 @@ void CsrWifiRouterCtrlWifiOffReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) netInterface_priv_t *interfacePriv = priv->interfacePriv[i]; if (interfacePriv->netdev_registered == 1) { netif_carrier_off(priv->netdev[i]); - UF_NETIF_TX_STOP_ALL_QUEUES(priv->netdev[i]); + netif_tx_stop_all_queues(priv->netdev[i]); interfacePriv->connected = UnifiConnectedUnknown; } interfacePriv->interfaceMode = 0; diff --git a/drivers/staging/csr/unifi_priv.h b/drivers/staging/csr/unifi_priv.h index f634b31..aec8e28 100644 --- a/drivers/staging/csr/unifi_priv.h +++ b/drivers/staging/csr/unifi_priv.h @@ -71,11 +71,6 @@ extern struct wake_lock unifi_sdio_wake_lock; #include "unifi_clients.h" -#define UF_NETIF_TX_WAKE_ALL_QUEUES(_netdev) netif_tx_wake_all_queues(_netdev) -#define UF_NETIF_TX_START_ALL_QUEUES(_netdev) netif_tx_start_all_queues(_netdev) -#define UF_NETIF_TX_STOP_ALL_QUEUES(_netdev) netif_tx_stop_all_queues(_netdev) - - #ifdef CSR_NATIVE_LINUX #include "sme_native/unifi_native.h" #else -- cgit v0.10.2 From 34f86d06f07cdf87598daa1588a08110047c0b2f Mon Sep 17 00:00:00 2001 From: Priit Laes Date: Sat, 1 Sep 2012 12:06:10 +0300 Subject: staging: csr: Remove all leftover kernel version checks \o/ Signed-off-by: Priit Laes Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/csr/csr_framework_ext.c b/drivers/staging/csr/csr_framework_ext.c index 12e7ddf..f91a4bf 100644 --- a/drivers/staging/csr/csr_framework_ext.c +++ b/drivers/staging/csr/csr_framework_ext.c @@ -12,20 +12,9 @@ #include #include #include - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34) -#include -#endif - -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 19) #include -#endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27) -#include -#else #include -#endif - +#include #include #include "csr_framework_ext.h" diff --git a/drivers/staging/csr/csr_time.c b/drivers/staging/csr/csr_time.c index 2043f25..7b597f7 100644 --- a/drivers/staging/csr/csr_time.c +++ b/drivers/staging/csr/csr_time.c @@ -10,13 +10,6 @@ #include #include - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33) -#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16) -#include -#include -#endif - #include #include diff --git a/drivers/staging/csr/io.c b/drivers/staging/csr/io.c index 4c929b2..caf48e3 100644 --- a/drivers/staging/csr/io.c +++ b/drivers/staging/csr/io.c @@ -70,11 +70,7 @@ static int In_use[MAX_UNIFI_DEVS]; * Mutex to prevent UDI clients to open the character device before the priv * is created and initialised. */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37) DEFINE_SEMAPHORE(Unifi_instance_mutex); -#else -DECLARE_MUTEX(Unifi_instance_mutex); -#endif /* * When the device is removed, unregister waits on Unifi_cleanup_wq * until all the UDI clients release the character device. @@ -177,21 +173,6 @@ uf_register_netdev(unifi_priv_t *priv, int interfaceTag) /* The device is registed */ interfacePriv->netdev_registered = 1; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) -#ifdef CONFIG_NET_SCHED - /* - * IMPORTANT: - * uf_install_qdisc() holds the network device lock, we can not - * install the qdisk before the network device is registered. - */ - r = uf_install_qdisc(priv->netdev[interfaceTag]); - if (r) { - unifi_error(priv, "Failed to install qdisc\n"); - return r; - } -#endif /* CONFIG_NET_SCHED */ -#endif /* LINUX_VERSION_CODE */ - #ifdef CSR_SUPPORT_SME /* * Register the inet handler; it notifies us for changes in the IP address. diff --git a/drivers/staging/csr/monitor.c b/drivers/staging/csr/monitor.c index ca7559b..7c524a1 100644 --- a/drivers/staging/csr/monitor.c +++ b/drivers/staging/csr/monitor.c @@ -191,11 +191,7 @@ netrx_radiotap(unifi_priv_t *priv, skb->dev = dev; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) skb->mac_header = skb->data; -#else - skb->mac.raw = skb->data; -#endif skb->pkt_type = PACKET_OTHERHOST; skb->protocol = __constant_htons(ETH_P_80211_RAW); memset(skb->cb, 0, sizeof(skb->cb)); diff --git a/drivers/staging/csr/sdio_mmc.c b/drivers/staging/csr/sdio_mmc.c index dd82ea4..af3e40b 100644 --- a/drivers/staging/csr/sdio_mmc.c +++ b/drivers/staging/csr/sdio_mmc.c @@ -31,7 +31,6 @@ struct wake_lock unifi_sdio_wake_lock; /* wakelock to prevent suspend while resu static CsrSdioFunctionDriver *sdio_func_drv; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) #ifdef CONFIG_PM static int uf_sdio_mmc_power_event(struct notifier_block *this, unsigned long event, void *ptr); #endif @@ -45,7 +44,6 @@ static int uf_sdio_mmc_power_event(struct notifier_block *this, unsigned long ev * returning immediately (at least on x86). */ static int card_is_powered = 1; -#endif /* 2.6.32 */ /* MMC uses ENOMEDIUM to indicate card gone away */ @@ -637,7 +635,6 @@ CsrSdioFunctionIdle(CsrSdioFunction *function) CsrResult CsrSdioPowerOn(CsrSdioFunction *function) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) struct sdio_func *func = (struct sdio_func *)function->priv; struct mmc_host *host = func->card->host; @@ -649,7 +646,6 @@ CsrSdioPowerOn(CsrSdioFunction *function) printk(KERN_INFO "SDIO: Skip power on; card is already powered.\n"); } _sdio_release_host(func); -#endif /* 2.6.32 */ return CSR_RESULT_SUCCESS; } /* CsrSdioPowerOn() */ @@ -667,7 +663,6 @@ CsrSdioPowerOn(CsrSdioFunction *function) void CsrSdioPowerOff(CsrSdioFunction *function) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) struct sdio_func *func = (struct sdio_func *)function->priv; struct mmc_host *host = func->card->host; @@ -679,7 +674,6 @@ CsrSdioPowerOff(CsrSdioFunction *function) printk(KERN_INFO "SDIO: Skip power off; card is already powered off.\n"); } _sdio_release_host(func); -#endif /* 2.6.32 */ } /* CsrSdioPowerOff() */ @@ -894,7 +888,6 @@ int csr_sdio_linux_install_irq(CsrSdioFunction *function) return r; } /* csr_sdio_linux_install_irq() */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) #ifdef CONFIG_PM /* @@ -1020,7 +1013,6 @@ uf_sdio_mmc_power_event(struct notifier_block *this, unsigned long event, void * } #endif /* CONFIG_PM */ -#endif /* 2.6.32 */ /* * --------------------------------------------------------------------------- @@ -1047,10 +1039,8 @@ uf_glue_sdio_probe(struct sdio_func *func, /* First of all claim the SDIO driver */ sdio_claim_host(func); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) /* Assume that the card is already powered */ card_is_powered = 1; -#endif /* Assumes one card per host, which is true for SDIO */ instance = func->card->host->index; @@ -1090,14 +1080,12 @@ uf_glue_sdio_probe(struct sdio_func *func, /* Pass context to the SDIO driver */ sdio_set_drvdata(func, sdio_ctx); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) #ifdef CONFIG_PM /* Register to get PM events */ if (uf_sdio_mmc_register_pm_notifier(sdio_ctx) == NULL) { unifi_error(NULL, "%s: Failed to register for PM events\n", __FUNCTION__); } #endif -#endif /* Register this device with the SDIO function driver */ /* Call the main UniFi driver inserted handler */ @@ -1153,12 +1141,10 @@ uf_glue_sdio_remove(struct sdio_func *func) sdio_func_drv->removed(sdio_ctx); } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) #ifdef CONFIG_PM /* Unregister for PM events */ uf_sdio_mmc_unregister_pm_notifier(sdio_ctx); #endif -#endif kfree(sdio_ctx); @@ -1179,7 +1165,6 @@ static const struct sdio_device_id unifi_ids[] = { MODULE_DEVICE_TABLE(sdio, unifi_ids); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) #ifdef CONFIG_PM /* @@ -1249,16 +1234,13 @@ static struct dev_pm_ops unifi_pm_ops = { #define UNIFI_PM_OPS NULL #endif /* CONFIG_PM */ -#endif /* 2.6.32 */ static struct sdio_driver unifi_driver = { .probe = uf_glue_sdio_probe, .remove = uf_glue_sdio_remove, .name = "unifi", .id_table = unifi_ids, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) .drv.pm = UNIFI_PM_OPS, -#endif /* 2.6.32 */ }; @@ -1302,12 +1284,10 @@ CsrSdioFunctionDriverRegister(CsrSdioFunctionDriver *sdio_drv) */ sdio_func_drv = sdio_drv; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) #ifdef CONFIG_PM /* Initialise PM notifier list */ INIT_LIST_HEAD(&uf_sdio_mmc_pm_notifiers.list); #endif -#endif /* Register ourself with mmc_core */ r = sdio_register_driver(&unifi_driver); diff --git a/drivers/staging/csr/sme_native.c b/drivers/staging/csr/sme_native.c index 845b654..d7a5125 100644 --- a/drivers/staging/csr/sme_native.c +++ b/drivers/staging/csr/sme_native.c @@ -24,11 +24,7 @@ uf_sme_init(unifi_priv_t *priv) { func_enter(); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37) sema_init(&priv->mlme_blocking_mutex, 1); -#else - init_MUTEX(&priv->mlme_blocking_mutex); -#endif #ifdef CSR_SUPPORT_WEXT { diff --git a/drivers/staging/csr/sme_sys.c b/drivers/staging/csr/sme_sys.c index 0c61e75..4330f2a 100644 --- a/drivers/staging/csr/sme_sys.c +++ b/drivers/staging/csr/sme_sys.c @@ -869,7 +869,6 @@ wifi_off(unifi_priv_t *priv) unifi_trace(priv, UDBG1, "wifi_off\n"); /* Destroy the Traffic Analysis Module */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) cancel_work_sync(&priv->ta_ind_work.task); cancel_work_sync(&priv->ta_sample_ind_work.task); #ifdef CSR_SUPPORT_WEXT @@ -884,7 +883,6 @@ wifi_off(unifi_priv_t *priv) cancel_work_sync(&netpriv->send_m4_ready_task); } } -#endif flush_workqueue(priv->unifi_workqueue); /* fw_init parameter can prevent power off UniFi, for debugging */ diff --git a/drivers/staging/csr/ul_int.c b/drivers/staging/csr/ul_int.c index 819690d..4013d02 100644 --- a/drivers/staging/csr/ul_int.c +++ b/drivers/staging/csr/ul_int.c @@ -45,11 +45,7 @@ ul_init_clients(unifi_priv_t *priv) int id; ul_client_t *ul_clients; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37) sema_init(&priv->udi_logging_mutex, 1); -#else - init_MUTEX(&priv->udi_logging_mutex); -#endif priv->logging_client = NULL; ul_clients = priv->ul_clients; diff --git a/drivers/staging/csr/unifi_pdu_processing.c b/drivers/staging/csr/unifi_pdu_processing.c index c28f4dd..ae7c8fc 100644 --- a/drivers/staging/csr/unifi_pdu_processing.c +++ b/drivers/staging/csr/unifi_pdu_processing.c @@ -23,9 +23,6 @@ #include "csr_wifi_hip_conversions.h" #include "csr_time.h" #include "unifi_priv.h" -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) -#include -#endif #include #ifdef CSR_SUPPORT_SME -- cgit v0.10.2 From 6f6ed3db33720276068d70c17ce305e4132a123f Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Wed, 5 Sep 2012 00:56:43 +0530 Subject: staging: csr: remove casting of return value from kmalloc as per Documentation/CodingStyle, casting of void pointer to any other pointer is not needed Signed-off-by: Devendra Naga Acked-by: Marcos Paulo de Souza Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/csr/sme_sys.c b/drivers/staging/csr/sme_sys.c index 4330f2a..240344c 100644 --- a/drivers/staging/csr/sme_sys.c +++ b/drivers/staging/csr/sme_sys.c @@ -2121,7 +2121,7 @@ static int peer_add_new_record(unifi_priv_t *priv,CsrWifiRouterCtrlPeerAddReq *r /* Allocate for the new station record , to avoid race condition would happen between ADD_PEER & * DEL_PEER the allocation made atomic memory rather than kernel memory */ - newRecord = (CsrWifiRouterCtrlStaInfo_t *) kmalloc(sizeof(CsrWifiRouterCtrlStaInfo_t), GFP_ATOMIC); + newRecord = kmalloc(sizeof(CsrWifiRouterCtrlStaInfo_t), GFP_ATOMIC); if (!newRecord) { unifi_error(priv, "failed to allocate the %d bytes of mem for station record\n", sizeof(CsrWifiRouterCtrlStaInfo_t)); -- cgit v0.10.2 From 7cd4e8c577bf6e927da70529553bf65b4240d8a8 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Wed, 5 Sep 2012 00:56:44 +0530 Subject: staging: csr: replace calls to kmalloc and memset with kzalloc the kzalloc does allocates memory and sets the data at the memory which is allocated to 0, The driver does uses the kmalloc and memset at some points in the code replace them with a single call to kzalloc Signed-off-by: Devendra Naga Acked-by: Marcos Paulo de Souza Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/csr/sme_sys.c b/drivers/staging/csr/sme_sys.c index 240344c..5b26c41 100644 --- a/drivers/staging/csr/sme_sys.c +++ b/drivers/staging/csr/sme_sys.c @@ -2813,12 +2813,11 @@ u8 blockack_session_start(unifi_priv_t *priv, } /* create and populate the new BA session structure */ - ba_session_tx = kmalloc(sizeof(ba_session_tx_struct), GFP_KERNEL); + ba_session_tx = kzalloc(sizeof(ba_session_tx_struct), GFP_KERNEL); if (!ba_session_tx) { unifi_error(priv, "%s: kmalloc failed for ba_session_tx\n", __FUNCTION__); return FALSE; } - memset(ba_session_tx, 0, sizeof(ba_session_tx_struct)); ba_session_tx->interfacePriv = interfacePriv; ba_session_tx->tID = tID; @@ -2903,26 +2902,23 @@ u8 blockack_session_start(unifi_priv_t *priv, return FALSE; } - ba_session_rx = kmalloc(sizeof(ba_session_rx_struct), GFP_KERNEL); + ba_session_rx = kzalloc(sizeof(ba_session_rx_struct), GFP_KERNEL); if (!ba_session_rx) { unifi_error(priv, "%s: kmalloc failed for ba_session_rx\n", __FUNCTION__); return FALSE; } - memset(ba_session_rx, 0, sizeof(ba_session_rx_struct)); ba_session_rx->wind_size = wind_size; ba_session_rx->start_sn = ba_session_rx->expected_sn = start_sn; ba_session_rx->trigger_ba_after_ssn = FALSE; - ba_session_rx->buffer = kmalloc(ba_session_rx->wind_size*sizeof(frame_desc_struct), GFP_KERNEL); + ba_session_rx->buffer = kzalloc(ba_session_rx->wind_size*sizeof(frame_desc_struct), GFP_KERNEL); if (!ba_session_rx->buffer) { kfree(ba_session_rx); unifi_error(priv, "%s: kmalloc failed for buffer\n", __FUNCTION__); return FALSE; } - memset(ba_session_rx->buffer, 0, ba_session_rx->wind_size*sizeof(frame_desc_struct)); - INIT_WORK(&ba_session_rx->send_ba_err_task, uf_send_ba_err_wq); if (timeout) { ba_session_rx->timeout = timeout; -- cgit v0.10.2 From 5e15a753cd98c377f9b101942d138898feccd19d Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Tue, 4 Sep 2012 17:01:06 +0200 Subject: Staging: ipack/bridges/tpci200: Reorganize tpci200_probe in preparation for functional changes. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These changes make it easier to add more initialization steps later on. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 5831af8..eda02e7 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -790,8 +790,8 @@ static int tpci200_pciprobe(struct pci_dev *pdev, tpci200->info = kzalloc(sizeof(struct tpci200_infos), GFP_KERNEL); if (!tpci200->info) { - kfree(tpci200); - return -ENOMEM; + ret = -ENOMEM; + goto out_err_info; } /* Save struct pci_dev pointer */ @@ -801,10 +801,9 @@ static int tpci200_pciprobe(struct pci_dev *pdev, /* register the device and initialize it */ ret = tpci200_install(tpci200); if (ret) { - dev_err(&pdev->dev, "Error during tpci200 install !\n"); - kfree(tpci200->info); - kfree(tpci200); - return -ENODEV; + dev_err(&pdev->dev, "error during tpci200 install\n"); + ret = -ENODEV; + goto out_err_install; } /* Register the carrier in the industry pack bus driver */ @@ -814,10 +813,8 @@ static int tpci200_pciprobe(struct pci_dev *pdev, if (!tpci200->info->ipack_bus) { dev_err(&pdev->dev, "error registering the carrier on ipack driver\n"); - tpci200_uninstall(tpci200); - kfree(tpci200->info); - kfree(tpci200); - return -EFAULT; + ret = -EFAULT; + goto out_err_bus_register; } /* save the bus number given by ipack to logging purpose */ @@ -831,6 +828,14 @@ static int tpci200_pciprobe(struct pci_dev *pdev, for (i = 0; i < TPCI200_NB_SLOT; i++) tpci200->slots[i].dev = ipack_device_register(tpci200->info->ipack_bus, i, i); + return 0; + +out_err_bus_register: + tpci200_uninstall(tpci200); +out_err_install: + kfree(tpci200->info); +out_err_info: + kfree(tpci200); return ret; } -- cgit v0.10.2 From cea2f7cdff2af520dfeb99eec7a0a0d729a3720f Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Tue, 4 Sep 2012 17:01:07 +0200 Subject: Staging: ipack/bridges/tpci200: Use the TPCI200 in big endian mode. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit During initialization we configure the TPCI200 so it does not swap data lanes on IndustryPack module access. The read and write functions are changed accordingly. We are taking this approach in the hope that all IP Carriers are able to present the Module memory layout unchanged. We can thus directly access the memory and registers of IP Modules without having to rely on the read and write wrappers currently exposed in ipack_bus_opts. A later patch will convert the existing driver and remove the wrappers. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index eda02e7..f2501c9 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -54,39 +54,39 @@ static struct tpci200_board *check_slot(struct ipack_device *dev) static inline unsigned char __tpci200_read8(void __iomem *address, unsigned long offset) { - return ioread8(address + (offset^1)); + return ioread8(address + offset); } static inline unsigned short __tpci200_read16(void __iomem *address, unsigned long offset) { - return ioread16(address + offset); + return ioread16be(address + offset); } static inline unsigned int __tpci200_read32(void __iomem *address, unsigned long offset) { - return swahw32(ioread32(address + offset)); + return ioread32be(address + offset); } static inline void __tpci200_write8(unsigned char value, void __iomem *address, unsigned long offset) { - iowrite8(value, address+(offset^1)); + iowrite8(value, address + offset); } static inline void __tpci200_write16(unsigned short value, void __iomem *address, unsigned long offset) { - iowrite16(value, address+offset); + iowrite16be(value, address + offset); } static inline void __tpci200_write32(unsigned int value, void __iomem *address, unsigned long offset) { - iowrite32(swahw32(value), address+offset); + iowrite32be(value, address + offset); } static struct ipack_addr_space *get_slot_address_space(struct ipack_device *dev, @@ -783,6 +783,7 @@ static int tpci200_pciprobe(struct pci_dev *pdev, { int ret, i; struct tpci200_board *tpci200; + __le32 reg32; tpci200 = kzalloc(sizeof(struct tpci200_board), GFP_KERNEL); if (!tpci200) @@ -794,6 +795,34 @@ static int tpci200_pciprobe(struct pci_dev *pdev, goto out_err_info; } + /* Obtain a mapping of the carrier's PCI configuration registers */ + ret = pci_request_region(pdev, TPCI200_CFG_MEM_BAR, + KBUILD_MODNAME " Configuration Memory"); + if (ret) { + dev_err(&pdev->dev, "Failed to allocate PCI Configuration Memory"); + ret = -EBUSY; + goto out_err_pci_request; + } + tpci200->info->cfg_regs = ioremap_nocache( + pci_resource_start(pdev, TPCI200_CFG_MEM_BAR), + pci_resource_len(pdev, TPCI200_CFG_MEM_BAR)); + if (!tpci200->info->cfg_regs) { + dev_err(&pdev->dev, "Failed to map PCI Configuration Memory"); + ret = -EFAULT; + goto out_err_ioremap; + } + + /* Disable byte swapping for 16 bit IP module access. This will ensure + * that the Industrypack big endian byte order is preserved by the + * carrier. */ + reg32 = ioread32(tpci200->info->cfg_regs + LAS1_DESC); + reg32 |= 1 << LAS_BIT_BIGENDIAN; + iowrite32(reg32, tpci200->info->cfg_regs + LAS1_DESC); + + reg32 = ioread32(tpci200->info->cfg_regs + LAS2_DESC); + reg32 |= 1 << LAS_BIT_BIGENDIAN; + iowrite32(reg32, tpci200->info->cfg_regs + LAS2_DESC); + /* Save struct pci_dev pointer */ tpci200->info->pdev = pdev; tpci200->info->id_table = (struct pci_device_id *)id; @@ -833,6 +862,10 @@ static int tpci200_pciprobe(struct pci_dev *pdev, out_err_bus_register: tpci200_uninstall(tpci200); out_err_install: + iounmap(tpci200->info->cfg_regs); +out_err_ioremap: + pci_release_region(pdev, TPCI200_CFG_MEM_BAR); +out_err_pci_request: kfree(tpci200->info); out_err_info: kfree(tpci200); @@ -843,6 +876,10 @@ static void __tpci200_pci_remove(struct tpci200_board *tpci200) { tpci200_uninstall(tpci200); ipack_bus_unregister(tpci200->info->ipack_bus); + + iounmap(tpci200->info->cfg_regs); + pci_release_region(tpci200->info->pdev, TPCI200_CFG_MEM_BAR); + kfree(tpci200->info); kfree(tpci200); } diff --git a/drivers/staging/ipack/bridges/tpci200.h b/drivers/staging/ipack/bridges/tpci200.h index d04510a..38acba1 100644 --- a/drivers/staging/ipack/bridges/tpci200.h +++ b/drivers/staging/ipack/bridges/tpci200.h @@ -31,6 +31,7 @@ #define TPCI200_SUBVENDOR_ID 0x1498 #define TPCI200_SUBDEVICE_ID 0x300A +#define TPCI200_CFG_MEM_BAR 0 #define TPCI200_IP_INTERFACE_BAR 2 #define TPCI200_IO_ID_INT_SPACES_BAR 3 #define TPCI200_MEM16_SPACE_BAR 4 @@ -97,6 +98,13 @@ #define TPCI200_SLOT_INT_MASK 0x00FF +/* PCI Configuration registers. The PCI bridge is a PLX Technology PCI9030. */ +#define LAS1_DESC 0x2C +#define LAS2_DESC 0x30 + +/* Bits in the LAS?_DESC registers */ +#define LAS_BIT_BIGENDIAN 24 + #define VME_IOID_SPACE "IOID" #define VME_MEM_SPACE "MEM" @@ -144,6 +152,7 @@ struct tpci200_infos { void __iomem *interface_regs; void __iomem *ioidint_space; void __iomem *mem8_space; + void __iomem *cfg_regs; struct ipack_bus_device *ipack_bus; }; struct tpci200_board { diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index fd0e301..963ed20 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -449,7 +449,7 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, */ ipoctal->dev->bus->ops->request_irq(ipoctal->dev, vector, ipoctal_irq_handler, ipoctal); - ipoctal->dev->bus->ops->write8(ipoctal->dev, IPACK_MEM_SPACE, 0, + ipoctal->dev->bus->ops->write8(ipoctal->dev, IPACK_MEM_SPACE, 1, vector); /* Register the TTY device */ -- cgit v0.10.2 From 64802dc8ed1e31ccc4d05f5d3ef7d215600589cb Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Tue, 4 Sep 2012 17:01:08 +0200 Subject: Staging: ipack/devices/ipoctal: Convert ipoctal to directly use ioread/write functions. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before it was using the functions in ipack_bus_ops. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index 963ed20..085b6c0 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "../ipack.h" #include "ipoctal.h" #include "scc2698.h" @@ -61,16 +62,12 @@ static inline void ipoctal_write_io_reg(struct ipoctal *ipoctal, unsigned char *dest, unsigned char value) { - unsigned long offset; - - offset = ((void __iomem *) dest) - ipoctal->dev->io_space.address; - ipoctal->dev->bus->ops->write8(ipoctal->dev, IPACK_IO_SPACE, offset, - value); + iowrite8(value, dest); } static inline void ipoctal_write_cr_cmd(struct ipoctal *ipoctal, - unsigned char *dest, - unsigned char value) + u8 __iomem *dest, + u8 value) { ipoctal_write_io_reg(ipoctal, dest, value); } @@ -78,13 +75,7 @@ static inline void ipoctal_write_cr_cmd(struct ipoctal *ipoctal, static inline unsigned char ipoctal_read_io_reg(struct ipoctal *ipoctal, unsigned char *src) { - unsigned long offset; - unsigned char value; - - offset = ((void __iomem *) src) - ipoctal->dev->io_space.address; - ipoctal->dev->bus->ops->read8(ipoctal->dev, IPACK_IO_SPACE, offset, - &value); - return value; + return ioread8(src); } static struct ipoctal *ipoctal_find_board(struct tty_struct *tty) @@ -331,14 +322,11 @@ static int ipoctal_check_model(struct ipack_device *dev, unsigned char *id) unsigned char manufacturerID; unsigned char board_id; - dev->bus->ops->read8(dev, IPACK_ID_SPACE, - IPACK_IDPROM_OFFSET_MANUFACTURER_ID, &manufacturerID); + manufacturerID = ioread8(dev->id_space.address + IPACK_IDPROM_OFFSET_MANUFACTURER_ID); if (manufacturerID != IP_OCTAL_MANUFACTURER_ID) return -ENODEV; - dev->bus->ops->read8(dev, IPACK_ID_SPACE, - IPACK_IDPROM_OFFSET_MODEL, (unsigned char *)&board_id); - + board_id = ioread8(dev->id_space.address + IPACK_IDPROM_OFFSET_MODEL); switch (board_id) { case IP_OCTAL_232_ID: case IP_OCTAL_422_ID: @@ -449,8 +437,7 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, */ ipoctal->dev->bus->ops->request_irq(ipoctal->dev, vector, ipoctal_irq_handler, ipoctal); - ipoctal->dev->bus->ops->write8(ipoctal->dev, IPACK_MEM_SPACE, 1, - vector); + iowrite8(vector, ipoctal->dev->mem_space.address + 1); /* Register the TTY device */ -- cgit v0.10.2 From b2e93e94d024a2a164af71cef6acaf16fda2279c Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Tue, 4 Sep 2012 17:01:09 +0200 Subject: Staging: ipack/bridges/tpci200: Remove the read/write functions from ipack_bus_ops. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit They are not used any longer. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index f2501c9..b81a8c9 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -51,218 +51,6 @@ static struct tpci200_board *check_slot(struct ipack_device *dev) return tpci200; } -static inline unsigned char __tpci200_read8(void __iomem *address, - unsigned long offset) -{ - return ioread8(address + offset); -} - -static inline unsigned short __tpci200_read16(void __iomem *address, - unsigned long offset) -{ - return ioread16be(address + offset); -} - -static inline unsigned int __tpci200_read32(void __iomem *address, - unsigned long offset) -{ - return ioread32be(address + offset); -} - -static inline void __tpci200_write8(unsigned char value, - void __iomem *address, unsigned long offset) -{ - iowrite8(value, address + offset); -} - -static inline void __tpci200_write16(unsigned short value, - void __iomem *address, - unsigned long offset) -{ - iowrite16be(value, address + offset); -} - -static inline void __tpci200_write32(unsigned int value, - void __iomem *address, - unsigned long offset) -{ - iowrite32be(value, address + offset); -} - -static struct ipack_addr_space *get_slot_address_space(struct ipack_device *dev, - int space) -{ - struct ipack_addr_space *addr; - - switch (space) { - case IPACK_IO_SPACE: - addr = &dev->io_space; - break; - case IPACK_ID_SPACE: - addr = &dev->id_space; - break; - case IPACK_MEM_SPACE: - addr = &dev->mem_space; - break; - default: - dev_err(&dev->dev, - "Slot [%d:%d] space number %d doesn't exist !\n", - dev->bus_nr, dev->slot, space); - return NULL; - break; - } - - if ((addr->size == 0) || (addr->address == NULL)) { - dev_err(&dev->dev, "Error, slot space not mapped !\n"); - return NULL; - } - - return addr; -} - -static int tpci200_read8(struct ipack_device *dev, int space, - unsigned long offset, unsigned char *value) -{ - struct ipack_addr_space *addr; - struct tpci200_board *tpci200; - - tpci200 = check_slot(dev); - if (tpci200 == NULL) - return -EINVAL; - - addr = get_slot_address_space(dev, space); - if (addr == NULL) - return -EINVAL; - - if (offset >= addr->size) { - dev_err(&dev->dev, "Error, slot space offset error !\n"); - return -EFAULT; - } - - *value = __tpci200_read8(addr->address, offset); - - return 0; -} - -static int tpci200_read16(struct ipack_device *dev, int space, - unsigned long offset, unsigned short *value) -{ - struct ipack_addr_space *addr; - struct tpci200_board *tpci200; - - tpci200 = check_slot(dev); - if (tpci200 == NULL) - return -EINVAL; - - addr = get_slot_address_space(dev, space); - if (addr == NULL) - return -EINVAL; - - if ((offset+2) >= addr->size) { - dev_err(&dev->dev, "Error, slot space offset error !\n"); - return -EFAULT; - } - *value = __tpci200_read16(addr->address, offset); - - return 0; -} - -static int tpci200_read32(struct ipack_device *dev, int space, - unsigned long offset, unsigned int *value) -{ - struct ipack_addr_space *addr; - struct tpci200_board *tpci200; - - tpci200 = check_slot(dev); - if (tpci200 == NULL) - return -EINVAL; - - addr = get_slot_address_space(dev, space); - if (addr == NULL) - return -EINVAL; - - if ((offset+4) >= addr->size) { - dev_err(&dev->dev, "Error, slot space offset error !\n"); - return -EFAULT; - } - - *value = __tpci200_read32(addr->address, offset); - - return 0; -} - -static int tpci200_write8(struct ipack_device *dev, int space, - unsigned long offset, unsigned char value) -{ - struct ipack_addr_space *addr; - struct tpci200_board *tpci200; - - tpci200 = check_slot(dev); - if (tpci200 == NULL) - return -EINVAL; - - addr = get_slot_address_space(dev, space); - if (addr == NULL) - return -EINVAL; - - if (offset >= addr->size) { - dev_err(&dev->dev, "Error, slot space offset error !\n"); - return -EFAULT; - } - - __tpci200_write8(value, addr->address, offset); - - return 0; -} - -static int tpci200_write16(struct ipack_device *dev, int space, - unsigned long offset, unsigned short value) -{ - struct ipack_addr_space *addr; - struct tpci200_board *tpci200; - - tpci200 = check_slot(dev); - if (tpci200 == NULL) - return -EINVAL; - - addr = get_slot_address_space(dev, space); - if (addr == NULL) - return -EINVAL; - - if ((offset+2) >= addr->size) { - dev_err(&dev->dev, "Error, slot space offset error !\n"); - return -EFAULT; - } - - __tpci200_write16(value, addr->address, offset); - - return 0; -} - -static int tpci200_write32(struct ipack_device *dev, int space, - unsigned long offset, unsigned int value) -{ - struct ipack_addr_space *addr; - struct tpci200_board *tpci200; - - tpci200 = check_slot(dev); - if (tpci200 == NULL) - return -EINVAL; - - addr = get_slot_address_space(dev, space); - if (addr == NULL) - return -EINVAL; - - if ((offset+4) >= addr->size) { - dev_err(&dev->dev, "Error, slot space offset error !\n"); - return -EFAULT; - } - - __tpci200_write32(value, addr->address, offset); - - return 0; -} - static void tpci200_unregister(struct tpci200_board *tpci200) { int i; @@ -749,12 +537,6 @@ static struct ipack_bus_ops tpci200_bus_ops = { .unmap_space = tpci200_slot_unmap_space, .request_irq = tpci200_request_irq, .free_irq = tpci200_free_irq, - .read8 = tpci200_read8, - .read16 = tpci200_read16, - .read32 = tpci200_read32, - .write8 = tpci200_write8, - .write16 = tpci200_write16, - .write32 = tpci200_write32, .remove_device = tpci200_slot_unregister, }; -- cgit v0.10.2 From 564bbf9b4ab0dc147a358f3481bc616b5c650a4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20Iglesias=20Gons=C3=A1lvez?= Date: Tue, 4 Sep 2012 17:01:10 +0200 Subject: Staging: ipack: remove read/write operations from ipack_bus_ops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit They are not used any longer. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h index 8bc001e..e3609b1 100644 --- a/drivers/staging/ipack/ipack.h +++ b/drivers/staging/ipack/ipack.h @@ -105,12 +105,6 @@ struct ipack_driver { * @unmap_space: unmap IP address space * @request_irq: request IRQ * @free_irq: free IRQ - * @read8: read unsigned char - * @read16: read unsigned short - * @read32: read unsigned int - * @write8: read unsigned char - * @write16: read unsigned short - * @write32: read unsigned int * @remove_device: tell the bridge module that the device has been removed */ struct ipack_bus_ops { @@ -118,12 +112,6 @@ struct ipack_bus_ops { int (*unmap_space) (struct ipack_device *dev, int space); int (*request_irq) (struct ipack_device *dev, int vector, int (*handler)(void *), void *arg); int (*free_irq) (struct ipack_device *dev); - int (*read8) (struct ipack_device *dev, int space, unsigned long offset, unsigned char *value); - int (*read16) (struct ipack_device *dev, int space, unsigned long offset, unsigned short *value); - int (*read32) (struct ipack_device *dev, int space, unsigned long offset, unsigned int *value); - int (*write8) (struct ipack_device *dev, int space, unsigned long offset, unsigned char value); - int (*write16) (struct ipack_device *dev, int space, unsigned long offset, unsigned short value); - int (*write32) (struct ipack_device *dev, int space, unsigned long offset, unsigned int value); int (*remove_device) (struct ipack_device *dev); }; -- cgit v0.10.2 From a498899a3eb7cd4b180423e2cb2376f82d3d86c0 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Tue, 4 Sep 2012 17:01:11 +0200 Subject: Staging: ipack/devices/ipoctal: ipoctal cleanups. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Define memory address space, fix sparse warnings and mark the structs reflecting hardware memory layout "packed" to be on the safe side. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index 085b6c0..76f8427 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -40,8 +40,8 @@ struct ipoctal { struct list_head list; struct ipack_device *dev; unsigned int board_id; - struct scc2698_channel *chan_regs; - struct scc2698_block *block_regs; + struct scc2698_channel __iomem *chan_regs; + struct scc2698_block __iomem *block_regs; struct ipoctal_stats chan_stats[NR_CHANNELS]; unsigned int nb_bytes[NR_CHANNELS]; unsigned int count_wr[NR_CHANNELS]; @@ -59,8 +59,8 @@ struct ipoctal { static LIST_HEAD(ipoctal_list); static inline void ipoctal_write_io_reg(struct ipoctal *ipoctal, - unsigned char *dest, - unsigned char value) + u8 __iomem *dest, + u8 value) { iowrite8(value, dest); } @@ -73,7 +73,7 @@ static inline void ipoctal_write_cr_cmd(struct ipoctal *ipoctal, } static inline unsigned char ipoctal_read_io_reg(struct ipoctal *ipoctal, - unsigned char *src) + u8 __iomem *src) { return ioread8(src); } @@ -391,9 +391,9 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, /* Save the virtual address to access the registers easily */ ipoctal->chan_regs = - (struct scc2698_channel *) ipoctal->dev->io_space.address; + (struct scc2698_channel __iomem *) ipoctal->dev->io_space.address; ipoctal->block_regs = - (struct scc2698_block *) ipoctal->dev->io_space.address; + (struct scc2698_block __iomem *) ipoctal->dev->io_space.address; /* Disable RX and TX before touching anything */ for (i = 0; i < NR_CHANNELS ; i++) { diff --git a/drivers/staging/ipack/devices/scc2698.h b/drivers/staging/ipack/devices/scc2698.h index 47f6269..fcab427 100644 --- a/drivers/staging/ipack/devices/scc2698.h +++ b/drivers/staging/ipack/devices/scc2698.h @@ -23,21 +23,21 @@ struct scc2698_channel { union { struct { - unsigned char d0, mr; /* Mode register 1/2*/ - unsigned char d1, sr; /* Status register */ - unsigned char d2, r1; /* reserved */ - unsigned char d3, rhr; /* Receive holding register (R) */ - unsigned char junk[8]; /* other crap for block control */ - } r; /* Read access */ + u8 d0, mr; /* Mode register 1/2*/ + u8 d1, sr; /* Status register */ + u8 d2, r1; /* reserved */ + u8 d3, rhr; /* Receive holding register (R) */ + u8 junk[8]; /* other crap for block control */ + } __packed r; /* Read access */ struct { - unsigned char d0, mr; /* Mode register 1/2 */ - unsigned char d1, csr; /* Clock select register */ - unsigned char d2, cr; /* Command register */ - unsigned char d3, thr; /* Transmit holding register */ - unsigned char junk[8]; /* other crap for block control */ - } w; /* Write access */ + u8 d0, mr; /* Mode register 1/2 */ + u8 d1, csr; /* Clock select register */ + u8 d2, cr; /* Command register */ + u8 d3, thr; /* Transmit holding register */ + u8 junk[8]; /* other crap for block control */ + } __packed w; /* Write access */ } u; -}; +} __packed; /* * struct scc2698_block - Block access to scc2698 IO @@ -50,43 +50,43 @@ struct scc2698_channel { struct scc2698_block { union { struct { - unsigned char d0, mra; /* Mode register 1/2 (a) */ - unsigned char d1, sra; /* Status register (a) */ - unsigned char d2, r1; /* reserved */ - unsigned char d3, rhra; /* Receive holding register (a) */ - unsigned char d4, ipcr; /* Input port change register of block */ - unsigned char d5, isr; /* Interrupt status register of block */ - unsigned char d6, ctur; /* Counter timer upper register of block */ - unsigned char d7, ctlr; /* Counter timer lower register of block */ - unsigned char d8, mrb; /* Mode register 1/2 (b) */ - unsigned char d9, srb; /* Status register (b) */ - unsigned char da, r2; /* reserved */ - unsigned char db, rhrb; /* Receive holding register (b) */ - unsigned char dc, r3; /* reserved */ - unsigned char dd, ip; /* Input port register of block */ - unsigned char de, ctg; /* Start counter timer of block */ - unsigned char df, cts; /* Stop counter timer of block */ - } r; /* Read access */ + u8 d0, mra; /* Mode register 1/2 (a) */ + u8 d1, sra; /* Status register (a) */ + u8 d2, r1; /* reserved */ + u8 d3, rhra; /* Receive holding register (a) */ + u8 d4, ipcr; /* Input port change register of block */ + u8 d5, isr; /* Interrupt status register of block */ + u8 d6, ctur; /* Counter timer upper register of block */ + u8 d7, ctlr; /* Counter timer lower register of block */ + u8 d8, mrb; /* Mode register 1/2 (b) */ + u8 d9, srb; /* Status register (b) */ + u8 da, r2; /* reserved */ + u8 db, rhrb; /* Receive holding register (b) */ + u8 dc, r3; /* reserved */ + u8 dd, ip; /* Input port register of block */ + u8 de, ctg; /* Start counter timer of block */ + u8 df, cts; /* Stop counter timer of block */ + } __packed r; /* Read access */ struct { - unsigned char d0, mra; /* Mode register 1/2 (a) */ - unsigned char d1, csra; /* Clock select register (a) */ - unsigned char d2, cra; /* Command register (a) */ - unsigned char d3, thra; /* Transmit holding register (a) */ - unsigned char d4, acr; /* Auxiliary control register of block */ - unsigned char d5, imr; /* Interrupt mask register of block */ - unsigned char d6, ctu; /* Counter timer upper register of block */ - unsigned char d7, ctl; /* Counter timer lower register of block */ - unsigned char d8, mrb; /* Mode register 1/2 (b) */ - unsigned char d9, csrb; /* Clock select register (a) */ - unsigned char da, crb; /* Command register (b) */ - unsigned char db, thrb; /* Transmit holding register (b) */ - unsigned char dc, r1; /* reserved */ - unsigned char dd, opcr; /* Output port configuration register of block */ - unsigned char de, r2; /* reserved */ - unsigned char df, r3; /* reserved */ - } w; /* Write access */ + u8 d0, mra; /* Mode register 1/2 (a) */ + u8 d1, csra; /* Clock select register (a) */ + u8 d2, cra; /* Command register (a) */ + u8 d3, thra; /* Transmit holding register (a) */ + u8 d4, acr; /* Auxiliary control register of block */ + u8 d5, imr; /* Interrupt mask register of block */ + u8 d6, ctu; /* Counter timer upper register of block */ + u8 d7, ctl; /* Counter timer lower register of block */ + u8 d8, mrb; /* Mode register 1/2 (b) */ + u8 d9, csrb; /* Clock select register (a) */ + u8 da, crb; /* Command register (b) */ + u8 db, thrb; /* Transmit holding register (b) */ + u8 dc, r1; /* reserved */ + u8 dd, opcr; /* Output port configuration register of block */ + u8 de, r2; /* reserved */ + u8 df, r3; /* reserved */ + } __packed w; /* Write access */ } u; -} ; +} __packed; #define MR1_CHRL_5_BITS (0x0 << 0) #define MR1_CHRL_6_BITS (0x1 << 0) -- cgit v0.10.2 From 1f43d7bfac880f63320c4dcbb8f864112946337f Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Tue, 4 Sep 2012 17:01:12 +0200 Subject: Staging: ipack/devices/ipoctal: Tidy up ipoctal some more. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No need to have a struct when it has only one field. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index 76f8427..c1d0c00 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -40,8 +40,8 @@ struct ipoctal { struct list_head list; struct ipack_device *dev; unsigned int board_id; - struct scc2698_channel __iomem *chan_regs; - struct scc2698_block __iomem *block_regs; + union scc2698_channel __iomem *chan_regs; + union scc2698_block __iomem *block_regs; struct ipoctal_stats chan_stats[NR_CHANNELS]; unsigned int nb_bytes[NR_CHANNELS]; unsigned int count_wr[NR_CHANNELS]; @@ -103,7 +103,7 @@ static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty) return -ENODEV; } - ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, + ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].w.cr, CR_ENABLE_RX); return 0; } @@ -216,9 +216,9 @@ static int ipoctal_irq_handler(void *arg) */ block = channel / 2; isr = ipoctal_read_io_reg(ipoctal, - &ipoctal->block_regs[block].u.r.isr); + &ipoctal->block_regs[block].r.isr); sr = ipoctal_read_io_reg(ipoctal, - &ipoctal->chan_regs[channel].u.r.sr); + &ipoctal->chan_regs[channel].r.sr); if ((channel % 2) == 1) { isr_tx_rdy = isr & ISR_TxRDY_B; @@ -235,13 +235,13 @@ static int ipoctal_irq_handler(void *arg) (sr & SR_TX_EMPTY) && (ipoctal->nb_bytes[channel] == 0)) { ipoctal_write_io_reg(ipoctal, - &ipoctal->chan_regs[channel].u.w.cr, + &ipoctal->chan_regs[channel].w.cr, CR_DISABLE_TX); ipoctal_write_cr_cmd(ipoctal, - &ipoctal->chan_regs[channel].u.w.cr, + &ipoctal->chan_regs[channel].w.cr, CR_CMD_NEGATE_RTSN); ipoctal_write_io_reg(ipoctal, - &ipoctal->chan_regs[channel].u.w.cr, + &ipoctal->chan_regs[channel].w.cr, CR_ENABLE_RX); ipoctal->write = 1; wake_up_interruptible(&ipoctal->queue[channel]); @@ -250,13 +250,13 @@ static int ipoctal_irq_handler(void *arg) /* RX data */ if (isr_rx_rdy && (sr & SR_RX_READY)) { value = ipoctal_read_io_reg(ipoctal, - &ipoctal->chan_regs[channel].u.r.rhr); + &ipoctal->chan_regs[channel].r.rhr); flag = TTY_NORMAL; /* Error: count statistics */ if (sr & SR_ERROR) { ipoctal_write_cr_cmd(ipoctal, - &ipoctal->chan_regs[channel].u.w.cr, + &ipoctal->chan_regs[channel].w.cr, CR_CMD_RESET_ERR_STATUS); if (sr & SR_OVERRUN_ERROR) { @@ -293,7 +293,7 @@ static int ipoctal_irq_handler(void *arg) value = ipoctal->tty_port[channel].xmit_buf[*pointer_write]; ipoctal_write_io_reg(ipoctal, - &ipoctal->chan_regs[channel].u.w.thr, + &ipoctal->chan_regs[channel].w.thr, value); ipoctal->chan_stats[channel].tx++; ipoctal->count_wr[channel]++; @@ -391,40 +391,40 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, /* Save the virtual address to access the registers easily */ ipoctal->chan_regs = - (struct scc2698_channel __iomem *) ipoctal->dev->io_space.address; + (union scc2698_channel __iomem *) ipoctal->dev->io_space.address; ipoctal->block_regs = - (struct scc2698_block __iomem *) ipoctal->dev->io_space.address; + (union scc2698_block __iomem *) ipoctal->dev->io_space.address; /* Disable RX and TX before touching anything */ for (i = 0; i < NR_CHANNELS ; i++) { - ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[i].u.w.cr, + ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[i].w.cr, CR_DISABLE_RX | CR_DISABLE_TX); - ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[i].u.w.cr, + ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[i].w.cr, CR_CMD_RESET_RX); - ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[i].u.w.cr, + ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[i].w.cr, CR_CMD_RESET_TX); ipoctal_write_io_reg(ipoctal, - &ipoctal->chan_regs[i].u.w.mr, + &ipoctal->chan_regs[i].w.mr, MR1_CHRL_8_BITS | MR1_ERROR_CHAR | MR1_RxINT_RxRDY); /* mr1 */ ipoctal_write_io_reg(ipoctal, - &ipoctal->chan_regs[i].u.w.mr, + &ipoctal->chan_regs[i].w.mr, 0); /* mr2 */ ipoctal_write_io_reg(ipoctal, - &ipoctal->chan_regs[i].u.w.csr, + &ipoctal->chan_regs[i].w.csr, TX_CLK_9600 | RX_CLK_9600); } for (i = 0; i < IP_OCTAL_NB_BLOCKS; i++) { ipoctal_write_io_reg(ipoctal, - &ipoctal->block_regs[i].u.w.acr, + &ipoctal->block_regs[i].w.acr, ACR_BRG_SET2); ipoctal_write_io_reg(ipoctal, - &ipoctal->block_regs[i].u.w.opcr, + &ipoctal->block_regs[i].w.opcr, OPCR_MPP_OUTPUT | OPCR_MPOa_RTSN | OPCR_MPOb_RTSN); ipoctal_write_io_reg(ipoctal, - &ipoctal->block_regs[i].u.w.imr, + &ipoctal->block_regs[i].w.imr, IMR_TxRDY_A | IMR_RxRDY_FFULL_A | IMR_DELTA_BREAK_A | IMR_TxRDY_B | IMR_RxRDY_FFULL_B | IMR_DELTA_BREAK_B); @@ -495,7 +495,7 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, * Enable again the RX. TX will be enabled when * there is something to send */ - ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[i].u.w.cr, + ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[i].w.cr, CR_ENABLE_RX); } @@ -545,10 +545,10 @@ static int ipoctal_write(struct ipoctal *ipoctal, unsigned int channel, /* As the IP-OCTAL 485 only supports half duplex, do it manually */ if (ipoctal->board_id == IP_OCTAL_485_ID) { ipoctal_write_io_reg(ipoctal, - &ipoctal->chan_regs[channel].u.w.cr, + &ipoctal->chan_regs[channel].w.cr, CR_DISABLE_RX); ipoctal_write_cr_cmd(ipoctal, - &ipoctal->chan_regs[channel].u.w.cr, + &ipoctal->chan_regs[channel].w.cr, CR_CMD_ASSERT_RTSN); } @@ -557,11 +557,11 @@ static int ipoctal_write(struct ipoctal *ipoctal, unsigned int channel, * operations */ ipoctal_write_io_reg(ipoctal, - &ipoctal->chan_regs[channel].u.w.cr, + &ipoctal->chan_regs[channel].w.cr, CR_ENABLE_TX); wait_event_interruptible(ipoctal->queue[channel], ipoctal->write); ipoctal_write_io_reg(ipoctal, - &ipoctal->chan_regs[channel].u.w.cr, + &ipoctal->chan_regs[channel].w.cr, CR_DISABLE_TX); ipoctal->write = 0; @@ -607,15 +607,15 @@ static void ipoctal_set_termios(struct tty_struct *tty, cflag = tty->termios->c_cflag; /* Disable and reset everything before change the setup */ - ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, + ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].w.cr, CR_DISABLE_RX | CR_DISABLE_TX); - ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, + ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr, CR_CMD_RESET_RX); - ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, + ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr, CR_CMD_RESET_TX); - ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, + ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr, CR_CMD_RESET_ERR_STATUS); - ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, + ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr, CR_CMD_RESET_MR); /* Set Bits per chars */ @@ -729,12 +729,12 @@ static void ipoctal_set_termios(struct tty_struct *tty, mr1 |= MR1_RxINT_RxRDY; /* Write the control registers */ - ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.mr, mr1); - ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.mr, mr2); - ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.csr, csr); + ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].w.mr, mr1); + ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].w.mr, mr2); + ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].w.csr, csr); /* Enable again the RX */ - ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, + ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].w.cr, CR_ENABLE_RX); } @@ -755,15 +755,15 @@ static void ipoctal_hangup(struct tty_struct *tty) tty_port_hangup(&ipoctal->tty_port[channel]); - ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, + ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].w.cr, CR_DISABLE_RX | CR_DISABLE_TX); - ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, + ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr, CR_CMD_RESET_RX); - ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, + ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr, CR_CMD_RESET_TX); - ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, + ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr, CR_CMD_RESET_ERR_STATUS); - ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, + ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr, CR_CMD_RESET_MR); clear_bit(ASYNCB_INITIALIZED, &ipoctal->tty_port[channel].flags); diff --git a/drivers/staging/ipack/devices/scc2698.h b/drivers/staging/ipack/devices/scc2698.h index fcab427..223838a 100644 --- a/drivers/staging/ipack/devices/scc2698.h +++ b/drivers/staging/ipack/devices/scc2698.h @@ -15,78 +15,74 @@ #define SCC2698_H_ /* - * struct scc2698_channel - Channel access to scc2698 IO + * union scc2698_channel - Channel access to scc2698 IO * * dn value are only spacer. * */ -struct scc2698_channel { - union { - struct { - u8 d0, mr; /* Mode register 1/2*/ - u8 d1, sr; /* Status register */ - u8 d2, r1; /* reserved */ - u8 d3, rhr; /* Receive holding register (R) */ - u8 junk[8]; /* other crap for block control */ - } __packed r; /* Read access */ - struct { - u8 d0, mr; /* Mode register 1/2 */ - u8 d1, csr; /* Clock select register */ - u8 d2, cr; /* Command register */ - u8 d3, thr; /* Transmit holding register */ - u8 junk[8]; /* other crap for block control */ - } __packed w; /* Write access */ - } u; -} __packed; +union scc2698_channel { + struct { + u8 d0, mr; /* Mode register 1/2*/ + u8 d1, sr; /* Status register */ + u8 d2, r1; /* reserved */ + u8 d3, rhr; /* Receive holding register (R) */ + u8 junk[8]; /* other crap for block control */ + } __packed r; /* Read access */ + struct { + u8 d0, mr; /* Mode register 1/2 */ + u8 d1, csr; /* Clock select register */ + u8 d2, cr; /* Command register */ + u8 d3, thr; /* Transmit holding register */ + u8 junk[8]; /* other crap for block control */ + } __packed w; /* Write access */ +}; /* - * struct scc2698_block - Block access to scc2698 IO + * union scc2698_block - Block access to scc2698 IO * * The scc2698 contain 4 block. * Each block containt two channel a and b. * dn value are only spacer. * */ -struct scc2698_block { - union { - struct { - u8 d0, mra; /* Mode register 1/2 (a) */ - u8 d1, sra; /* Status register (a) */ - u8 d2, r1; /* reserved */ - u8 d3, rhra; /* Receive holding register (a) */ - u8 d4, ipcr; /* Input port change register of block */ - u8 d5, isr; /* Interrupt status register of block */ - u8 d6, ctur; /* Counter timer upper register of block */ - u8 d7, ctlr; /* Counter timer lower register of block */ - u8 d8, mrb; /* Mode register 1/2 (b) */ - u8 d9, srb; /* Status register (b) */ - u8 da, r2; /* reserved */ - u8 db, rhrb; /* Receive holding register (b) */ - u8 dc, r3; /* reserved */ - u8 dd, ip; /* Input port register of block */ - u8 de, ctg; /* Start counter timer of block */ - u8 df, cts; /* Stop counter timer of block */ - } __packed r; /* Read access */ - struct { - u8 d0, mra; /* Mode register 1/2 (a) */ - u8 d1, csra; /* Clock select register (a) */ - u8 d2, cra; /* Command register (a) */ - u8 d3, thra; /* Transmit holding register (a) */ - u8 d4, acr; /* Auxiliary control register of block */ - u8 d5, imr; /* Interrupt mask register of block */ - u8 d6, ctu; /* Counter timer upper register of block */ - u8 d7, ctl; /* Counter timer lower register of block */ - u8 d8, mrb; /* Mode register 1/2 (b) */ - u8 d9, csrb; /* Clock select register (a) */ - u8 da, crb; /* Command register (b) */ - u8 db, thrb; /* Transmit holding register (b) */ - u8 dc, r1; /* reserved */ - u8 dd, opcr; /* Output port configuration register of block */ - u8 de, r2; /* reserved */ - u8 df, r3; /* reserved */ - } __packed w; /* Write access */ - } u; -} __packed; +union scc2698_block { + struct { + u8 d0, mra; /* Mode register 1/2 (a) */ + u8 d1, sra; /* Status register (a) */ + u8 d2, r1; /* reserved */ + u8 d3, rhra; /* Receive holding register (a) */ + u8 d4, ipcr; /* Input port change register of block */ + u8 d5, isr; /* Interrupt status register of block */ + u8 d6, ctur; /* Counter timer upper register of block */ + u8 d7, ctlr; /* Counter timer lower register of block */ + u8 d8, mrb; /* Mode register 1/2 (b) */ + u8 d9, srb; /* Status register (b) */ + u8 da, r2; /* reserved */ + u8 db, rhrb; /* Receive holding register (b) */ + u8 dc, r3; /* reserved */ + u8 dd, ip; /* Input port register of block */ + u8 de, ctg; /* Start counter timer of block */ + u8 df, cts; /* Stop counter timer of block */ + } __packed r; /* Read access */ + struct { + u8 d0, mra; /* Mode register 1/2 (a) */ + u8 d1, csra; /* Clock select register (a) */ + u8 d2, cra; /* Command register (a) */ + u8 d3, thra; /* Transmit holding register (a) */ + u8 d4, acr; /* Auxiliary control register of block */ + u8 d5, imr; /* Interrupt mask register of block */ + u8 d6, ctu; /* Counter timer upper register of block */ + u8 d7, ctl; /* Counter timer lower register of block */ + u8 d8, mrb; /* Mode register 1/2 (b) */ + u8 d9, csrb; /* Clock select register (a) */ + u8 da, crb; /* Command register (b) */ + u8 db, thrb; /* Transmit holding register (b) */ + u8 dc, r1; /* reserved */ + u8 dd, opcr; /* Output port configuration register of block */ + u8 de, r2; /* reserved */ + u8 df, r3; /* reserved */ + } __packed w; /* Write access */ +}; #define MR1_CHRL_5_BITS (0x0 << 0) #define MR1_CHRL_6_BITS (0x1 << 0) -- cgit v0.10.2 From 849e0ad257d259b8443c63d74e3bcc32ebf336af Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Tue, 4 Sep 2012 17:01:13 +0200 Subject: Staging: ipack: implement ipack device table. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The modaliases look like ipack:fXvNdM, where X is the format version (8 bit) and N and M are the vendor and device ID represented as 32 bit hexadecimal numbers each. Using 32 bits allows us to define IPACK_ANY_ID as (~0) without interfering with the valid ids. The resulting modalias string for ipoctal.ko looks like this (once ipoctal provides a device table): alias: ipack:f01v000000F0d00000048* alias: ipack:f01v000000F0d0000002A* alias: ipack:f01v000000F0d00000022* (output from modinfo) Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h index e3609b1..703142d 100644 --- a/drivers/staging/ipack/ipack.h +++ b/drivers/staging/ipack/ipack.h @@ -9,6 +9,7 @@ * Software Foundation; version 2 of the License. */ +#include #include #define IPACK_IDPROM_OFFSET_I 0x01 @@ -95,6 +96,7 @@ struct ipack_driver_ops { */ struct ipack_driver { struct device_driver driver; + const struct ipack_device_id *id_table; struct ipack_driver_ops *ops; }; @@ -169,3 +171,27 @@ void ipack_driver_unregister(struct ipack_driver *edrv); */ struct ipack_device *ipack_device_register(struct ipack_bus_device *bus, int slot, int irqv); void ipack_device_unregister(struct ipack_device *dev); + +/** + * DEFINE_IPACK_DEVICE_TABLE - macro used to describe a IndustryPack table + * @_table: device table name + * + * This macro is used to create a struct ipack_device_id array (a device table) + * in a generic manner. + */ +#define DEFINE_IPACK_DEVICE_TABLE(_table) \ + const struct ipack_device_id _table[] __devinitconst + +/** + * IPACK_DEVICE - macro used to describe a specific IndustryPack device + * @_format: the format version (currently either 1 or 2, 8 bit value) + * @vend: the 8 or 24 bit IndustryPack Vendor ID + * @dev: the 8 or 16 bit IndustryPack Device ID + * + * This macro is used to create a struct ipack_device_id that matches a specific + * device. + */ +#define IPACK_DEVICE(_format, vend, dev) \ + .format = (_format), \ + .vendor = (vend), \ + .device = (dev) diff --git a/drivers/staging/ipack/ipack_ids.h b/drivers/staging/ipack/ipack_ids.h new file mode 100644 index 0000000..ba85ec5 --- /dev/null +++ b/drivers/staging/ipack/ipack_ids.h @@ -0,0 +1,27 @@ +/* + * IndustryPack Fromat, Vendor and Device IDs. + */ + +/* ID section format versions */ +#define IPACK_ID_VERSION_INVALID 0x00 +#define IPACK_ID_VERSION_1 0x01 +#define IPACK_ID_VERSION_2 0x02 + +/* Vendors and devices. Sort key: vendor first, device next. */ +#define IPACK1_VENDOR_ID_RESERVED1 0x00 +#define IPACK1_VENDOR_ID_RESERVED2 0xFF +#define IPACK1_VENDOR_ID_UNREGISTRED01 0x01 +#define IPACK1_VENDOR_ID_UNREGISTRED02 0x02 +#define IPACK1_VENDOR_ID_UNREGISTRED03 0x03 +#define IPACK1_VENDOR_ID_UNREGISTRED04 0x04 +#define IPACK1_VENDOR_ID_UNREGISTRED05 0x05 +#define IPACK1_VENDOR_ID_UNREGISTRED06 0x06 +#define IPACK1_VENDOR_ID_UNREGISTRED07 0x07 +#define IPACK1_VENDOR_ID_UNREGISTRED08 0x08 +#define IPACK1_VENDOR_ID_UNREGISTRED09 0x09 +#define IPACK1_VENDOR_ID_UNREGISTRED10 0x0A +#define IPACK1_VENDOR_ID_UNREGISTRED11 0x0B +#define IPACK1_VENDOR_ID_UNREGISTRED12 0x0C +#define IPACK1_VENDOR_ID_UNREGISTRED13 0x0D +#define IPACK1_VENDOR_ID_UNREGISTRED14 0x0E +#define IPACK1_VENDOR_ID_UNREGISTRED15 0x0F diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 6955045..999c4c2 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -600,4 +600,11 @@ struct x86_cpu_id { #define X86_MODEL_ANY 0 #define X86_FEATURE_ANY 0 /* Same as FPU, you can't test for that */ +#define IPACK_ANY_ID (~0) +struct ipack_device_id { + __u8 format; /* Format version or IPACK_ANY_ID */ + __u32 vendor; /* Vendor ID or IPACK_ANY_ID */ + __u32 device; /* Device ID or IPACK_ANY_ID */ +}; + #endif /* LINUX_MOD_DEVICETABLE_H */ diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 7ed6864..3c22bda 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -966,6 +966,21 @@ static int do_isapnp_entry(const char *filename, } ADD_TO_DEVTABLE("isapnp", struct isapnp_device_id, do_isapnp_entry); +/* Looks like: "ipack:fNvNdN". */ +static int do_ipack_entry(const char *filename, + struct ipack_device_id *id, char *alias) +{ + id->vendor = TO_NATIVE(id->vendor); + id->device = TO_NATIVE(id->device); + strcpy(alias, "ipack:"); + ADD(alias, "f", id->format != IPACK_ANY_ID, id->format); + ADD(alias, "v", id->vendor != IPACK_ANY_ID, id->vendor); + ADD(alias, "d", id->device != IPACK_ANY_ID, id->device); + add_wildcard(alias); + return 1; +} +ADD_TO_DEVTABLE("ipack", struct ipack_device_id, do_ipack_entry); + /* * Append a match expression for a single masked hex digit. * outp points to a pointer to the character at which to append. -- cgit v0.10.2 From 187e4782401329663bda870f432fdbeb8154fe3f Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Tue, 4 Sep 2012 17:01:14 +0200 Subject: Staging: ipack: Read the ID space during device registration. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We keep a copy of the ID space for later use. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c index c1cd97a..da9e7bd 100644 --- a/drivers/staging/ipack/ipack.c +++ b/drivers/staging/ipack/ipack.c @@ -22,6 +22,7 @@ static DEFINE_IDA(ipack_ida); static void ipack_device_release(struct device *dev) { struct ipack_device *device = to_ipack_dev(dev); + kfree(device->id); kfree(device); } @@ -117,6 +118,77 @@ void ipack_driver_unregister(struct ipack_driver *edrv) } EXPORT_SYMBOL_GPL(ipack_driver_unregister); +static int ipack_device_read_id(struct ipack_device *dev) +{ + u8 __iomem *idmem; + int i; + int ret = 0; + + ret = dev->bus->ops->map_space(dev, 0, IPACK_ID_SPACE); + if (ret) { + dev_err(&dev->dev, "error mapping memory\n"); + return ret; + } + idmem = dev->id_space.address; + + /* Determine ID PROM Data Format. If we find the ids "IPAC" or "IPAH" + * we are dealing with a IndustryPack format 1 device. If we detect + * "VITA4 " (16 bit big endian formatted) we are dealing with a + * IndustryPack format 2 device */ + if ((ioread8(idmem + 1) == 'I') && + (ioread8(idmem + 3) == 'P') && + (ioread8(idmem + 5) == 'A') && + ((ioread8(idmem + 7) == 'C') || + (ioread8(idmem + 7) == 'H'))) { + dev->id_format = IPACK_ID_VERSION_1; + dev->id_avail = ioread8(idmem + 0x15); + if ((dev->id_avail < 0x0c) || (dev->id_avail > 0x40)) { + dev_warn(&dev->dev, "invalid id size"); + dev->id_avail = 0x0c; + } + } else if ((ioread8(idmem + 0) == 'I') && + (ioread8(idmem + 1) == 'V') && + (ioread8(idmem + 2) == 'A') && + (ioread8(idmem + 3) == 'T') && + (ioread8(idmem + 4) == ' ') && + (ioread8(idmem + 5) == '4')) { + dev->id_format = IPACK_ID_VERSION_2; + dev->id_avail = ioread16be(idmem + 0x16); + if ((dev->id_avail < 0x1a) || (dev->id_avail > 0x40)) { + dev_warn(&dev->dev, "invalid id size"); + dev->id_avail = 0x1a; + } + } else { + dev->id_format = IPACK_ID_VERSION_INVALID; + dev->id_avail = 0; + } + + if (!dev->id_avail) { + ret = -ENODEV; + goto out; + } + + /* Obtain the amount of memory required to store a copy of the complete + * ID ROM contents */ + dev->id = kmalloc(dev->id_avail, GFP_KERNEL); + if (!dev->id) { + dev_err(&dev->dev, "dev->id alloc failed.\n"); + ret = -ENOMEM; + goto out; + } + for (i = 0; i < dev->id_avail; i++) { + if (dev->id_format == IPACK_ID_VERSION_1) + dev->id[i] = ioread8(idmem + (i << 1) + 1); + else + dev->id[i] = ioread8(idmem + i); + } + +out: + dev->bus->ops->unmap_space(dev, IPACK_ID_SPACE); + + return ret; +} + struct ipack_device *ipack_device_register(struct ipack_bus_device *bus, int slot, int irqv) { @@ -137,8 +209,16 @@ struct ipack_device *ipack_device_register(struct ipack_bus_device *bus, dev_set_name(&dev->dev, "ipack-dev.%u.%u", dev->bus_nr, dev->slot); + ret = ipack_device_read_id(dev); + if (ret < 0) { + dev_err(&dev->dev, "error reading device id section.\n"); + kfree(dev); + return NULL; + } + ret = device_register(&dev->dev); if (ret < 0) { + kfree(dev->id); kfree(dev); return NULL; } diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h index 703142d..2851e33 100644 --- a/drivers/staging/ipack/ipack.h +++ b/drivers/staging/ipack/ipack.h @@ -12,6 +12,8 @@ #include #include +#include "ipack_ids.h" + #define IPACK_IDPROM_OFFSET_I 0x01 #define IPACK_IDPROM_OFFSET_P 0x03 #define IPACK_IDPROM_OFFSET_A 0x05 @@ -72,6 +74,9 @@ struct ipack_device { struct ipack_addr_space io_space; struct ipack_addr_space mem_space; struct device dev; + unsigned char *id; + size_t id_avail; + u8 id_format; }; /** -- cgit v0.10.2 From e8ed3276c24238adb7e676d56a82bc9c7f4fe912 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Tue, 4 Sep 2012 17:01:15 +0200 Subject: Staging: ipack: Parse vendor and device id. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also expose the values through sysfs. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c index da9e7bd..9474226 100644 --- a/drivers/staging/ipack/ipack.c +++ b/drivers/staging/ipack/ipack.c @@ -63,11 +63,57 @@ static int ipack_bus_remove(struct device *device) return 0; } +#define ipack_device_attr(field, format_string) \ +static ssize_t \ +field##_show(struct device *dev, struct device_attribute *attr, \ + char *buf) \ +{ \ + struct ipack_device *idev = to_ipack_dev(dev); \ + return sprintf(buf, format_string, idev->field); \ +} + +static ssize_t +id_vendor_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct ipack_device *idev = to_ipack_dev(dev); + switch (idev->id_format) { + case IPACK_ID_VERSION_1: + return sprintf(buf, "0x%02x\n", idev->id_vendor); + case IPACK_ID_VERSION_2: + return sprintf(buf, "0x%06x\n", idev->id_vendor); + default: + return -EIO; + } +} + +static ssize_t +id_device_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct ipack_device *idev = to_ipack_dev(dev); + switch (idev->id_format) { + case IPACK_ID_VERSION_1: + return sprintf(buf, "0x%02x\n", idev->id_device); + case IPACK_ID_VERSION_2: + return sprintf(buf, "0x%04x\n", idev->id_device); + default: + return -EIO; + } +} + +ipack_device_attr(id_format, "0x%hhu\n"); + +static struct device_attribute ipack_dev_attrs[] = { + __ATTR_RO(id_device), + __ATTR_RO(id_format), + __ATTR_RO(id_vendor), +}; + static struct bus_type ipack_bus_type = { - .name = "ipack", - .probe = ipack_bus_probe, - .match = ipack_bus_match, - .remove = ipack_bus_remove, + .name = "ipack", + .probe = ipack_bus_probe, + .match = ipack_bus_match, + .remove = ipack_bus_remove, + .dev_attrs = ipack_dev_attrs, }; struct ipack_bus_device *ipack_bus_register(struct device *parent, int slots, @@ -118,6 +164,23 @@ void ipack_driver_unregister(struct ipack_driver *edrv) } EXPORT_SYMBOL_GPL(ipack_driver_unregister); +static void ipack_parse_id1(struct ipack_device *dev) +{ + u8 *id = dev->id; + + dev->id_vendor = id[4]; + dev->id_device = id[5]; +} + +static void ipack_parse_id2(struct ipack_device *dev) +{ + __be16 *id = (__be16 *) dev->id; + + dev->id_vendor = ((be16_to_cpu(id[3]) & 0xff) << 16) + + be16_to_cpu(id[4]); + dev->id_device = be16_to_cpu(id[5]); +} + static int ipack_device_read_id(struct ipack_device *dev) { u8 __iomem *idmem; @@ -183,6 +246,16 @@ static int ipack_device_read_id(struct ipack_device *dev) dev->id[i] = ioread8(idmem + i); } + /* now we can finally work with the copy */ + switch (dev->id_format) { + case IPACK_ID_VERSION_1: + ipack_parse_id1(dev); + break; + case IPACK_ID_VERSION_2: + ipack_parse_id2(dev); + break; + } + out: dev->bus->ops->unmap_space(dev, IPACK_ID_SPACE); diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h index 2851e33..a3cd559 100644 --- a/drivers/staging/ipack/ipack.h +++ b/drivers/staging/ipack/ipack.h @@ -74,8 +74,10 @@ struct ipack_device { struct ipack_addr_space io_space; struct ipack_addr_space mem_space; struct device dev; - unsigned char *id; + u8 *id; size_t id_avail; + u32 id_vendor; + u32 id_device; u8 id_format; }; -- cgit v0.10.2 From 7db5e3cb91efbc8a0803dfdcc3a0c9cb43217df4 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Tue, 4 Sep 2012 17:01:16 +0200 Subject: Staging: ipack: Move device ids from ipoctal.c to ipack_ids.h. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rename them in the process. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index c1d0c00..ed08864 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -25,11 +25,6 @@ #include "ipoctal.h" #include "scc2698.h" -#define IP_OCTAL_MANUFACTURER_ID 0xF0 -#define IP_OCTAL_232_ID 0x22 -#define IP_OCTAL_422_ID 0x2A -#define IP_OCTAL_485_ID 0x48 - #define IP_OCTAL_ID_SPACE_VECTOR 0x41 #define IP_OCTAL_NB_BLOCKS 4 @@ -231,7 +226,7 @@ static int ipoctal_irq_handler(void *arg) /* In case of RS-485, change from TX to RX when finishing TX. * Half-duplex. */ - if ((ipoctal->board_id == IP_OCTAL_485_ID) && + if ((ipoctal->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) && (sr & SR_TX_EMPTY) && (ipoctal->nb_bytes[channel] == 0)) { ipoctal_write_io_reg(ipoctal, @@ -304,7 +299,7 @@ static int ipoctal_irq_handler(void *arg) if ((ipoctal->nb_bytes[channel] == 0) && (waitqueue_active(&ipoctal->queue[channel]))) { - if (ipoctal->board_id != IP_OCTAL_485_ID) { + if (ipoctal->board_id != IPACK1_DEVICE_ID_SBS_OCTAL_485) { ipoctal->write = 1; wake_up_interruptible(&ipoctal->queue[channel]); } @@ -322,15 +317,16 @@ static int ipoctal_check_model(struct ipack_device *dev, unsigned char *id) unsigned char manufacturerID; unsigned char board_id; + manufacturerID = ioread8(dev->id_space.address + IPACK_IDPROM_OFFSET_MANUFACTURER_ID); - if (manufacturerID != IP_OCTAL_MANUFACTURER_ID) + if (manufacturerID != IPACK1_VENDOR_ID_SBS) return -ENODEV; board_id = ioread8(dev->id_space.address + IPACK_IDPROM_OFFSET_MODEL); switch (board_id) { - case IP_OCTAL_232_ID: - case IP_OCTAL_422_ID: - case IP_OCTAL_485_ID: + case IPACK1_DEVICE_ID_SBS_OCTAL_232: + case IPACK1_DEVICE_ID_SBS_OCTAL_422: + case IPACK1_DEVICE_ID_SBS_OCTAL_485: *id = board_id; break; default: @@ -543,7 +539,7 @@ static int ipoctal_write(struct ipoctal *ipoctal, unsigned int channel, ipoctal_copy_write_buffer(ipoctal, channel, buf, count); /* As the IP-OCTAL 485 only supports half duplex, do it manually */ - if (ipoctal->board_id == IP_OCTAL_485_ID) { + if (ipoctal->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) { ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].w.cr, CR_DISABLE_RX); @@ -654,7 +650,7 @@ static void ipoctal_set_termios(struct tty_struct *tty, /* Set the flow control */ switch (ipoctal->board_id) { - case IP_OCTAL_232_ID: + case IPACK1_DEVICE_ID_SBS_OCTAL_232: if (cflag & CRTSCTS) { mr1 |= MR1_RxRTS_CONTROL_ON; mr2 |= MR2_TxRTS_CONTROL_OFF | MR2_CTS_ENABLE_TX_ON; @@ -663,11 +659,11 @@ static void ipoctal_set_termios(struct tty_struct *tty, mr2 |= MR2_TxRTS_CONTROL_OFF | MR2_CTS_ENABLE_TX_OFF; } break; - case IP_OCTAL_422_ID: + case IPACK1_DEVICE_ID_SBS_OCTAL_422: mr1 |= MR1_RxRTS_CONTROL_OFF; mr2 |= MR2_TxRTS_CONTROL_OFF | MR2_CTS_ENABLE_TX_OFF; break; - case IP_OCTAL_485_ID: + case IPACK1_DEVICE_ID_SBS_OCTAL_485: mr1 |= MR1_RxRTS_CONTROL_OFF; mr2 |= MR2_TxRTS_CONTROL_ON | MR2_CTS_ENABLE_TX_OFF; break; diff --git a/drivers/staging/ipack/ipack_ids.h b/drivers/staging/ipack/ipack_ids.h index ba85ec5..8153fee 100644 --- a/drivers/staging/ipack/ipack_ids.h +++ b/drivers/staging/ipack/ipack_ids.h @@ -25,3 +25,8 @@ #define IPACK1_VENDOR_ID_UNREGISTRED13 0x0D #define IPACK1_VENDOR_ID_UNREGISTRED14 0x0E #define IPACK1_VENDOR_ID_UNREGISTRED15 0x0F + +#define IPACK1_VENDOR_ID_SBS 0xF0 +#define IPACK1_DEVICE_ID_SBS_OCTAL_232 0x22 +#define IPACK1_DEVICE_ID_SBS_OCTAL_422 0x2A +#define IPACK1_DEVICE_ID_SBS_OCTAL_485 0x48 -- cgit v0.10.2 From e80111354ac95cd0453e12caf9044938b7a78137 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Tue, 4 Sep 2012 17:01:17 +0200 Subject: Staging: ipack: Make ipack_driver_ops const. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index ed08864..7e1e6f7 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -28,7 +28,6 @@ #define IP_OCTAL_ID_SPACE_VECTOR 0x41 #define IP_OCTAL_NB_BLOCKS 4 -static struct ipack_driver driver; static const struct tty_operations ipoctal_fops; struct ipoctal { @@ -846,15 +845,18 @@ static void ipoctal_remove(struct ipack_device *device) } } -static struct ipack_driver_ops ipoctal_drv_ops = { +static const struct ipack_driver_ops ipoctal_drv_ops = { .match = ipoctal_match, .probe = ipoctal_probe, .remove = ipoctal_remove, }; +static struct ipack_driver driver = { + .ops = &ipoctal_drv_ops, +}; + static int __init ipoctal_init(void) { - driver.ops = &ipoctal_drv_ops; return ipack_driver_register(&driver, THIS_MODULE, KBUILD_MODNAME); } diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h index a3cd559..e6e38e7 100644 --- a/drivers/staging/ipack/ipack.h +++ b/drivers/staging/ipack/ipack.h @@ -104,7 +104,7 @@ struct ipack_driver_ops { struct ipack_driver { struct device_driver driver; const struct ipack_device_id *id_table; - struct ipack_driver_ops *ops; + const struct ipack_driver_ops *ops; }; /** -- cgit v0.10.2 From fdfc8cf5d28d6ce6fbf795aab456921f4f64d063 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Tue, 4 Sep 2012 17:01:18 +0200 Subject: Staging: ipack/devices/ipoctal: Expose DEVICE_TABLE for ipoctal. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The modalias entries for the module are now created. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index 7e1e6f7..829b887 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -845,6 +845,18 @@ static void ipoctal_remove(struct ipack_device *device) } } +static DEFINE_IPACK_DEVICE_TABLE(ipoctal_ids) = { + { IPACK_DEVICE(IPACK_ID_VERSION_1, IPACK1_VENDOR_ID_SBS, + IPACK1_DEVICE_ID_SBS_OCTAL_232) }, + { IPACK_DEVICE(IPACK_ID_VERSION_1, IPACK1_VENDOR_ID_SBS, + IPACK1_DEVICE_ID_SBS_OCTAL_422) }, + { IPACK_DEVICE(IPACK_ID_VERSION_1, IPACK1_VENDOR_ID_SBS, + IPACK1_DEVICE_ID_SBS_OCTAL_485) }, + { 0, }, +}; + +MODULE_DEVICE_TABLE(ipack, ipoctal_ids); + static const struct ipack_driver_ops ipoctal_drv_ops = { .match = ipoctal_match, .probe = ipoctal_probe, @@ -853,6 +865,7 @@ static const struct ipack_driver_ops ipoctal_drv_ops = { static struct ipack_driver driver = { .ops = &ipoctal_drv_ops, + .id_table = ipoctal_ids, }; static int __init ipoctal_init(void) -- cgit v0.10.2 From 4aa09d47d45ee8ced196c49031159ada2aef5b1d Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Tue, 4 Sep 2012 17:01:19 +0200 Subject: Staging: ipack: Implement device matching on the bus level. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Devices are match based upon their vendor and device ids. Since the individual drivers provide a list of supported ids they do not need to implement the matching themselves. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index 829b887..c94a9df 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -777,27 +777,6 @@ static const struct tty_operations ipoctal_fops = { .hangup = ipoctal_hangup, }; -static int ipoctal_match(struct ipack_device *dev) -{ - int res; - unsigned char board_id; - - if ((!dev->bus->ops) || (!dev->bus->ops->map_space) || - (!dev->bus->ops->unmap_space)) - return 0; - - res = dev->bus->ops->map_space(dev, 0, IPACK_ID_SPACE); - if (res) - return 0; - - res = ipoctal_check_model(dev, &board_id); - dev->bus->ops->unmap_space(dev, IPACK_ID_SPACE); - if (!res) - return 1; - - return 0; -} - static int ipoctal_probe(struct ipack_device *dev) { int res; @@ -858,8 +837,7 @@ static DEFINE_IPACK_DEVICE_TABLE(ipoctal_ids) = { MODULE_DEVICE_TABLE(ipack, ipoctal_ids); static const struct ipack_driver_ops ipoctal_drv_ops = { - .match = ipoctal_match, - .probe = ipoctal_probe, + .probe = ipoctal_probe, .remove = ipoctal_remove, }; diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c index 9474226..a328629 100644 --- a/drivers/staging/ipack/ipack.c +++ b/drivers/staging/ipack/ipack.c @@ -26,20 +26,43 @@ static void ipack_device_release(struct device *dev) kfree(device); } -static int ipack_bus_match(struct device *device, struct device_driver *driver) +static inline const struct ipack_device_id * +ipack_match_one_device(const struct ipack_device_id *id, + const struct ipack_device *device) { - int ret; - struct ipack_device *dev = to_ipack_dev(device); - struct ipack_driver *drv = to_ipack_driver(driver); + if ((id->format == IPACK_ANY_ID || id->format == device->id_format) && + (id->vendor == IPACK_ANY_ID || id->vendor == device->id_vendor) && + (id->device == IPACK_ANY_ID || id->device == device->id_device)) + return id; + return NULL; +} - if ((!drv->ops) || (!drv->ops->match)) - return -EINVAL; +static const struct ipack_device_id * +ipack_match_id(const struct ipack_device_id *ids, struct ipack_device *idev) +{ + if (ids) { + while (ids->vendor || ids->device) { + if (ipack_match_one_device(ids, idev)) + return ids; + ids++; + } + } + return NULL; +} - ret = drv->ops->match(dev); - if (ret) - dev->driver = drv; +static int ipack_bus_match(struct device *dev, struct device_driver *drv) +{ + struct ipack_device *idev = to_ipack_dev(dev); + struct ipack_driver *idrv = to_ipack_driver(drv); + const struct ipack_device_id *found_id; - return ret; + found_id = ipack_match_id(idrv->id_table, idev); + if (found_id) { + idev->driver = idrv; + return 1; + } + + return 0; } static int ipack_bus_probe(struct device *device) diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h index e6e38e7..0f482fd 100644 --- a/drivers/staging/ipack/ipack.h +++ b/drivers/staging/ipack/ipack.h @@ -84,13 +84,11 @@ struct ipack_device { /** * struct ipack_driver_ops -- callbacks to mezzanine driver for installing/removing one device * - * @match: Match function * @probe: Probe function * @remove: tell the driver that the carrier board wants to remove one device */ struct ipack_driver_ops { - int (*match) (struct ipack_device *dev); int (*probe) (struct ipack_device *dev); void (*remove) (struct ipack_device *dev); }; -- cgit v0.10.2 From 35eb97bb67e7581ba1372ffc8c28770ca0568404 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Tue, 4 Sep 2012 17:01:20 +0200 Subject: Staging: ipack: Expose modalias through sysfs. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also include it in the hotplug event so that udev can provide the respective driver. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c index a328629..a5ef28f 100644 --- a/drivers/staging/ipack/ipack.c +++ b/drivers/staging/ipack/ipack.c @@ -86,6 +86,31 @@ static int ipack_bus_remove(struct device *device) return 0; } +#ifdef CONFIG_HOTPLUG + +static int ipack_uevent(struct device *dev, struct kobj_uevent_env *env) +{ + struct ipack_device *idev; + + if (!dev) + return -ENODEV; + + idev = to_ipack_dev(dev); + + if (add_uevent_var(env, + "MODALIAS=ipack:f%02Xv%08Xd%08X", idev->id_format, + idev->id_vendor, idev->id_device)) + return -ENOMEM; + + return 0; +} + +#else /* !CONFIG_HOTPLUG */ + +#define ipack_uevent NULL + +#endif /* !CONFIG_HOTPLUG */ + #define ipack_device_attr(field, format_string) \ static ssize_t \ field##_show(struct device *dev, struct device_attribute *attr, \ @@ -123,12 +148,22 @@ id_device_show(struct device *dev, struct device_attribute *attr, char *buf) } } +static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct ipack_device *idev = to_ipack_dev(dev); + + return sprintf(buf, "ipac:f%02Xv%08Xd%08X", idev->id_format, + idev->id_vendor, idev->id_device); +} + ipack_device_attr(id_format, "0x%hhu\n"); static struct device_attribute ipack_dev_attrs[] = { __ATTR_RO(id_device), __ATTR_RO(id_format), __ATTR_RO(id_vendor), + __ATTR_RO(modalias), }; static struct bus_type ipack_bus_type = { @@ -137,6 +172,7 @@ static struct bus_type ipack_bus_type = { .match = ipack_bus_match, .remove = ipack_bus_remove, .dev_attrs = ipack_dev_attrs, + .uevent = ipack_uevent, }; struct ipack_bus_device *ipack_bus_register(struct device *parent, int slots, -- cgit v0.10.2 From 5d72c848d2a3b4af7f8f32d89af02a486d321bd6 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Tue, 4 Sep 2012 17:01:21 +0200 Subject: Staging: ipack: Provide ID Prom through sysfs. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c index a5ef28f..ff907fa 100644 --- a/drivers/staging/ipack/ipack.c +++ b/drivers/staging/ipack/ipack.c @@ -120,6 +120,36 @@ field##_show(struct device *dev, struct device_attribute *attr, \ return sprintf(buf, format_string, idev->field); \ } +static ssize_t id_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned int i, c, l, s; + struct ipack_device *idev = to_ipack_dev(dev); + + + switch (idev->id_format) { + case IPACK_ID_VERSION_1: + l = 0x7; s = 1; break; + case IPACK_ID_VERSION_2: + l = 0xf; s = 2; break; + default: + return -EIO; + } + c = 0; + for (i = 0; i < idev->id_avail; i++) { + if (i > 0) { + if ((i & l) == 0) + buf[c++] = '\n'; + else if ((i & s) == 0) + buf[c++] = ' '; + } + sprintf(&buf[c], "%02x", idev->id[i]); + c += 2; + } + buf[c++] = '\n'; + return c; +} + static ssize_t id_vendor_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -160,6 +190,7 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, ipack_device_attr(id_format, "0x%hhu\n"); static struct device_attribute ipack_dev_attrs[] = { + __ATTR_RO(id), __ATTR_RO(id_device), __ATTR_RO(id_format), __ATTR_RO(id_vendor), -- cgit v0.10.2 From 1549360ae7d050d9dfff53012f1ef43c181a7024 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Sep 2012 15:28:26 -0700 Subject: staging: comedi: addi_apci_all.c: remove unused file The Makefile for the comedi subsystem does not compile this file for any .config selection. This file would allow building one big driver to support all the addi-data cards. The addi-data drivers are a big enough mess as-is. Just remove this file. Signed-off-by: H Hartley Sweeten Cc: Iam Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/addi_apci_all.c b/drivers/staging/comedi/drivers/addi_apci_all.c deleted file mode 100644 index aeb1b26..0000000 --- a/drivers/staging/comedi/drivers/addi_apci_all.c +++ /dev/null @@ -1,18 +0,0 @@ -#define CONFIG_APCI_035 1 -#define CONFIG_APCI_1032 1 -#define CONFIG_APCI_1500 1 -#define CONFIG_APCI_1516 1 -#define CONFIG_APCI_1564 1 -#define CONFIG_APCI_16XX 1 -#define CONFIG_APCI_1710 1 -#define CONFIG_APCI_2016 1 -#define CONFIG_APCI_2032 1 -#define CONFIG_APCI_2200 1 -#define CONFIG_APCI_3001 1 -#define CONFIG_APCI_3120 1 -#define CONFIG_APCI_3200 1 -#define CONFIG_APCI_3300 1 -#define CONFIG_APCI_3501 1 -#define CONFIG_APCI_3XXX 1 - -#include "addi-data/addi_common.c" -- cgit v0.10.2 From a8b1e45f56732041c6f1b052939adc2a37f1df1e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Sep 2012 15:28:54 -0700 Subject: staging: comedi: amcc_s5933_58.h: remove unused file Nothing in the comedi subsystem references this header file. It's actually almost a straight copy of the addi_amcc_s5933.h file anyway. Just remove the file. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/addi-data/amcc_s5933_58.h b/drivers/staging/comedi/drivers/addi-data/amcc_s5933_58.h deleted file mode 100644 index c26c28c..0000000 --- a/drivers/staging/comedi/drivers/addi-data/amcc_s5933_58.h +++ /dev/null @@ -1,453 +0,0 @@ -/* - Modified by umesh on 16th may 2001 - Modified by sarath on 22nd may 2001 -*/ - -/* - comedi/drivers/amcc_s5933_v_58.h - - Stuff for AMCC S5933 PCI Controller - - Author: Michal Dobes - - Inspirated from general-purpose AMCC S5933 PCI Matchmaker driver - made by Andrea Cisternino - and as result of espionage from MITE code made by David A. Schleef. - Thanks to AMCC for their on-line documentation and bus master DMA - example. -*/ - -#ifndef _AMCC_S5933_H_ -#define _AMCC_S5933_H_ - -#include -#include "../../comedidev.h" - -/***********Added by sarath for compatibility with APCI3120 - -*************************/ - -#define FIFO_ADVANCE_ON_BYTE_2 0x20000000 /* written on base0 */ - -#define AMWEN_ENABLE 0x02 /* added for step 6 dma written on base2 */ -#define A2P_FIFO_WRITE_ENABLE 0x01 - -#define AGCSTS_TC_ENABLE 0x10000000 /* Added for transfer count enable bit */ - -/* ADDON RELATED ADDITIONS */ -/* Constant */ -#define APCI3120_ENABLE_TRANSFER_ADD_ON_LOW 0x00 -#define APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH 0x1200 -#define APCI3120_A2P_FIFO_MANAGEMENT 0x04000400L -#define APCI3120_AMWEN_ENABLE 0x02 -#define APCI3120_A2P_FIFO_WRITE_ENABLE 0x01 -#define APCI3120_FIFO_ADVANCE_ON_BYTE_2 0x20000000L -#define APCI3120_ENABLE_WRITE_TC_INT 0x00004000L -#define APCI3120_CLEAR_WRITE_TC_INT 0x00040000L -#define APCI3120_DISABLE_AMWEN_AND_A2P_FIFO_WRITE 0x0 -#define APCI3120_DISABLE_BUS_MASTER_ADD_ON 0x0 -#define APCI3120_DISABLE_BUS_MASTER_PCI 0x0 - - /* ADD_ON ::: this needed since apci supports 16 bit interface to add on */ -#define APCI3120_ADD_ON_AGCSTS_LOW 0x3C -#define APCI3120_ADD_ON_AGCSTS_HIGH APCI3120_ADD_ON_AGCSTS_LOW + 2 -#define APCI3120_ADD_ON_MWAR_LOW 0x24 -#define APCI3120_ADD_ON_MWAR_HIGH APCI3120_ADD_ON_MWAR_LOW + 2 -#define APCI3120_ADD_ON_MWTC_LOW 0x058 -#define APCI3120_ADD_ON_MWTC_HIGH APCI3120_ADD_ON_MWTC_LOW + 2 - -/* AMCC */ -#define APCI3120_AMCC_OP_MCSR 0x3C -#define APCI3120_AMCC_OP_REG_INTCSR 0x38 - -/*******from here all upward definitions are added by sarath */ - -/****************************************************************************/ -/* AMCC Operation Register Offsets - PCI */ -/****************************************************************************/ - -#define AMCC_OP_REG_OMB1 0x00 -#define AMCC_OP_REG_OMB2 0x04 -#define AMCC_OP_REG_OMB3 0x08 -#define AMCC_OP_REG_OMB4 0x0c -#define AMCC_OP_REG_IMB1 0x10 -#define AMCC_OP_REG_IMB2 0x14 -#define AMCC_OP_REG_IMB3 0x18 -#define AMCC_OP_REG_IMB4 0x1c -#define AMCC_OP_REG_FIFO 0x20 -#define AMCC_OP_REG_MWAR 0x24 -#define AMCC_OP_REG_MWTC 0x28 -#define AMCC_OP_REG_MRAR 0x2c -#define AMCC_OP_REG_MRTC 0x30 -#define AMCC_OP_REG_MBEF 0x34 -#define AMCC_OP_REG_INTCSR 0x38 -#define AMCC_OP_REG_INTCSR_SRC (AMCC_OP_REG_INTCSR + 2) /* int source */ -#define AMCC_OP_REG_INTCSR_FEC (AMCC_OP_REG_INTCSR + 3) /* FIFO ctrl */ -#define AMCC_OP_REG_MCSR 0x3c -#define AMCC_OP_REG_MCSR_NVDATA (AMCC_OP_REG_MCSR + 2) /* Data in byte 2 */ -#define AMCC_OP_REG_MCSR_NVCMD (AMCC_OP_REG_MCSR + 3) /* Command in byte 3 */ - -#define AMCC_FIFO_DEPTH_DWORD 8 -#define AMCC_FIFO_DEPTH_BYTES (8 * sizeof (u32)) - -/****************************************************************************/ -/* AMCC Operation Registers Size - PCI */ -/****************************************************************************/ - -#define AMCC_OP_REG_SIZE 64 /* in bytes */ - -/****************************************************************************/ -/* AMCC Operation Register Offsets - Add-on */ -/****************************************************************************/ - -#define AMCC_OP_REG_AIMB1 0x00 -#define AMCC_OP_REG_AIMB2 0x04 -#define AMCC_OP_REG_AIMB3 0x08 -#define AMCC_OP_REG_AIMB4 0x0c -#define AMCC_OP_REG_AOMB1 0x10 -#define AMCC_OP_REG_AOMB2 0x14 -#define AMCC_OP_REG_AOMB3 0x18 -#define AMCC_OP_REG_AOMB4 0x1c -#define AMCC_OP_REG_AFIFO 0x20 -#define AMCC_OP_REG_AMWAR 0x24 -#define AMCC_OP_REG_APTA 0x28 -#define AMCC_OP_REG_APTD 0x2c -#define AMCC_OP_REG_AMRAR 0x30 -#define AMCC_OP_REG_AMBEF 0x34 -#define AMCC_OP_REG_AINT 0x38 -#define AMCC_OP_REG_AGCSTS 0x3c -#define AMCC_OP_REG_AMWTC 0x58 -#define AMCC_OP_REG_AMRTC 0x5c - -/****************************************************************************/ -/* AMCC - Add-on General Control/Status Register */ -/****************************************************************************/ - -#define AGCSTS_CONTROL_MASK 0xfffff000 -#define AGCSTS_NV_ACC_MASK 0xe0000000 -#define AGCSTS_RESET_MASK 0x0e000000 -#define AGCSTS_NV_DA_MASK 0x00ff0000 -#define AGCSTS_BIST_MASK 0x0000f000 -#define AGCSTS_STATUS_MASK 0x000000ff -#define AGCSTS_TCZERO_MASK 0x000000c0 -#define AGCSTS_FIFO_ST_MASK 0x0000003f - -#define AGCSTS_RESET_MBFLAGS 0x08000000 -#define AGCSTS_RESET_P2A_FIFO 0x04000000 -#define AGCSTS_RESET_A2P_FIFO 0x02000000 -#define AGCSTS_RESET_FIFOS (AGCSTS_RESET_A2P_FIFO | AGCSTS_RESET_P2A_FIFO) - -#define AGCSTS_A2P_TCOUNT 0x00000080 -#define AGCSTS_P2A_TCOUNT 0x00000040 - -#define AGCSTS_FS_P2A_EMPTY 0x00000020 -#define AGCSTS_FS_P2A_HALF 0x00000010 -#define AGCSTS_FS_P2A_FULL 0x00000008 - -#define AGCSTS_FS_A2P_EMPTY 0x00000004 -#define AGCSTS_FS_A2P_HALF 0x00000002 -#define AGCSTS_FS_A2P_FULL 0x00000001 - -/****************************************************************************/ -/* AMCC - Add-on Interrupt Control/Status Register */ -/****************************************************************************/ - -#define AINT_INT_MASK 0x00ff0000 -#define AINT_SEL_MASK 0x0000ffff -#define AINT_IS_ENSEL_MASK 0x00001f1f - -#define AINT_INT_ASSERTED 0x00800000 -#define AINT_BM_ERROR 0x00200000 -#define AINT_BIST_INT 0x00100000 - -#define AINT_RT_COMPLETE 0x00080000 -#define AINT_WT_COMPLETE 0x00040000 - -#define AINT_OUT_MB_INT 0x00020000 -#define AINT_IN_MB_INT 0x00010000 - -#define AINT_READ_COMPL 0x00008000 -#define AINT_WRITE_COMPL 0x00004000 - -#define AINT_OMB_ENABLE 0x00001000 -#define AINT_OMB_SELECT 0x00000c00 -#define AINT_OMB_BYTE 0x00000300 - -#define AINT_IMB_ENABLE 0x00000010 -#define AINT_IMB_SELECT 0x0000000c -#define AINT_IMB_BYTE 0x00000003 - -/* Enable Bus Mastering */ -#define EN_A2P_TRANSFERS 0x00000400 -/* FIFO Flag Reset */ -#define RESET_A2P_FLAGS 0x04000000L -/* FIFO Relative Priority */ -#define A2P_HI_PRIORITY 0x00000100L -/* Identify Interrupt Sources */ -#define ANY_S593X_INT 0x00800000L -#define READ_TC_INT 0x00080000L -#define WRITE_TC_INT 0x00040000L -#define IN_MB_INT 0x00020000L -#define MASTER_ABORT_INT 0x00100000L -#define TARGET_ABORT_INT 0x00200000L -#define BUS_MASTER_INT 0x00200000L - -/****************************************************************************/ - -struct pcilst_struct { - struct pcilst_struct *next; - int used; - struct pci_dev *pcidev; - unsigned short vendor; - unsigned short device; - unsigned int master; - unsigned char pci_bus; - unsigned char pci_slot; - unsigned char pci_func; - unsigned int io_addr[5]; - unsigned int irq; -}; - -struct pcilst_struct *amcc_devices; /* ptr to root list of all amcc devices */ - -/****************************************************************************/ - -void v_pci_card_list_init(unsigned short pci_vendor, char display); -void v_pci_card_list_cleanup(unsigned short pci_vendor); -struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id, - unsigned short - device_id); -int i_find_free_pci_card_by_position(unsigned short vendor_id, - unsigned short device_id, - unsigned short pci_bus, - unsigned short pci_slot, - struct pcilst_struct **card); -struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id, - unsigned short device_id, - unsigned short pci_bus, - unsigned short pci_slot); - -int i_pci_card_alloc(struct pcilst_struct *amcc); -int i_pci_card_free(struct pcilst_struct *amcc); -void v_pci_card_list_display(void); -int i_pci_card_data(struct pcilst_struct *amcc, - unsigned char *pci_bus, unsigned char *pci_slot, - unsigned char *pci_func, unsigned short *io_addr, - unsigned short *irq, unsigned short *master); - -/****************************************************************************/ - -/* build list of amcc cards in this system */ -void v_pci_card_list_init(unsigned short pci_vendor, char display) -{ - struct pci_dev *pcidev; - struct pcilst_struct *amcc, *last; - int i; - - amcc_devices = NULL; - last = NULL; - - pci_for_each_dev(pcidev) { - if (pcidev->vendor == pci_vendor) { - amcc = kzalloc(sizeof(*amcc), GFP_KERNEL); - if (amcc == NULL) - continue; - - amcc->pcidev = pcidev; - if (last) { - last->next = amcc; - } else { - amcc_devices = amcc; - } - last = amcc; - - amcc->vendor = pcidev->vendor; - amcc->device = pcidev->device; -#if 0 - amcc->master = pcidev->master; /* how get this information under 2.4 kernels? */ -#endif - amcc->pci_bus = pcidev->bus->number; - amcc->pci_slot = PCI_SLOT(pcidev->devfn); - amcc->pci_func = PCI_FUNC(pcidev->devfn); - for (i = 0; i < 5; i++) - amcc->io_addr[i] = - pcidev->resource[i].start & ~3UL; - amcc->irq = pcidev->irq; - } - } - - if (display) - v_pci_card_list_display(); -} - -/****************************************************************************/ -/* free up list of amcc cards in this system */ -void v_pci_card_list_cleanup(unsigned short pci_vendor) -{ - struct pcilst_struct *amcc, *next; - - for (amcc = amcc_devices; amcc; amcc = next) { - next = amcc->next; - kfree(amcc); - } - - amcc_devices = NULL; -} - -/****************************************************************************/ -/* find first unused card with this device_id */ -struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id, - unsigned short device_id) -{ - struct pcilst_struct *amcc, *next; - - for (amcc = amcc_devices; amcc; amcc = next) { - next = amcc->next; - if ((!amcc->used) && (amcc->device == device_id) - && (amcc->vendor == vendor_id)) - return amcc; - - } - - return NULL; -} - -/****************************************************************************/ -/* find card on requested position */ -int i_find_free_pci_card_by_position(unsigned short vendor_id, - unsigned short device_id, - unsigned short pci_bus, - unsigned short pci_slot, - struct pcilst_struct **card) -{ - struct pcilst_struct *amcc, *next; - - *card = NULL; - for (amcc = amcc_devices; amcc; amcc = next) { - next = amcc->next; - if ((amcc->vendor == vendor_id) && (amcc->device == device_id) - && (amcc->pci_bus == pci_bus) - && (amcc->pci_slot == pci_slot)) { - if (!(amcc->used)) { - *card = amcc; - return 0; /* ok, card is found */ - } else { - printk - (" - \nCard on requested position is used b:s %d:%d!\n", - pci_bus, pci_slot); - return 2; /* card exist but is used */ - } - } - } - - return 1; /* no card found */ -} - -/****************************************************************************/ -/* mark card as used */ -int i_pci_card_alloc(struct pcilst_struct *amcc) -{ - if (!amcc) - return -1; - - if (amcc->used) - return 1; - amcc->used = 1; - return 0; -} - -/****************************************************************************/ -/* mark card as free */ -int i_pci_card_free(struct pcilst_struct *amcc) -{ - if (!amcc) - return -1; - - if (!amcc->used) - return 1; - amcc->used = 0; - return 0; -} - -/****************************************************************************/ -/* display list of found cards */ -void v_pci_card_list_display(void) -{ - struct pcilst_struct *amcc, *next; - - printk("List of pci cards\n"); - printk("bus:slot:func vendor device master io_amcc io_daq irq used\n"); - - for (amcc = amcc_devices; amcc; amcc = next) { - next = amcc->next; - printk - ("%2d %2d %2d 0x%4x 0x%4x %3s 0x%4x 0x%4x %2d %2d\n", - amcc->pci_bus, amcc->pci_slot, amcc->pci_func, - amcc->vendor, amcc->device, amcc->master ? "yes" : "no", - amcc->io_addr[0], amcc->io_addr[2], amcc->irq, amcc->used); - - } -} - -/****************************************************************************/ -/* return all card information for driver */ -int i_pci_card_data(struct pcilst_struct *amcc, - unsigned char *pci_bus, unsigned char *pci_slot, - unsigned char *pci_func, unsigned short *io_addr, - unsigned short *irq, unsigned short *master) -{ - int i; - - if (!amcc) - return -1; - *pci_bus = amcc->pci_bus; - *pci_slot = amcc->pci_slot; - *pci_func = amcc->pci_func; - for (i = 0; i < 5; i++) - io_addr[i] = amcc->io_addr[i]; - *irq = amcc->irq; - *master = amcc->master; - return 0; -} - -/****************************************************************************/ -/* select and alloc card */ -struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id, - unsigned short device_id, - unsigned short pci_bus, - unsigned short pci_slot) -{ - struct pcilst_struct *card; - - if ((pci_bus < 1) & (pci_slot < 1)) { /* use autodetection */ - card = ptr_find_free_pci_card_by_device(vendor_id, device_id); - if (card == NULL) { - printk(" - Unused card not found in system!\n"); - return NULL; - } - } else { - switch (i_find_free_pci_card_by_position(vendor_id, device_id, - pci_bus, pci_slot, - &card)) { - case 1: - printk - (" - Card not found on requested position b:s %d:%d!\n", - pci_bus, pci_slot); - return NULL; - case 2: - printk - (" - Card on requested position is used b:s %d:%d!\n", - pci_bus, pci_slot); - return NULL; - } - } - - if (i_pci_card_alloc(card) != 0) { - printk(" - Can't allocate card!\n"); - return NULL; - } - - return card; -} - -#endif -- cgit v0.10.2 From fd445899d1aa0b49bf725ab98f2f052a38823bc5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Sep 2012 15:29:28 -0700 Subject: staging: comedi: addi_amcc_S5920.[ch]: remove unnecessary files The addi_amcc_S5920.c file only has the function i_AddiHeaderRW_ReadEeprom() in it. The addi_amcc_S5920.h file has a prototype for this function and a couple defines for the magic numbers used when accessing the eeprom. The .c file is not actually built by any .config selection, or by an The .h file is only #include'd by the hwdrv_apci3200.c file. That file actually has a local version of the i_AddiHeaderRW_ReadEeprom() function that is identical to the one in the .c file. Just move the #define's from the .h file into hwdrv_apci3200.c and remove the addi_amcc_S5920.[ch] files. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c b/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c deleted file mode 100644 index b973095..0000000 --- a/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c +++ /dev/null @@ -1,195 +0,0 @@ -/** -@verbatim - -Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - - ADDI-DATA GmbH - Dieselstrasse 3 - D-77833 Ottersweier - Tel: +19(0)7223/9493-0 - Fax: +49(0)7223/9493-92 - http://www.addi-data.com - info@addi-data.com - -This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -You should also find the complete GPL in the COPYING file accompanying this source code. - -@endverbatim -*/ -/* - +-----------------------------------------------------------------------+ - | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier | - +-----------------------------------------------------------------------+ - | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com | - | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com | - +-------------------------------+---------------------------------------+ - | Project : ADDI HEADER READ WRITER | Compiler : Visual C++ | - | Module name : S5920.cpp | Version : 6.0 | - +-------------------------------+---------------------------------------+ - | Author : E. LIBS Date : 02/05/2002 | - +-----------------------------------------------------------------------+ - | Description : DLL with the S5920 PCI Controller functions | - +-----------------------------------------------------------------------+ - | UPDATE'S | - +-----------------------------------------------------------------------+ - | Date | Author | Description of updates | - +----------+-----------+------------------------------------------------+ - | 28/08/02 | LIBS Eric | Add return codes each time a function of the | - | | | Addi Library is called | - +-----------------------------------------------------------------------+ - | 31/07/03 | KRAUTH J. | Changes for the MSX-Box | - +-----------------------------------------------------------------------+ -*/ - -#include "addi_amcc_S5920.h" - -/*+----------------------------------------------------------------------------+*/ -/*| Function Name : int i_AddiHeaderRW_ReadEeprom |*/ -/*| (int i_NbOfWordsToRead, |*/ -/*| unsigned int dw_PCIBoardEepromAddress, |*/ -/*| unsigned short w_EepromStartAddress, |*/ -/*| unsigned short * pw_DataRead) |*/ -/*+----------------------------------------------------------------------------+*/ -/*| Task : Read word from the 5920 eeprom. |*/ -/*+----------------------------------------------------------------------------+*/ -/*| Input Parameters : int i_NbOfWordsToRead : Nbr. of word to read |*/ -/*| unsigned int dw_PCIBoardEepromAddress : Address of the eeprom |*/ -/*| unsigned short w_EepromStartAddress : Eeprom start address |*/ -/*+----------------------------------------------------------------------------+*/ -/*| Output Parameters : unsigned short * pw_DataRead : Read data |*/ -/*+----------------------------------------------------------------------------+*/ -/*| Return Value : - |*/ -/*+----------------------------------------------------------------------------+*/ - -int i_AddiHeaderRW_ReadEeprom(int i_NbOfWordsToRead, - unsigned int dw_PCIBoardEepromAddress, - unsigned short w_EepromStartAddress, unsigned short *pw_DataRead) -{ - unsigned int dw_eeprom_busy = 0; - int i_Counter = 0; - int i_WordCounter; - int i; - unsigned char pb_ReadByte[1]; - unsigned char b_ReadLowByte = 0; - unsigned char b_ReadHighByte = 0; - unsigned char b_SelectedAddressLow = 0; - unsigned char b_SelectedAddressHigh = 0; - unsigned short w_ReadWord = 0; - - for (i_WordCounter = 0; i_WordCounter < i_NbOfWordsToRead; - i_WordCounter++) { - do { - dw_eeprom_busy = - inl(dw_PCIBoardEepromAddress + - AMCC_OP_REG_MCSR); - dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY; - } while (dw_eeprom_busy == EEPROM_BUSY); - - for (i_Counter = 0; i_Counter < 2; i_Counter++) { - b_SelectedAddressLow = (w_EepromStartAddress + i_Counter) % 256; /* Read the low 8 bit part */ - b_SelectedAddressHigh = (w_EepromStartAddress + i_Counter) / 256; /* Read the high 8 bit part */ - - /* Select the load low address mode */ - outb(NVCMD_LOAD_LOW, - dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR + - 3); - - /* Wait on busy */ - do { - dw_eeprom_busy = - inl(dw_PCIBoardEepromAddress + - AMCC_OP_REG_MCSR); - dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY; - } while (dw_eeprom_busy == EEPROM_BUSY); - - /* Load the low address */ - outb(b_SelectedAddressLow, - dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR + - 2); - - /* Wait on busy */ - do { - dw_eeprom_busy = - inl(dw_PCIBoardEepromAddress + - AMCC_OP_REG_MCSR); - dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY; - } while (dw_eeprom_busy == EEPROM_BUSY); - - /* Select the load high address mode */ - outb(NVCMD_LOAD_HIGH, - dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR + - 3); - - /* Wait on busy */ - do { - dw_eeprom_busy = - inl(dw_PCIBoardEepromAddress + - AMCC_OP_REG_MCSR); - dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY; - } while (dw_eeprom_busy == EEPROM_BUSY); - - /* Load the high address */ - outb(b_SelectedAddressHigh, - dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR + - 2); - - /* Wait on busy */ - do { - dw_eeprom_busy = - inl(dw_PCIBoardEepromAddress + - AMCC_OP_REG_MCSR); - dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY; - } while (dw_eeprom_busy == EEPROM_BUSY); - - /* Select the READ mode */ - outb(NVCMD_BEGIN_READ, - dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR + - 3); - - /* Wait on busy */ - do { - dw_eeprom_busy = - inl(dw_PCIBoardEepromAddress + - AMCC_OP_REG_MCSR); - dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY; - } while (dw_eeprom_busy == EEPROM_BUSY); - - /* Read data into the EEPROM */ - *pb_ReadByte = - inb(dw_PCIBoardEepromAddress + - AMCC_OP_REG_MCSR + 2); - - /* Wait on busy */ - do { - dw_eeprom_busy = - inl(dw_PCIBoardEepromAddress + - AMCC_OP_REG_MCSR); - dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY; - } while (dw_eeprom_busy == EEPROM_BUSY); - - /* Select the upper address part */ - if (i_Counter == 0) - b_ReadLowByte = pb_ReadByte[0]; - else - b_ReadHighByte = pb_ReadByte[0]; - - /* Sleep */ - msleep(1); - - } - w_ReadWord = - (b_ReadLowByte | (((unsigned short)b_ReadHighByte) * - 256)); - - pw_DataRead[i_WordCounter] = w_ReadWord; - - w_EepromStartAddress += 2; /* to read the next word */ - - } /* for (...) i_NbOfWordsToRead */ - return 0; -} diff --git a/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.h b/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.h deleted file mode 100644 index 9afdb13..0000000 --- a/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - * - * ADDI-DATA GmbH - * Dieselstrasse 3 - * D-77833 Ottersweier - * Tel: +19(0)7223/9493-0 - * Fax: +49(0)7223/9493-92 - * http://www.addi-data.com - * info@addi-data.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#define AMCC_OP_REG_MCSR 0x3c -#define EEPROM_BUSY 0x80000000 -#define NVCMD_LOAD_LOW (0x4 << 5) /* nvRam load low command */ -#define NVCMD_LOAD_HIGH (0x5 << 5) /* nvRam load high command */ -#define NVCMD_BEGIN_READ (0x7 << 5) /* nvRam begin read command */ -#define NVCMD_BEGIN_WRITE (0x6 << 5) /* EEPROM begin write command */ - -int i_AddiHeaderRW_ReadEeprom(int i_NbOfWordsToRead, - unsigned int dw_PCIBoardEepromAddress, - unsigned short w_EepromStartAddress, unsigned short *pw_DataRead); diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c index f9545b0..5aed4a1 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c @@ -57,11 +57,8 @@ You should also find the complete GPL in the COPYING file accompanying this sour +----------------------------------------------------------------------------+ */ #include "hwdrv_apci3200.h" -/* Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ -#include "addi_amcc_S5920.h" -/* #define PRINT_INFO */ -/* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ +/* #define PRINT_INFO */ /* BEGIN JK 06.07.04: Management of sevrals boards */ /* @@ -90,7 +87,12 @@ You should also find the complete GPL in the COPYING file accompanying this sour struct str_BoardInfos s_BoardInfos[100]; /* 100 will be the max number of boards to be used */ /* END JK 06.07.04: Management of sevrals boards */ -/* Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ +#define AMCC_OP_REG_MCSR 0x3c +#define EEPROM_BUSY 0x80000000 +#define NVCMD_LOAD_LOW (0x4 << 5) /* nvRam load low command */ +#define NVCMD_LOAD_HIGH (0x5 << 5) /* nvRam load high command */ +#define NVCMD_BEGIN_READ (0x7 << 5) /* nvRam begin read command */ +#define NVCMD_BEGIN_WRITE (0x6 << 5) /* EEPROM begin write command */ /*+----------------------------------------------------------------------------+*/ /*| Function Name : int i_AddiHeaderRW_ReadEeprom |*/ -- cgit v0.10.2 From c396147048fff69d764e5c3d2adca875c7c90a58 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 5 Sep 2012 11:02:39 +0100 Subject: staging: comedi: das08: No need to manipulate PCI ref count Now that this driver no longer supports "manual" attachment of PCI devices in its `attach` hook (`das08_attach()`), it no longer has code that searches for a suitable PCI device and increments its reference count. Since the driver no longer has any reason for incrementing and decrementing the PCI device's reference count, the calls to `pci_dev_get()` and `pci_dev_put()` can be removed. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 70ad8af..2614961 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -793,13 +793,6 @@ das08_attach_pci(struct comedi_device *dev, struct pci_dev *pdev) dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); return -EINVAL; } - /* - * Need to 'get' the PCI device to match the 'put' in das08_detach(). - * TODO: Remove the pci_dev_get() and matching pci_dev_put() once - * support for manual attachment of PCI devices via das08_attach() - * has been removed. - */ - pci_dev_get(pdev); devpriv = dev->private; devpriv->pdev = pdev; /* enable PCI device and reserve I/O spaces */ @@ -864,7 +857,6 @@ static void __maybe_unused das08_detach(struct comedi_device *dev) if (devpriv && devpriv->pdev) { if (dev->iobase) comedi_pci_disable(devpriv->pdev); - pci_dev_put(devpriv->pdev); } } } -- cgit v0.10.2 From 40a3ee02f8ce9ecdc1ea085d0b59502baa8976c3 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 5 Sep 2012 11:02:40 +0100 Subject: staging: comedi: das08: Use struct comedi_device hw_dev for PCI Remove the pointer to the PCI device from the private data `struct das08_private_struct`. Use `comedi_set_hw_dev()` to save a pointer to the PCI device (actually, its embedded `struct device`) and `comedi_to_pci_dev()` to retrieve it. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 2614961..0c69b05 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -778,7 +778,6 @@ das08_find_pci_board(struct pci_dev *pdev) static int __devinit __maybe_unused das08_attach_pci(struct comedi_device *dev, struct pci_dev *pdev) { - struct das08_private_struct *devpriv; unsigned long iobase; int ret; @@ -793,8 +792,7 @@ das08_attach_pci(struct comedi_device *dev, struct pci_dev *pdev) dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); return -EINVAL; } - devpriv = dev->private; - devpriv->pdev = pdev; + comedi_set_hw_dev(dev, &pdev->dev); /* enable PCI device and reserve I/O spaces */ if (comedi_pci_enable(pdev, dev->driver->driver_name)) { dev_err(dev->class_dev, @@ -847,16 +845,16 @@ EXPORT_SYMBOL_GPL(das08_common_detach); static void __maybe_unused das08_detach(struct comedi_device *dev) { const struct das08_board_struct *thisboard = comedi_board(dev); - struct das08_private_struct *devpriv = dev->private; das08_common_detach(dev); if (is_isa_board(thisboard)) { if (dev->iobase) release_region(dev->iobase, thisboard->iosize); } else if (is_pci_board(thisboard)) { - if (devpriv && devpriv->pdev) { + struct pci_dev *pdev = comedi_to_pci_dev(dev); + if (pdev) { if (dev->iobase) - comedi_pci_disable(devpriv->pdev); + comedi_pci_disable(pdev); } } } diff --git a/drivers/staging/comedi/drivers/das08.h b/drivers/staging/comedi/drivers/das08.h index 4231be5..0314bae 100644 --- a/drivers/staging/comedi/drivers/das08.h +++ b/drivers/staging/comedi/drivers/das08.h @@ -51,7 +51,6 @@ struct das08_private_struct { unsigned int do_mux_bits; /* bits for do/mux register on boards without separate do register */ unsigned int do_bits; /* bits for do register on boards with register dedicated to digital out only */ const unsigned int *pg_gainlist; - struct pci_dev *pdev; /* struct for pci-das08 */ unsigned int ao_readback[2]; /* assume 2 AO channels */ }; -- cgit v0.10.2 From b9f789fb1f439e8dad14e4da76b7a48fd358c5c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20Iglesias=20Gons=C3=A1lvez?= Date: Wed, 5 Sep 2012 09:08:17 +0200 Subject: Staging: ipack: fix build failure in powerpc allyesconfig MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Caused by commit 187e47824013 ("Staging: ipack: Read the ID space during device registration"). drivers/staging/ipack/ipack.c: In function 'ipack_device_read_id': drivers/staging/ipack/ipack.c:291:2: error: implicit declaration of function 'ioread8' [-Werror=implicit-function-declaration] drivers/staging/ipack/ipack.c:309:3: error: implicit declaration of function 'ioread16be' [-Werror=implicit-function-declaration] Reported-by: Stephen Rothwell Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c index ff907fa..b3736c0 100644 --- a/drivers/staging/ipack/ipack.c +++ b/drivers/staging/ipack/ipack.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "ipack.h" #define to_ipack_dev(device) container_of(device, struct ipack_device, dev) -- cgit v0.10.2 From 094e74c2040b4afce4c41e628811a8eb2ff57878 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 5 Sep 2012 14:48:48 +0800 Subject: staging: ozwpan: use list_move_tail instead of list_del/list_add_tail Using list_move_tail() instead of list_del() + list_add_tail(). spatch with a semantic match is used to found this problem. (http://coccinelle.lip6.fr/) Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ozwpan/ozhcd.c b/drivers/staging/ozwpan/ozhcd.c index 76821cb..2e087ac 100644 --- a/drivers/staging/ozwpan/ozhcd.c +++ b/drivers/staging/ozwpan/ozhcd.c @@ -1068,8 +1068,7 @@ int oz_hcd_heartbeat(void *hport) ep->credit -= urb->number_of_packets; oz_event_log(OZ_EVT_EP_CREDIT, ep->ep_num, 0, 0, ep->credit); - list_del(&urbl->link); - list_add_tail(&urbl->link, &xfr_list); + list_move_tail(&urbl->link, &xfr_list); } } spin_unlock_bh(&ozhcd->hcd_lock); @@ -1150,8 +1149,7 @@ int oz_hcd_heartbeat(void *hport) urb->error_count = 0; urb->start_frame = ep->start_frame; ep->start_frame += urb->number_of_packets; - list_del(&urbl->link); - list_add_tail(&urbl->link, &xfr_list); + list_move_tail(&urbl->link, &xfr_list); ep->credit -= urb->number_of_packets; oz_event_log(OZ_EVT_EP_CREDIT, ep->ep_num | USB_DIR_IN, 0, 0, ep->credit); @@ -1183,8 +1181,7 @@ int oz_hcd_heartbeat(void *hport) oz_trace("%ld: Request 0x%p timeout\n", now, urbl->urb); urbl->submit_jiffies = now; - list_del(e); - list_add_tail(e, &xfr_list); + list_move_tail(e, &xfr_list); } } if (!list_empty(&ep->urb_list)) @@ -1307,16 +1304,14 @@ static void oz_clean_endpoints_for_interface(struct usb_hcd *hcd, port->out_ep[i] = 0; /* Remove from isoc list if present. */ - list_del(e); - list_add_tail(e, &ep_list); + list_move_tail(e, &ep_list); } /* Gather IN endpoints. */ if ((mask & (1<<(i+OZ_NB_ENDPOINTS))) && port->in_ep[i]) { e = &port->in_ep[i]->link; port->in_ep[i] = 0; - list_del(e); - list_add_tail(e, &ep_list); + list_move_tail(e, &ep_list); } } spin_unlock_bh(&ozhcd->hcd_lock); -- cgit v0.10.2 From e5d2cb4a0b59fa3f4ecc2d47ca6afacada7794d2 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 5 Sep 2012 14:49:15 +0800 Subject: staging: gdm72xx: use list_move_tail instead of list_del/list_add_tail Using list_move_tail() instead of list_del() + list_add_tail(). spatch with a semantic match is used to found this problem. (http://coccinelle.lip6.fr/) Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/gdm72xx/gdm_usb.c b/drivers/staging/gdm72xx/gdm_usb.c index c7a22fa..932a797 100644 --- a/drivers/staging/gdm72xx/gdm_usb.c +++ b/drivers/staging/gdm72xx/gdm_usb.c @@ -178,8 +178,7 @@ static struct usb_rx *get_rx_struct(struct rx_cxt *rx) } r = list_entry(rx->free_list.next, struct usb_rx, list); - list_del(&r->list); - list_add_tail(&r->list, &rx->used_list); + list_move_tail(&r->list, &rx->used_list); return r; } -- cgit v0.10.2 From 92adcc805764f5b5c552741298c079ce2de8757e Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Wed, 5 Sep 2012 15:33:46 +0530 Subject: staging: slicoss: remove default case after we done with request_firmware we are returning -ENOENT when there is no firmware file for a matching device id. then we start calling request_firmware, after this we do checks on the firmware length of corresponding device id, since the default case is handled in the begining itself there is no need of a default case at the firmware length checks Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c index 170e0df..10dcd33 100644 --- a/drivers/staging/slicoss/slicoss.c +++ b/drivers/staging/slicoss/slicoss.c @@ -539,9 +539,6 @@ static int slic_card_download_gbrcv(struct adapter *adapter) return -EINVAL; } break; - default: - ASSERT(0); - break; } /* start download */ slic_reg32_write(&slic_regs->slic_rcv_wcs, SLIC_RCVWCS_BEGIN, FLUSH); -- cgit v0.10.2 From 71329965273d65d6de1bc34c6b314515d52ae49a Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Wed, 5 Sep 2012 15:33:48 +0530 Subject: staging: slicoss: clean the spinlock code in slic_entry_open the locked variable is used for checking whether the function acquired lock, then unlock. actually with out this we can achieve the same lock and unlock senario, remove the locked variable and also cleanup the code around. Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c index 10dcd33..850eb10 100644 --- a/drivers/staging/slicoss/slicoss.c +++ b/drivers/staging/slicoss/slicoss.c @@ -3132,7 +3132,6 @@ static int slic_entry_open(struct net_device *dev) { struct adapter *adapter = netdev_priv(dev); struct sliccard *card = adapter->card; - u32 locked = 0; int status; ASSERT(adapter); @@ -3142,7 +3141,6 @@ static int slic_entry_open(struct net_device *dev) spin_lock_irqsave(&slic_global.driver_lock.lock, slic_global.driver_lock.flags); - locked = 1; if (!adapter->activated) { card->adapters_activated++; slic_global.num_slic_ports_active++; @@ -3156,23 +3154,15 @@ static int slic_entry_open(struct net_device *dev) slic_global.num_slic_ports_active--; adapter->activated = 0; } - if (locked) { - spin_unlock_irqrestore(&slic_global.driver_lock.lock, - slic_global.driver_lock.flags); - locked = 0; - } - return status; + goto spin_unlock; } if (!card->master) card->master = adapter; - if (locked) { - spin_unlock_irqrestore(&slic_global.driver_lock.lock, - slic_global.driver_lock.flags); - locked = 0; - } - - return 0; +spin_unlock: + spin_unlock_irqrestore(&slic_global.driver_lock.lock, + slic_global.driver_lock.flags); + return status; } static void slic_card_cleanup(struct sliccard *card) -- cgit v0.10.2 From 8f6f4c17bb9a1c45355254247d164fc3e2a1289b Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Wed, 5 Sep 2012 15:33:49 +0530 Subject: staging: slicoss: remove return statement at the end of slic_mcast_set_list this function return void, means return at the end of this function is not needed Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c index 850eb10..0755bc1 100644 --- a/drivers/staging/slicoss/slicoss.c +++ b/drivers/staging/slicoss/slicoss.c @@ -2552,7 +2552,6 @@ static void slic_mcast_set_list(struct net_device *dev) if (status == 0) slic_mcast_set_mask(adapter); } - return; } #define XMIT_FAIL_LINK_STATE 1 -- cgit v0.10.2 From b8131fc0e1c37563c278743e6def971be993cdda Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Wed, 5 Sep 2012 15:33:47 +0530 Subject: staging: slicoss: fix a null deref when pci_alloc_consistent fail we are dereferencing the pshmem , and the pci_alloc_consistent can fail returning null, do a memcpy if we have a valid pshmem Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c index 0755bc1..cd920da 100644 --- a/drivers/staging/slicoss/slicoss.c +++ b/drivers/staging/slicoss/slicoss.c @@ -3701,9 +3701,8 @@ static void slic_init_adapter(struct net_device *netdev, phys_shmem); ASSERT(adapter->pshmem); - memset(adapter->pshmem, 0, sizeof(struct slic_shmem)); - - return; + if (adapter->pshmem) + memset(adapter->pshmem, 0, sizeof(struct slic_shmem)); } static const struct net_device_ops slic_netdev_ops = { -- cgit v0.10.2 From 3ddd31fa34485ccbe358432a632bec148be18127 Mon Sep 17 00:00:00 2001 From: Marcus Karlsson Date: Sat, 1 Sep 2012 22:29:46 +0200 Subject: staging: zcache: fix spelling of comment Fix spelling in tmem.c: Transcedent -> Transcendent Signed-off-by: Marcus Karlsson Acked-by: Konrad Rzeszutek Wilk Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/zcache/tmem.c b/drivers/staging/zcache/tmem.c index eaa9021..56c8e60 100644 --- a/drivers/staging/zcache/tmem.c +++ b/drivers/staging/zcache/tmem.c @@ -3,7 +3,7 @@ * * Copyright (c) 2009-2011, Dan Magenheimer, Oracle Corp. * - * The primary purpose of Transcedent Memory ("tmem") is to map object-oriented + * The primary purpose of Transcendent Memory ("tmem") is to map object-oriented * "handles" (triples containing a pool id, and object id, and an index), to * pages in a page-accessible memory (PAM). Tmem references the PAM pages via * an abstract "pampd" (PAM page-descriptor), which can be operated on by a -- cgit v0.10.2 From c857ce1659b058c087bce9874cb4eeb5adbf04c5 Mon Sep 17 00:00:00 2001 From: Dan Magenheimer Date: Wed, 5 Sep 2012 13:44:59 -0700 Subject: staging: ramster: remove old driver to prep for new base [V2: rebased to apply to 20120905 staging-next, no other changes] To prep for moving the ramster codebase on top of the new redesigned zcache2 codebase, we remove ramster (as well as its contained diverged v1.1 version of zcache) entirely. Acked-by: Konrad Rzeszutek Wilk Signed-off-by: Dan Magenheimer Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index e3402d5..e25e1e1 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -122,8 +122,6 @@ source "drivers/staging/android/Kconfig" source "drivers/staging/telephony/Kconfig" -source "drivers/staging/ramster/Kconfig" - source "drivers/staging/ozwpan/Kconfig" source "drivers/staging/ccg/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 3be59d0..7ab2d51 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -54,7 +54,6 @@ obj-$(CONFIG_MFD_NVEC) += nvec/ obj-$(CONFIG_DRM_OMAP) += omapdrm/ obj-$(CONFIG_ANDROID) += android/ obj-$(CONFIG_PHONE) += telephony/ -obj-$(CONFIG_RAMSTER) += ramster/ obj-$(CONFIG_USB_WPAN_HCD) += ozwpan/ obj-$(CONFIG_USB_G_CCG) += ccg/ obj-$(CONFIG_WIMAX_GDM72XX) += gdm72xx/ diff --git a/drivers/staging/ramster/Kconfig b/drivers/staging/ramster/Kconfig deleted file mode 100644 index 8349887..0000000 --- a/drivers/staging/ramster/Kconfig +++ /dev/null @@ -1,13 +0,0 @@ -config RAMSTER - bool "Cross-machine RAM capacity sharing, aka peer-to-peer tmem" - depends on (CLEANCACHE || FRONTSWAP) && CONFIGFS_FS=y && !ZCACHE && !XVMALLOC && !HIGHMEM && NET - select LZO_COMPRESS - select LZO_DECOMPRESS - default n - help - RAMster allows RAM on other machines in a cluster to be utilized - dynamically and symmetrically instead of swapping to a local swap - disk, thus improving performance on memory-constrained workloads - while minimizing total RAM across the cluster. RAMster, like - zcache, compresses swap pages into local RAM, but then remotifies - the compressed pages to another node in the RAMster cluster. diff --git a/drivers/staging/ramster/Makefile b/drivers/staging/ramster/Makefile deleted file mode 100644 index bcc13c8..0000000 --- a/drivers/staging/ramster/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-$(CONFIG_RAMSTER) += zcache-main.o tmem.o r2net.o xvmalloc.o cluster/ diff --git a/drivers/staging/ramster/TODO b/drivers/staging/ramster/TODO deleted file mode 100644 index 46fcf0c..0000000 --- a/drivers/staging/ramster/TODO +++ /dev/null @@ -1,13 +0,0 @@ -For this staging driver, RAMster duplicates code from drivers/staging/zcache -then incorporates changes to the local copy of the code. For V5, it also -directly incorporates the soon-to-be-removed drivers/staging/zram/xvmalloc.[ch] -as all testing has been done with xvmalloc rather than the new zsmalloc. -Before RAMster can be promoted from staging, the zcache and RAMster drivers -should be either merged or reorganized to separate out common code. - -Until V4, RAMster duplicated code from fs/ocfs2/cluster, but this made -RAMster incompatible with ocfs2 running in the same kernel and included -lots of code that could be removed. As of V5, the ocfs2 code has been -mined and made RAMster-specific, made to communicate with a userland -ramster-tools package rather than ocfs2-tools, and can co-exist with ocfs2 -both in the same kernel and in userland on the same machine. diff --git a/drivers/staging/ramster/cluster/Makefile b/drivers/staging/ramster/cluster/Makefile deleted file mode 100644 index 9c69436..0000000 --- a/drivers/staging/ramster/cluster/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -obj-$(CONFIG_RAMSTER) += ramster_nodemanager.o - -ramster_nodemanager-objs := heartbeat.o masklog.o nodemanager.o tcp.o diff --git a/drivers/staging/ramster/cluster/heartbeat.c b/drivers/staging/ramster/cluster/heartbeat.c deleted file mode 100644 index 0020949..0000000 --- a/drivers/staging/ramster/cluster/heartbeat.c +++ /dev/null @@ -1,464 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; -*- - * vim: noexpandtab sw=8 ts=8 sts=0: - * - * Copyright (C) 2004, 2005, 2012 Oracle. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 021110-1307, USA. - */ - -#include -#include -#include - -#include "heartbeat.h" -#include "tcp.h" -#include "nodemanager.h" - -#include "masklog.h" - -/* - * The first heartbeat pass had one global thread that would serialize all hb - * callback calls. This global serializing sem should only be removed once - * we've made sure that all callees can deal with being called concurrently - * from multiple hb region threads. - */ -static DECLARE_RWSEM(r2hb_callback_sem); - -/* - * multiple hb threads are watching multiple regions. A node is live - * whenever any of the threads sees activity from the node in its region. - */ -static DEFINE_SPINLOCK(r2hb_live_lock); -static unsigned long r2hb_live_node_bitmap[BITS_TO_LONGS(R2NM_MAX_NODES)]; - -static struct r2hb_callback { - struct list_head list; -} r2hb_callbacks[R2HB_NUM_CB]; - -enum r2hb_heartbeat_modes { - R2HB_HEARTBEAT_LOCAL = 0, - R2HB_HEARTBEAT_GLOBAL, - R2HB_HEARTBEAT_NUM_MODES, -}; - -char *r2hb_heartbeat_mode_desc[R2HB_HEARTBEAT_NUM_MODES] = { - "local", /* R2HB_HEARTBEAT_LOCAL */ - "global", /* R2HB_HEARTBEAT_GLOBAL */ -}; - -unsigned int r2hb_dead_threshold = R2HB_DEFAULT_DEAD_THRESHOLD; -unsigned int r2hb_heartbeat_mode = R2HB_HEARTBEAT_LOCAL; - -/* Only sets a new threshold if there are no active regions. - * - * No locking or otherwise interesting code is required for reading - * r2hb_dead_threshold as it can't change once regions are active and - * it's not interesting to anyone until then anyway. */ -static void r2hb_dead_threshold_set(unsigned int threshold) -{ - if (threshold > R2HB_MIN_DEAD_THRESHOLD) { - spin_lock(&r2hb_live_lock); - r2hb_dead_threshold = threshold; - spin_unlock(&r2hb_live_lock); - } -} - -static int r2hb_global_hearbeat_mode_set(unsigned int hb_mode) -{ - int ret = -1; - - if (hb_mode < R2HB_HEARTBEAT_NUM_MODES) { - spin_lock(&r2hb_live_lock); - r2hb_heartbeat_mode = hb_mode; - ret = 0; - spin_unlock(&r2hb_live_lock); - } - - return ret; -} - -void r2hb_exit(void) -{ -} - -int r2hb_init(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(r2hb_callbacks); i++) - INIT_LIST_HEAD(&r2hb_callbacks[i].list); - - memset(r2hb_live_node_bitmap, 0, sizeof(r2hb_live_node_bitmap)); - - return 0; -} - -/* if we're already in a callback then we're already serialized by the sem */ -static void r2hb_fill_node_map_from_callback(unsigned long *map, - unsigned bytes) -{ - BUG_ON(bytes < (BITS_TO_LONGS(R2NM_MAX_NODES) * sizeof(unsigned long))); - - memcpy(map, &r2hb_live_node_bitmap, bytes); -} - -/* - * get a map of all nodes that are heartbeating in any regions - */ -void r2hb_fill_node_map(unsigned long *map, unsigned bytes) -{ - /* callers want to serialize this map and callbacks so that they - * can trust that they don't miss nodes coming to the party */ - down_read(&r2hb_callback_sem); - spin_lock(&r2hb_live_lock); - r2hb_fill_node_map_from_callback(map, bytes); - spin_unlock(&r2hb_live_lock); - up_read(&r2hb_callback_sem); -} -EXPORT_SYMBOL_GPL(r2hb_fill_node_map); - -/* - * heartbeat configfs bits. The heartbeat set is a default set under - * the cluster set in nodemanager.c. - */ - -/* heartbeat set */ - -struct r2hb_hb_group { - struct config_group hs_group; - /* some stuff? */ -}; - -static struct r2hb_hb_group *to_r2hb_hb_group(struct config_group *group) -{ - return group ? - container_of(group, struct r2hb_hb_group, hs_group) - : NULL; -} - -static struct config_item r2hb_config_item; - -static struct config_item *r2hb_hb_group_make_item(struct config_group *group, - const char *name) -{ - int ret; - - if (strlen(name) > R2HB_MAX_REGION_NAME_LEN) { - ret = -ENAMETOOLONG; - goto free; - } - - config_item_put(&r2hb_config_item); - - return &r2hb_config_item; -free: - return ERR_PTR(ret); -} - -static void r2hb_hb_group_drop_item(struct config_group *group, - struct config_item *item) -{ - if (r2hb_global_heartbeat_active()) { - printk(KERN_NOTICE "ramster: Heartbeat %s " - "on region %s (%s)\n", - "stopped/aborted", config_item_name(item), - "no region"); - } - - config_item_put(item); -} - -struct r2hb_hb_group_attribute { - struct configfs_attribute attr; - ssize_t (*show)(struct r2hb_hb_group *, char *); - ssize_t (*store)(struct r2hb_hb_group *, const char *, size_t); -}; - -static ssize_t r2hb_hb_group_show(struct config_item *item, - struct configfs_attribute *attr, - char *page) -{ - struct r2hb_hb_group *reg = to_r2hb_hb_group(to_config_group(item)); - struct r2hb_hb_group_attribute *r2hb_hb_group_attr = - container_of(attr, struct r2hb_hb_group_attribute, attr); - ssize_t ret = 0; - - if (r2hb_hb_group_attr->show) - ret = r2hb_hb_group_attr->show(reg, page); - return ret; -} - -static ssize_t r2hb_hb_group_store(struct config_item *item, - struct configfs_attribute *attr, - const char *page, size_t count) -{ - struct r2hb_hb_group *reg = to_r2hb_hb_group(to_config_group(item)); - struct r2hb_hb_group_attribute *r2hb_hb_group_attr = - container_of(attr, struct r2hb_hb_group_attribute, attr); - ssize_t ret = -EINVAL; - - if (r2hb_hb_group_attr->store) - ret = r2hb_hb_group_attr->store(reg, page, count); - return ret; -} - -static ssize_t r2hb_hb_group_threshold_show(struct r2hb_hb_group *group, - char *page) -{ - return sprintf(page, "%u\n", r2hb_dead_threshold); -} - -static ssize_t r2hb_hb_group_threshold_store(struct r2hb_hb_group *group, - const char *page, - size_t count) -{ - unsigned long tmp; - char *p = (char *)page; - int err; - - err = kstrtoul(p, 10, &tmp); - if (err) - return err; - - /* this will validate ranges for us. */ - r2hb_dead_threshold_set((unsigned int) tmp); - - return count; -} - -static -ssize_t r2hb_hb_group_mode_show(struct r2hb_hb_group *group, - char *page) -{ - return sprintf(page, "%s\n", - r2hb_heartbeat_mode_desc[r2hb_heartbeat_mode]); -} - -static -ssize_t r2hb_hb_group_mode_store(struct r2hb_hb_group *group, - const char *page, size_t count) -{ - unsigned int i; - int ret; - size_t len; - - len = (page[count - 1] == '\n') ? count - 1 : count; - if (!len) - return -EINVAL; - - for (i = 0; i < R2HB_HEARTBEAT_NUM_MODES; ++i) { - if (strnicmp(page, r2hb_heartbeat_mode_desc[i], len)) - continue; - - ret = r2hb_global_hearbeat_mode_set(i); - if (!ret) - printk(KERN_NOTICE "ramster: Heartbeat mode " - "set to %s\n", - r2hb_heartbeat_mode_desc[i]); - return count; - } - - return -EINVAL; - -} - -static struct r2hb_hb_group_attribute r2hb_hb_group_attr_threshold = { - .attr = { .ca_owner = THIS_MODULE, - .ca_name = "dead_threshold", - .ca_mode = S_IRUGO | S_IWUSR }, - .show = r2hb_hb_group_threshold_show, - .store = r2hb_hb_group_threshold_store, -}; - -static struct r2hb_hb_group_attribute r2hb_hb_group_attr_mode = { - .attr = { .ca_owner = THIS_MODULE, - .ca_name = "mode", - .ca_mode = S_IRUGO | S_IWUSR }, - .show = r2hb_hb_group_mode_show, - .store = r2hb_hb_group_mode_store, -}; - -static struct configfs_attribute *r2hb_hb_group_attrs[] = { - &r2hb_hb_group_attr_threshold.attr, - &r2hb_hb_group_attr_mode.attr, - NULL, -}; - -static struct configfs_item_operations r2hb_hearbeat_group_item_ops = { - .show_attribute = r2hb_hb_group_show, - .store_attribute = r2hb_hb_group_store, -}; - -static struct configfs_group_operations r2hb_hb_group_group_ops = { - .make_item = r2hb_hb_group_make_item, - .drop_item = r2hb_hb_group_drop_item, -}; - -static struct config_item_type r2hb_hb_group_type = { - .ct_group_ops = &r2hb_hb_group_group_ops, - .ct_item_ops = &r2hb_hearbeat_group_item_ops, - .ct_attrs = r2hb_hb_group_attrs, - .ct_owner = THIS_MODULE, -}; - -/* this is just here to avoid touching group in heartbeat.h which the - * entire damn world #includes */ -struct config_group *r2hb_alloc_hb_set(void) -{ - struct r2hb_hb_group *hs = NULL; - struct config_group *ret = NULL; - - hs = kzalloc(sizeof(struct r2hb_hb_group), GFP_KERNEL); - if (hs == NULL) - goto out; - - config_group_init_type_name(&hs->hs_group, "heartbeat", - &r2hb_hb_group_type); - - ret = &hs->hs_group; -out: - if (ret == NULL) - kfree(hs); - return ret; -} - -void r2hb_free_hb_set(struct config_group *group) -{ - struct r2hb_hb_group *hs = to_r2hb_hb_group(group); - kfree(hs); -} - -/* hb callback registration and issuing */ - -static struct r2hb_callback *hbcall_from_type(enum r2hb_callback_type type) -{ - if (type == R2HB_NUM_CB) - return ERR_PTR(-EINVAL); - - return &r2hb_callbacks[type]; -} - -void r2hb_setup_callback(struct r2hb_callback_func *hc, - enum r2hb_callback_type type, - r2hb_cb_func *func, - void *data, - int priority) -{ - INIT_LIST_HEAD(&hc->hc_item); - hc->hc_func = func; - hc->hc_data = data; - hc->hc_priority = priority; - hc->hc_type = type; - hc->hc_magic = R2HB_CB_MAGIC; -} -EXPORT_SYMBOL_GPL(r2hb_setup_callback); - -int r2hb_register_callback(const char *region_uuid, - struct r2hb_callback_func *hc) -{ - struct r2hb_callback_func *tmp; - struct list_head *iter; - struct r2hb_callback *hbcall; - int ret; - - BUG_ON(hc->hc_magic != R2HB_CB_MAGIC); - BUG_ON(!list_empty(&hc->hc_item)); - - hbcall = hbcall_from_type(hc->hc_type); - if (IS_ERR(hbcall)) { - ret = PTR_ERR(hbcall); - goto out; - } - - down_write(&r2hb_callback_sem); - - list_for_each(iter, &hbcall->list) { - tmp = list_entry(iter, struct r2hb_callback_func, hc_item); - if (hc->hc_priority < tmp->hc_priority) { - list_add_tail(&hc->hc_item, iter); - break; - } - } - if (list_empty(&hc->hc_item)) - list_add_tail(&hc->hc_item, &hbcall->list); - - up_write(&r2hb_callback_sem); - ret = 0; -out: - mlog(ML_CLUSTER, "returning %d on behalf of %p for funcs %p\n", - ret, __builtin_return_address(0), hc); - return ret; -} -EXPORT_SYMBOL_GPL(r2hb_register_callback); - -void r2hb_unregister_callback(const char *region_uuid, - struct r2hb_callback_func *hc) -{ - BUG_ON(hc->hc_magic != R2HB_CB_MAGIC); - - mlog(ML_CLUSTER, "on behalf of %p for funcs %p\n", - __builtin_return_address(0), hc); - - /* XXX Can this happen _with_ a region reference? */ - if (list_empty(&hc->hc_item)) - return; - - down_write(&r2hb_callback_sem); - - list_del_init(&hc->hc_item); - - up_write(&r2hb_callback_sem); -} -EXPORT_SYMBOL_GPL(r2hb_unregister_callback); - -int r2hb_check_node_heartbeating_from_callback(u8 node_num) -{ - unsigned long testing_map[BITS_TO_LONGS(R2NM_MAX_NODES)]; - - r2hb_fill_node_map_from_callback(testing_map, sizeof(testing_map)); - if (!test_bit(node_num, testing_map)) { - mlog(ML_HEARTBEAT, - "node (%u) does not have heartbeating enabled.\n", - node_num); - return 0; - } - - return 1; -} -EXPORT_SYMBOL_GPL(r2hb_check_node_heartbeating_from_callback); - -void r2hb_stop_all_regions(void) -{ -} -EXPORT_SYMBOL_GPL(r2hb_stop_all_regions); - -/* - * this is just a hack until we get the plumbing which flips file systems - * read only and drops the hb ref instead of killing the node dead. - */ -int r2hb_global_heartbeat_active(void) -{ - return (r2hb_heartbeat_mode == R2HB_HEARTBEAT_GLOBAL); -} -EXPORT_SYMBOL(r2hb_global_heartbeat_active); - -/* added for RAMster */ -void r2hb_manual_set_node_heartbeating(int node_num) -{ - if (node_num < R2NM_MAX_NODES) - set_bit(node_num, r2hb_live_node_bitmap); -} -EXPORT_SYMBOL(r2hb_manual_set_node_heartbeating); diff --git a/drivers/staging/ramster/cluster/heartbeat.h b/drivers/staging/ramster/cluster/heartbeat.h deleted file mode 100644 index 6cbc775..0000000 --- a/drivers/staging/ramster/cluster/heartbeat.h +++ /dev/null @@ -1,87 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; -*- - * vim: noexpandtab sw=8 ts=8 sts=0: - * - * heartbeat.h - * - * Function prototypes - * - * Copyright (C) 2004 Oracle. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 021110-1307, USA. - * - */ - -#ifndef R2CLUSTER_HEARTBEAT_H -#define R2CLUSTER_HEARTBEAT_H - -#define R2HB_REGION_TIMEOUT_MS 2000 - -#define R2HB_MAX_REGION_NAME_LEN 32 - -/* number of changes to be seen as live */ -#define R2HB_LIVE_THRESHOLD 2 -/* number of equal samples to be seen as dead */ -extern unsigned int r2hb_dead_threshold; -#define R2HB_DEFAULT_DEAD_THRESHOLD 31 -/* Otherwise MAX_WRITE_TIMEOUT will be zero... */ -#define R2HB_MIN_DEAD_THRESHOLD 2 -#define R2HB_MAX_WRITE_TIMEOUT_MS \ - (R2HB_REGION_TIMEOUT_MS * (r2hb_dead_threshold - 1)) - -#define R2HB_CB_MAGIC 0x51d1e4ec - -/* callback stuff */ -enum r2hb_callback_type { - R2HB_NODE_DOWN_CB = 0, - R2HB_NODE_UP_CB, - R2HB_NUM_CB -}; - -struct r2nm_node; -typedef void (r2hb_cb_func)(struct r2nm_node *, int, void *); - -struct r2hb_callback_func { - u32 hc_magic; - struct list_head hc_item; - r2hb_cb_func *hc_func; - void *hc_data; - int hc_priority; - enum r2hb_callback_type hc_type; -}; - -struct config_group *r2hb_alloc_hb_set(void); -void r2hb_free_hb_set(struct config_group *group); - -void r2hb_setup_callback(struct r2hb_callback_func *hc, - enum r2hb_callback_type type, - r2hb_cb_func *func, - void *data, - int priority); -int r2hb_register_callback(const char *region_uuid, - struct r2hb_callback_func *hc); -void r2hb_unregister_callback(const char *region_uuid, - struct r2hb_callback_func *hc); -void r2hb_fill_node_map(unsigned long *map, - unsigned bytes); -void r2hb_exit(void); -int r2hb_init(void); -int r2hb_check_node_heartbeating_from_callback(u8 node_num); -void r2hb_stop_all_regions(void); -int r2hb_get_all_regions(char *region_uuids, u8 numregions); -int r2hb_global_heartbeat_active(void); -void r2hb_manual_set_node_heartbeating(int); - -#endif /* R2CLUSTER_HEARTBEAT_H */ diff --git a/drivers/staging/ramster/cluster/masklog.c b/drivers/staging/ramster/cluster/masklog.c deleted file mode 100644 index 1261d85..0000000 --- a/drivers/staging/ramster/cluster/masklog.c +++ /dev/null @@ -1,155 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; -*- - * vim: noexpandtab sw=8 ts=8 sts=0: - * - * Copyright (C) 2004, 2005, 2012 Oracle. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 021110-1307, USA. - */ - -#include -#include -#include -#include -#include -#include - -#include "masklog.h" - -struct mlog_bits r2_mlog_and_bits = MLOG_BITS_RHS(MLOG_INITIAL_AND_MASK); -EXPORT_SYMBOL_GPL(r2_mlog_and_bits); -struct mlog_bits r2_mlog_not_bits = MLOG_BITS_RHS(0); -EXPORT_SYMBOL_GPL(r2_mlog_not_bits); - -static ssize_t mlog_mask_show(u64 mask, char *buf) -{ - char *state; - - if (__mlog_test_u64(mask, r2_mlog_and_bits)) - state = "allow"; - else if (__mlog_test_u64(mask, r2_mlog_not_bits)) - state = "deny"; - else - state = "off"; - - return snprintf(buf, PAGE_SIZE, "%s\n", state); -} - -static ssize_t mlog_mask_store(u64 mask, const char *buf, size_t count) -{ - if (!strnicmp(buf, "allow", 5)) { - __mlog_set_u64(mask, r2_mlog_and_bits); - __mlog_clear_u64(mask, r2_mlog_not_bits); - } else if (!strnicmp(buf, "deny", 4)) { - __mlog_set_u64(mask, r2_mlog_not_bits); - __mlog_clear_u64(mask, r2_mlog_and_bits); - } else if (!strnicmp(buf, "off", 3)) { - __mlog_clear_u64(mask, r2_mlog_not_bits); - __mlog_clear_u64(mask, r2_mlog_and_bits); - } else - return -EINVAL; - - return count; -} - -struct mlog_attribute { - struct attribute attr; - u64 mask; -}; - -#define to_mlog_attr(_attr) container_of(_attr, struct mlog_attribute, attr) - -#define define_mask(_name) { \ - .attr = { \ - .name = #_name, \ - .mode = S_IRUGO | S_IWUSR, \ - }, \ - .mask = ML_##_name, \ -} - -static struct mlog_attribute mlog_attrs[MLOG_MAX_BITS] = { - define_mask(TCP), - define_mask(MSG), - define_mask(SOCKET), - define_mask(HEARTBEAT), - define_mask(HB_BIO), - define_mask(DLMFS), - define_mask(DLM), - define_mask(DLM_DOMAIN), - define_mask(DLM_THREAD), - define_mask(DLM_MASTER), - define_mask(DLM_RECOVERY), - define_mask(DLM_GLUE), - define_mask(VOTE), - define_mask(CONN), - define_mask(QUORUM), - define_mask(BASTS), - define_mask(CLUSTER), - define_mask(ERROR), - define_mask(NOTICE), - define_mask(KTHREAD), -}; - -static struct attribute *mlog_attr_ptrs[MLOG_MAX_BITS] = {NULL, }; - -static ssize_t mlog_show(struct kobject *obj, struct attribute *attr, - char *buf) -{ - struct mlog_attribute *mlog_attr = to_mlog_attr(attr); - - return mlog_mask_show(mlog_attr->mask, buf); -} - -static ssize_t mlog_store(struct kobject *obj, struct attribute *attr, - const char *buf, size_t count) -{ - struct mlog_attribute *mlog_attr = to_mlog_attr(attr); - - return mlog_mask_store(mlog_attr->mask, buf, count); -} - -static const struct sysfs_ops mlog_attr_ops = { - .show = mlog_show, - .store = mlog_store, -}; - -static struct kobj_type mlog_ktype = { - .default_attrs = mlog_attr_ptrs, - .sysfs_ops = &mlog_attr_ops, -}; - -static struct kset mlog_kset = { - .kobj = {.ktype = &mlog_ktype}, -}; - -int r2_mlog_sys_init(struct kset *r2cb_kset) -{ - int i = 0; - - while (mlog_attrs[i].attr.mode) { - mlog_attr_ptrs[i] = &mlog_attrs[i].attr; - i++; - } - mlog_attr_ptrs[i] = NULL; - - kobject_set_name(&mlog_kset.kobj, "logmask"); - mlog_kset.kobj.kset = r2cb_kset; - return kset_register(&mlog_kset); -} - -void r2_mlog_sys_shutdown(void) -{ - kset_unregister(&mlog_kset); -} diff --git a/drivers/staging/ramster/cluster/masklog.h b/drivers/staging/ramster/cluster/masklog.h deleted file mode 100644 index 918ae11..0000000 --- a/drivers/staging/ramster/cluster/masklog.h +++ /dev/null @@ -1,220 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; -*- - * vim: noexpandtab sw=8 ts=8 sts=0: - * - * Copyright (C) 2005, 2012 Oracle. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 021110-1307, USA. - */ - -#ifndef R2CLUSTER_MASKLOG_H -#define R2CLUSTER_MASKLOG_H - -/* - * For now this is a trivial wrapper around printk() that gives the critical - * ability to enable sets of debugging output at run-time. In the future this - * will almost certainly be redirected to relayfs so that it can pay a - * substantially lower heisenberg tax. - * - * Callers associate the message with a bitmask and a global bitmask is - * maintained with help from /proc. If any of the bits match the message is - * output. - * - * We must have efficient bit tests on i386 and it seems gcc still emits crazy - * code for the 64bit compare. It emits very good code for the dual unsigned - * long tests, though, completely avoiding tests that can never pass if the - * caller gives a constant bitmask that fills one of the longs with all 0s. So - * the desire is to have almost all of the calls decided on by comparing just - * one of the longs. This leads to having infrequently given bits that are - * frequently matched in the high bits. - * - * _ERROR and _NOTICE are used for messages that always go to the console and - * have appropriate KERN_ prefixes. We wrap these in our function instead of - * just calling printk() so that this can eventually make its way through - * relayfs along with the debugging messages. Everything else gets KERN_DEBUG. - * The inline tests and macro dance give GCC the opportunity to quite cleverly - * only emit the appropriage printk() when the caller passes in a constant - * mask, as is almost always the case. - * - * All this bitmask nonsense is managed from the files under - * /sys/fs/r2cb/logmask/. Reading the files gives a straightforward - * indication of which bits are allowed (allow) or denied (off/deny). - * ENTRY deny - * EXIT deny - * TCP off - * MSG off - * SOCKET off - * ERROR allow - * NOTICE allow - * - * Writing changes the state of a given bit and requires a strictly formatted - * single write() call: - * - * write(fd, "allow", 5); - * - * Echoing allow/deny/off string into the logmask files can flip the bits - * on or off as expected; here is the bash script for example: - * - * log_mask="/sys/fs/r2cb/log_mask" - * for node in ENTRY EXIT TCP MSG SOCKET ERROR NOTICE; do - * echo allow >"$log_mask"/"$node" - * done - * - * The debugfs.ramster tool can also flip the bits with the -l option: - * - * debugfs.ramster -l TCP allow - */ - -/* for task_struct */ -#include - -/* bits that are frequently given and infrequently matched in the low word */ -/* NOTE: If you add a flag, you need to also update masklog.c! */ -#define ML_TCP 0x0000000000000001ULL /* net cluster/tcp.c */ -#define ML_MSG 0x0000000000000002ULL /* net network messages */ -#define ML_SOCKET 0x0000000000000004ULL /* net socket lifetime */ -#define ML_HEARTBEAT 0x0000000000000008ULL /* hb all heartbeat tracking */ -#define ML_HB_BIO 0x0000000000000010ULL /* hb io tracing */ -#define ML_DLMFS 0x0000000000000020ULL /* dlm user dlmfs */ -#define ML_DLM 0x0000000000000040ULL /* dlm general debugging */ -#define ML_DLM_DOMAIN 0x0000000000000080ULL /* dlm domain debugging */ -#define ML_DLM_THREAD 0x0000000000000100ULL /* dlm domain thread */ -#define ML_DLM_MASTER 0x0000000000000200ULL /* dlm master functions */ -#define ML_DLM_RECOVERY 0x0000000000000400ULL /* dlm master functions */ -#define ML_DLM_GLUE 0x0000000000000800ULL /* ramster dlm glue layer */ -#define ML_VOTE 0x0000000000001000ULL /* ramster node messaging */ -#define ML_CONN 0x0000000000002000ULL /* net connection management */ -#define ML_QUORUM 0x0000000000004000ULL /* net connection quorum */ -#define ML_BASTS 0x0000000000008000ULL /* dlmglue asts and basts */ -#define ML_CLUSTER 0x0000000000010000ULL /* cluster stack */ - -/* bits that are infrequently given and frequently matched in the high word */ -#define ML_ERROR 0x1000000000000000ULL /* sent to KERN_ERR */ -#define ML_NOTICE 0x2000000000000000ULL /* setn to KERN_NOTICE */ -#define ML_KTHREAD 0x4000000000000000ULL /* kernel thread activity */ - -#define MLOG_INITIAL_AND_MASK (ML_ERROR|ML_NOTICE) -#ifndef MLOG_MASK_PREFIX -#define MLOG_MASK_PREFIX 0 -#endif - -/* - * When logging is disabled, force the bit test to 0 for anything other - * than errors and notices, allowing gcc to remove the code completely. - * When enabled, allow all masks. - */ -#if defined(CONFIG_RAMSTER_DEBUG_MASKLOG) -#define ML_ALLOWED_BITS (~0) -#else -#define ML_ALLOWED_BITS (ML_ERROR|ML_NOTICE) -#endif - -#define MLOG_MAX_BITS 64 - -struct mlog_bits { - unsigned long words[MLOG_MAX_BITS / BITS_PER_LONG]; -}; - -extern struct mlog_bits r2_mlog_and_bits, r2_mlog_not_bits; - -#if BITS_PER_LONG == 32 - -#define __mlog_test_u64(mask, bits) \ - ((u32)(mask & 0xffffffff) & bits.words[0] || \ - ((u64)(mask) >> 32) & bits.words[1]) -#define __mlog_set_u64(mask, bits) do { \ - bits.words[0] |= (u32)(mask & 0xffffffff); \ - bits.words[1] |= (u64)(mask) >> 32; \ -} while (0) -#define __mlog_clear_u64(mask, bits) do { \ - bits.words[0] &= ~((u32)(mask & 0xffffffff)); \ - bits.words[1] &= ~((u64)(mask) >> 32); \ -} while (0) -#define MLOG_BITS_RHS(mask) { \ - { \ - [0] = (u32)(mask & 0xffffffff), \ - [1] = (u64)(mask) >> 32, \ - } \ -} - -#else /* 32bit long above, 64bit long below */ - -#define __mlog_test_u64(mask, bits) ((mask) & bits.words[0]) -#define __mlog_set_u64(mask, bits) do { \ - bits.words[0] |= (mask); \ -} while (0) -#define __mlog_clear_u64(mask, bits) do { \ - bits.words[0] &= ~(mask); \ -} while (0) -#define MLOG_BITS_RHS(mask) { { (mask) } } - -#endif - -/* - * smp_processor_id() "helpfully" screams when called outside preemptible - * regions in current kernels. sles doesn't have the variants that don't - * scream. just do this instead of trying to guess which we're building - * against.. *sigh*. - */ -#define __mlog_cpu_guess ({ \ - unsigned long _cpu = get_cpu(); \ - put_cpu(); \ - _cpu; \ -}) - -/* In the following two macros, the whitespace after the ',' just - * before ##args is intentional. Otherwise, gcc 2.95 will eat the - * previous token if args expands to nothing. - */ -#define __mlog_printk(level, fmt, args...) \ - printk(level "(%s,%u,%lu):%s:%d " fmt, current->comm, \ - task_pid_nr(current), __mlog_cpu_guess, \ - __PRETTY_FUNCTION__, __LINE__ , ##args) - -#define mlog(mask, fmt, args...) do { \ - u64 __m = MLOG_MASK_PREFIX | (mask); \ - if ((__m & ML_ALLOWED_BITS) && \ - __mlog_test_u64(__m, r2_mlog_and_bits) && \ - !__mlog_test_u64(__m, r2_mlog_not_bits)) { \ - if (__m & ML_ERROR) \ - __mlog_printk(KERN_ERR, "ERROR: "fmt , ##args); \ - else if (__m & ML_NOTICE) \ - __mlog_printk(KERN_NOTICE, fmt , ##args); \ - else \ - __mlog_printk(KERN_INFO, fmt , ##args); \ - } \ -} while (0) - -#define mlog_errno(st) do { \ - int _st = (st); \ - if (_st != -ERESTARTSYS && _st != -EINTR && \ - _st != AOP_TRUNCATED_PAGE && _st != -ENOSPC) \ - mlog(ML_ERROR, "status = %lld\n", (long long)_st); \ -} while (0) - -#define mlog_bug_on_msg(cond, fmt, args...) do { \ - if (cond) { \ - mlog(ML_ERROR, "bug expression: " #cond "\n"); \ - mlog(ML_ERROR, fmt, ##args); \ - BUG(); \ - } \ -} while (0) - -#include -#include -int r2_mlog_sys_init(struct kset *r2cb_subsys); -void r2_mlog_sys_shutdown(void); - -#endif /* R2CLUSTER_MASKLOG_H */ diff --git a/drivers/staging/ramster/cluster/nodemanager.c b/drivers/staging/ramster/cluster/nodemanager.c deleted file mode 100644 index de0e5c8..0000000 --- a/drivers/staging/ramster/cluster/nodemanager.c +++ /dev/null @@ -1,992 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; -*- - * vim: noexpandtab sw=8 ts=8 sts=0: - * - * Copyright (C) 2004, 2005, 2012 Oracle. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 021110-1307, USA. - */ - -#include -#include -#include -#include - -#include "tcp.h" -#include "nodemanager.h" -#include "heartbeat.h" -#include "masklog.h" - -/* for now we operate under the assertion that there can be only one - * cluster active at a time. Changing this will require trickling - * cluster references throughout where nodes are looked up */ -struct r2nm_cluster *r2nm_single_cluster; - -char *r2nm_fence_method_desc[R2NM_FENCE_METHODS] = { - "reset", /* R2NM_FENCE_RESET */ - "panic", /* R2NM_FENCE_PANIC */ -}; - -struct r2nm_node *r2nm_get_node_by_num(u8 node_num) -{ - struct r2nm_node *node = NULL; - - if (node_num >= R2NM_MAX_NODES || r2nm_single_cluster == NULL) - goto out; - - read_lock(&r2nm_single_cluster->cl_nodes_lock); - node = r2nm_single_cluster->cl_nodes[node_num]; - if (node) - config_item_get(&node->nd_item); - read_unlock(&r2nm_single_cluster->cl_nodes_lock); -out: - return node; -} -EXPORT_SYMBOL_GPL(r2nm_get_node_by_num); - -int r2nm_configured_node_map(unsigned long *map, unsigned bytes) -{ - struct r2nm_cluster *cluster = r2nm_single_cluster; - - BUG_ON(bytes < (sizeof(cluster->cl_nodes_bitmap))); - - if (cluster == NULL) - return -EINVAL; - - read_lock(&cluster->cl_nodes_lock); - memcpy(map, cluster->cl_nodes_bitmap, sizeof(cluster->cl_nodes_bitmap)); - read_unlock(&cluster->cl_nodes_lock); - - return 0; -} -EXPORT_SYMBOL_GPL(r2nm_configured_node_map); - -static struct r2nm_node *r2nm_node_ip_tree_lookup(struct r2nm_cluster *cluster, - __be32 ip_needle, - struct rb_node ***ret_p, - struct rb_node **ret_parent) -{ - struct rb_node **p = &cluster->cl_node_ip_tree.rb_node; - struct rb_node *parent = NULL; - struct r2nm_node *node, *ret = NULL; - - while (*p) { - int cmp; - - parent = *p; - node = rb_entry(parent, struct r2nm_node, nd_ip_node); - - cmp = memcmp(&ip_needle, &node->nd_ipv4_address, - sizeof(ip_needle)); - if (cmp < 0) - p = &(*p)->rb_left; - else if (cmp > 0) - p = &(*p)->rb_right; - else { - ret = node; - break; - } - } - - if (ret_p != NULL) - *ret_p = p; - if (ret_parent != NULL) - *ret_parent = parent; - - return ret; -} - -struct r2nm_node *r2nm_get_node_by_ip(__be32 addr) -{ - struct r2nm_node *node = NULL; - struct r2nm_cluster *cluster = r2nm_single_cluster; - - if (cluster == NULL) - goto out; - - read_lock(&cluster->cl_nodes_lock); - node = r2nm_node_ip_tree_lookup(cluster, addr, NULL, NULL); - if (node) - config_item_get(&node->nd_item); - read_unlock(&cluster->cl_nodes_lock); - -out: - return node; -} -EXPORT_SYMBOL_GPL(r2nm_get_node_by_ip); - -void r2nm_node_put(struct r2nm_node *node) -{ - config_item_put(&node->nd_item); -} -EXPORT_SYMBOL_GPL(r2nm_node_put); - -void r2nm_node_get(struct r2nm_node *node) -{ - config_item_get(&node->nd_item); -} -EXPORT_SYMBOL_GPL(r2nm_node_get); - -u8 r2nm_this_node(void) -{ - u8 node_num = R2NM_MAX_NODES; - - if (r2nm_single_cluster && r2nm_single_cluster->cl_has_local) - node_num = r2nm_single_cluster->cl_local_node; - - return node_num; -} -EXPORT_SYMBOL_GPL(r2nm_this_node); - -/* node configfs bits */ - -static struct r2nm_cluster *to_r2nm_cluster(struct config_item *item) -{ - return item ? - container_of(to_config_group(item), struct r2nm_cluster, - cl_group) - : NULL; -} - -static struct r2nm_node *to_r2nm_node(struct config_item *item) -{ - return item ? container_of(item, struct r2nm_node, nd_item) : NULL; -} - -static void r2nm_node_release(struct config_item *item) -{ - struct r2nm_node *node = to_r2nm_node(item); - kfree(node); -} - -static ssize_t r2nm_node_num_read(struct r2nm_node *node, char *page) -{ - return sprintf(page, "%d\n", node->nd_num); -} - -static struct r2nm_cluster *to_r2nm_cluster_from_node(struct r2nm_node *node) -{ - /* through the first node_set .parent - * mycluster/nodes/mynode == r2nm_cluster->r2nm_node_group->r2nm_node */ - return to_r2nm_cluster(node->nd_item.ci_parent->ci_parent); -} - -enum { - R2NM_NODE_ATTR_NUM = 0, - R2NM_NODE_ATTR_PORT, - R2NM_NODE_ATTR_ADDRESS, - R2NM_NODE_ATTR_LOCAL, -}; - -static ssize_t r2nm_node_num_write(struct r2nm_node *node, const char *page, - size_t count) -{ - struct r2nm_cluster *cluster = to_r2nm_cluster_from_node(node); - unsigned long tmp; - char *p = (char *)page; - int err; - - err = kstrtoul(p, 10, &tmp); - if (err) - return err; - - if (tmp >= R2NM_MAX_NODES) - return -ERANGE; - - /* once we're in the cl_nodes tree networking can look us up by - * node number and try to use our address and port attributes - * to connect to this node.. make sure that they've been set - * before writing the node attribute? */ - if (!test_bit(R2NM_NODE_ATTR_ADDRESS, &node->nd_set_attributes) || - !test_bit(R2NM_NODE_ATTR_PORT, &node->nd_set_attributes)) - return -EINVAL; /* XXX */ - - write_lock(&cluster->cl_nodes_lock); - if (cluster->cl_nodes[tmp]) - p = NULL; - else { - cluster->cl_nodes[tmp] = node; - node->nd_num = tmp; - set_bit(tmp, cluster->cl_nodes_bitmap); - } - write_unlock(&cluster->cl_nodes_lock); - if (p == NULL) - return -EEXIST; - - return count; -} -static ssize_t r2nm_node_ipv4_port_read(struct r2nm_node *node, char *page) -{ - return sprintf(page, "%u\n", ntohs(node->nd_ipv4_port)); -} - -static ssize_t r2nm_node_ipv4_port_write(struct r2nm_node *node, - const char *page, size_t count) -{ - unsigned long tmp; - char *p = (char *)page; - int err; - - err = kstrtoul(p, 10, &tmp); - if (err) - return err; - - if (tmp == 0) - return -EINVAL; - if (tmp >= (u16)-1) - return -ERANGE; - - node->nd_ipv4_port = htons(tmp); - - return count; -} - -static ssize_t r2nm_node_ipv4_address_read(struct r2nm_node *node, char *page) -{ - return sprintf(page, "%pI4\n", &node->nd_ipv4_address); -} - -static ssize_t r2nm_node_ipv4_address_write(struct r2nm_node *node, - const char *page, - size_t count) -{ - struct r2nm_cluster *cluster = to_r2nm_cluster_from_node(node); - int ret, i; - struct rb_node **p, *parent; - unsigned int octets[4]; - __be32 ipv4_addr = 0; - - ret = sscanf(page, "%3u.%3u.%3u.%3u", &octets[3], &octets[2], - &octets[1], &octets[0]); - if (ret != 4) - return -EINVAL; - - for (i = 0; i < ARRAY_SIZE(octets); i++) { - if (octets[i] > 255) - return -ERANGE; - be32_add_cpu(&ipv4_addr, octets[i] << (i * 8)); - } - - ret = 0; - write_lock(&cluster->cl_nodes_lock); - if (r2nm_node_ip_tree_lookup(cluster, ipv4_addr, &p, &parent)) - ret = -EEXIST; - else { - rb_link_node(&node->nd_ip_node, parent, p); - rb_insert_color(&node->nd_ip_node, &cluster->cl_node_ip_tree); - } - write_unlock(&cluster->cl_nodes_lock); - if (ret) - return ret; - - memcpy(&node->nd_ipv4_address, &ipv4_addr, sizeof(ipv4_addr)); - - return count; -} - -static ssize_t r2nm_node_local_read(struct r2nm_node *node, char *page) -{ - return sprintf(page, "%d\n", node->nd_local); -} - -static ssize_t r2nm_node_local_write(struct r2nm_node *node, const char *page, - size_t count) -{ - struct r2nm_cluster *cluster = to_r2nm_cluster_from_node(node); - unsigned long tmp; - char *p = (char *)page; - ssize_t ret; - int err; - - err = kstrtoul(p, 10, &tmp); - if (err) - return err; - - tmp = !!tmp; /* boolean of whether this node wants to be local */ - - /* setting local turns on networking rx for now so we require having - * set everything else first */ - if (!test_bit(R2NM_NODE_ATTR_ADDRESS, &node->nd_set_attributes) || - !test_bit(R2NM_NODE_ATTR_NUM, &node->nd_set_attributes) || - !test_bit(R2NM_NODE_ATTR_PORT, &node->nd_set_attributes)) - return -EINVAL; /* XXX */ - - /* the only failure case is trying to set a new local node - * when a different one is already set */ - if (tmp && tmp == cluster->cl_has_local && - cluster->cl_local_node != node->nd_num) - return -EBUSY; - - /* bring up the rx thread if we're setting the new local node. */ - if (tmp && !cluster->cl_has_local) { - ret = r2net_start_listening(node); - if (ret) - return ret; - } - - if (!tmp && cluster->cl_has_local && - cluster->cl_local_node == node->nd_num) { - r2net_stop_listening(node); - cluster->cl_local_node = R2NM_INVALID_NODE_NUM; - } - - node->nd_local = tmp; - if (node->nd_local) { - cluster->cl_has_local = tmp; - cluster->cl_local_node = node->nd_num; - } - - return count; -} - -struct r2nm_node_attribute { - struct configfs_attribute attr; - ssize_t (*show)(struct r2nm_node *, char *); - ssize_t (*store)(struct r2nm_node *, const char *, size_t); -}; - -static struct r2nm_node_attribute r2nm_node_attr_num = { - .attr = { .ca_owner = THIS_MODULE, - .ca_name = "num", - .ca_mode = S_IRUGO | S_IWUSR }, - .show = r2nm_node_num_read, - .store = r2nm_node_num_write, -}; - -static struct r2nm_node_attribute r2nm_node_attr_ipv4_port = { - .attr = { .ca_owner = THIS_MODULE, - .ca_name = "ipv4_port", - .ca_mode = S_IRUGO | S_IWUSR }, - .show = r2nm_node_ipv4_port_read, - .store = r2nm_node_ipv4_port_write, -}; - -static struct r2nm_node_attribute r2nm_node_attr_ipv4_address = { - .attr = { .ca_owner = THIS_MODULE, - .ca_name = "ipv4_address", - .ca_mode = S_IRUGO | S_IWUSR }, - .show = r2nm_node_ipv4_address_read, - .store = r2nm_node_ipv4_address_write, -}; - -static struct r2nm_node_attribute r2nm_node_attr_local = { - .attr = { .ca_owner = THIS_MODULE, - .ca_name = "local", - .ca_mode = S_IRUGO | S_IWUSR }, - .show = r2nm_node_local_read, - .store = r2nm_node_local_write, -}; - -static struct configfs_attribute *r2nm_node_attrs[] = { - [R2NM_NODE_ATTR_NUM] = &r2nm_node_attr_num.attr, - [R2NM_NODE_ATTR_PORT] = &r2nm_node_attr_ipv4_port.attr, - [R2NM_NODE_ATTR_ADDRESS] = &r2nm_node_attr_ipv4_address.attr, - [R2NM_NODE_ATTR_LOCAL] = &r2nm_node_attr_local.attr, - NULL, -}; - -static int r2nm_attr_index(struct configfs_attribute *attr) -{ - int i; - for (i = 0; i < ARRAY_SIZE(r2nm_node_attrs); i++) { - if (attr == r2nm_node_attrs[i]) - return i; - } - BUG(); - return 0; -} - -static ssize_t r2nm_node_show(struct config_item *item, - struct configfs_attribute *attr, - char *page) -{ - struct r2nm_node *node = to_r2nm_node(item); - struct r2nm_node_attribute *r2nm_node_attr = - container_of(attr, struct r2nm_node_attribute, attr); - ssize_t ret = 0; - - if (r2nm_node_attr->show) - ret = r2nm_node_attr->show(node, page); - return ret; -} - -static ssize_t r2nm_node_store(struct config_item *item, - struct configfs_attribute *attr, - const char *page, size_t count) -{ - struct r2nm_node *node = to_r2nm_node(item); - struct r2nm_node_attribute *r2nm_node_attr = - container_of(attr, struct r2nm_node_attribute, attr); - ssize_t ret; - int attr_index = r2nm_attr_index(attr); - - if (r2nm_node_attr->store == NULL) { - ret = -EINVAL; - goto out; - } - - if (test_bit(attr_index, &node->nd_set_attributes)) - return -EBUSY; - - ret = r2nm_node_attr->store(node, page, count); - if (ret < count) - goto out; - - set_bit(attr_index, &node->nd_set_attributes); -out: - return ret; -} - -static struct configfs_item_operations r2nm_node_item_ops = { - .release = r2nm_node_release, - .show_attribute = r2nm_node_show, - .store_attribute = r2nm_node_store, -}; - -static struct config_item_type r2nm_node_type = { - .ct_item_ops = &r2nm_node_item_ops, - .ct_attrs = r2nm_node_attrs, - .ct_owner = THIS_MODULE, -}; - -/* node set */ - -struct r2nm_node_group { - struct config_group ns_group; - /* some stuff? */ -}; - -#if 0 -static struct r2nm_node_group *to_r2nm_node_group(struct config_group *group) -{ - return group ? - container_of(group, struct r2nm_node_group, ns_group) - : NULL; -} -#endif - -struct r2nm_cluster_attribute { - struct configfs_attribute attr; - ssize_t (*show)(struct r2nm_cluster *, char *); - ssize_t (*store)(struct r2nm_cluster *, const char *, size_t); -}; - -static ssize_t r2nm_cluster_attr_write(const char *page, ssize_t count, - unsigned int *val) -{ - unsigned long tmp; - char *p = (char *)page; - int err; - - err = kstrtoul(p, 10, &tmp); - if (err) - return err; - - if (tmp == 0) - return -EINVAL; - if (tmp >= (u32)-1) - return -ERANGE; - - *val = tmp; - - return count; -} - -static ssize_t r2nm_cluster_attr_idle_timeout_ms_read( - struct r2nm_cluster *cluster, char *page) -{ - return sprintf(page, "%u\n", cluster->cl_idle_timeout_ms); -} - -static ssize_t r2nm_cluster_attr_idle_timeout_ms_write( - struct r2nm_cluster *cluster, const char *page, size_t count) -{ - ssize_t ret; - unsigned int val = 0; - - ret = r2nm_cluster_attr_write(page, count, &val); - - if (ret > 0) { - if (cluster->cl_idle_timeout_ms != val - && r2net_num_connected_peers()) { - mlog(ML_NOTICE, - "r2net: cannot change idle timeout after " - "the first peer has agreed to it." - " %d connected peers\n", - r2net_num_connected_peers()); - ret = -EINVAL; - } else if (val <= cluster->cl_keepalive_delay_ms) { - mlog(ML_NOTICE, "r2net: idle timeout must be larger " - "than keepalive delay\n"); - ret = -EINVAL; - } else { - cluster->cl_idle_timeout_ms = val; - } - } - - return ret; -} - -static ssize_t r2nm_cluster_attr_keepalive_delay_ms_read( - struct r2nm_cluster *cluster, char *page) -{ - return sprintf(page, "%u\n", cluster->cl_keepalive_delay_ms); -} - -static ssize_t r2nm_cluster_attr_keepalive_delay_ms_write( - struct r2nm_cluster *cluster, const char *page, size_t count) -{ - ssize_t ret; - unsigned int val = 0; - - ret = r2nm_cluster_attr_write(page, count, &val); - - if (ret > 0) { - if (cluster->cl_keepalive_delay_ms != val - && r2net_num_connected_peers()) { - mlog(ML_NOTICE, - "r2net: cannot change keepalive delay after" - " the first peer has agreed to it." - " %d connected peers\n", - r2net_num_connected_peers()); - ret = -EINVAL; - } else if (val >= cluster->cl_idle_timeout_ms) { - mlog(ML_NOTICE, "r2net: keepalive delay must be " - "smaller than idle timeout\n"); - ret = -EINVAL; - } else { - cluster->cl_keepalive_delay_ms = val; - } - } - - return ret; -} - -static ssize_t r2nm_cluster_attr_reconnect_delay_ms_read( - struct r2nm_cluster *cluster, char *page) -{ - return sprintf(page, "%u\n", cluster->cl_reconnect_delay_ms); -} - -static ssize_t r2nm_cluster_attr_reconnect_delay_ms_write( - struct r2nm_cluster *cluster, const char *page, size_t count) -{ - return r2nm_cluster_attr_write(page, count, - &cluster->cl_reconnect_delay_ms); -} - -static ssize_t r2nm_cluster_attr_fence_method_read( - struct r2nm_cluster *cluster, char *page) -{ - ssize_t ret = 0; - - if (cluster) - ret = sprintf(page, "%s\n", - r2nm_fence_method_desc[cluster->cl_fence_method]); - return ret; -} - -static ssize_t r2nm_cluster_attr_fence_method_write( - struct r2nm_cluster *cluster, const char *page, size_t count) -{ - unsigned int i; - - if (page[count - 1] != '\n') - goto bail; - - for (i = 0; i < R2NM_FENCE_METHODS; ++i) { - if (count != strlen(r2nm_fence_method_desc[i]) + 1) - continue; - if (strncasecmp(page, r2nm_fence_method_desc[i], count - 1)) - continue; - if (cluster->cl_fence_method != i) { - printk(KERN_INFO "ramster: Changing fence method to %s\n", - r2nm_fence_method_desc[i]); - cluster->cl_fence_method = i; - } - return count; - } - -bail: - return -EINVAL; -} - -static struct r2nm_cluster_attribute r2nm_cluster_attr_idle_timeout_ms = { - .attr = { .ca_owner = THIS_MODULE, - .ca_name = "idle_timeout_ms", - .ca_mode = S_IRUGO | S_IWUSR }, - .show = r2nm_cluster_attr_idle_timeout_ms_read, - .store = r2nm_cluster_attr_idle_timeout_ms_write, -}; - -static struct r2nm_cluster_attribute r2nm_cluster_attr_keepalive_delay_ms = { - .attr = { .ca_owner = THIS_MODULE, - .ca_name = "keepalive_delay_ms", - .ca_mode = S_IRUGO | S_IWUSR }, - .show = r2nm_cluster_attr_keepalive_delay_ms_read, - .store = r2nm_cluster_attr_keepalive_delay_ms_write, -}; - -static struct r2nm_cluster_attribute r2nm_cluster_attr_reconnect_delay_ms = { - .attr = { .ca_owner = THIS_MODULE, - .ca_name = "reconnect_delay_ms", - .ca_mode = S_IRUGO | S_IWUSR }, - .show = r2nm_cluster_attr_reconnect_delay_ms_read, - .store = r2nm_cluster_attr_reconnect_delay_ms_write, -}; - -static struct r2nm_cluster_attribute r2nm_cluster_attr_fence_method = { - .attr = { .ca_owner = THIS_MODULE, - .ca_name = "fence_method", - .ca_mode = S_IRUGO | S_IWUSR }, - .show = r2nm_cluster_attr_fence_method_read, - .store = r2nm_cluster_attr_fence_method_write, -}; - -static struct configfs_attribute *r2nm_cluster_attrs[] = { - &r2nm_cluster_attr_idle_timeout_ms.attr, - &r2nm_cluster_attr_keepalive_delay_ms.attr, - &r2nm_cluster_attr_reconnect_delay_ms.attr, - &r2nm_cluster_attr_fence_method.attr, - NULL, -}; -static ssize_t r2nm_cluster_show(struct config_item *item, - struct configfs_attribute *attr, - char *page) -{ - struct r2nm_cluster *cluster = to_r2nm_cluster(item); - struct r2nm_cluster_attribute *r2nm_cluster_attr = - container_of(attr, struct r2nm_cluster_attribute, attr); - ssize_t ret = 0; - - if (r2nm_cluster_attr->show) - ret = r2nm_cluster_attr->show(cluster, page); - return ret; -} - -static ssize_t r2nm_cluster_store(struct config_item *item, - struct configfs_attribute *attr, - const char *page, size_t count) -{ - struct r2nm_cluster *cluster = to_r2nm_cluster(item); - struct r2nm_cluster_attribute *r2nm_cluster_attr = - container_of(attr, struct r2nm_cluster_attribute, attr); - ssize_t ret; - - if (r2nm_cluster_attr->store == NULL) { - ret = -EINVAL; - goto out; - } - - ret = r2nm_cluster_attr->store(cluster, page, count); - if (ret < count) - goto out; -out: - return ret; -} - -static struct config_item *r2nm_node_group_make_item(struct config_group *group, - const char *name) -{ - struct r2nm_node *node = NULL; - - if (strlen(name) > R2NM_MAX_NAME_LEN) - return ERR_PTR(-ENAMETOOLONG); - - node = kzalloc(sizeof(struct r2nm_node), GFP_KERNEL); - if (node == NULL) - return ERR_PTR(-ENOMEM); - - strcpy(node->nd_name, name); /* use item.ci_namebuf instead? */ - config_item_init_type_name(&node->nd_item, name, &r2nm_node_type); - spin_lock_init(&node->nd_lock); - - mlog(ML_CLUSTER, "r2nm: Registering node %s\n", name); - - return &node->nd_item; -} - -static void r2nm_node_group_drop_item(struct config_group *group, - struct config_item *item) -{ - struct r2nm_node *node = to_r2nm_node(item); - struct r2nm_cluster *cluster = - to_r2nm_cluster(group->cg_item.ci_parent); - - r2net_disconnect_node(node); - - if (cluster->cl_has_local && - (cluster->cl_local_node == node->nd_num)) { - cluster->cl_has_local = 0; - cluster->cl_local_node = R2NM_INVALID_NODE_NUM; - r2net_stop_listening(node); - } - - /* XXX call into net to stop this node from trading messages */ - - write_lock(&cluster->cl_nodes_lock); - - /* XXX sloppy */ - if (node->nd_ipv4_address) - rb_erase(&node->nd_ip_node, &cluster->cl_node_ip_tree); - - /* nd_num might be 0 if the node number hasn't been set.. */ - if (cluster->cl_nodes[node->nd_num] == node) { - cluster->cl_nodes[node->nd_num] = NULL; - clear_bit(node->nd_num, cluster->cl_nodes_bitmap); - } - write_unlock(&cluster->cl_nodes_lock); - - mlog(ML_CLUSTER, "r2nm: Unregistered node %s\n", - config_item_name(&node->nd_item)); - - config_item_put(item); -} - -static struct configfs_group_operations r2nm_node_group_group_ops = { - .make_item = r2nm_node_group_make_item, - .drop_item = r2nm_node_group_drop_item, -}; - -static struct config_item_type r2nm_node_group_type = { - .ct_group_ops = &r2nm_node_group_group_ops, - .ct_owner = THIS_MODULE, -}; - -/* cluster */ - -static void r2nm_cluster_release(struct config_item *item) -{ - struct r2nm_cluster *cluster = to_r2nm_cluster(item); - - kfree(cluster->cl_group.default_groups); - kfree(cluster); -} - -static struct configfs_item_operations r2nm_cluster_item_ops = { - .release = r2nm_cluster_release, - .show_attribute = r2nm_cluster_show, - .store_attribute = r2nm_cluster_store, -}; - -static struct config_item_type r2nm_cluster_type = { - .ct_item_ops = &r2nm_cluster_item_ops, - .ct_attrs = r2nm_cluster_attrs, - .ct_owner = THIS_MODULE, -}; - -/* cluster set */ - -struct r2nm_cluster_group { - struct configfs_subsystem cs_subsys; - /* some stuff? */ -}; - -#if 0 -static struct r2nm_cluster_group * -to_r2nm_cluster_group(struct config_group *group) -{ - return group ? - container_of(to_configfs_subsystem(group), - struct r2nm_cluster_group, cs_subsys) - : NULL; -} -#endif - -static struct config_group * -r2nm_cluster_group_make_group(struct config_group *group, - const char *name) -{ - struct r2nm_cluster *cluster = NULL; - struct r2nm_node_group *ns = NULL; - struct config_group *r2hb_group = NULL, *ret = NULL; - void *defs = NULL; - - /* this runs under the parent dir's i_mutex; there can be only - * one caller in here at a time */ - if (r2nm_single_cluster) - return ERR_PTR(-ENOSPC); - - cluster = kzalloc(sizeof(struct r2nm_cluster), GFP_KERNEL); - ns = kzalloc(sizeof(struct r2nm_node_group), GFP_KERNEL); - defs = kcalloc(3, sizeof(struct config_group *), GFP_KERNEL); - r2hb_group = r2hb_alloc_hb_set(); - if (cluster == NULL || ns == NULL || r2hb_group == NULL || defs == NULL) - goto out; - - config_group_init_type_name(&cluster->cl_group, name, - &r2nm_cluster_type); - config_group_init_type_name(&ns->ns_group, "node", - &r2nm_node_group_type); - - cluster->cl_group.default_groups = defs; - cluster->cl_group.default_groups[0] = &ns->ns_group; - cluster->cl_group.default_groups[1] = r2hb_group; - cluster->cl_group.default_groups[2] = NULL; - rwlock_init(&cluster->cl_nodes_lock); - cluster->cl_node_ip_tree = RB_ROOT; - cluster->cl_reconnect_delay_ms = R2NET_RECONNECT_DELAY_MS_DEFAULT; - cluster->cl_idle_timeout_ms = R2NET_IDLE_TIMEOUT_MS_DEFAULT; - cluster->cl_keepalive_delay_ms = R2NET_KEEPALIVE_DELAY_MS_DEFAULT; - cluster->cl_fence_method = R2NM_FENCE_RESET; - - ret = &cluster->cl_group; - r2nm_single_cluster = cluster; - -out: - if (ret == NULL) { - kfree(cluster); - kfree(ns); - r2hb_free_hb_set(r2hb_group); - kfree(defs); - ret = ERR_PTR(-ENOMEM); - } - - return ret; -} - -static void r2nm_cluster_group_drop_item(struct config_group *group, - struct config_item *item) -{ - struct r2nm_cluster *cluster = to_r2nm_cluster(item); - int i; - struct config_item *killme; - - BUG_ON(r2nm_single_cluster != cluster); - r2nm_single_cluster = NULL; - - for (i = 0; cluster->cl_group.default_groups[i]; i++) { - killme = &cluster->cl_group.default_groups[i]->cg_item; - cluster->cl_group.default_groups[i] = NULL; - config_item_put(killme); - } - - config_item_put(item); -} - -static struct configfs_group_operations r2nm_cluster_group_group_ops = { - .make_group = r2nm_cluster_group_make_group, - .drop_item = r2nm_cluster_group_drop_item, -}; - -static struct config_item_type r2nm_cluster_group_type = { - .ct_group_ops = &r2nm_cluster_group_group_ops, - .ct_owner = THIS_MODULE, -}; - -static struct r2nm_cluster_group r2nm_cluster_group = { - .cs_subsys = { - .su_group = { - .cg_item = { - .ci_namebuf = "cluster", - .ci_type = &r2nm_cluster_group_type, - }, - }, - }, -}; - -int r2nm_depend_item(struct config_item *item) -{ - return configfs_depend_item(&r2nm_cluster_group.cs_subsys, item); -} - -void r2nm_undepend_item(struct config_item *item) -{ - configfs_undepend_item(&r2nm_cluster_group.cs_subsys, item); -} - -int r2nm_depend_this_node(void) -{ - int ret = 0; - struct r2nm_node *local_node; - - local_node = r2nm_get_node_by_num(r2nm_this_node()); - if (!local_node) { - ret = -EINVAL; - goto out; - } - - ret = r2nm_depend_item(&local_node->nd_item); - r2nm_node_put(local_node); - -out: - return ret; -} - -void r2nm_undepend_this_node(void) -{ - struct r2nm_node *local_node; - - local_node = r2nm_get_node_by_num(r2nm_this_node()); - BUG_ON(!local_node); - - r2nm_undepend_item(&local_node->nd_item); - r2nm_node_put(local_node); -} - - -static void __exit exit_r2nm(void) -{ - /* XXX sync with hb callbacks and shut down hb? */ - r2net_unregister_hb_callbacks(); - configfs_unregister_subsystem(&r2nm_cluster_group.cs_subsys); - - r2net_exit(); - r2hb_exit(); -} - -static int __init init_r2nm(void) -{ - int ret = -1; - - ret = r2hb_init(); - if (ret) - goto out; - - ret = r2net_init(); - if (ret) - goto out_r2hb; - - ret = r2net_register_hb_callbacks(); - if (ret) - goto out_r2net; - - config_group_init(&r2nm_cluster_group.cs_subsys.su_group); - mutex_init(&r2nm_cluster_group.cs_subsys.su_mutex); - ret = configfs_register_subsystem(&r2nm_cluster_group.cs_subsys); - if (ret) { - printk(KERN_ERR "nodemanager: Registration returned %d\n", ret); - goto out_callbacks; - } - - if (!ret) - goto out; - - configfs_unregister_subsystem(&r2nm_cluster_group.cs_subsys); -out_callbacks: - r2net_unregister_hb_callbacks(); -out_r2net: - r2net_exit(); -out_r2hb: - r2hb_exit(); -out: - return ret; -} - -MODULE_AUTHOR("Oracle"); -MODULE_LICENSE("GPL"); - -module_init(init_r2nm) -module_exit(exit_r2nm) diff --git a/drivers/staging/ramster/cluster/nodemanager.h b/drivers/staging/ramster/cluster/nodemanager.h deleted file mode 100644 index 41a04df..0000000 --- a/drivers/staging/ramster/cluster/nodemanager.h +++ /dev/null @@ -1,88 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; -*- - * vim: noexpandtab sw=8 ts=8 sts=0: - * - * nodemanager.h - * - * Function prototypes - * - * Copyright (C) 2004 Oracle. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 021110-1307, USA. - * - */ - -#ifndef R2CLUSTER_NODEMANAGER_H -#define R2CLUSTER_NODEMANAGER_H - -#include "ramster_nodemanager.h" - -/* This totally doesn't belong here. */ -#include -#include - -enum r2nm_fence_method { - R2NM_FENCE_RESET = 0, - R2NM_FENCE_PANIC, - R2NM_FENCE_METHODS, /* Number of fence methods */ -}; - -struct r2nm_node { - spinlock_t nd_lock; - struct config_item nd_item; - char nd_name[R2NM_MAX_NAME_LEN+1]; /* replace? */ - __u8 nd_num; - /* only one address per node, as attributes, for now. */ - __be32 nd_ipv4_address; - __be16 nd_ipv4_port; - struct rb_node nd_ip_node; - /* there can be only one local node for now */ - int nd_local; - - unsigned long nd_set_attributes; -}; - -struct r2nm_cluster { - struct config_group cl_group; - unsigned cl_has_local:1; - u8 cl_local_node; - rwlock_t cl_nodes_lock; - struct r2nm_node *cl_nodes[R2NM_MAX_NODES]; - struct rb_root cl_node_ip_tree; - unsigned int cl_idle_timeout_ms; - unsigned int cl_keepalive_delay_ms; - unsigned int cl_reconnect_delay_ms; - enum r2nm_fence_method cl_fence_method; - - /* part of a hack for disk bitmap.. will go eventually. - zab */ - unsigned long cl_nodes_bitmap[BITS_TO_LONGS(R2NM_MAX_NODES)]; -}; - -extern struct r2nm_cluster *r2nm_single_cluster; - -u8 r2nm_this_node(void); - -int r2nm_configured_node_map(unsigned long *map, unsigned bytes); -struct r2nm_node *r2nm_get_node_by_num(u8 node_num); -struct r2nm_node *r2nm_get_node_by_ip(__be32 addr); -void r2nm_node_get(struct r2nm_node *node); -void r2nm_node_put(struct r2nm_node *node); - -int r2nm_depend_item(struct config_item *item); -void r2nm_undepend_item(struct config_item *item); -int r2nm_depend_this_node(void); -void r2nm_undepend_this_node(void); - -#endif /* R2CLUSTER_NODEMANAGER_H */ diff --git a/drivers/staging/ramster/cluster/ramster_nodemanager.h b/drivers/staging/ramster/cluster/ramster_nodemanager.h deleted file mode 100644 index 49f879d..0000000 --- a/drivers/staging/ramster/cluster/ramster_nodemanager.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; -*- - * vim: noexpandtab sw=8 ts=8 sts=0: - * - * ramster_nodemanager.h - * - * Header describing the interface between userspace and the kernel - * for the ramster_nodemanager module. - * - * Copyright (C) 2002, 2004, 2012 Oracle. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 021110-1307, USA. - * - */ - -#ifndef _RAMSTER_NODEMANAGER_H -#define _RAMSTER_NODEMANAGER_H - -#define R2NM_API_VERSION 5 - -#define R2NM_MAX_NODES 255 -#define R2NM_INVALID_NODE_NUM 255 - -/* host name, group name, cluster name all 64 bytes */ -#define R2NM_MAX_NAME_LEN 64 /* __NEW_UTS_LEN */ - -#endif /* _RAMSTER_NODEMANAGER_H */ diff --git a/drivers/staging/ramster/cluster/tcp.c b/drivers/staging/ramster/cluster/tcp.c deleted file mode 100644 index d0a07d7..0000000 --- a/drivers/staging/ramster/cluster/tcp.c +++ /dev/null @@ -1,2256 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; -*- - * - * vim: noexpandtab sw=8 ts=8 sts=0: - * - * Copyright (C) 2004 Oracle. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 021110-1307, USA. - * - * ---- - * - * Callers for this were originally written against a very simple synchronus - * API. This implementation reflects those simple callers. Some day I'm sure - * we'll need to move to a more robust posting/callback mechanism. - * - * Transmit calls pass in kernel virtual addresses and block copying this into - * the socket's tx buffers via a usual blocking sendmsg. They'll block waiting - * for a failed socket to timeout. TX callers can also pass in a poniter to an - * 'int' which gets filled with an errno off the wire in response to the - * message they send. - * - * Handlers for unsolicited messages are registered. Each socket has a page - * that incoming data is copied into. First the header, then the data. - * Handlers are called from only one thread with a reference to this per-socket - * page. This page is destroyed after the handler call, so it can't be - * referenced beyond the call. Handlers may block but are discouraged from - * doing so. - * - * Any framing errors (bad magic, large payload lengths) close a connection. - * - * Our sock_container holds the state we associate with a socket. It's current - * framing state is held there as well as the refcounting we do around when it - * is safe to tear down the socket. The socket is only finally torn down from - * the container when the container loses all of its references -- so as long - * as you hold a ref on the container you can trust that the socket is valid - * for use with kernel socket APIs. - * - * Connections are initiated between a pair of nodes when the node with the - * higher node number gets a heartbeat callback which indicates that the lower - * numbered node has started heartbeating. The lower numbered node is passive - * and only accepts the connection if the higher numbered node is heartbeating. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#include "heartbeat.h" -#include "tcp.h" -#include "nodemanager.h" -#define MLOG_MASK_PREFIX ML_TCP -#include "masklog.h" - -#include "tcp_internal.h" - -#define SC_NODEF_FMT "node %s (num %u) at %pI4:%u" - -/* - * In the following two log macros, the whitespace after the ',' just - * before ##args is intentional. Otherwise, gcc 2.95 will eat the - * previous token if args expands to nothing. - */ -#define msglog(hdr, fmt, args...) do { \ - typeof(hdr) __hdr = (hdr); \ - mlog(ML_MSG, "[mag %u len %u typ %u stat %d sys_stat %d " \ - "key %08x num %u] " fmt, \ - be16_to_cpu(__hdr->magic), be16_to_cpu(__hdr->data_len), \ - be16_to_cpu(__hdr->msg_type), be32_to_cpu(__hdr->status), \ - be32_to_cpu(__hdr->sys_status), be32_to_cpu(__hdr->key), \ - be32_to_cpu(__hdr->msg_num) , ##args); \ -} while (0) - -#define sclog(sc, fmt, args...) do { \ - typeof(sc) __sc = (sc); \ - mlog(ML_SOCKET, "[sc %p refs %d sock %p node %u page %p " \ - "pg_off %zu] " fmt, __sc, \ - atomic_read(&__sc->sc_kref.refcount), __sc->sc_sock, \ - __sc->sc_node->nd_num, __sc->sc_page, __sc->sc_page_off , \ - ##args); \ -} while (0) - -static DEFINE_RWLOCK(r2net_handler_lock); -static struct rb_root r2net_handler_tree = RB_ROOT; - -static struct r2net_node r2net_nodes[R2NM_MAX_NODES]; - -/* XXX someday we'll need better accounting */ -static struct socket *r2net_listen_sock; - -/* - * listen work is only queued by the listening socket callbacks on the - * r2net_wq. teardown detaches the callbacks before destroying the workqueue. - * quorum work is queued as sock containers are shutdown.. stop_listening - * tears down all the node's sock containers, preventing future shutdowns - * and queued quorum work, before canceling delayed quorum work and - * destroying the work queue. - */ -static struct workqueue_struct *r2net_wq; -static struct work_struct r2net_listen_work; - -static struct r2hb_callback_func r2net_hb_up, r2net_hb_down; -#define R2NET_HB_PRI 0x1 - -static struct r2net_handshake *r2net_hand; -static struct r2net_msg *r2net_keep_req, *r2net_keep_resp; - -static int r2net_sys_err_translations[R2NET_ERR_MAX] = { - [R2NET_ERR_NONE] = 0, - [R2NET_ERR_NO_HNDLR] = -ENOPROTOOPT, - [R2NET_ERR_OVERFLOW] = -EOVERFLOW, - [R2NET_ERR_DIED] = -EHOSTDOWN,}; - -/* can't quite avoid *all* internal declarations :/ */ -static void r2net_sc_connect_completed(struct work_struct *work); -static void r2net_rx_until_empty(struct work_struct *work); -static void r2net_shutdown_sc(struct work_struct *work); -static void r2net_listen_data_ready(struct sock *sk, int bytes); -static void r2net_sc_send_keep_req(struct work_struct *work); -static void r2net_idle_timer(unsigned long data); -static void r2net_sc_postpone_idle(struct r2net_sock_container *sc); -static void r2net_sc_reset_idle_timer(struct r2net_sock_container *sc); - -#ifdef CONFIG_DEBUG_FS -static void r2net_init_nst(struct r2net_send_tracking *nst, u32 msgtype, - u32 msgkey, struct task_struct *task, u8 node) -{ - INIT_LIST_HEAD(&nst->st_net_debug_item); - nst->st_task = task; - nst->st_msg_type = msgtype; - nst->st_msg_key = msgkey; - nst->st_node = node; -} - -static inline void r2net_set_nst_sock_time(struct r2net_send_tracking *nst) -{ - nst->st_sock_time = ktime_get(); -} - -static inline void r2net_set_nst_send_time(struct r2net_send_tracking *nst) -{ - nst->st_send_time = ktime_get(); -} - -static inline void r2net_set_nst_status_time(struct r2net_send_tracking *nst) -{ - nst->st_status_time = ktime_get(); -} - -static inline void r2net_set_nst_sock_container(struct r2net_send_tracking *nst, - struct r2net_sock_container *sc) -{ - nst->st_sc = sc; -} - -static inline void r2net_set_nst_msg_id(struct r2net_send_tracking *nst, - u32 msg_id) -{ - nst->st_id = msg_id; -} - -static inline void r2net_set_sock_timer(struct r2net_sock_container *sc) -{ - sc->sc_tv_timer = ktime_get(); -} - -static inline void r2net_set_data_ready_time(struct r2net_sock_container *sc) -{ - sc->sc_tv_data_ready = ktime_get(); -} - -static inline void r2net_set_advance_start_time(struct r2net_sock_container *sc) -{ - sc->sc_tv_advance_start = ktime_get(); -} - -static inline void r2net_set_advance_stop_time(struct r2net_sock_container *sc) -{ - sc->sc_tv_advance_stop = ktime_get(); -} - -static inline void r2net_set_func_start_time(struct r2net_sock_container *sc) -{ - sc->sc_tv_func_start = ktime_get(); -} - -static inline void r2net_set_func_stop_time(struct r2net_sock_container *sc) -{ - sc->sc_tv_func_stop = ktime_get(); -} - -#else /* CONFIG_DEBUG_FS */ -# define r2net_init_nst(a, b, c, d, e) -# define r2net_set_nst_sock_time(a) -# define r2net_set_nst_send_time(a) -# define r2net_set_nst_status_time(a) -# define r2net_set_nst_sock_container(a, b) -# define r2net_set_nst_msg_id(a, b) -# define r2net_set_sock_timer(a) -# define r2net_set_data_ready_time(a) -# define r2net_set_advance_start_time(a) -# define r2net_set_advance_stop_time(a) -# define r2net_set_func_start_time(a) -# define r2net_set_func_stop_time(a) -#endif /* CONFIG_DEBUG_FS */ - -#ifdef CONFIG_RAMSTER_FS_STATS -static ktime_t r2net_get_func_run_time(struct r2net_sock_container *sc) -{ - return ktime_sub(sc->sc_tv_func_stop, sc->sc_tv_func_start); -} - -static void r2net_update_send_stats(struct r2net_send_tracking *nst, - struct r2net_sock_container *sc) -{ - sc->sc_tv_status_total = ktime_add(sc->sc_tv_status_total, - ktime_sub(ktime_get(), - nst->st_status_time)); - sc->sc_tv_send_total = ktime_add(sc->sc_tv_send_total, - ktime_sub(nst->st_status_time, - nst->st_send_time)); - sc->sc_tv_acquiry_total = ktime_add(sc->sc_tv_acquiry_total, - ktime_sub(nst->st_send_time, - nst->st_sock_time)); - sc->sc_send_count++; -} - -static void r2net_update_recv_stats(struct r2net_sock_container *sc) -{ - sc->sc_tv_process_total = ktime_add(sc->sc_tv_process_total, - r2net_get_func_run_time(sc)); - sc->sc_recv_count++; -} - -#else - -# define r2net_update_send_stats(a, b) - -# define r2net_update_recv_stats(sc) - -#endif /* CONFIG_RAMSTER_FS_STATS */ - -static inline int r2net_reconnect_delay(void) -{ - return r2nm_single_cluster->cl_reconnect_delay_ms; -} - -static inline int r2net_keepalive_delay(void) -{ - return r2nm_single_cluster->cl_keepalive_delay_ms; -} - -static inline int r2net_idle_timeout(void) -{ - return r2nm_single_cluster->cl_idle_timeout_ms; -} - -static inline int r2net_sys_err_to_errno(enum r2net_system_error err) -{ - int trans; - BUG_ON(err >= R2NET_ERR_MAX); - trans = r2net_sys_err_translations[err]; - - /* Just in case we mess up the translation table above */ - BUG_ON(err != R2NET_ERR_NONE && trans == 0); - return trans; -} - -struct r2net_node *r2net_nn_from_num(u8 node_num) -{ - BUG_ON(node_num >= ARRAY_SIZE(r2net_nodes)); - return &r2net_nodes[node_num]; -} - -static u8 r2net_num_from_nn(struct r2net_node *nn) -{ - BUG_ON(nn == NULL); - return nn - r2net_nodes; -} - -/* ------------------------------------------------------------ */ - -static int r2net_prep_nsw(struct r2net_node *nn, struct r2net_status_wait *nsw) -{ - int ret = 0; - - do { - if (!idr_pre_get(&nn->nn_status_idr, GFP_ATOMIC)) { - ret = -EAGAIN; - break; - } - spin_lock(&nn->nn_lock); - ret = idr_get_new(&nn->nn_status_idr, nsw, &nsw->ns_id); - if (ret == 0) - list_add_tail(&nsw->ns_node_item, - &nn->nn_status_list); - spin_unlock(&nn->nn_lock); - } while (ret == -EAGAIN); - - if (ret == 0) { - init_waitqueue_head(&nsw->ns_wq); - nsw->ns_sys_status = R2NET_ERR_NONE; - nsw->ns_status = 0; - } - - return ret; -} - -static void r2net_complete_nsw_locked(struct r2net_node *nn, - struct r2net_status_wait *nsw, - enum r2net_system_error sys_status, - s32 status) -{ - assert_spin_locked(&nn->nn_lock); - - if (!list_empty(&nsw->ns_node_item)) { - list_del_init(&nsw->ns_node_item); - nsw->ns_sys_status = sys_status; - nsw->ns_status = status; - idr_remove(&nn->nn_status_idr, nsw->ns_id); - wake_up(&nsw->ns_wq); - } -} - -static void r2net_complete_nsw(struct r2net_node *nn, - struct r2net_status_wait *nsw, - u64 id, enum r2net_system_error sys_status, - s32 status) -{ - spin_lock(&nn->nn_lock); - if (nsw == NULL) { - if (id > INT_MAX) - goto out; - - nsw = idr_find(&nn->nn_status_idr, id); - if (nsw == NULL) - goto out; - } - - r2net_complete_nsw_locked(nn, nsw, sys_status, status); - -out: - spin_unlock(&nn->nn_lock); - return; -} - -static void r2net_complete_nodes_nsw(struct r2net_node *nn) -{ - struct r2net_status_wait *nsw, *tmp; - unsigned int num_kills = 0; - - assert_spin_locked(&nn->nn_lock); - - list_for_each_entry_safe(nsw, tmp, &nn->nn_status_list, ns_node_item) { - r2net_complete_nsw_locked(nn, nsw, R2NET_ERR_DIED, 0); - num_kills++; - } - - mlog(0, "completed %d messages for node %u\n", num_kills, - r2net_num_from_nn(nn)); -} - -static int r2net_nsw_completed(struct r2net_node *nn, - struct r2net_status_wait *nsw) -{ - int completed; - spin_lock(&nn->nn_lock); - completed = list_empty(&nsw->ns_node_item); - spin_unlock(&nn->nn_lock); - return completed; -} - -/* ------------------------------------------------------------ */ - -static void sc_kref_release(struct kref *kref) -{ - struct r2net_sock_container *sc = container_of(kref, - struct r2net_sock_container, sc_kref); - BUG_ON(timer_pending(&sc->sc_idle_timeout)); - - sclog(sc, "releasing\n"); - - if (sc->sc_sock) { - sock_release(sc->sc_sock); - sc->sc_sock = NULL; - } - - r2nm_undepend_item(&sc->sc_node->nd_item); - r2nm_node_put(sc->sc_node); - sc->sc_node = NULL; - - r2net_debug_del_sc(sc); - kfree(sc); -} - -static void sc_put(struct r2net_sock_container *sc) -{ - sclog(sc, "put\n"); - kref_put(&sc->sc_kref, sc_kref_release); -} -static void sc_get(struct r2net_sock_container *sc) -{ - sclog(sc, "get\n"); - kref_get(&sc->sc_kref); -} -static struct r2net_sock_container *sc_alloc(struct r2nm_node *node) -{ - struct r2net_sock_container *sc, *ret = NULL; - struct page *page = NULL; - int status = 0; - - page = alloc_page(GFP_NOFS); - sc = kzalloc(sizeof(*sc), GFP_NOFS); - if (sc == NULL || page == NULL) - goto out; - - kref_init(&sc->sc_kref); - r2nm_node_get(node); - sc->sc_node = node; - - /* pin the node item of the remote node */ - status = r2nm_depend_item(&node->nd_item); - if (status) { - mlog_errno(status); - r2nm_node_put(node); - goto out; - } - INIT_WORK(&sc->sc_connect_work, r2net_sc_connect_completed); - INIT_WORK(&sc->sc_rx_work, r2net_rx_until_empty); - INIT_WORK(&sc->sc_shutdown_work, r2net_shutdown_sc); - INIT_DELAYED_WORK(&sc->sc_keepalive_work, r2net_sc_send_keep_req); - - init_timer(&sc->sc_idle_timeout); - sc->sc_idle_timeout.function = r2net_idle_timer; - sc->sc_idle_timeout.data = (unsigned long)sc; - - sclog(sc, "alloced\n"); - - ret = sc; - sc->sc_page = page; - r2net_debug_add_sc(sc); - sc = NULL; - page = NULL; - -out: - if (page) - __free_page(page); - kfree(sc); - - return ret; -} - -/* ------------------------------------------------------------ */ - -static void r2net_sc_queue_work(struct r2net_sock_container *sc, - struct work_struct *work) -{ - sc_get(sc); - if (!queue_work(r2net_wq, work)) - sc_put(sc); -} -static void r2net_sc_queue_delayed_work(struct r2net_sock_container *sc, - struct delayed_work *work, - int delay) -{ - sc_get(sc); - if (!queue_delayed_work(r2net_wq, work, delay)) - sc_put(sc); -} -static void r2net_sc_cancel_delayed_work(struct r2net_sock_container *sc, - struct delayed_work *work) -{ - if (cancel_delayed_work(work)) - sc_put(sc); -} - -static atomic_t r2net_connected_peers = ATOMIC_INIT(0); - -int r2net_num_connected_peers(void) -{ - return atomic_read(&r2net_connected_peers); -} - -static void r2net_set_nn_state(struct r2net_node *nn, - struct r2net_sock_container *sc, - unsigned valid, int err) -{ - int was_valid = nn->nn_sc_valid; - int was_err = nn->nn_persistent_error; - struct r2net_sock_container *old_sc = nn->nn_sc; - - assert_spin_locked(&nn->nn_lock); - - if (old_sc && !sc) - atomic_dec(&r2net_connected_peers); - else if (!old_sc && sc) - atomic_inc(&r2net_connected_peers); - - /* the node num comparison and single connect/accept path should stop - * an non-null sc from being overwritten with another */ - BUG_ON(sc && nn->nn_sc && nn->nn_sc != sc); - mlog_bug_on_msg(err && valid, "err %d valid %u\n", err, valid); - mlog_bug_on_msg(valid && !sc, "valid %u sc %p\n", valid, sc); - - if (was_valid && !valid && err == 0) - err = -ENOTCONN; - - mlog(ML_CONN, "node %u sc: %p -> %p, valid %u -> %u, err %d -> %d\n", - r2net_num_from_nn(nn), nn->nn_sc, sc, nn->nn_sc_valid, valid, - nn->nn_persistent_error, err); - - nn->nn_sc = sc; - nn->nn_sc_valid = valid ? 1 : 0; - nn->nn_persistent_error = err; - - /* mirrors r2net_tx_can_proceed() */ - if (nn->nn_persistent_error || nn->nn_sc_valid) - wake_up(&nn->nn_sc_wq); - - if (!was_err && nn->nn_persistent_error) { - queue_delayed_work(r2net_wq, &nn->nn_still_up, - msecs_to_jiffies(R2NET_QUORUM_DELAY_MS)); - } - - if (was_valid && !valid) { - printk(KERN_NOTICE "ramster: No longer connected to " - SC_NODEF_FMT "\n", - old_sc->sc_node->nd_name, old_sc->sc_node->nd_num, - &old_sc->sc_node->nd_ipv4_address, - ntohs(old_sc->sc_node->nd_ipv4_port)); - r2net_complete_nodes_nsw(nn); - } - - if (!was_valid && valid) { - cancel_delayed_work(&nn->nn_connect_expired); - printk(KERN_NOTICE "ramster: %s " SC_NODEF_FMT "\n", - r2nm_this_node() > sc->sc_node->nd_num ? - "Connected to" : "Accepted connection from", - sc->sc_node->nd_name, sc->sc_node->nd_num, - &sc->sc_node->nd_ipv4_address, - ntohs(sc->sc_node->nd_ipv4_port)); - } - - /* trigger the connecting worker func as long as we're not valid, - * it will back off if it shouldn't connect. This can be called - * from node config teardown and so needs to be careful about - * the work queue actually being up. */ - if (!valid && r2net_wq) { - unsigned long delay; - /* delay if we're within a RECONNECT_DELAY of the - * last attempt */ - delay = (nn->nn_last_connect_attempt + - msecs_to_jiffies(r2net_reconnect_delay())) - - jiffies; - if (delay > msecs_to_jiffies(r2net_reconnect_delay())) - delay = 0; - mlog(ML_CONN, "queueing conn attempt in %lu jiffies\n", delay); - queue_delayed_work(r2net_wq, &nn->nn_connect_work, delay); - - /* - * Delay the expired work after idle timeout. - * - * We might have lots of failed connection attempts that run - * through here but we only cancel the connect_expired work when - * a connection attempt succeeds. So only the first enqueue of - * the connect_expired work will do anything. The rest will see - * that it's already queued and do nothing. - */ - delay += msecs_to_jiffies(r2net_idle_timeout()); - queue_delayed_work(r2net_wq, &nn->nn_connect_expired, delay); - } - - /* keep track of the nn's sc ref for the caller */ - if ((old_sc == NULL) && sc) - sc_get(sc); - if (old_sc && (old_sc != sc)) { - r2net_sc_queue_work(old_sc, &old_sc->sc_shutdown_work); - sc_put(old_sc); - } -} - -/* see r2net_register_callbacks() */ -static void r2net_data_ready(struct sock *sk, int bytes) -{ - void (*ready)(struct sock *sk, int bytes); - - read_lock(&sk->sk_callback_lock); - if (sk->sk_user_data) { - struct r2net_sock_container *sc = sk->sk_user_data; - sclog(sc, "data_ready hit\n"); - r2net_set_data_ready_time(sc); - r2net_sc_queue_work(sc, &sc->sc_rx_work); - ready = sc->sc_data_ready; - } else { - ready = sk->sk_data_ready; - } - read_unlock(&sk->sk_callback_lock); - - ready(sk, bytes); -} - -/* see r2net_register_callbacks() */ -static void r2net_state_change(struct sock *sk) -{ - void (*state_change)(struct sock *sk); - struct r2net_sock_container *sc; - - read_lock(&sk->sk_callback_lock); - sc = sk->sk_user_data; - if (sc == NULL) { - state_change = sk->sk_state_change; - goto out; - } - - sclog(sc, "state_change to %d\n", sk->sk_state); - - state_change = sc->sc_state_change; - - switch (sk->sk_state) { - - /* ignore connecting sockets as they make progress */ - case TCP_SYN_SENT: - case TCP_SYN_RECV: - break; - case TCP_ESTABLISHED: - r2net_sc_queue_work(sc, &sc->sc_connect_work); - break; - default: - printk(KERN_INFO "ramster: Connection to " - SC_NODEF_FMT " shutdown, state %d\n", - sc->sc_node->nd_name, sc->sc_node->nd_num, - &sc->sc_node->nd_ipv4_address, - ntohs(sc->sc_node->nd_ipv4_port), sk->sk_state); - r2net_sc_queue_work(sc, &sc->sc_shutdown_work); - break; - - } -out: - read_unlock(&sk->sk_callback_lock); - state_change(sk); -} - -/* - * we register callbacks so we can queue work on events before calling - * the original callbacks. our callbacks are careful to test user_data - * to discover when they've reaced with r2net_unregister_callbacks(). - */ -static void r2net_register_callbacks(struct sock *sk, - struct r2net_sock_container *sc) -{ - write_lock_bh(&sk->sk_callback_lock); - - /* accepted sockets inherit the old listen socket data ready */ - if (sk->sk_data_ready == r2net_listen_data_ready) { - sk->sk_data_ready = sk->sk_user_data; - sk->sk_user_data = NULL; - } - - BUG_ON(sk->sk_user_data != NULL); - sk->sk_user_data = sc; - sc_get(sc); - - sc->sc_data_ready = sk->sk_data_ready; - sc->sc_state_change = sk->sk_state_change; - sk->sk_data_ready = r2net_data_ready; - sk->sk_state_change = r2net_state_change; - - mutex_init(&sc->sc_send_lock); - - write_unlock_bh(&sk->sk_callback_lock); -} - -static int r2net_unregister_callbacks(struct sock *sk, - struct r2net_sock_container *sc) -{ - int ret = 0; - - write_lock_bh(&sk->sk_callback_lock); - if (sk->sk_user_data == sc) { - ret = 1; - sk->sk_user_data = NULL; - sk->sk_data_ready = sc->sc_data_ready; - sk->sk_state_change = sc->sc_state_change; - } - write_unlock_bh(&sk->sk_callback_lock); - - return ret; -} - -/* - * this is a little helper that is called by callers who have seen a problem - * with an sc and want to detach it from the nn if someone already hasn't beat - * them to it. if an error is given then the shutdown will be persistent - * and pending transmits will be canceled. - */ -static void r2net_ensure_shutdown(struct r2net_node *nn, - struct r2net_sock_container *sc, - int err) -{ - spin_lock(&nn->nn_lock); - if (nn->nn_sc == sc) - r2net_set_nn_state(nn, NULL, 0, err); - spin_unlock(&nn->nn_lock); -} - -/* - * This work queue function performs the blocking parts of socket shutdown. A - * few paths lead here. set_nn_state will trigger this callback if it sees an - * sc detached from the nn. state_change will also trigger this callback - * directly when it sees errors. In that case we need to call set_nn_state - * ourselves as state_change couldn't get the nn_lock and call set_nn_state - * itself. - */ -static void r2net_shutdown_sc(struct work_struct *work) -{ - struct r2net_sock_container *sc = - container_of(work, struct r2net_sock_container, - sc_shutdown_work); - struct r2net_node *nn = r2net_nn_from_num(sc->sc_node->nd_num); - - sclog(sc, "shutting down\n"); - - /* drop the callbacks ref and call shutdown only once */ - if (r2net_unregister_callbacks(sc->sc_sock->sk, sc)) { - /* we shouldn't flush as we're in the thread, the - * races with pending sc work structs are harmless */ - del_timer_sync(&sc->sc_idle_timeout); - r2net_sc_cancel_delayed_work(sc, &sc->sc_keepalive_work); - sc_put(sc); - kernel_sock_shutdown(sc->sc_sock, SHUT_RDWR); - } - - /* not fatal so failed connects before the other guy has our - * heartbeat can be retried */ - r2net_ensure_shutdown(nn, sc, 0); - sc_put(sc); -} - -/* ------------------------------------------------------------ */ - -static int r2net_handler_cmp(struct r2net_msg_handler *nmh, u32 msg_type, - u32 key) -{ - int ret = memcmp(&nmh->nh_key, &key, sizeof(key)); - - if (ret == 0) - ret = memcmp(&nmh->nh_msg_type, &msg_type, sizeof(msg_type)); - - return ret; -} - -static struct r2net_msg_handler * -r2net_handler_tree_lookup(u32 msg_type, u32 key, struct rb_node ***ret_p, - struct rb_node **ret_parent) -{ - struct rb_node **p = &r2net_handler_tree.rb_node; - struct rb_node *parent = NULL; - struct r2net_msg_handler *nmh, *ret = NULL; - int cmp; - - while (*p) { - parent = *p; - nmh = rb_entry(parent, struct r2net_msg_handler, nh_node); - cmp = r2net_handler_cmp(nmh, msg_type, key); - - if (cmp < 0) - p = &(*p)->rb_left; - else if (cmp > 0) - p = &(*p)->rb_right; - else { - ret = nmh; - break; - } - } - - if (ret_p != NULL) - *ret_p = p; - if (ret_parent != NULL) - *ret_parent = parent; - - return ret; -} - -static void r2net_handler_kref_release(struct kref *kref) -{ - struct r2net_msg_handler *nmh; - nmh = container_of(kref, struct r2net_msg_handler, nh_kref); - - kfree(nmh); -} - -static void r2net_handler_put(struct r2net_msg_handler *nmh) -{ - kref_put(&nmh->nh_kref, r2net_handler_kref_release); -} - -/* max_len is protection for the handler func. incoming messages won't - * be given to the handler if their payload is longer than the max. */ -int r2net_register_handler(u32 msg_type, u32 key, u32 max_len, - r2net_msg_handler_func *func, void *data, - r2net_post_msg_handler_func *post_func, - struct list_head *unreg_list) -{ - struct r2net_msg_handler *nmh = NULL; - struct rb_node **p, *parent; - int ret = 0; - - if (max_len > R2NET_MAX_PAYLOAD_BYTES) { - mlog(0, "max_len for message handler out of range: %u\n", - max_len); - ret = -EINVAL; - goto out; - } - - if (!msg_type) { - mlog(0, "no message type provided: %u, %p\n", msg_type, func); - ret = -EINVAL; - goto out; - - } - if (!func) { - mlog(0, "no message handler provided: %u, %p\n", - msg_type, func); - ret = -EINVAL; - goto out; - } - - nmh = kzalloc(sizeof(struct r2net_msg_handler), GFP_NOFS); - if (nmh == NULL) { - ret = -ENOMEM; - goto out; - } - - nmh->nh_func = func; - nmh->nh_func_data = data; - nmh->nh_post_func = post_func; - nmh->nh_msg_type = msg_type; - nmh->nh_max_len = max_len; - nmh->nh_key = key; - /* the tree and list get this ref.. they're both removed in - * unregister when this ref is dropped */ - kref_init(&nmh->nh_kref); - INIT_LIST_HEAD(&nmh->nh_unregister_item); - - write_lock(&r2net_handler_lock); - if (r2net_handler_tree_lookup(msg_type, key, &p, &parent)) - ret = -EEXIST; - else { - rb_link_node(&nmh->nh_node, parent, p); - rb_insert_color(&nmh->nh_node, &r2net_handler_tree); - list_add_tail(&nmh->nh_unregister_item, unreg_list); - - mlog(ML_TCP, "registered handler func %p type %u key %08x\n", - func, msg_type, key); - /* we've had some trouble with handlers seemingly vanishing. */ - mlog_bug_on_msg(r2net_handler_tree_lookup(msg_type, key, &p, - &parent) == NULL, - "couldn't find handler we *just* registered " - "for type %u key %08x\n", msg_type, key); - } - write_unlock(&r2net_handler_lock); - if (ret) - goto out; - -out: - if (ret) - kfree(nmh); - - return ret; -} -EXPORT_SYMBOL_GPL(r2net_register_handler); - -void r2net_unregister_handler_list(struct list_head *list) -{ - struct r2net_msg_handler *nmh, *n; - - write_lock(&r2net_handler_lock); - list_for_each_entry_safe(nmh, n, list, nh_unregister_item) { - mlog(ML_TCP, "unregistering handler func %p type %u key %08x\n", - nmh->nh_func, nmh->nh_msg_type, nmh->nh_key); - rb_erase(&nmh->nh_node, &r2net_handler_tree); - list_del_init(&nmh->nh_unregister_item); - kref_put(&nmh->nh_kref, r2net_handler_kref_release); - } - write_unlock(&r2net_handler_lock); -} -EXPORT_SYMBOL_GPL(r2net_unregister_handler_list); - -static struct r2net_msg_handler *r2net_handler_get(u32 msg_type, u32 key) -{ - struct r2net_msg_handler *nmh; - - read_lock(&r2net_handler_lock); - nmh = r2net_handler_tree_lookup(msg_type, key, NULL, NULL); - if (nmh) - kref_get(&nmh->nh_kref); - read_unlock(&r2net_handler_lock); - - return nmh; -} - -/* ------------------------------------------------------------ */ - -static int r2net_recv_tcp_msg(struct socket *sock, void *data, size_t len) -{ - int ret; - mm_segment_t oldfs; - struct kvec vec = { - .iov_len = len, - .iov_base = data, - }; - struct msghdr msg = { - .msg_iovlen = 1, - .msg_iov = (struct iovec *)&vec, - .msg_flags = MSG_DONTWAIT, - }; - - oldfs = get_fs(); - set_fs(get_ds()); - ret = sock_recvmsg(sock, &msg, len, msg.msg_flags); - set_fs(oldfs); - - return ret; -} - -static int r2net_send_tcp_msg(struct socket *sock, struct kvec *vec, - size_t veclen, size_t total) -{ - int ret; - mm_segment_t oldfs; - struct msghdr msg = { - .msg_iov = (struct iovec *)vec, - .msg_iovlen = veclen, - }; - - if (sock == NULL) { - ret = -EINVAL; - goto out; - } - - oldfs = get_fs(); - set_fs(get_ds()); - ret = sock_sendmsg(sock, &msg, total); - set_fs(oldfs); - if (ret != total) { - mlog(ML_ERROR, "sendmsg returned %d instead of %zu\n", ret, - total); - if (ret >= 0) - ret = -EPIPE; /* should be smarter, I bet */ - goto out; - } - - ret = 0; -out: - if (ret < 0) - mlog(0, "returning error: %d\n", ret); - return ret; -} - -static void r2net_sendpage(struct r2net_sock_container *sc, - void *kmalloced_virt, - size_t size) -{ - struct r2net_node *nn = r2net_nn_from_num(sc->sc_node->nd_num); - ssize_t ret; - - while (1) { - mutex_lock(&sc->sc_send_lock); - ret = sc->sc_sock->ops->sendpage(sc->sc_sock, - virt_to_page(kmalloced_virt), - (long)kmalloced_virt & ~PAGE_MASK, - size, MSG_DONTWAIT); - mutex_unlock(&sc->sc_send_lock); - if (ret == size) - break; - if (ret == (ssize_t)-EAGAIN) { - mlog(0, "sendpage of size %zu to " SC_NODEF_FMT - " returned EAGAIN\n", size, sc->sc_node->nd_name, - sc->sc_node->nd_num, - &sc->sc_node->nd_ipv4_address, - ntohs(sc->sc_node->nd_ipv4_port)); - cond_resched(); - continue; - } - mlog(ML_ERROR, "sendpage of size %zu to " SC_NODEF_FMT - " failed with %zd\n", size, sc->sc_node->nd_name, - sc->sc_node->nd_num, &sc->sc_node->nd_ipv4_address, - ntohs(sc->sc_node->nd_ipv4_port), ret); - r2net_ensure_shutdown(nn, sc, 0); - break; - } -} - -static void r2net_init_msg(struct r2net_msg *msg, u16 data_len, - u16 msg_type, u32 key) -{ - memset(msg, 0, sizeof(struct r2net_msg)); - msg->magic = cpu_to_be16(R2NET_MSG_MAGIC); - msg->data_len = cpu_to_be16(data_len); - msg->msg_type = cpu_to_be16(msg_type); - msg->sys_status = cpu_to_be32(R2NET_ERR_NONE); - msg->status = 0; - msg->key = cpu_to_be32(key); -} - -static int r2net_tx_can_proceed(struct r2net_node *nn, - struct r2net_sock_container **sc_ret, - int *error) -{ - int ret = 0; - - spin_lock(&nn->nn_lock); - if (nn->nn_persistent_error) { - ret = 1; - *sc_ret = NULL; - *error = nn->nn_persistent_error; - } else if (nn->nn_sc_valid) { - kref_get(&nn->nn_sc->sc_kref); - - ret = 1; - *sc_ret = nn->nn_sc; - *error = 0; - } - spin_unlock(&nn->nn_lock); - - return ret; -} - -/* Get a map of all nodes to which this node is currently connected to */ -void r2net_fill_node_map(unsigned long *map, unsigned bytes) -{ - struct r2net_sock_container *sc; - int node, ret; - - BUG_ON(bytes < (BITS_TO_LONGS(R2NM_MAX_NODES) * sizeof(unsigned long))); - - memset(map, 0, bytes); - for (node = 0; node < R2NM_MAX_NODES; ++node) { - r2net_tx_can_proceed(r2net_nn_from_num(node), &sc, &ret); - if (!ret) { - set_bit(node, map); - sc_put(sc); - } - } -} -EXPORT_SYMBOL_GPL(r2net_fill_node_map); - -int r2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec, - size_t caller_veclen, u8 target_node, int *status) -{ - int ret = 0; - struct r2net_msg *msg = NULL; - size_t veclen, caller_bytes = 0; - struct kvec *vec = NULL; - struct r2net_sock_container *sc = NULL; - struct r2net_node *nn = r2net_nn_from_num(target_node); - struct r2net_status_wait nsw = { - .ns_node_item = LIST_HEAD_INIT(nsw.ns_node_item), - }; - struct r2net_send_tracking nst; - - /* this may be a general bug fix */ - init_waitqueue_head(&nsw.ns_wq); - - r2net_init_nst(&nst, msg_type, key, current, target_node); - - if (r2net_wq == NULL) { - mlog(0, "attempt to tx without r2netd running\n"); - ret = -ESRCH; - goto out; - } - - if (caller_veclen == 0) { - mlog(0, "bad kvec array length\n"); - ret = -EINVAL; - goto out; - } - - caller_bytes = iov_length((struct iovec *)caller_vec, caller_veclen); - if (caller_bytes > R2NET_MAX_PAYLOAD_BYTES) { - mlog(0, "total payload len %zu too large\n", caller_bytes); - ret = -EINVAL; - goto out; - } - - if (target_node == r2nm_this_node()) { - ret = -ELOOP; - goto out; - } - - r2net_debug_add_nst(&nst); - - r2net_set_nst_sock_time(&nst); - - wait_event(nn->nn_sc_wq, r2net_tx_can_proceed(nn, &sc, &ret)); - if (ret) - goto out; - - r2net_set_nst_sock_container(&nst, sc); - - veclen = caller_veclen + 1; - vec = kmalloc(sizeof(struct kvec) * veclen, GFP_ATOMIC); - if (vec == NULL) { - mlog(0, "failed to %zu element kvec!\n", veclen); - ret = -ENOMEM; - goto out; - } - - msg = kmalloc(sizeof(struct r2net_msg), GFP_ATOMIC); - if (!msg) { - mlog(0, "failed to allocate a r2net_msg!\n"); - ret = -ENOMEM; - goto out; - } - - r2net_init_msg(msg, caller_bytes, msg_type, key); - - vec[0].iov_len = sizeof(struct r2net_msg); - vec[0].iov_base = msg; - memcpy(&vec[1], caller_vec, caller_veclen * sizeof(struct kvec)); - - ret = r2net_prep_nsw(nn, &nsw); - if (ret) - goto out; - - msg->msg_num = cpu_to_be32(nsw.ns_id); - r2net_set_nst_msg_id(&nst, nsw.ns_id); - - r2net_set_nst_send_time(&nst); - - /* finally, convert the message header to network byte-order - * and send */ - mutex_lock(&sc->sc_send_lock); - ret = r2net_send_tcp_msg(sc->sc_sock, vec, veclen, - sizeof(struct r2net_msg) + caller_bytes); - mutex_unlock(&sc->sc_send_lock); - msglog(msg, "sending returned %d\n", ret); - if (ret < 0) { - mlog(0, "error returned from r2net_send_tcp_msg=%d\n", ret); - goto out; - } - - /* wait on other node's handler */ - r2net_set_nst_status_time(&nst); - wait_event(nsw.ns_wq, r2net_nsw_completed(nn, &nsw)); - - r2net_update_send_stats(&nst, sc); - - /* Note that we avoid overwriting the callers status return - * variable if a system error was reported on the other - * side. Callers beware. */ - ret = r2net_sys_err_to_errno(nsw.ns_sys_status); - if (status && !ret) - *status = nsw.ns_status; - - mlog(0, "woken, returning system status %d, user status %d\n", - ret, nsw.ns_status); -out: - r2net_debug_del_nst(&nst); /* must be before dropping sc and node */ - if (sc) - sc_put(sc); - kfree(vec); - kfree(msg); - r2net_complete_nsw(nn, &nsw, 0, 0, 0); - return ret; -} -EXPORT_SYMBOL_GPL(r2net_send_message_vec); - -int r2net_send_message(u32 msg_type, u32 key, void *data, u32 len, - u8 target_node, int *status) -{ - struct kvec vec = { - .iov_base = data, - .iov_len = len, - }; - return r2net_send_message_vec(msg_type, key, &vec, 1, - target_node, status); -} -EXPORT_SYMBOL_GPL(r2net_send_message); - -static int r2net_send_status_magic(struct socket *sock, struct r2net_msg *hdr, - enum r2net_system_error syserr, int err) -{ - struct kvec vec = { - .iov_base = hdr, - .iov_len = sizeof(struct r2net_msg), - }; - - BUG_ON(syserr >= R2NET_ERR_MAX); - - /* leave other fields intact from the incoming message, msg_num - * in particular */ - hdr->sys_status = cpu_to_be32(syserr); - hdr->status = cpu_to_be32(err); - /* twiddle the magic */ - hdr->magic = cpu_to_be16(R2NET_MSG_STATUS_MAGIC); - hdr->data_len = 0; - - msglog(hdr, "about to send status magic %d\n", err); - /* hdr has been in host byteorder this whole time */ - return r2net_send_tcp_msg(sock, &vec, 1, sizeof(struct r2net_msg)); -} - -/* - * "data magic" is a long version of "status magic" where the message - * payload actually contains data to be passed in reply to certain messages - */ -static int r2net_send_data_magic(struct r2net_sock_container *sc, - struct r2net_msg *hdr, - void *data, size_t data_len, - enum r2net_system_error syserr, int err) -{ - struct kvec vec[2]; - int ret; - - vec[0].iov_base = hdr; - vec[0].iov_len = sizeof(struct r2net_msg); - vec[1].iov_base = data; - vec[1].iov_len = data_len; - - BUG_ON(syserr >= R2NET_ERR_MAX); - - /* leave other fields intact from the incoming message, msg_num - * in particular */ - hdr->sys_status = cpu_to_be32(syserr); - hdr->status = cpu_to_be32(err); - hdr->magic = cpu_to_be16(R2NET_MSG_DATA_MAGIC); /* twiddle magic */ - hdr->data_len = cpu_to_be16(data_len); - - msglog(hdr, "about to send data magic %d\n", err); - /* hdr has been in host byteorder this whole time */ - ret = r2net_send_tcp_msg(sc->sc_sock, vec, 2, - sizeof(struct r2net_msg) + data_len); - return ret; -} - -/* - * called by a message handler to convert an otherwise normal reply - * message into a "data magic" message - */ -void r2net_force_data_magic(struct r2net_msg *hdr, u16 msgtype, u32 msgkey) -{ - hdr->magic = cpu_to_be16(R2NET_MSG_DATA_MAGIC); - hdr->msg_type = cpu_to_be16(msgtype); - hdr->key = cpu_to_be32(msgkey); -} - -/* this returns -errno if the header was unknown or too large, etc. - * after this is called the buffer us reused for the next message */ -static int r2net_process_message(struct r2net_sock_container *sc, - struct r2net_msg *hdr) -{ - struct r2net_node *nn = r2net_nn_from_num(sc->sc_node->nd_num); - int ret = 0, handler_status; - enum r2net_system_error syserr; - struct r2net_msg_handler *nmh = NULL; - void *ret_data = NULL; - int data_magic = 0; - - msglog(hdr, "processing message\n"); - - r2net_sc_postpone_idle(sc); - - switch (be16_to_cpu(hdr->magic)) { - - case R2NET_MSG_STATUS_MAGIC: - /* special type for returning message status */ - r2net_complete_nsw(nn, NULL, be32_to_cpu(hdr->msg_num), - be32_to_cpu(hdr->sys_status), - be32_to_cpu(hdr->status)); - goto out; - case R2NET_MSG_KEEP_REQ_MAGIC: - r2net_sendpage(sc, r2net_keep_resp, sizeof(*r2net_keep_resp)); - goto out; - case R2NET_MSG_KEEP_RESP_MAGIC: - goto out; - case R2NET_MSG_MAGIC: - break; - case R2NET_MSG_DATA_MAGIC: - /* - * unlike a normal status magic, a data magic DOES - * (MUST) have a handler, so the control flow is - * a little funky here as a result - */ - data_magic = 1; - break; - default: - msglog(hdr, "bad magic\n"); - ret = -EINVAL; - goto out; - break; - } - - /* find a handler for it */ - handler_status = 0; - nmh = r2net_handler_get(be16_to_cpu(hdr->msg_type), - be32_to_cpu(hdr->key)); - if (!nmh) { - mlog(ML_TCP, "couldn't find handler for type %u key %08x\n", - be16_to_cpu(hdr->msg_type), be32_to_cpu(hdr->key)); - syserr = R2NET_ERR_NO_HNDLR; - goto out_respond; - } - - syserr = R2NET_ERR_NONE; - - if (be16_to_cpu(hdr->data_len) > nmh->nh_max_len) - syserr = R2NET_ERR_OVERFLOW; - - if (syserr != R2NET_ERR_NONE) - goto out_respond; - - r2net_set_func_start_time(sc); - sc->sc_msg_key = be32_to_cpu(hdr->key); - sc->sc_msg_type = be16_to_cpu(hdr->msg_type); - handler_status = (nmh->nh_func)(hdr, sizeof(struct r2net_msg) + - be16_to_cpu(hdr->data_len), - nmh->nh_func_data, &ret_data); - if (data_magic) { - /* - * handler handled data sent in reply to request - * so complete the transaction - */ - r2net_complete_nsw(nn, NULL, be32_to_cpu(hdr->msg_num), - be32_to_cpu(hdr->sys_status), handler_status); - goto out; - } - /* - * handler changed magic to DATA_MAGIC to reply to request for data, - * implies ret_data points to data to return and handler_status - * is the number of bytes of data - */ - if (be16_to_cpu(hdr->magic) == R2NET_MSG_DATA_MAGIC) { - ret = r2net_send_data_magic(sc, hdr, - ret_data, handler_status, - syserr, 0); - hdr = NULL; - mlog(0, "sending data reply %d, syserr %d returned %d\n", - handler_status, syserr, ret); - r2net_set_func_stop_time(sc); - - r2net_update_recv_stats(sc); - goto out; - } - r2net_set_func_stop_time(sc); - - r2net_update_recv_stats(sc); - -out_respond: - /* this destroys the hdr, so don't use it after this */ - mutex_lock(&sc->sc_send_lock); - ret = r2net_send_status_magic(sc->sc_sock, hdr, syserr, - handler_status); - mutex_unlock(&sc->sc_send_lock); - hdr = NULL; - mlog(0, "sending handler status %d, syserr %d returned %d\n", - handler_status, syserr, ret); - - if (nmh) { - BUG_ON(ret_data != NULL && nmh->nh_post_func == NULL); - if (nmh->nh_post_func) - (nmh->nh_post_func)(handler_status, nmh->nh_func_data, - ret_data); - } - -out: - if (nmh) - r2net_handler_put(nmh); - return ret; -} - -static int r2net_check_handshake(struct r2net_sock_container *sc) -{ - struct r2net_handshake *hand = page_address(sc->sc_page); - struct r2net_node *nn = r2net_nn_from_num(sc->sc_node->nd_num); - - if (hand->protocol_version != cpu_to_be64(R2NET_PROTOCOL_VERSION)) { - printk(KERN_NOTICE "ramster: " SC_NODEF_FMT " Advertised net " - "protocol version %llu but %llu is required. " - "Disconnecting.\n", sc->sc_node->nd_name, - sc->sc_node->nd_num, &sc->sc_node->nd_ipv4_address, - ntohs(sc->sc_node->nd_ipv4_port), - (unsigned long long)be64_to_cpu(hand->protocol_version), - R2NET_PROTOCOL_VERSION); - - /* don't bother reconnecting if its the wrong version. */ - r2net_ensure_shutdown(nn, sc, -ENOTCONN); - return -1; - } - - /* - * Ensure timeouts are consistent with other nodes, otherwise - * we can end up with one node thinking that the other must be down, - * but isn't. This can ultimately cause corruption. - */ - if (be32_to_cpu(hand->r2net_idle_timeout_ms) != - r2net_idle_timeout()) { - printk(KERN_NOTICE "ramster: " SC_NODEF_FMT " uses a network " - "idle timeout of %u ms, but we use %u ms locally. " - "Disconnecting.\n", sc->sc_node->nd_name, - sc->sc_node->nd_num, &sc->sc_node->nd_ipv4_address, - ntohs(sc->sc_node->nd_ipv4_port), - be32_to_cpu(hand->r2net_idle_timeout_ms), - r2net_idle_timeout()); - r2net_ensure_shutdown(nn, sc, -ENOTCONN); - return -1; - } - - if (be32_to_cpu(hand->r2net_keepalive_delay_ms) != - r2net_keepalive_delay()) { - printk(KERN_NOTICE "ramster: " SC_NODEF_FMT " uses a keepalive " - "delay of %u ms, but we use %u ms locally. " - "Disconnecting.\n", sc->sc_node->nd_name, - sc->sc_node->nd_num, &sc->sc_node->nd_ipv4_address, - ntohs(sc->sc_node->nd_ipv4_port), - be32_to_cpu(hand->r2net_keepalive_delay_ms), - r2net_keepalive_delay()); - r2net_ensure_shutdown(nn, sc, -ENOTCONN); - return -1; - } - - if (be32_to_cpu(hand->r2hb_heartbeat_timeout_ms) != - R2HB_MAX_WRITE_TIMEOUT_MS) { - printk(KERN_NOTICE "ramster: " SC_NODEF_FMT " uses a heartbeat " - "timeout of %u ms, but we use %u ms locally. " - "Disconnecting.\n", sc->sc_node->nd_name, - sc->sc_node->nd_num, &sc->sc_node->nd_ipv4_address, - ntohs(sc->sc_node->nd_ipv4_port), - be32_to_cpu(hand->r2hb_heartbeat_timeout_ms), - R2HB_MAX_WRITE_TIMEOUT_MS); - r2net_ensure_shutdown(nn, sc, -ENOTCONN); - return -1; - } - - sc->sc_handshake_ok = 1; - - spin_lock(&nn->nn_lock); - /* set valid and queue the idle timers only if it hasn't been - * shut down already */ - if (nn->nn_sc == sc) { - r2net_sc_reset_idle_timer(sc); - atomic_set(&nn->nn_timeout, 0); - r2net_set_nn_state(nn, sc, 1, 0); - } - spin_unlock(&nn->nn_lock); - - /* shift everything up as though it wasn't there */ - sc->sc_page_off -= sizeof(struct r2net_handshake); - if (sc->sc_page_off) - memmove(hand, hand + 1, sc->sc_page_off); - - return 0; -} - -/* this demuxes the queued rx bytes into header or payload bits and calls - * handlers as each full message is read off the socket. it returns -error, - * == 0 eof, or > 0 for progress made.*/ -static int r2net_advance_rx(struct r2net_sock_container *sc) -{ - struct r2net_msg *hdr; - int ret = 0; - void *data; - size_t datalen; - - sclog(sc, "receiving\n"); - r2net_set_advance_start_time(sc); - - if (unlikely(sc->sc_handshake_ok == 0)) { - if (sc->sc_page_off < sizeof(struct r2net_handshake)) { - data = page_address(sc->sc_page) + sc->sc_page_off; - datalen = sizeof(struct r2net_handshake) - - sc->sc_page_off; - ret = r2net_recv_tcp_msg(sc->sc_sock, data, datalen); - if (ret > 0) - sc->sc_page_off += ret; - } - - if (sc->sc_page_off == sizeof(struct r2net_handshake)) { - r2net_check_handshake(sc); - if (unlikely(sc->sc_handshake_ok == 0)) - ret = -EPROTO; - } - goto out; - } - - /* do we need more header? */ - if (sc->sc_page_off < sizeof(struct r2net_msg)) { - data = page_address(sc->sc_page) + sc->sc_page_off; - datalen = sizeof(struct r2net_msg) - sc->sc_page_off; - ret = r2net_recv_tcp_msg(sc->sc_sock, data, datalen); - if (ret > 0) { - sc->sc_page_off += ret; - /* only swab incoming here.. we can - * only get here once as we cross from - * being under to over */ - if (sc->sc_page_off == sizeof(struct r2net_msg)) { - hdr = page_address(sc->sc_page); - if (be16_to_cpu(hdr->data_len) > - R2NET_MAX_PAYLOAD_BYTES) - ret = -EOVERFLOW; - } - } - if (ret <= 0) - goto out; - } - - if (sc->sc_page_off < sizeof(struct r2net_msg)) { - /* oof, still don't have a header */ - goto out; - } - - /* this was swabbed above when we first read it */ - hdr = page_address(sc->sc_page); - - msglog(hdr, "at page_off %zu\n", sc->sc_page_off); - - /* do we need more payload? */ - if (sc->sc_page_off - sizeof(struct r2net_msg) < - be16_to_cpu(hdr->data_len)) { - /* need more payload */ - data = page_address(sc->sc_page) + sc->sc_page_off; - datalen = (sizeof(struct r2net_msg) + - be16_to_cpu(hdr->data_len)) - - sc->sc_page_off; - ret = r2net_recv_tcp_msg(sc->sc_sock, data, datalen); - if (ret > 0) - sc->sc_page_off += ret; - if (ret <= 0) - goto out; - } - - if (sc->sc_page_off - sizeof(struct r2net_msg) == - be16_to_cpu(hdr->data_len)) { - /* we can only get here once, the first time we read - * the payload.. so set ret to progress if the handler - * works out. after calling this the message is toast */ - ret = r2net_process_message(sc, hdr); - if (ret == 0) - ret = 1; - sc->sc_page_off = 0; - } - -out: - sclog(sc, "ret = %d\n", ret); - r2net_set_advance_stop_time(sc); - return ret; -} - -/* this work func is triggerd by data ready. it reads until it can read no - * more. it interprets 0, eof, as fatal. if data_ready hits while we're doing - * our work the work struct will be marked and we'll be called again. */ -static void r2net_rx_until_empty(struct work_struct *work) -{ - struct r2net_sock_container *sc = - container_of(work, struct r2net_sock_container, sc_rx_work); - int ret; - - do { - ret = r2net_advance_rx(sc); - } while (ret > 0); - - if (ret <= 0 && ret != -EAGAIN) { - struct r2net_node *nn = r2net_nn_from_num(sc->sc_node->nd_num); - sclog(sc, "saw error %d, closing\n", ret); - /* not permanent so read failed handshake can retry */ - r2net_ensure_shutdown(nn, sc, 0); - } - - sc_put(sc); -} - -static int r2net_set_nodelay(struct socket *sock) -{ - int ret, val = 1; - mm_segment_t oldfs; - - oldfs = get_fs(); - set_fs(KERNEL_DS); - - /* - * Dear unsuspecting programmer, - * - * Don't use sock_setsockopt() for SOL_TCP. It doesn't check its level - * argument and assumes SOL_SOCKET so, say, your TCP_NODELAY will - * silently turn into SO_DEBUG. - * - * Yours, - * Keeper of hilariously fragile interfaces. - */ - ret = sock->ops->setsockopt(sock, SOL_TCP, TCP_NODELAY, - (char __user *)&val, sizeof(val)); - - set_fs(oldfs); - return ret; -} - -static void r2net_initialize_handshake(void) -{ - r2net_hand->r2hb_heartbeat_timeout_ms = cpu_to_be32( - R2HB_MAX_WRITE_TIMEOUT_MS); - r2net_hand->r2net_idle_timeout_ms = cpu_to_be32(r2net_idle_timeout()); - r2net_hand->r2net_keepalive_delay_ms = cpu_to_be32( - r2net_keepalive_delay()); - r2net_hand->r2net_reconnect_delay_ms = cpu_to_be32( - r2net_reconnect_delay()); -} - -/* ------------------------------------------------------------ */ - -/* called when a connect completes and after a sock is accepted. the - * rx path will see the response and mark the sc valid */ -static void r2net_sc_connect_completed(struct work_struct *work) -{ - struct r2net_sock_container *sc = - container_of(work, struct r2net_sock_container, - sc_connect_work); - - mlog(ML_MSG, "sc sending handshake with ver %llu id %llx\n", - (unsigned long long)R2NET_PROTOCOL_VERSION, - (unsigned long long)be64_to_cpu(r2net_hand->connector_id)); - - r2net_initialize_handshake(); - r2net_sendpage(sc, r2net_hand, sizeof(*r2net_hand)); - sc_put(sc); -} - -/* this is called as a work_struct func. */ -static void r2net_sc_send_keep_req(struct work_struct *work) -{ - struct r2net_sock_container *sc = - container_of(work, struct r2net_sock_container, - sc_keepalive_work.work); - - r2net_sendpage(sc, r2net_keep_req, sizeof(*r2net_keep_req)); - sc_put(sc); -} - -/* socket shutdown does a del_timer_sync against this as it tears down. - * we can't start this timer until we've got to the point in sc buildup - * where shutdown is going to be involved */ -static void r2net_idle_timer(unsigned long data) -{ - struct r2net_sock_container *sc = (struct r2net_sock_container *)data; -#ifdef CONFIG_DEBUG_FS - unsigned long msecs = ktime_to_ms(ktime_get()) - - ktime_to_ms(sc->sc_tv_timer); -#else - unsigned long msecs = r2net_idle_timeout(); -#endif - - printk(KERN_NOTICE "ramster: Connection to " SC_NODEF_FMT " has been " - "idle for %lu.%lu secs, shutting it down.\n", - sc->sc_node->nd_name, sc->sc_node->nd_num, - &sc->sc_node->nd_ipv4_address, ntohs(sc->sc_node->nd_ipv4_port), - msecs / 1000, msecs % 1000); - - /* - * Initialize the nn_timeout so that the next connection attempt - * will continue in r2net_start_connect. - */ - /* Avoid spurious shutdowns... not sure if this is still necessary */ - pr_err("ramster_idle_timer, skipping shutdown work\n"); -#if 0 - /* old code used to do these two lines */ - atomic_set(&nn->nn_timeout, 1); - r2net_sc_queue_work(sc, &sc->sc_shutdown_work); -#endif -} - -static void r2net_sc_reset_idle_timer(struct r2net_sock_container *sc) -{ - r2net_sc_cancel_delayed_work(sc, &sc->sc_keepalive_work); - r2net_sc_queue_delayed_work(sc, &sc->sc_keepalive_work, - msecs_to_jiffies(r2net_keepalive_delay())); - r2net_set_sock_timer(sc); - mod_timer(&sc->sc_idle_timeout, - jiffies + msecs_to_jiffies(r2net_idle_timeout())); -} - -static void r2net_sc_postpone_idle(struct r2net_sock_container *sc) -{ - /* Only push out an existing timer */ - if (timer_pending(&sc->sc_idle_timeout)) - r2net_sc_reset_idle_timer(sc); -} - -/* this work func is kicked whenever a path sets the nn state which doesn't - * have valid set. This includes seeing hb come up, losing a connection, - * having a connect attempt fail, etc. This centralizes the logic which decides - * if a connect attempt should be made or if we should give up and all future - * transmit attempts should fail */ -static void r2net_start_connect(struct work_struct *work) -{ - struct r2net_node *nn = - container_of(work, struct r2net_node, nn_connect_work.work); - struct r2net_sock_container *sc = NULL; - struct r2nm_node *node = NULL, *mynode = NULL; - struct socket *sock = NULL; - struct sockaddr_in myaddr = {0, }, remoteaddr = {0, }; - int ret = 0, stop; - unsigned int timeout; - - /* if we're greater we initiate tx, otherwise we accept */ - if (r2nm_this_node() <= r2net_num_from_nn(nn)) - goto out; - - /* watch for racing with tearing a node down */ - node = r2nm_get_node_by_num(r2net_num_from_nn(nn)); - if (node == NULL) { - ret = 0; - goto out; - } - - mynode = r2nm_get_node_by_num(r2nm_this_node()); - if (mynode == NULL) { - ret = 0; - goto out; - } - - spin_lock(&nn->nn_lock); - /* - * see if we already have one pending or have given up. - * For nn_timeout, it is set when we close the connection - * because of the idle time out. So it means that we have - * at least connected to that node successfully once, - * now try to connect to it again. - */ - timeout = atomic_read(&nn->nn_timeout); - stop = (nn->nn_sc || - (nn->nn_persistent_error && - (nn->nn_persistent_error != -ENOTCONN || timeout == 0))); - spin_unlock(&nn->nn_lock); - if (stop) - goto out; - - nn->nn_last_connect_attempt = jiffies; - - sc = sc_alloc(node); - if (sc == NULL) { - mlog(0, "couldn't allocate sc\n"); - ret = -ENOMEM; - goto out; - } - - ret = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock); - if (ret < 0) { - mlog(0, "can't create socket: %d\n", ret); - goto out; - } - sc->sc_sock = sock; /* freed by sc_kref_release */ - - sock->sk->sk_allocation = GFP_ATOMIC; - - myaddr.sin_family = AF_INET; - myaddr.sin_addr.s_addr = mynode->nd_ipv4_address; - myaddr.sin_port = htons(0); /* any port */ - - ret = sock->ops->bind(sock, (struct sockaddr *)&myaddr, - sizeof(myaddr)); - if (ret) { - mlog(ML_ERROR, "bind failed with %d at address %pI4\n", - ret, &mynode->nd_ipv4_address); - goto out; - } - - ret = r2net_set_nodelay(sc->sc_sock); - if (ret) { - mlog(ML_ERROR, "setting TCP_NODELAY failed with %d\n", ret); - goto out; - } - - r2net_register_callbacks(sc->sc_sock->sk, sc); - - spin_lock(&nn->nn_lock); - /* handshake completion will set nn->nn_sc_valid */ - r2net_set_nn_state(nn, sc, 0, 0); - spin_unlock(&nn->nn_lock); - - remoteaddr.sin_family = AF_INET; - remoteaddr.sin_addr.s_addr = node->nd_ipv4_address; - remoteaddr.sin_port = node->nd_ipv4_port; - - ret = sc->sc_sock->ops->connect(sc->sc_sock, - (struct sockaddr *)&remoteaddr, - sizeof(remoteaddr), - O_NONBLOCK); - if (ret == -EINPROGRESS) - ret = 0; - -out: - if (ret) { - printk(KERN_NOTICE "ramster: Connect attempt to " SC_NODEF_FMT - " failed with errno %d\n", sc->sc_node->nd_name, - sc->sc_node->nd_num, &sc->sc_node->nd_ipv4_address, - ntohs(sc->sc_node->nd_ipv4_port), ret); - /* 0 err so that another will be queued and attempted - * from set_nn_state */ - if (sc) - r2net_ensure_shutdown(nn, sc, 0); - } - if (sc) - sc_put(sc); - if (node) - r2nm_node_put(node); - if (mynode) - r2nm_node_put(mynode); - - return; -} - -static void r2net_connect_expired(struct work_struct *work) -{ - struct r2net_node *nn = - container_of(work, struct r2net_node, nn_connect_expired.work); - - spin_lock(&nn->nn_lock); - if (!nn->nn_sc_valid) { - printk(KERN_NOTICE "ramster: No connection established with " - "node %u after %u.%u seconds, giving up.\n", - r2net_num_from_nn(nn), - r2net_idle_timeout() / 1000, - r2net_idle_timeout() % 1000); - - r2net_set_nn_state(nn, NULL, 0, -ENOTCONN); - } - spin_unlock(&nn->nn_lock); -} - -static void r2net_still_up(struct work_struct *work) -{ -} - -/* ------------------------------------------------------------ */ - -void r2net_disconnect_node(struct r2nm_node *node) -{ - struct r2net_node *nn = r2net_nn_from_num(node->nd_num); - - /* don't reconnect until it's heartbeating again */ - spin_lock(&nn->nn_lock); - atomic_set(&nn->nn_timeout, 0); - r2net_set_nn_state(nn, NULL, 0, -ENOTCONN); - spin_unlock(&nn->nn_lock); - - if (r2net_wq) { - cancel_delayed_work(&nn->nn_connect_expired); - cancel_delayed_work(&nn->nn_connect_work); - cancel_delayed_work(&nn->nn_still_up); - flush_workqueue(r2net_wq); - } -} - -static void r2net_hb_node_down_cb(struct r2nm_node *node, int node_num, - void *data) -{ - if (!node) - return; - - if (node_num != r2nm_this_node()) - r2net_disconnect_node(node); - - BUG_ON(atomic_read(&r2net_connected_peers) < 0); -} - -static void r2net_hb_node_up_cb(struct r2nm_node *node, int node_num, - void *data) -{ - struct r2net_node *nn = r2net_nn_from_num(node_num); - - BUG_ON(!node); - - /* ensure an immediate connect attempt */ - nn->nn_last_connect_attempt = jiffies - - (msecs_to_jiffies(r2net_reconnect_delay()) + 1); - - if (node_num != r2nm_this_node()) { - /* believe it or not, accept and node hearbeating testing - * can succeed for this node before we got here.. so - * only use set_nn_state to clear the persistent error - * if that hasn't already happened */ - spin_lock(&nn->nn_lock); - atomic_set(&nn->nn_timeout, 0); - if (nn->nn_persistent_error) - r2net_set_nn_state(nn, NULL, 0, 0); - spin_unlock(&nn->nn_lock); - } -} - -void r2net_unregister_hb_callbacks(void) -{ - r2hb_unregister_callback(NULL, &r2net_hb_up); - r2hb_unregister_callback(NULL, &r2net_hb_down); -} - -int r2net_register_hb_callbacks(void) -{ - int ret; - - r2hb_setup_callback(&r2net_hb_down, R2HB_NODE_DOWN_CB, - r2net_hb_node_down_cb, NULL, R2NET_HB_PRI); - r2hb_setup_callback(&r2net_hb_up, R2HB_NODE_UP_CB, - r2net_hb_node_up_cb, NULL, R2NET_HB_PRI); - - ret = r2hb_register_callback(NULL, &r2net_hb_up); - if (ret == 0) - ret = r2hb_register_callback(NULL, &r2net_hb_down); - - if (ret) - r2net_unregister_hb_callbacks(); - - return ret; -} - -/* ------------------------------------------------------------ */ - -static int r2net_accept_one(struct socket *sock) -{ - int ret, slen; - struct sockaddr_in sin; - struct socket *new_sock = NULL; - struct r2nm_node *node = NULL; - struct r2nm_node *local_node = NULL; - struct r2net_sock_container *sc = NULL; - struct r2net_node *nn; - - BUG_ON(sock == NULL); - ret = sock_create_lite(sock->sk->sk_family, sock->sk->sk_type, - sock->sk->sk_protocol, &new_sock); - if (ret) - goto out; - - new_sock->type = sock->type; - new_sock->ops = sock->ops; - ret = sock->ops->accept(sock, new_sock, O_NONBLOCK); - if (ret < 0) - goto out; - - new_sock->sk->sk_allocation = GFP_ATOMIC; - - ret = r2net_set_nodelay(new_sock); - if (ret) { - mlog(ML_ERROR, "setting TCP_NODELAY failed with %d\n", ret); - goto out; - } - - slen = sizeof(sin); - ret = new_sock->ops->getname(new_sock, (struct sockaddr *) &sin, - &slen, 1); - if (ret < 0) - goto out; - - node = r2nm_get_node_by_ip(sin.sin_addr.s_addr); - if (node == NULL) { - printk(KERN_NOTICE "ramster: Attempt to connect from unknown " - "node at %pI4:%d\n", &sin.sin_addr.s_addr, - ntohs(sin.sin_port)); - ret = -EINVAL; - goto out; - } - - if (r2nm_this_node() >= node->nd_num) { - local_node = r2nm_get_node_by_num(r2nm_this_node()); - printk(KERN_NOTICE "ramster: Unexpected connect attempt seen " - "at node '%s' (%u, %pI4:%d) from node '%s' (%u, " - "%pI4:%d)\n", local_node->nd_name, local_node->nd_num, - &(local_node->nd_ipv4_address), - ntohs(local_node->nd_ipv4_port), node->nd_name, - node->nd_num, &sin.sin_addr.s_addr, ntohs(sin.sin_port)); - ret = -EINVAL; - goto out; - } - - /* this happens all the time when the other node sees our heartbeat - * and tries to connect before we see their heartbeat */ - if (!r2hb_check_node_heartbeating_from_callback(node->nd_num)) { - mlog(ML_CONN, "attempt to connect from node '%s' at " - "%pI4:%d but it isn't heartbeating\n", - node->nd_name, &sin.sin_addr.s_addr, - ntohs(sin.sin_port)); - ret = -EINVAL; - goto out; - } - - nn = r2net_nn_from_num(node->nd_num); - - spin_lock(&nn->nn_lock); - if (nn->nn_sc) - ret = -EBUSY; - else - ret = 0; - spin_unlock(&nn->nn_lock); - if (ret) { - printk(KERN_NOTICE "ramster: Attempt to connect from node '%s' " - "at %pI4:%d but it already has an open connection\n", - node->nd_name, &sin.sin_addr.s_addr, - ntohs(sin.sin_port)); - goto out; - } - - sc = sc_alloc(node); - if (sc == NULL) { - ret = -ENOMEM; - goto out; - } - - sc->sc_sock = new_sock; - new_sock = NULL; - - spin_lock(&nn->nn_lock); - atomic_set(&nn->nn_timeout, 0); - r2net_set_nn_state(nn, sc, 0, 0); - spin_unlock(&nn->nn_lock); - - r2net_register_callbacks(sc->sc_sock->sk, sc); - r2net_sc_queue_work(sc, &sc->sc_rx_work); - - r2net_initialize_handshake(); - r2net_sendpage(sc, r2net_hand, sizeof(*r2net_hand)); - -out: - if (new_sock) - sock_release(new_sock); - if (node) - r2nm_node_put(node); - if (local_node) - r2nm_node_put(local_node); - if (sc) - sc_put(sc); - return ret; -} - -static void r2net_accept_many(struct work_struct *work) -{ - struct socket *sock = r2net_listen_sock; - while (r2net_accept_one(sock) == 0) - cond_resched(); -} - -static void r2net_listen_data_ready(struct sock *sk, int bytes) -{ - void (*ready)(struct sock *sk, int bytes); - - read_lock(&sk->sk_callback_lock); - ready = sk->sk_user_data; - if (ready == NULL) { /* check for teardown race */ - ready = sk->sk_data_ready; - goto out; - } - - /* ->sk_data_ready is also called for a newly established child socket - * before it has been accepted and the acceptor has set up their - * data_ready.. we only want to queue listen work for our listening - * socket */ - if (sk->sk_state == TCP_LISTEN) { - mlog(ML_TCP, "bytes: %d\n", bytes); - queue_work(r2net_wq, &r2net_listen_work); - } - -out: - read_unlock(&sk->sk_callback_lock); - ready(sk, bytes); -} - -static int r2net_open_listening_sock(__be32 addr, __be16 port) -{ - struct socket *sock = NULL; - int ret; - struct sockaddr_in sin = { - .sin_family = PF_INET, - .sin_addr = { .s_addr = addr }, - .sin_port = port, - }; - - ret = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock); - if (ret < 0) { - printk(KERN_ERR "ramster: Error %d while creating socket\n", - ret); - goto out; - } - - sock->sk->sk_allocation = GFP_ATOMIC; - - write_lock_bh(&sock->sk->sk_callback_lock); - sock->sk->sk_user_data = sock->sk->sk_data_ready; - sock->sk->sk_data_ready = r2net_listen_data_ready; - write_unlock_bh(&sock->sk->sk_callback_lock); - - r2net_listen_sock = sock; - INIT_WORK(&r2net_listen_work, r2net_accept_many); - - sock->sk->sk_reuse = SK_CAN_REUSE; - ret = sock->ops->bind(sock, (struct sockaddr *)&sin, sizeof(sin)); - if (ret < 0) { - printk(KERN_ERR "ramster: Error %d while binding socket at " - "%pI4:%u\n", ret, &addr, ntohs(port)); - goto out; - } - - ret = sock->ops->listen(sock, 64); - if (ret < 0) - printk(KERN_ERR "ramster: Error %d while listening on %pI4:%u\n", - ret, &addr, ntohs(port)); - -out: - if (ret) { - r2net_listen_sock = NULL; - if (sock) - sock_release(sock); - } - return ret; -} - -/* - * called from node manager when we should bring up our network listening - * socket. node manager handles all the serialization to only call this - * once and to match it with r2net_stop_listening(). note, - * r2nm_this_node() doesn't work yet as we're being called while it - * is being set up. - */ -int r2net_start_listening(struct r2nm_node *node) -{ - int ret = 0; - - BUG_ON(r2net_wq != NULL); - BUG_ON(r2net_listen_sock != NULL); - - mlog(ML_KTHREAD, "starting r2net thread...\n"); - r2net_wq = create_singlethread_workqueue("r2net"); - if (r2net_wq == NULL) { - mlog(ML_ERROR, "unable to launch r2net thread\n"); - return -ENOMEM; /* ? */ - } - - ret = r2net_open_listening_sock(node->nd_ipv4_address, - node->nd_ipv4_port); - if (ret) { - destroy_workqueue(r2net_wq); - r2net_wq = NULL; - } - - return ret; -} - -/* again, r2nm_this_node() doesn't work here as we're involved in - * tearing it down */ -void r2net_stop_listening(struct r2nm_node *node) -{ - struct socket *sock = r2net_listen_sock; - size_t i; - - BUG_ON(r2net_wq == NULL); - BUG_ON(r2net_listen_sock == NULL); - - /* stop the listening socket from generating work */ - write_lock_bh(&sock->sk->sk_callback_lock); - sock->sk->sk_data_ready = sock->sk->sk_user_data; - sock->sk->sk_user_data = NULL; - write_unlock_bh(&sock->sk->sk_callback_lock); - - for (i = 0; i < ARRAY_SIZE(r2net_nodes); i++) { - struct r2nm_node *node = r2nm_get_node_by_num(i); - if (node) { - r2net_disconnect_node(node); - r2nm_node_put(node); - } - } - - /* finish all work and tear down the work queue */ - mlog(ML_KTHREAD, "waiting for r2net thread to exit....\n"); - destroy_workqueue(r2net_wq); - r2net_wq = NULL; - - sock_release(r2net_listen_sock); - r2net_listen_sock = NULL; -} - -void r2net_hb_node_up_manual(int node_num) -{ - struct r2nm_node dummy; - if (r2nm_single_cluster == NULL) - pr_err("ramster: cluster not alive, node_up_manual ignored\n"); - else { - r2hb_manual_set_node_heartbeating(node_num); - r2net_hb_node_up_cb(&dummy, node_num, NULL); - } -} - -/* ------------------------------------------------------------ */ - -int r2net_init(void) -{ - unsigned long i; - - if (r2net_debugfs_init()) - return -ENOMEM; - - r2net_hand = kzalloc(sizeof(struct r2net_handshake), GFP_KERNEL); - r2net_keep_req = kzalloc(sizeof(struct r2net_msg), GFP_KERNEL); - r2net_keep_resp = kzalloc(sizeof(struct r2net_msg), GFP_KERNEL); - if (!r2net_hand || !r2net_keep_req || !r2net_keep_resp) { - kfree(r2net_hand); - kfree(r2net_keep_req); - kfree(r2net_keep_resp); - return -ENOMEM; - } - - r2net_hand->protocol_version = cpu_to_be64(R2NET_PROTOCOL_VERSION); - r2net_hand->connector_id = cpu_to_be64(1); - - r2net_keep_req->magic = cpu_to_be16(R2NET_MSG_KEEP_REQ_MAGIC); - r2net_keep_resp->magic = cpu_to_be16(R2NET_MSG_KEEP_RESP_MAGIC); - - for (i = 0; i < ARRAY_SIZE(r2net_nodes); i++) { - struct r2net_node *nn = r2net_nn_from_num(i); - - atomic_set(&nn->nn_timeout, 0); - spin_lock_init(&nn->nn_lock); - INIT_DELAYED_WORK(&nn->nn_connect_work, r2net_start_connect); - INIT_DELAYED_WORK(&nn->nn_connect_expired, - r2net_connect_expired); - INIT_DELAYED_WORK(&nn->nn_still_up, r2net_still_up); - /* until we see hb from a node we'll return einval */ - nn->nn_persistent_error = -ENOTCONN; - init_waitqueue_head(&nn->nn_sc_wq); - idr_init(&nn->nn_status_idr); - INIT_LIST_HEAD(&nn->nn_status_list); - } - - return 0; -} - -void r2net_exit(void) -{ - kfree(r2net_hand); - kfree(r2net_keep_req); - kfree(r2net_keep_resp); - r2net_debugfs_exit(); -} diff --git a/drivers/staging/ramster/cluster/tcp.h b/drivers/staging/ramster/cluster/tcp.h deleted file mode 100644 index 9d05833..0000000 --- a/drivers/staging/ramster/cluster/tcp.h +++ /dev/null @@ -1,159 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; -*- - * vim: noexpandtab sw=8 ts=8 sts=0: - * - * tcp.h - * - * Function prototypes - * - * Copyright (C) 2004 Oracle. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 021110-1307, USA. - * - */ - -#ifndef R2CLUSTER_TCP_H -#define R2CLUSTER_TCP_H - -#include -#ifdef __KERNEL__ -#include -#include -#else -#include -#endif -#include -#include - -struct r2net_msg { - __be16 magic; - __be16 data_len; - __be16 msg_type; - __be16 pad1; - __be32 sys_status; - __be32 status; - __be32 key; - __be32 msg_num; - __u8 buf[0]; -}; - -typedef int (r2net_msg_handler_func)(struct r2net_msg *msg, u32 len, void *data, - void **ret_data); -typedef void (r2net_post_msg_handler_func)(int status, void *data, - void *ret_data); - -#define R2NET_MAX_PAYLOAD_BYTES (4096 - sizeof(struct r2net_msg)) - -/* same as hb delay, we're waiting for another node to recognize our hb */ -#define R2NET_RECONNECT_DELAY_MS_DEFAULT 2000 - -#define R2NET_KEEPALIVE_DELAY_MS_DEFAULT 2000 -#define R2NET_IDLE_TIMEOUT_MS_DEFAULT 30000 - - -/* TODO: figure this out.... */ -static inline int r2net_link_down(int err, struct socket *sock) -{ - if (sock) { - if (sock->sk->sk_state != TCP_ESTABLISHED && - sock->sk->sk_state != TCP_CLOSE_WAIT) - return 1; - } - - if (err >= 0) - return 0; - switch (err) { - - /* ????????????????????????? */ - case -ERESTARTSYS: - case -EBADF: - /* When the server has died, an ICMP port unreachable - * message prompts ECONNREFUSED. */ - case -ECONNREFUSED: - case -ENOTCONN: - case -ECONNRESET: - case -EPIPE: - return 1; - - } - return 0; -} - -enum { - R2NET_DRIVER_UNINITED, - R2NET_DRIVER_READY, -}; - -int r2net_send_message(u32 msg_type, u32 key, void *data, u32 len, - u8 target_node, int *status); -int r2net_send_message_vec(u32 msg_type, u32 key, struct kvec *vec, - size_t veclen, u8 target_node, int *status); - -int r2net_register_handler(u32 msg_type, u32 key, u32 max_len, - r2net_msg_handler_func *func, void *data, - r2net_post_msg_handler_func *post_func, - struct list_head *unreg_list); -void r2net_unregister_handler_list(struct list_head *list); - -void r2net_fill_node_map(unsigned long *map, unsigned bytes); - -void r2net_force_data_magic(struct r2net_msg *, u16, u32); -void r2net_hb_node_up_manual(int); -struct r2net_node *r2net_nn_from_num(u8); - -struct r2nm_node; -int r2net_register_hb_callbacks(void); -void r2net_unregister_hb_callbacks(void); -int r2net_start_listening(struct r2nm_node *node); -void r2net_stop_listening(struct r2nm_node *node); -void r2net_disconnect_node(struct r2nm_node *node); -int r2net_num_connected_peers(void); - -int r2net_init(void); -void r2net_exit(void); - -struct r2net_send_tracking; -struct r2net_sock_container; - -#if 0 -int r2net_debugfs_init(void); -void r2net_debugfs_exit(void); -void r2net_debug_add_nst(struct r2net_send_tracking *nst); -void r2net_debug_del_nst(struct r2net_send_tracking *nst); -void r2net_debug_add_sc(struct r2net_sock_container *sc); -void r2net_debug_del_sc(struct r2net_sock_container *sc); -#else -static inline int r2net_debugfs_init(void) -{ - return 0; -} -static inline void r2net_debugfs_exit(void) -{ -} -static inline void r2net_debug_add_nst(struct r2net_send_tracking *nst) -{ -} -static inline void r2net_debug_del_nst(struct r2net_send_tracking *nst) -{ -} -static inline void r2net_debug_add_sc(struct r2net_sock_container *sc) -{ -} -static inline void r2net_debug_del_sc(struct r2net_sock_container *sc) -{ -} -#endif /* CONFIG_DEBUG_FS */ - -#endif /* R2CLUSTER_TCP_H */ diff --git a/drivers/staging/ramster/cluster/tcp_internal.h b/drivers/staging/ramster/cluster/tcp_internal.h deleted file mode 100644 index 4d8cc9f..0000000 --- a/drivers/staging/ramster/cluster/tcp_internal.h +++ /dev/null @@ -1,248 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; -*- - * vim: noexpandtab sw=8 ts=8 sts=0: - * - * Copyright (C) 2005 Oracle. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 021110-1307, USA. - */ - -#ifndef R2CLUSTER_TCP_INTERNAL_H -#define R2CLUSTER_TCP_INTERNAL_H - -#define R2NET_MSG_MAGIC ((u16)0xfa55) -#define R2NET_MSG_STATUS_MAGIC ((u16)0xfa56) -#define R2NET_MSG_KEEP_REQ_MAGIC ((u16)0xfa57) -#define R2NET_MSG_KEEP_RESP_MAGIC ((u16)0xfa58) -/* - * "data magic" is a long version of "status magic" where the message - * payload actually contains data to be passed in reply to certain messages - */ -#define R2NET_MSG_DATA_MAGIC ((u16)0xfa59) - -/* we're delaying our quorum decision so that heartbeat will have timed - * out truly dead nodes by the time we come around to making decisions - * on their number */ -#define R2NET_QUORUM_DELAY_MS \ - ((r2hb_dead_threshold + 2) * R2HB_REGION_TIMEOUT_MS) - -/* - * This version number represents quite a lot, unfortunately. It not - * only represents the raw network message protocol on the wire but also - * locking semantics of the file system using the protocol. It should - * be somewhere else, I'm sure, but right now it isn't. - * - * With version 11, we separate out the filesystem locking portion. The - * filesystem now has a major.minor version it negotiates. Version 11 - * introduces this negotiation to the r2dlm protocol, and as such the - * version here in tcp_internal.h should not need to be bumped for - * filesystem locking changes. - * - * New in version 11 - * - Negotiation of filesystem locking in the dlm join. - * - * New in version 10: - * - Meta/data locks combined - * - * New in version 9: - * - All votes removed - * - * New in version 8: - * - Replace delete inode votes with a cluster lock - * - * New in version 7: - * - DLM join domain includes the live nodemap - * - * New in version 6: - * - DLM lockres remote refcount fixes. - * - * New in version 5: - * - Network timeout checking protocol - * - * New in version 4: - * - Remove i_generation from lock names for better stat performance. - * - * New in version 3: - * - Replace dentry votes with a cluster lock - * - * New in version 2: - * - full 64 bit i_size in the metadata lock lvbs - * - introduction of "rw" lock and pushing meta/data locking down - */ -#define R2NET_PROTOCOL_VERSION 11ULL -struct r2net_handshake { - __be64 protocol_version; - __be64 connector_id; - __be32 r2hb_heartbeat_timeout_ms; - __be32 r2net_idle_timeout_ms; - __be32 r2net_keepalive_delay_ms; - __be32 r2net_reconnect_delay_ms; -}; - -struct r2net_node { - /* this is never called from int/bh */ - spinlock_t nn_lock; - - /* set the moment an sc is allocated and a connect is started */ - struct r2net_sock_container *nn_sc; - /* _valid is only set after the handshake passes and tx can happen */ - unsigned nn_sc_valid:1; - /* if this is set tx just returns it */ - int nn_persistent_error; - /* It is only set to 1 after the idle time out. */ - atomic_t nn_timeout; - - /* threads waiting for an sc to arrive wait on the wq for generation - * to increase. it is increased when a connecting socket succeeds - * or fails or when an accepted socket is attached. */ - wait_queue_head_t nn_sc_wq; - - struct idr nn_status_idr; - struct list_head nn_status_list; - - /* connects are attempted from when heartbeat comes up until either hb - * goes down, the node is unconfigured, no connect attempts succeed - * before R2NET_CONN_IDLE_DELAY, or a connect succeeds. connect_work - * is queued from set_nn_state both from hb up and from itself if a - * connect attempt fails and so can be self-arming. shutdown is - * careful to first mark the nn such that no connects will be attempted - * before canceling delayed connect work and flushing the queue. */ - struct delayed_work nn_connect_work; - unsigned long nn_last_connect_attempt; - - /* this is queued as nodes come up and is canceled when a connection is - * established. this expiring gives up on the node and errors out - * transmits */ - struct delayed_work nn_connect_expired; - - /* after we give up on a socket we wait a while before deciding - * that it is still heartbeating and that we should do some - * quorum work */ - struct delayed_work nn_still_up; -}; - -struct r2net_sock_container { - struct kref sc_kref; - /* the next two are valid for the life time of the sc */ - struct socket *sc_sock; - struct r2nm_node *sc_node; - - /* all of these sc work structs hold refs on the sc while they are - * queued. they should not be able to ref a freed sc. the teardown - * race is with r2net_wq destruction in r2net_stop_listening() */ - - /* rx and connect work are generated from socket callbacks. sc - * shutdown removes the callbacks and then flushes the work queue */ - struct work_struct sc_rx_work; - struct work_struct sc_connect_work; - /* shutdown work is triggered in two ways. the simple way is - * for a code path calls ensure_shutdown which gets a lock, removes - * the sc from the nn, and queues the work. in this case the - * work is single-shot. the work is also queued from a sock - * callback, though, and in this case the work will find the sc - * still on the nn and will call ensure_shutdown itself.. this - * ends up triggering the shutdown work again, though nothing - * will be done in that second iteration. so work queue teardown - * has to be careful to remove the sc from the nn before waiting - * on the work queue so that the shutdown work doesn't remove the - * sc and rearm itself. - */ - struct work_struct sc_shutdown_work; - - struct timer_list sc_idle_timeout; - struct delayed_work sc_keepalive_work; - - unsigned sc_handshake_ok:1; - - struct page *sc_page; - size_t sc_page_off; - - /* original handlers for the sockets */ - void (*sc_state_change)(struct sock *sk); - void (*sc_data_ready)(struct sock *sk, int bytes); - - u32 sc_msg_key; - u16 sc_msg_type; - -#ifdef CONFIG_DEBUG_FS - struct list_head sc_net_debug_item; - ktime_t sc_tv_timer; - ktime_t sc_tv_data_ready; - ktime_t sc_tv_advance_start; - ktime_t sc_tv_advance_stop; - ktime_t sc_tv_func_start; - ktime_t sc_tv_func_stop; -#endif -#ifdef CONFIG_RAMSTER_FS_STATS - ktime_t sc_tv_acquiry_total; - ktime_t sc_tv_send_total; - ktime_t sc_tv_status_total; - u32 sc_send_count; - u32 sc_recv_count; - ktime_t sc_tv_process_total; -#endif - struct mutex sc_send_lock; -}; - -struct r2net_msg_handler { - struct rb_node nh_node; - u32 nh_max_len; - u32 nh_msg_type; - u32 nh_key; - r2net_msg_handler_func *nh_func; - r2net_msg_handler_func *nh_func_data; - r2net_post_msg_handler_func - *nh_post_func; - struct kref nh_kref; - struct list_head nh_unregister_item; -}; - -enum r2net_system_error { - R2NET_ERR_NONE = 0, - R2NET_ERR_NO_HNDLR, - R2NET_ERR_OVERFLOW, - R2NET_ERR_DIED, - R2NET_ERR_MAX -}; - -struct r2net_status_wait { - enum r2net_system_error ns_sys_status; - s32 ns_status; - int ns_id; - wait_queue_head_t ns_wq; - struct list_head ns_node_item; -}; - -#ifdef CONFIG_DEBUG_FS -/* just for state dumps */ -struct r2net_send_tracking { - struct list_head st_net_debug_item; - struct task_struct *st_task; - struct r2net_sock_container *st_sc; - u32 st_id; - u32 st_msg_type; - u32 st_msg_key; - u8 st_node; - ktime_t st_sock_time; - ktime_t st_send_time; - ktime_t st_status_time; -}; -#else -struct r2net_send_tracking { - u32 dummy; -}; -#endif /* CONFIG_DEBUG_FS */ - -#endif /* R2CLUSTER_TCP_INTERNAL_H */ diff --git a/drivers/staging/ramster/r2net.c b/drivers/staging/ramster/r2net.c deleted file mode 100644 index fc830c3..0000000 --- a/drivers/staging/ramster/r2net.c +++ /dev/null @@ -1,401 +0,0 @@ -/* - * r2net.c - * - * Copyright (c) 2011, Dan Magenheimer, Oracle Corp. - * - * Ramster_r2net provides an interface between zcache and r2net. - * - * FIXME: support more than two nodes - */ - -#include -#include "cluster/tcp.h" -#include "cluster/nodemanager.h" -#include "tmem.h" -#include "zcache.h" -#include "ramster.h" - -#define RAMSTER_TESTING - -#define RMSTR_KEY 0x77347734 - -enum { - RMSTR_TMEM_PUT_EPH = 100, - RMSTR_TMEM_PUT_PERS, - RMSTR_TMEM_ASYNC_GET_REQUEST, - RMSTR_TMEM_ASYNC_GET_AND_FREE_REQUEST, - RMSTR_TMEM_ASYNC_GET_REPLY, - RMSTR_TMEM_FLUSH, - RMSTR_TMEM_FLOBJ, - RMSTR_TMEM_DESTROY_POOL, -}; - -#define RMSTR_R2NET_MAX_LEN \ - (R2NET_MAX_PAYLOAD_BYTES - sizeof(struct tmem_xhandle)) - -#include "cluster/tcp_internal.h" - -static struct r2nm_node *r2net_target_node; -static int r2net_target_nodenum; - -int r2net_remote_target_node_set(int node_num) -{ - int ret = -1; - - r2net_target_node = r2nm_get_node_by_num(node_num); - if (r2net_target_node != NULL) { - r2net_target_nodenum = node_num; - r2nm_node_put(r2net_target_node); - ret = 0; - } - return ret; -} - -/* FIXME following buffer should be per-cpu, protected by preempt_disable */ -static char ramster_async_get_buf[R2NET_MAX_PAYLOAD_BYTES]; - -static int ramster_remote_async_get_request_handler(struct r2net_msg *msg, - u32 len, void *data, void **ret_data) -{ - char *pdata; - struct tmem_xhandle xh; - int found; - size_t size = RMSTR_R2NET_MAX_LEN; - u16 msgtype = be16_to_cpu(msg->msg_type); - bool get_and_free = (msgtype == RMSTR_TMEM_ASYNC_GET_AND_FREE_REQUEST); - unsigned long flags; - - xh = *(struct tmem_xhandle *)msg->buf; - if (xh.xh_data_size > RMSTR_R2NET_MAX_LEN) - BUG(); - pdata = ramster_async_get_buf; - *(struct tmem_xhandle *)pdata = xh; - pdata += sizeof(struct tmem_xhandle); - local_irq_save(flags); - found = zcache_get(xh.client_id, xh.pool_id, &xh.oid, xh.index, - pdata, &size, 1, get_and_free ? 1 : -1); - local_irq_restore(flags); - if (found < 0) { - /* a zero size indicates the get failed */ - size = 0; - } - if (size > RMSTR_R2NET_MAX_LEN) - BUG(); - *ret_data = pdata - sizeof(struct tmem_xhandle); - /* now make caller (r2net_process_message) handle specially */ - r2net_force_data_magic(msg, RMSTR_TMEM_ASYNC_GET_REPLY, RMSTR_KEY); - return size + sizeof(struct tmem_xhandle); -} - -static int ramster_remote_async_get_reply_handler(struct r2net_msg *msg, - u32 len, void *data, void **ret_data) -{ - char *in = (char *)msg->buf; - int datalen = len - sizeof(struct r2net_msg); - int ret = -1; - struct tmem_xhandle *xh = (struct tmem_xhandle *)in; - - in += sizeof(struct tmem_xhandle); - datalen -= sizeof(struct tmem_xhandle); - BUG_ON(datalen < 0 || datalen > PAGE_SIZE); - ret = zcache_localify(xh->pool_id, &xh->oid, xh->index, - in, datalen, xh->extra); -#ifdef RAMSTER_TESTING - if (ret == -EEXIST) - pr_err("TESTING ArrgREP, aborted overwrite on racy put\n"); -#endif - return ret; -} - -int ramster_remote_put_handler(struct r2net_msg *msg, - u32 len, void *data, void **ret_data) -{ - struct tmem_xhandle *xh; - char *p = (char *)msg->buf; - int datalen = len - sizeof(struct r2net_msg) - - sizeof(struct tmem_xhandle); - u16 msgtype = be16_to_cpu(msg->msg_type); - bool ephemeral = (msgtype == RMSTR_TMEM_PUT_EPH); - unsigned long flags; - int ret; - - xh = (struct tmem_xhandle *)p; - p += sizeof(struct tmem_xhandle); - zcache_autocreate_pool(xh->client_id, xh->pool_id, ephemeral); - local_irq_save(flags); - ret = zcache_put(xh->client_id, xh->pool_id, &xh->oid, xh->index, - p, datalen, 1, ephemeral ? 1 : -1); - local_irq_restore(flags); - return ret; -} - -int ramster_remote_flush_handler(struct r2net_msg *msg, - u32 len, void *data, void **ret_data) -{ - struct tmem_xhandle *xh; - char *p = (char *)msg->buf; - - xh = (struct tmem_xhandle *)p; - p += sizeof(struct tmem_xhandle); - (void)zcache_flush(xh->client_id, xh->pool_id, &xh->oid, xh->index); - return 0; -} - -int ramster_remote_flobj_handler(struct r2net_msg *msg, - u32 len, void *data, void **ret_data) -{ - struct tmem_xhandle *xh; - char *p = (char *)msg->buf; - - xh = (struct tmem_xhandle *)p; - p += sizeof(struct tmem_xhandle); - (void)zcache_flush_object(xh->client_id, xh->pool_id, &xh->oid); - return 0; -} - -int ramster_remote_async_get(struct tmem_xhandle *xh, bool free, int remotenode, - size_t expect_size, uint8_t expect_cksum, - void *extra) -{ - int ret = -1, status; - struct r2nm_node *node = NULL; - struct kvec vec[1]; - size_t veclen = 1; - u32 msg_type; - - node = r2nm_get_node_by_num(remotenode); - if (node == NULL) - goto out; - xh->client_id = r2nm_this_node(); /* which node is getting */ - xh->xh_data_cksum = expect_cksum; - xh->xh_data_size = expect_size; - xh->extra = extra; - vec[0].iov_len = sizeof(*xh); - vec[0].iov_base = xh; - if (free) - msg_type = RMSTR_TMEM_ASYNC_GET_AND_FREE_REQUEST; - else - msg_type = RMSTR_TMEM_ASYNC_GET_REQUEST; - ret = r2net_send_message_vec(msg_type, RMSTR_KEY, - vec, veclen, remotenode, &status); - r2nm_node_put(node); - if (ret < 0) { - /* FIXME handle bad message possibilities here? */ - pr_err("UNTESTED ret<0 in ramster_remote_async_get\n"); - } - ret = status; -out: - return ret; -} - -#ifdef RAMSTER_TESTING -/* leave me here to see if it catches a weird crash */ -static void ramster_check_irq_counts(void) -{ - static int last_hardirq_cnt, last_softirq_cnt, last_preempt_cnt; - int cur_hardirq_cnt, cur_softirq_cnt, cur_preempt_cnt; - - cur_hardirq_cnt = hardirq_count() >> HARDIRQ_SHIFT; - if (cur_hardirq_cnt > last_hardirq_cnt) { - last_hardirq_cnt = cur_hardirq_cnt; - if (!(last_hardirq_cnt&(last_hardirq_cnt-1))) - pr_err("RAMSTER TESTING RRP hardirq_count=%d\n", - last_hardirq_cnt); - } - cur_softirq_cnt = softirq_count() >> SOFTIRQ_SHIFT; - if (cur_softirq_cnt > last_softirq_cnt) { - last_softirq_cnt = cur_softirq_cnt; - if (!(last_softirq_cnt&(last_softirq_cnt-1))) - pr_err("RAMSTER TESTING RRP softirq_count=%d\n", - last_softirq_cnt); - } - cur_preempt_cnt = preempt_count() & PREEMPT_MASK; - if (cur_preempt_cnt > last_preempt_cnt) { - last_preempt_cnt = cur_preempt_cnt; - if (!(last_preempt_cnt&(last_preempt_cnt-1))) - pr_err("RAMSTER TESTING RRP preempt_count=%d\n", - last_preempt_cnt); - } -} -#endif - -int ramster_remote_put(struct tmem_xhandle *xh, char *data, size_t size, - bool ephemeral, int *remotenode) -{ - int nodenum, ret = -1, status; - struct r2nm_node *node = NULL; - struct kvec vec[2]; - size_t veclen = 2; - u32 msg_type; -#ifdef RAMSTER_TESTING - struct r2net_node *nn; -#endif - - BUG_ON(size > RMSTR_R2NET_MAX_LEN); - xh->client_id = r2nm_this_node(); /* which node is putting */ - vec[0].iov_len = sizeof(*xh); - vec[0].iov_base = xh; - vec[1].iov_len = size; - vec[1].iov_base = data; - node = r2net_target_node; - if (!node) - goto out; - - nodenum = r2net_target_nodenum; - - r2nm_node_get(node); - -#ifdef RAMSTER_TESTING - nn = r2net_nn_from_num(nodenum); - WARN_ON_ONCE(nn->nn_persistent_error || !nn->nn_sc_valid); -#endif - - if (ephemeral) - msg_type = RMSTR_TMEM_PUT_EPH; - else - msg_type = RMSTR_TMEM_PUT_PERS; -#ifdef RAMSTER_TESTING - /* leave me here to see if it catches a weird crash */ - ramster_check_irq_counts(); -#endif - - ret = r2net_send_message_vec(msg_type, RMSTR_KEY, vec, veclen, - nodenum, &status); -#ifdef RAMSTER_TESTING - if (ret != 0) { - static unsigned long cnt; - cnt++; - if (!(cnt&(cnt-1))) - pr_err("ramster_remote_put: message failed, ret=%d, cnt=%lu\n", - ret, cnt); - ret = -1; - } -#endif - if (ret < 0) - ret = -1; - else { - ret = status; - *remotenode = nodenum; - } - - r2nm_node_put(node); -out: - return ret; -} - -int ramster_remote_flush(struct tmem_xhandle *xh, int remotenode) -{ - int ret = -1, status; - struct r2nm_node *node = NULL; - struct kvec vec[1]; - size_t veclen = 1; - - node = r2nm_get_node_by_num(remotenode); - BUG_ON(node == NULL); - xh->client_id = r2nm_this_node(); /* which node is flushing */ - vec[0].iov_len = sizeof(*xh); - vec[0].iov_base = xh; - BUG_ON(irqs_disabled()); - BUG_ON(in_softirq()); - ret = r2net_send_message_vec(RMSTR_TMEM_FLUSH, RMSTR_KEY, - vec, veclen, remotenode, &status); - r2nm_node_put(node); - return ret; -} - -int ramster_remote_flush_object(struct tmem_xhandle *xh, int remotenode) -{ - int ret = -1, status; - struct r2nm_node *node = NULL; - struct kvec vec[1]; - size_t veclen = 1; - - node = r2nm_get_node_by_num(remotenode); - BUG_ON(node == NULL); - xh->client_id = r2nm_this_node(); /* which node is flobjing */ - vec[0].iov_len = sizeof(*xh); - vec[0].iov_base = xh; - ret = r2net_send_message_vec(RMSTR_TMEM_FLOBJ, RMSTR_KEY, - vec, veclen, remotenode, &status); - r2nm_node_put(node); - return ret; -} - -/* - * Handler registration - */ - -static LIST_HEAD(r2net_unreg_list); - -static void r2net_unregister_handlers(void) -{ - r2net_unregister_handler_list(&r2net_unreg_list); -} - -int r2net_register_handlers(void) -{ - int status; - - status = r2net_register_handler(RMSTR_TMEM_PUT_EPH, RMSTR_KEY, - RMSTR_R2NET_MAX_LEN, - ramster_remote_put_handler, - NULL, NULL, &r2net_unreg_list); - if (status) - goto bail; - - status = r2net_register_handler(RMSTR_TMEM_PUT_PERS, RMSTR_KEY, - RMSTR_R2NET_MAX_LEN, - ramster_remote_put_handler, - NULL, NULL, &r2net_unreg_list); - if (status) - goto bail; - - status = r2net_register_handler(RMSTR_TMEM_ASYNC_GET_REQUEST, RMSTR_KEY, - RMSTR_R2NET_MAX_LEN, - ramster_remote_async_get_request_handler, - NULL, NULL, - &r2net_unreg_list); - if (status) - goto bail; - - status = r2net_register_handler(RMSTR_TMEM_ASYNC_GET_AND_FREE_REQUEST, - RMSTR_KEY, RMSTR_R2NET_MAX_LEN, - ramster_remote_async_get_request_handler, - NULL, NULL, - &r2net_unreg_list); - if (status) - goto bail; - - status = r2net_register_handler(RMSTR_TMEM_ASYNC_GET_REPLY, RMSTR_KEY, - RMSTR_R2NET_MAX_LEN, - ramster_remote_async_get_reply_handler, - NULL, NULL, - &r2net_unreg_list); - if (status) - goto bail; - - status = r2net_register_handler(RMSTR_TMEM_FLUSH, RMSTR_KEY, - RMSTR_R2NET_MAX_LEN, - ramster_remote_flush_handler, - NULL, NULL, - &r2net_unreg_list); - if (status) - goto bail; - - status = r2net_register_handler(RMSTR_TMEM_FLOBJ, RMSTR_KEY, - RMSTR_R2NET_MAX_LEN, - ramster_remote_flobj_handler, - NULL, NULL, - &r2net_unreg_list); - if (status) - goto bail; - - pr_info("ramster: r2net handlers registered\n"); - -bail: - if (status) { - r2net_unregister_handlers(); - pr_err("ramster: couldn't register r2net handlers\n"); - } - return status; -} diff --git a/drivers/staging/ramster/ramster.h b/drivers/staging/ramster/ramster.h deleted file mode 100644 index 0c9455e..0000000 --- a/drivers/staging/ramster/ramster.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * ramster.h - * - * Peer-to-peer transcendent memory - * - * Copyright (c) 2009-2012, Dan Magenheimer, Oracle Corp. - */ - -#ifndef _RAMSTER_H_ -#define _RAMSTER_H_ - -/* - * format of remote pampd: - * bit 0 == intransit - * bit 1 == is_remote... if this bit is set, then - * bit 2-9 == remotenode - * bit 10-22 == size - * bit 23-30 == cksum - */ -#define FAKE_PAMPD_INTRANSIT_BITS 1 -#define FAKE_PAMPD_ISREMOTE_BITS 1 -#define FAKE_PAMPD_REMOTENODE_BITS 8 -#define FAKE_PAMPD_REMOTESIZE_BITS 13 -#define FAKE_PAMPD_CHECKSUM_BITS 8 - -#define FAKE_PAMPD_INTRANSIT_SHIFT 0 -#define FAKE_PAMPD_ISREMOTE_SHIFT (FAKE_PAMPD_INTRANSIT_SHIFT + \ - FAKE_PAMPD_INTRANSIT_BITS) -#define FAKE_PAMPD_REMOTENODE_SHIFT (FAKE_PAMPD_ISREMOTE_SHIFT + \ - FAKE_PAMPD_ISREMOTE_BITS) -#define FAKE_PAMPD_REMOTESIZE_SHIFT (FAKE_PAMPD_REMOTENODE_SHIFT + \ - FAKE_PAMPD_REMOTENODE_BITS) -#define FAKE_PAMPD_CHECKSUM_SHIFT (FAKE_PAMPD_REMOTESIZE_SHIFT + \ - FAKE_PAMPD_REMOTESIZE_BITS) - -#define FAKE_PAMPD_MASK(x) ((1UL << (x)) - 1) - -static inline void *pampd_make_remote(int remotenode, size_t size, - unsigned char cksum) -{ - unsigned long fake_pampd = 0; - fake_pampd |= 1UL << FAKE_PAMPD_ISREMOTE_SHIFT; - fake_pampd |= ((unsigned long)remotenode & - FAKE_PAMPD_MASK(FAKE_PAMPD_REMOTENODE_BITS)) << - FAKE_PAMPD_REMOTENODE_SHIFT; - fake_pampd |= ((unsigned long)size & - FAKE_PAMPD_MASK(FAKE_PAMPD_REMOTESIZE_BITS)) << - FAKE_PAMPD_REMOTESIZE_SHIFT; - fake_pampd |= ((unsigned long)cksum & - FAKE_PAMPD_MASK(FAKE_PAMPD_CHECKSUM_BITS)) << - FAKE_PAMPD_CHECKSUM_SHIFT; - return (void *)fake_pampd; -} - -static inline unsigned int pampd_remote_node(void *pampd) -{ - unsigned long fake_pampd = (unsigned long)pampd; - return (fake_pampd >> FAKE_PAMPD_REMOTENODE_SHIFT) & - FAKE_PAMPD_MASK(FAKE_PAMPD_REMOTENODE_BITS); -} - -static inline unsigned int pampd_remote_size(void *pampd) -{ - unsigned long fake_pampd = (unsigned long)pampd; - return (fake_pampd >> FAKE_PAMPD_REMOTESIZE_SHIFT) & - FAKE_PAMPD_MASK(FAKE_PAMPD_REMOTESIZE_BITS); -} - -static inline unsigned char pampd_remote_cksum(void *pampd) -{ - unsigned long fake_pampd = (unsigned long)pampd; - return (fake_pampd >> FAKE_PAMPD_CHECKSUM_SHIFT) & - FAKE_PAMPD_MASK(FAKE_PAMPD_CHECKSUM_BITS); -} - -static inline bool pampd_is_remote(void *pampd) -{ - unsigned long fake_pampd = (unsigned long)pampd; - return (fake_pampd >> FAKE_PAMPD_ISREMOTE_SHIFT) & - FAKE_PAMPD_MASK(FAKE_PAMPD_ISREMOTE_BITS); -} - -static inline bool pampd_is_intransit(void *pampd) -{ - unsigned long fake_pampd = (unsigned long)pampd; - return (fake_pampd >> FAKE_PAMPD_INTRANSIT_SHIFT) & - FAKE_PAMPD_MASK(FAKE_PAMPD_INTRANSIT_BITS); -} - -/* note that it is a BUG for intransit to be set without isremote also set */ -static inline void *pampd_mark_intransit(void *pampd) -{ - unsigned long fake_pampd = (unsigned long)pampd; - - fake_pampd |= 1UL << FAKE_PAMPD_ISREMOTE_SHIFT; - fake_pampd |= 1UL << FAKE_PAMPD_INTRANSIT_SHIFT; - return (void *)fake_pampd; -} - -static inline void *pampd_mask_intransit_and_remote(void *marked_pampd) -{ - unsigned long pampd = (unsigned long)marked_pampd; - - pampd &= ~(1UL << FAKE_PAMPD_INTRANSIT_SHIFT); - pampd &= ~(1UL << FAKE_PAMPD_ISREMOTE_SHIFT); - return (void *)pampd; -} - -extern int ramster_remote_async_get(struct tmem_xhandle *, - bool, int, size_t, uint8_t, void *extra); -extern int ramster_remote_put(struct tmem_xhandle *, char *, size_t, - bool, int *); -extern int ramster_remote_flush(struct tmem_xhandle *, int); -extern int ramster_remote_flush_object(struct tmem_xhandle *, int); -extern int r2net_register_handlers(void); -extern int r2net_remote_target_node_set(int); - -#endif /* _TMEM_H */ diff --git a/drivers/staging/ramster/tmem.c b/drivers/staging/ramster/tmem.c deleted file mode 100644 index 8f2f689..0000000 --- a/drivers/staging/ramster/tmem.c +++ /dev/null @@ -1,851 +0,0 @@ -/* - * In-kernel transcendent memory (generic implementation) - * - * Copyright (c) 2009-2011, Dan Magenheimer, Oracle Corp. - * - * The primary purpose of Transcedent Memory ("tmem") is to map object-oriented - * "handles" (triples containing a pool id, and object id, and an index), to - * pages in a page-accessible memory (PAM). Tmem references the PAM pages via - * an abstract "pampd" (PAM page-descriptor), which can be operated on by a - * set of functions (pamops). Each pampd contains some representation of - * PAGE_SIZE bytes worth of data. Tmem must support potentially millions of - * pages and must be able to insert, find, and delete these pages at a - * potential frequency of thousands per second concurrently across many CPUs, - * (and, if used with KVM, across many vcpus across many guests). - * Tmem is tracked with a hierarchy of data structures, organized by - * the elements in a handle-tuple: pool_id, object_id, and page index. - * One or more "clients" (e.g. guests) each provide one or more tmem_pools. - * Each pool, contains a hash table of rb_trees of tmem_objs. Each - * tmem_obj contains a radix-tree-like tree of pointers, with intermediate - * nodes called tmem_objnodes. Each leaf pointer in this tree points to - * a pampd, which is accessible only through a small set of callbacks - * registered by the PAM implementation (see tmem_register_pamops). Tmem - * does all memory allocation via a set of callbacks registered by the tmem - * host implementation (e.g. see tmem_register_hostops). - */ - -#include -#include -#include -#include - -#include "tmem.h" - -/* data structure sentinels used for debugging... see tmem.h */ -#define POOL_SENTINEL 0x87658765 -#define OBJ_SENTINEL 0x12345678 -#define OBJNODE_SENTINEL 0xfedcba09 - -/* - * A tmem host implementation must use this function to register callbacks - * for memory allocation. - */ -static struct tmem_hostops tmem_hostops; - -static void tmem_objnode_tree_init(void); - -void tmem_register_hostops(struct tmem_hostops *m) -{ - tmem_objnode_tree_init(); - tmem_hostops = *m; -} - -/* - * A tmem host implementation must use this function to register - * callbacks for a page-accessible memory (PAM) implementation - */ -static struct tmem_pamops tmem_pamops; - -void tmem_register_pamops(struct tmem_pamops *m) -{ - tmem_pamops = *m; -} - -/* - * Oid's are potentially very sparse and tmem_objs may have an indeterminately - * short life, being added and deleted at a relatively high frequency. - * So an rb_tree is an ideal data structure to manage tmem_objs. But because - * of the potentially huge number of tmem_objs, each pool manages a hashtable - * of rb_trees to reduce search, insert, delete, and rebalancing time. - * Each hashbucket also has a lock to manage concurrent access. - * - * The following routines manage tmem_objs. When any tmem_obj is accessed, - * the hashbucket lock must be held. - */ - -/* searches for object==oid in pool, returns locked object if found */ -static struct tmem_obj *tmem_obj_find(struct tmem_hashbucket *hb, - struct tmem_oid *oidp) -{ - struct rb_node *rbnode; - struct tmem_obj *obj; - - rbnode = hb->obj_rb_root.rb_node; - while (rbnode) { - BUG_ON(RB_EMPTY_NODE(rbnode)); - obj = rb_entry(rbnode, struct tmem_obj, rb_tree_node); - switch (tmem_oid_compare(oidp, &obj->oid)) { - case 0: /* equal */ - goto out; - case -1: - rbnode = rbnode->rb_left; - break; - case 1: - rbnode = rbnode->rb_right; - break; - } - } - obj = NULL; -out: - return obj; -} - -static void tmem_pampd_destroy_all_in_obj(struct tmem_obj *); - -/* free an object that has no more pampds in it */ -static void tmem_obj_free(struct tmem_obj *obj, struct tmem_hashbucket *hb) -{ - struct tmem_pool *pool; - - BUG_ON(obj == NULL); - ASSERT_SENTINEL(obj, OBJ); - BUG_ON(obj->pampd_count > 0); - pool = obj->pool; - BUG_ON(pool == NULL); - if (obj->objnode_tree_root != NULL) /* may be "stump" with no leaves */ - tmem_pampd_destroy_all_in_obj(obj); - BUG_ON(obj->objnode_tree_root != NULL); - BUG_ON((long)obj->objnode_count != 0); - atomic_dec(&pool->obj_count); - BUG_ON(atomic_read(&pool->obj_count) < 0); - INVERT_SENTINEL(obj, OBJ); - obj->pool = NULL; - tmem_oid_set_invalid(&obj->oid); - rb_erase(&obj->rb_tree_node, &hb->obj_rb_root); -} - -/* - * initialize, and insert an tmem_object_root (called only if find failed) - */ -static void tmem_obj_init(struct tmem_obj *obj, struct tmem_hashbucket *hb, - struct tmem_pool *pool, - struct tmem_oid *oidp) -{ - struct rb_root *root = &hb->obj_rb_root; - struct rb_node **new = &(root->rb_node), *parent = NULL; - struct tmem_obj *this; - - BUG_ON(pool == NULL); - atomic_inc(&pool->obj_count); - obj->objnode_tree_height = 0; - obj->objnode_tree_root = NULL; - obj->pool = pool; - obj->oid = *oidp; - obj->objnode_count = 0; - obj->pampd_count = 0; - (*tmem_pamops.new_obj)(obj); - SET_SENTINEL(obj, OBJ); - while (*new) { - BUG_ON(RB_EMPTY_NODE(*new)); - this = rb_entry(*new, struct tmem_obj, rb_tree_node); - parent = *new; - switch (tmem_oid_compare(oidp, &this->oid)) { - case 0: - BUG(); /* already present; should never happen! */ - break; - case -1: - new = &(*new)->rb_left; - break; - case 1: - new = &(*new)->rb_right; - break; - } - } - rb_link_node(&obj->rb_tree_node, parent, new); - rb_insert_color(&obj->rb_tree_node, root); -} - -/* - * Tmem is managed as a set of tmem_pools with certain attributes, such as - * "ephemeral" vs "persistent". These attributes apply to all tmem_objs - * and all pampds that belong to a tmem_pool. A tmem_pool is created - * or deleted relatively rarely (for example, when a filesystem is - * mounted or unmounted. - */ - -/* flush all data from a pool and, optionally, free it */ -static void tmem_pool_flush(struct tmem_pool *pool, bool destroy) -{ - struct rb_node *rbnode; - struct tmem_obj *obj; - struct tmem_hashbucket *hb = &pool->hashbucket[0]; - int i; - - BUG_ON(pool == NULL); - for (i = 0; i < TMEM_HASH_BUCKETS; i++, hb++) { - spin_lock(&hb->lock); - rbnode = rb_first(&hb->obj_rb_root); - while (rbnode != NULL) { - obj = rb_entry(rbnode, struct tmem_obj, rb_tree_node); - rbnode = rb_next(rbnode); - tmem_pampd_destroy_all_in_obj(obj); - tmem_obj_free(obj, hb); - (*tmem_hostops.obj_free)(obj, pool); - } - spin_unlock(&hb->lock); - } - if (destroy) - list_del(&pool->pool_list); -} - -/* - * A tmem_obj contains a radix-tree-like tree in which the intermediate - * nodes are called tmem_objnodes. (The kernel lib/radix-tree.c implementation - * is very specialized and tuned for specific uses and is not particularly - * suited for use from this code, though some code from the core algorithms has - * been reused, thus the copyright notices below). Each tmem_objnode contains - * a set of pointers which point to either a set of intermediate tmem_objnodes - * or a set of of pampds. - * - * Portions Copyright (C) 2001 Momchil Velikov - * Portions Copyright (C) 2001 Christoph Hellwig - * Portions Copyright (C) 2005 SGI, Christoph Lameter - */ - -struct tmem_objnode_tree_path { - struct tmem_objnode *objnode; - int offset; -}; - -/* objnode height_to_maxindex translation */ -static unsigned long tmem_objnode_tree_h2max[OBJNODE_TREE_MAX_PATH + 1]; - -static void tmem_objnode_tree_init(void) -{ - unsigned int ht, tmp; - - for (ht = 0; ht < ARRAY_SIZE(tmem_objnode_tree_h2max); ht++) { - tmp = ht * OBJNODE_TREE_MAP_SHIFT; - if (tmp >= OBJNODE_TREE_INDEX_BITS) - tmem_objnode_tree_h2max[ht] = ~0UL; - else - tmem_objnode_tree_h2max[ht] = - (~0UL >> (OBJNODE_TREE_INDEX_BITS - tmp - 1)) >> 1; - } -} - -static struct tmem_objnode *tmem_objnode_alloc(struct tmem_obj *obj) -{ - struct tmem_objnode *objnode; - - ASSERT_SENTINEL(obj, OBJ); - BUG_ON(obj->pool == NULL); - ASSERT_SENTINEL(obj->pool, POOL); - objnode = (*tmem_hostops.objnode_alloc)(obj->pool); - if (unlikely(objnode == NULL)) - goto out; - objnode->obj = obj; - SET_SENTINEL(objnode, OBJNODE); - memset(&objnode->slots, 0, sizeof(objnode->slots)); - objnode->slots_in_use = 0; - obj->objnode_count++; -out: - return objnode; -} - -static void tmem_objnode_free(struct tmem_objnode *objnode) -{ - struct tmem_pool *pool; - int i; - - BUG_ON(objnode == NULL); - for (i = 0; i < OBJNODE_TREE_MAP_SIZE; i++) - BUG_ON(objnode->slots[i] != NULL); - ASSERT_SENTINEL(objnode, OBJNODE); - INVERT_SENTINEL(objnode, OBJNODE); - BUG_ON(objnode->obj == NULL); - ASSERT_SENTINEL(objnode->obj, OBJ); - pool = objnode->obj->pool; - BUG_ON(pool == NULL); - ASSERT_SENTINEL(pool, POOL); - objnode->obj->objnode_count--; - objnode->obj = NULL; - (*tmem_hostops.objnode_free)(objnode, pool); -} - -/* - * lookup index in object and return associated pampd (or NULL if not found) - */ -static void **__tmem_pampd_lookup_in_obj(struct tmem_obj *obj, uint32_t index) -{ - unsigned int height, shift; - struct tmem_objnode **slot = NULL; - - BUG_ON(obj == NULL); - ASSERT_SENTINEL(obj, OBJ); - BUG_ON(obj->pool == NULL); - ASSERT_SENTINEL(obj->pool, POOL); - - height = obj->objnode_tree_height; - if (index > tmem_objnode_tree_h2max[obj->objnode_tree_height]) - goto out; - if (height == 0 && obj->objnode_tree_root) { - slot = &obj->objnode_tree_root; - goto out; - } - shift = (height-1) * OBJNODE_TREE_MAP_SHIFT; - slot = &obj->objnode_tree_root; - while (height > 0) { - if (*slot == NULL) - goto out; - slot = (struct tmem_objnode **) - ((*slot)->slots + - ((index >> shift) & OBJNODE_TREE_MAP_MASK)); - shift -= OBJNODE_TREE_MAP_SHIFT; - height--; - } -out: - return slot != NULL ? (void **)slot : NULL; -} - -static void *tmem_pampd_lookup_in_obj(struct tmem_obj *obj, uint32_t index) -{ - struct tmem_objnode **slot; - - slot = (struct tmem_objnode **)__tmem_pampd_lookup_in_obj(obj, index); - return slot != NULL ? *slot : NULL; -} - -static void *tmem_pampd_replace_in_obj(struct tmem_obj *obj, uint32_t index, - void *new_pampd, bool no_free) -{ - struct tmem_objnode **slot; - void *ret = NULL; - - slot = (struct tmem_objnode **)__tmem_pampd_lookup_in_obj(obj, index); - if ((slot != NULL) && (*slot != NULL)) { - void *old_pampd = *(void **)slot; - *(void **)slot = new_pampd; - if (!no_free) - (*tmem_pamops.free)(old_pampd, obj->pool, - NULL, 0, false); - ret = new_pampd; - } - return ret; -} - -static int tmem_pampd_add_to_obj(struct tmem_obj *obj, uint32_t index, - void *pampd) -{ - int ret = 0; - struct tmem_objnode *objnode = NULL, *newnode, *slot; - unsigned int height, shift; - int offset = 0; - - /* if necessary, extend the tree to be higher */ - if (index > tmem_objnode_tree_h2max[obj->objnode_tree_height]) { - height = obj->objnode_tree_height + 1; - if (index > tmem_objnode_tree_h2max[height]) - while (index > tmem_objnode_tree_h2max[height]) - height++; - if (obj->objnode_tree_root == NULL) { - obj->objnode_tree_height = height; - goto insert; - } - do { - newnode = tmem_objnode_alloc(obj); - if (!newnode) { - ret = -ENOMEM; - goto out; - } - newnode->slots[0] = obj->objnode_tree_root; - newnode->slots_in_use = 1; - obj->objnode_tree_root = newnode; - obj->objnode_tree_height++; - } while (height > obj->objnode_tree_height); - } -insert: - slot = obj->objnode_tree_root; - height = obj->objnode_tree_height; - shift = (height-1) * OBJNODE_TREE_MAP_SHIFT; - while (height > 0) { - if (slot == NULL) { - /* add a child objnode. */ - slot = tmem_objnode_alloc(obj); - if (!slot) { - ret = -ENOMEM; - goto out; - } - if (objnode) { - - objnode->slots[offset] = slot; - objnode->slots_in_use++; - } else - obj->objnode_tree_root = slot; - } - /* go down a level */ - offset = (index >> shift) & OBJNODE_TREE_MAP_MASK; - objnode = slot; - slot = objnode->slots[offset]; - shift -= OBJNODE_TREE_MAP_SHIFT; - height--; - } - BUG_ON(slot != NULL); - if (objnode) { - objnode->slots_in_use++; - objnode->slots[offset] = pampd; - } else - obj->objnode_tree_root = pampd; - obj->pampd_count++; -out: - return ret; -} - -static void *tmem_pampd_delete_from_obj(struct tmem_obj *obj, uint32_t index) -{ - struct tmem_objnode_tree_path path[OBJNODE_TREE_MAX_PATH + 1]; - struct tmem_objnode_tree_path *pathp = path; - struct tmem_objnode *slot = NULL; - unsigned int height, shift; - int offset; - - BUG_ON(obj == NULL); - ASSERT_SENTINEL(obj, OBJ); - BUG_ON(obj->pool == NULL); - ASSERT_SENTINEL(obj->pool, POOL); - height = obj->objnode_tree_height; - if (index > tmem_objnode_tree_h2max[height]) - goto out; - slot = obj->objnode_tree_root; - if (height == 0 && obj->objnode_tree_root) { - obj->objnode_tree_root = NULL; - goto out; - } - shift = (height - 1) * OBJNODE_TREE_MAP_SHIFT; - pathp->objnode = NULL; - do { - if (slot == NULL) - goto out; - pathp++; - offset = (index >> shift) & OBJNODE_TREE_MAP_MASK; - pathp->offset = offset; - pathp->objnode = slot; - slot = slot->slots[offset]; - shift -= OBJNODE_TREE_MAP_SHIFT; - height--; - } while (height > 0); - if (slot == NULL) - goto out; - while (pathp->objnode) { - pathp->objnode->slots[pathp->offset] = NULL; - pathp->objnode->slots_in_use--; - if (pathp->objnode->slots_in_use) { - if (pathp->objnode == obj->objnode_tree_root) { - while (obj->objnode_tree_height > 0 && - obj->objnode_tree_root->slots_in_use == 1 && - obj->objnode_tree_root->slots[0]) { - struct tmem_objnode *to_free = - obj->objnode_tree_root; - - obj->objnode_tree_root = - to_free->slots[0]; - obj->objnode_tree_height--; - to_free->slots[0] = NULL; - to_free->slots_in_use = 0; - tmem_objnode_free(to_free); - } - } - goto out; - } - tmem_objnode_free(pathp->objnode); /* 0 slots used, free it */ - pathp--; - } - obj->objnode_tree_height = 0; - obj->objnode_tree_root = NULL; - -out: - if (slot != NULL) - obj->pampd_count--; - BUG_ON(obj->pampd_count < 0); - return slot; -} - -/* recursively walk the objnode_tree destroying pampds and objnodes */ -static void tmem_objnode_node_destroy(struct tmem_obj *obj, - struct tmem_objnode *objnode, - unsigned int ht) -{ - int i; - - if (ht == 0) - return; - for (i = 0; i < OBJNODE_TREE_MAP_SIZE; i++) { - if (objnode->slots[i]) { - if (ht == 1) { - obj->pampd_count--; - (*tmem_pamops.free)(objnode->slots[i], - obj->pool, NULL, 0, true); - objnode->slots[i] = NULL; - continue; - } - tmem_objnode_node_destroy(obj, objnode->slots[i], ht-1); - tmem_objnode_free(objnode->slots[i]); - objnode->slots[i] = NULL; - } - } -} - -static void tmem_pampd_destroy_all_in_obj(struct tmem_obj *obj) -{ - if (obj->objnode_tree_root == NULL) - return; - if (obj->objnode_tree_height == 0) { - obj->pampd_count--; - (*tmem_pamops.free)(obj->objnode_tree_root, - obj->pool, NULL, 0, true); - } else { - tmem_objnode_node_destroy(obj, obj->objnode_tree_root, - obj->objnode_tree_height); - tmem_objnode_free(obj->objnode_tree_root); - obj->objnode_tree_height = 0; - } - obj->objnode_tree_root = NULL; - (*tmem_pamops.free_obj)(obj->pool, obj); -} - -/* - * Tmem is operated on by a set of well-defined actions: - * "put", "get", "flush", "flush_object", "new pool" and "destroy pool". - * (The tmem ABI allows for subpages and exchanges but these operations - * are not included in this implementation.) - * - * These "tmem core" operations are implemented in the following functions. - */ - -/* - * "Put" a page, e.g. copy a page from the kernel into newly allocated - * PAM space (if such space is available). Tmem_put is complicated by - * a corner case: What if a page with matching handle already exists in - * tmem? To guarantee coherency, one of two actions is necessary: Either - * the data for the page must be overwritten, or the page must be - * "flushed" so that the data is not accessible to a subsequent "get". - * Since these "duplicate puts" are relatively rare, this implementation - * always flushes for simplicity. - */ -int tmem_put(struct tmem_pool *pool, struct tmem_oid *oidp, uint32_t index, - char *data, size_t size, bool raw, int ephemeral) -{ - struct tmem_obj *obj = NULL, *objfound = NULL, *objnew = NULL; - void *pampd = NULL, *pampd_del = NULL; - int ret = -ENOMEM; - struct tmem_hashbucket *hb; - - hb = &pool->hashbucket[tmem_oid_hash(oidp)]; - spin_lock(&hb->lock); - obj = objfound = tmem_obj_find(hb, oidp); - if (obj != NULL) { - pampd = tmem_pampd_lookup_in_obj(objfound, index); - if (pampd != NULL) { - /* if found, is a dup put, flush the old one */ - pampd_del = tmem_pampd_delete_from_obj(obj, index); - BUG_ON(pampd_del != pampd); - (*tmem_pamops.free)(pampd, pool, oidp, index, true); - if (obj->pampd_count == 0) { - objnew = obj; - objfound = NULL; - } - pampd = NULL; - } - } else { - obj = objnew = (*tmem_hostops.obj_alloc)(pool); - if (unlikely(obj == NULL)) { - ret = -ENOMEM; - goto out; - } - tmem_obj_init(obj, hb, pool, oidp); - } - BUG_ON(obj == NULL); - BUG_ON(((objnew != obj) && (objfound != obj)) || (objnew == objfound)); - pampd = (*tmem_pamops.create)(data, size, raw, ephemeral, - obj->pool, &obj->oid, index); - if (unlikely(pampd == NULL)) - goto free; - ret = tmem_pampd_add_to_obj(obj, index, pampd); - if (unlikely(ret == -ENOMEM)) - /* may have partially built objnode tree ("stump") */ - goto delete_and_free; - goto out; - -delete_and_free: - (void)tmem_pampd_delete_from_obj(obj, index); -free: - if (pampd) - (*tmem_pamops.free)(pampd, pool, NULL, 0, true); - if (objnew) { - tmem_obj_free(objnew, hb); - (*tmem_hostops.obj_free)(objnew, pool); - } -out: - spin_unlock(&hb->lock); - return ret; -} - -void *tmem_localify_get_pampd(struct tmem_pool *pool, struct tmem_oid *oidp, - uint32_t index, struct tmem_obj **ret_obj, - void **saved_hb) -{ - struct tmem_hashbucket *hb; - struct tmem_obj *obj = NULL; - void *pampd = NULL; - - hb = &pool->hashbucket[tmem_oid_hash(oidp)]; - spin_lock(&hb->lock); - obj = tmem_obj_find(hb, oidp); - if (likely(obj != NULL)) - pampd = tmem_pampd_lookup_in_obj(obj, index); - *ret_obj = obj; - *saved_hb = (void *)hb; - /* note, hashbucket remains locked */ - return pampd; -} - -void tmem_localify_finish(struct tmem_obj *obj, uint32_t index, - void *pampd, void *saved_hb, bool delete) -{ - struct tmem_hashbucket *hb = (struct tmem_hashbucket *)saved_hb; - - BUG_ON(!spin_is_locked(&hb->lock)); - if (pampd != NULL) { - BUG_ON(obj == NULL); - (void)tmem_pampd_replace_in_obj(obj, index, pampd, 1); - } else if (delete) { - BUG_ON(obj == NULL); - (void)tmem_pampd_delete_from_obj(obj, index); - } - spin_unlock(&hb->lock); -} - -static int tmem_repatriate(void **ppampd, struct tmem_hashbucket *hb, - struct tmem_pool *pool, struct tmem_oid *oidp, - uint32_t index, bool free, char *data) -{ - void *old_pampd = *ppampd, *new_pampd = NULL; - bool intransit = false; - int ret = 0; - - - if (!is_ephemeral(pool)) - new_pampd = (*tmem_pamops.repatriate_preload)( - old_pampd, pool, oidp, index, &intransit); - if (intransit) - ret = -EAGAIN; - else if (new_pampd != NULL) - *ppampd = new_pampd; - /* must release the hb->lock else repatriate can't sleep */ - spin_unlock(&hb->lock); - if (!intransit) - ret = (*tmem_pamops.repatriate)(old_pampd, new_pampd, pool, - oidp, index, free, data); - return ret; -} - -/* - * "Get" a page, e.g. if one can be found, copy the tmem page with the - * matching handle from PAM space to the kernel. By tmem definition, - * when a "get" is successful on an ephemeral page, the page is "flushed", - * and when a "get" is successful on a persistent page, the page is retained - * in tmem. Note that to preserve - * coherency, "get" can never be skipped if tmem contains the data. - * That is, if a get is done with a certain handle and fails, any - * subsequent "get" must also fail (unless of course there is a - * "put" done with the same handle). - - */ -int tmem_get(struct tmem_pool *pool, struct tmem_oid *oidp, uint32_t index, - char *data, size_t *size, bool raw, int get_and_free) -{ - struct tmem_obj *obj; - void *pampd; - bool ephemeral = is_ephemeral(pool); - int ret = -1; - struct tmem_hashbucket *hb; - bool free = (get_and_free == 1) || ((get_and_free == 0) && ephemeral); - bool lock_held = 0; - void **ppampd; - -again: - hb = &pool->hashbucket[tmem_oid_hash(oidp)]; - spin_lock(&hb->lock); - lock_held = 1; - obj = tmem_obj_find(hb, oidp); - if (obj == NULL) - goto out; - ppampd = __tmem_pampd_lookup_in_obj(obj, index); - if (ppampd == NULL) - goto out; - if (tmem_pamops.is_remote(*ppampd)) { - ret = tmem_repatriate(ppampd, hb, pool, oidp, - index, free, data); - lock_held = 0; /* note hb->lock has been unlocked */ - if (ret == -EAGAIN) { - /* rare I think, but should cond_resched()??? */ - usleep_range(10, 1000); - goto again; - } else if (ret != 0) { - if (ret != -ENOENT) - pr_err("UNTESTED case in tmem_get, ret=%d\n", - ret); - ret = -1; - goto out; - } - goto out; - } - if (free) - pampd = tmem_pampd_delete_from_obj(obj, index); - else - pampd = tmem_pampd_lookup_in_obj(obj, index); - if (pampd == NULL) - goto out; - if (free) { - if (obj->pampd_count == 0) { - tmem_obj_free(obj, hb); - (*tmem_hostops.obj_free)(obj, pool); - obj = NULL; - } - } - if (free) - ret = (*tmem_pamops.get_data_and_free)( - data, size, raw, pampd, pool, oidp, index); - else - ret = (*tmem_pamops.get_data)( - data, size, raw, pampd, pool, oidp, index); - if (ret < 0) - goto out; - ret = 0; -out: - if (lock_held) - spin_unlock(&hb->lock); - return ret; -} - -/* - * If a page in tmem matches the handle, "flush" this page from tmem such - * that any subsequent "get" does not succeed (unless, of course, there - * was another "put" with the same handle). - */ -int tmem_flush_page(struct tmem_pool *pool, - struct tmem_oid *oidp, uint32_t index) -{ - struct tmem_obj *obj; - void *pampd; - int ret = -1; - struct tmem_hashbucket *hb; - - hb = &pool->hashbucket[tmem_oid_hash(oidp)]; - spin_lock(&hb->lock); - obj = tmem_obj_find(hb, oidp); - if (obj == NULL) - goto out; - pampd = tmem_pampd_delete_from_obj(obj, index); - if (pampd == NULL) - goto out; - (*tmem_pamops.free)(pampd, pool, oidp, index, true); - if (obj->pampd_count == 0) { - tmem_obj_free(obj, hb); - (*tmem_hostops.obj_free)(obj, pool); - } - ret = 0; - -out: - spin_unlock(&hb->lock); - return ret; -} - -/* - * If a page in tmem matches the handle, replace the page so that any - * subsequent "get" gets the new page. Returns the new page if - * there was a page to replace, else returns NULL. - */ -int tmem_replace(struct tmem_pool *pool, struct tmem_oid *oidp, - uint32_t index, void *new_pampd) -{ - struct tmem_obj *obj; - int ret = -1; - struct tmem_hashbucket *hb; - - hb = &pool->hashbucket[tmem_oid_hash(oidp)]; - spin_lock(&hb->lock); - obj = tmem_obj_find(hb, oidp); - if (obj == NULL) - goto out; - new_pampd = tmem_pampd_replace_in_obj(obj, index, new_pampd, 0); - ret = (*tmem_pamops.replace_in_obj)(new_pampd, obj); -out: - spin_unlock(&hb->lock); - return ret; -} - -/* - * "Flush" all pages in tmem matching this oid. - */ -int tmem_flush_object(struct tmem_pool *pool, struct tmem_oid *oidp) -{ - struct tmem_obj *obj; - struct tmem_hashbucket *hb; - int ret = -1; - - hb = &pool->hashbucket[tmem_oid_hash(oidp)]; - spin_lock(&hb->lock); - obj = tmem_obj_find(hb, oidp); - if (obj == NULL) - goto out; - tmem_pampd_destroy_all_in_obj(obj); - tmem_obj_free(obj, hb); - (*tmem_hostops.obj_free)(obj, pool); - ret = 0; - -out: - spin_unlock(&hb->lock); - return ret; -} - -/* - * "Flush" all pages (and tmem_objs) from this tmem_pool and disable - * all subsequent access to this tmem_pool. - */ -int tmem_destroy_pool(struct tmem_pool *pool) -{ - int ret = -1; - - if (pool == NULL) - goto out; - tmem_pool_flush(pool, 1); - ret = 0; -out: - return ret; -} - -static LIST_HEAD(tmem_global_pool_list); - -/* - * Create a new tmem_pool with the provided flag and return - * a pool id provided by the tmem host implementation. - */ -void tmem_new_pool(struct tmem_pool *pool, uint32_t flags) -{ - int persistent = flags & TMEM_POOL_PERSIST; - int shared = flags & TMEM_POOL_SHARED; - struct tmem_hashbucket *hb = &pool->hashbucket[0]; - int i; - - for (i = 0; i < TMEM_HASH_BUCKETS; i++, hb++) { - hb->obj_rb_root = RB_ROOT; - spin_lock_init(&hb->lock); - } - INIT_LIST_HEAD(&pool->pool_list); - atomic_set(&pool->obj_count, 0); - SET_SENTINEL(pool, POOL); - list_add_tail(&pool->pool_list, &tmem_global_pool_list); - pool->persistent = persistent; - pool->shared = shared; -} diff --git a/drivers/staging/ramster/tmem.h b/drivers/staging/ramster/tmem.h deleted file mode 100644 index 47f1918..0000000 --- a/drivers/staging/ramster/tmem.h +++ /dev/null @@ -1,244 +0,0 @@ -/* - * tmem.h - * - * Transcendent memory - * - * Copyright (c) 2009-2011, Dan Magenheimer, Oracle Corp. - */ - -#ifndef _TMEM_H_ -#define _TMEM_H_ - -#include -#include -#include - -/* - * These are pre-defined by the Xen<->Linux ABI - */ -#define TMEM_PUT_PAGE 4 -#define TMEM_GET_PAGE 5 -#define TMEM_FLUSH_PAGE 6 -#define TMEM_FLUSH_OBJECT 7 -#define TMEM_POOL_PERSIST 1 -#define TMEM_POOL_SHARED 2 -#define TMEM_POOL_PRECOMPRESSED 4 -#define TMEM_POOL_PAGESIZE_SHIFT 4 -#define TMEM_POOL_PAGESIZE_MASK 0xf -#define TMEM_POOL_RESERVED_BITS 0x00ffff00 - -/* - * sentinels have proven very useful for debugging but can be removed - * or disabled before final merge. - */ -#define SENTINELS -#ifdef SENTINELS -#define DECL_SENTINEL uint32_t sentinel; -#define SET_SENTINEL(_x, _y) (_x->sentinel = _y##_SENTINEL) -#define INVERT_SENTINEL(_x, _y) (_x->sentinel = ~_y##_SENTINEL) -#define ASSERT_SENTINEL(_x, _y) WARN_ON(_x->sentinel != _y##_SENTINEL) -#define ASSERT_INVERTED_SENTINEL(_x, _y) WARN_ON(_x->sentinel != ~_y##_SENTINEL) -#else -#define DECL_SENTINEL -#define SET_SENTINEL(_x, _y) do { } while (0) -#define INVERT_SENTINEL(_x, _y) do { } while (0) -#define ASSERT_SENTINEL(_x, _y) do { } while (0) -#define ASSERT_INVERTED_SENTINEL(_x, _y) do { } while (0) -#endif - -#define ASSERT_SPINLOCK(_l) WARN_ON(!spin_is_locked(_l)) - -/* - * A pool is the highest-level data structure managed by tmem and - * usually corresponds to a large independent set of pages such as - * a filesystem. Each pool has an id, and certain attributes and counters. - * It also contains a set of hash buckets, each of which contains an rbtree - * of objects and a lock to manage concurrency within the pool. - */ - -#define TMEM_HASH_BUCKET_BITS 8 -#define TMEM_HASH_BUCKETS (1<persistent) -#define is_ephemeral(_p) (!(_p->persistent)) - -/* - * An object id ("oid") is large: 192-bits (to ensure, for example, files - * in a modern filesystem can be uniquely identified). - */ - -struct tmem_oid { - uint64_t oid[3]; -}; - -struct tmem_xhandle { - uint8_t client_id; - uint8_t xh_data_cksum; - uint16_t xh_data_size; - uint16_t pool_id; - struct tmem_oid oid; - uint32_t index; - void *extra; -}; - -static inline struct tmem_xhandle tmem_xhandle_fill(uint16_t client_id, - struct tmem_pool *pool, - struct tmem_oid *oidp, - uint32_t index) -{ - struct tmem_xhandle xh; - xh.client_id = client_id; - xh.xh_data_cksum = (uint8_t)-1; - xh.xh_data_size = (uint16_t)-1; - xh.pool_id = pool->pool_id; - xh.oid = *oidp; - xh.index = index; - return xh; -} - -static inline void tmem_oid_set_invalid(struct tmem_oid *oidp) -{ - oidp->oid[0] = oidp->oid[1] = oidp->oid[2] = -1UL; -} - -static inline bool tmem_oid_valid(struct tmem_oid *oidp) -{ - return oidp->oid[0] != -1UL || oidp->oid[1] != -1UL || - oidp->oid[2] != -1UL; -} - -static inline int tmem_oid_compare(struct tmem_oid *left, - struct tmem_oid *right) -{ - int ret; - - if (left->oid[2] == right->oid[2]) { - if (left->oid[1] == right->oid[1]) { - if (left->oid[0] == right->oid[0]) - ret = 0; - else if (left->oid[0] < right->oid[0]) - ret = -1; - else - return 1; - } else if (left->oid[1] < right->oid[1]) - ret = -1; - else - ret = 1; - } else if (left->oid[2] < right->oid[2]) - ret = -1; - else - ret = 1; - return ret; -} - -static inline unsigned tmem_oid_hash(struct tmem_oid *oidp) -{ - return hash_long(oidp->oid[0] ^ oidp->oid[1] ^ oidp->oid[2], - TMEM_HASH_BUCKET_BITS); -} - -/* - * A tmem_obj contains an identifier (oid), pointers to the parent - * pool and the rb_tree to which it belongs, counters, and an ordered - * set of pampds, structured in a radix-tree-like tree. The intermediate - * nodes of the tree are called tmem_objnodes. - */ - -struct tmem_objnode; - -struct tmem_obj { - struct tmem_oid oid; - struct tmem_pool *pool; - struct rb_node rb_tree_node; - struct tmem_objnode *objnode_tree_root; - unsigned int objnode_tree_height; - unsigned long objnode_count; - long pampd_count; - /* for current design of ramster, all pages belonging to - * an object reside on the same remotenode and extra is - * used to record the number of the remotenode so a - * flush-object operation can specify it */ - void *extra; /* for use by pampd implementation */ - DECL_SENTINEL -}; - -#define OBJNODE_TREE_MAP_SHIFT 6 -#define OBJNODE_TREE_MAP_SIZE (1UL << OBJNODE_TREE_MAP_SHIFT) -#define OBJNODE_TREE_MAP_MASK (OBJNODE_TREE_MAP_SIZE-1) -#define OBJNODE_TREE_INDEX_BITS (8 /* CHAR_BIT */ * sizeof(unsigned long)) -#define OBJNODE_TREE_MAX_PATH \ - (OBJNODE_TREE_INDEX_BITS/OBJNODE_TREE_MAP_SHIFT + 2) - -struct tmem_objnode { - struct tmem_obj *obj; - DECL_SENTINEL - void *slots[OBJNODE_TREE_MAP_SIZE]; - unsigned int slots_in_use; -}; - -/* pampd abstract datatype methods provided by the PAM implementation */ -struct tmem_pamops { - void *(*create)(char *, size_t, bool, int, - struct tmem_pool *, struct tmem_oid *, uint32_t); - int (*get_data)(char *, size_t *, bool, void *, struct tmem_pool *, - struct tmem_oid *, uint32_t); - int (*get_data_and_free)(char *, size_t *, bool, void *, - struct tmem_pool *, struct tmem_oid *, - uint32_t); - void (*free)(void *, struct tmem_pool *, - struct tmem_oid *, uint32_t, bool); - void (*free_obj)(struct tmem_pool *, struct tmem_obj *); - bool (*is_remote)(void *); - void *(*repatriate_preload)(void *, struct tmem_pool *, - struct tmem_oid *, uint32_t, bool *); - int (*repatriate)(void *, void *, struct tmem_pool *, - struct tmem_oid *, uint32_t, bool, void *); - void (*new_obj)(struct tmem_obj *); - int (*replace_in_obj)(void *, struct tmem_obj *); -}; -extern void tmem_register_pamops(struct tmem_pamops *m); - -/* memory allocation methods provided by the host implementation */ -struct tmem_hostops { - struct tmem_obj *(*obj_alloc)(struct tmem_pool *); - void (*obj_free)(struct tmem_obj *, struct tmem_pool *); - struct tmem_objnode *(*objnode_alloc)(struct tmem_pool *); - void (*objnode_free)(struct tmem_objnode *, struct tmem_pool *); -}; -extern void tmem_register_hostops(struct tmem_hostops *m); - -/* core tmem accessor functions */ -extern int tmem_put(struct tmem_pool *, struct tmem_oid *, uint32_t index, - char *, size_t, bool, int); -extern int tmem_get(struct tmem_pool *, struct tmem_oid *, uint32_t index, - char *, size_t *, bool, int); -extern int tmem_replace(struct tmem_pool *, struct tmem_oid *, uint32_t index, - void *); -extern void *tmem_localify_get_pampd(struct tmem_pool *, struct tmem_oid *, - uint32_t index, struct tmem_obj **, - void **); -extern void tmem_localify_finish(struct tmem_obj *, uint32_t index, - void *, void *, bool); -extern int tmem_flush_page(struct tmem_pool *, struct tmem_oid *, - uint32_t index); -extern int tmem_flush_object(struct tmem_pool *, struct tmem_oid *); -extern int tmem_destroy_pool(struct tmem_pool *); -extern void tmem_new_pool(struct tmem_pool *, uint32_t); -#endif /* _TMEM_H */ diff --git a/drivers/staging/ramster/xvmalloc.c b/drivers/staging/ramster/xvmalloc.c deleted file mode 100644 index 44ceb0b..0000000 --- a/drivers/staging/ramster/xvmalloc.c +++ /dev/null @@ -1,509 +0,0 @@ -/* - * xvmalloc memory allocator - * - * Copyright (C) 2008, 2009, 2010 Nitin Gupta - * - * This code is released using a dual license strategy: BSD/GPL - * You can choose the licence that better fits your requirements. - * - * Released under the terms of 3-clause BSD License - * Released under the terms of GNU General Public License Version 2.0 - */ - -#ifdef CONFIG_ZRAM_DEBUG -#define DEBUG -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "xvmalloc.h" -#include "xvmalloc_int.h" - -static void stat_inc(u64 *value) -{ - *value = *value + 1; -} - -static void stat_dec(u64 *value) -{ - *value = *value - 1; -} - -static int test_flag(struct block_header *block, enum blockflags flag) -{ - return block->prev & BIT(flag); -} - -static void set_flag(struct block_header *block, enum blockflags flag) -{ - block->prev |= BIT(flag); -} - -static void clear_flag(struct block_header *block, enum blockflags flag) -{ - block->prev &= ~BIT(flag); -} - -/* - * Given pair, provide a dereferencable pointer. - * This is called from xv_malloc/xv_free path, so it - * needs to be fast. - */ -static void *get_ptr_atomic(struct page *page, u16 offset) -{ - unsigned char *base; - - base = kmap_atomic(page); - return base + offset; -} - -static void put_ptr_atomic(void *ptr) -{ - kunmap_atomic(ptr); -} - -static u32 get_blockprev(struct block_header *block) -{ - return block->prev & PREV_MASK; -} - -static void set_blockprev(struct block_header *block, u16 new_offset) -{ - block->prev = new_offset | (block->prev & FLAGS_MASK); -} - -static struct block_header *BLOCK_NEXT(struct block_header *block) -{ - return (struct block_header *) - ((char *)block + block->size + XV_ALIGN); -} - -/* - * Get index of free list containing blocks of maximum size - * which is less than or equal to given size. - */ -static u32 get_index_for_insert(u32 size) -{ - if (unlikely(size > XV_MAX_ALLOC_SIZE)) - size = XV_MAX_ALLOC_SIZE; - size &= ~FL_DELTA_MASK; - return (size - XV_MIN_ALLOC_SIZE) >> FL_DELTA_SHIFT; -} - -/* - * Get index of free list having blocks of size greater than - * or equal to requested size. - */ -static u32 get_index(u32 size) -{ - if (unlikely(size < XV_MIN_ALLOC_SIZE)) - size = XV_MIN_ALLOC_SIZE; - size = ALIGN(size, FL_DELTA); - return (size - XV_MIN_ALLOC_SIZE) >> FL_DELTA_SHIFT; -} - -/** - * find_block - find block of at least given size - * @pool: memory pool to search from - * @size: size of block required - * @page: page containing required block - * @offset: offset within the page where block is located. - * - * Searches two level bitmap to locate block of at least - * the given size. If such a block is found, it provides - * to identify this block and returns index - * in freelist where we found this block. - * Otherwise, returns 0 and params are not touched. - */ -static u32 find_block(struct xv_pool *pool, u32 size, - struct page **page, u32 *offset) -{ - ulong flbitmap, slbitmap; - u32 flindex, slindex, slbitstart; - - /* There are no free blocks in this pool */ - if (!pool->flbitmap) - return 0; - - /* Get freelist index corresponding to this size */ - slindex = get_index(size); - slbitmap = pool->slbitmap[slindex / BITS_PER_LONG]; - slbitstart = slindex % BITS_PER_LONG; - - /* - * If freelist is not empty at this index, we found the - * block - head of this list. This is approximate best-fit match. - */ - if (test_bit(slbitstart, &slbitmap)) { - *page = pool->freelist[slindex].page; - *offset = pool->freelist[slindex].offset; - return slindex; - } - - /* - * No best-fit found. Search a bit further in bitmap for a free block. - * Second level bitmap consists of series of 32-bit chunks. Search - * further in the chunk where we expected a best-fit, starting from - * index location found above. - */ - slbitstart++; - slbitmap >>= slbitstart; - - /* Skip this search if we were already at end of this bitmap chunk */ - if ((slbitstart != BITS_PER_LONG) && slbitmap) { - slindex += __ffs(slbitmap) + 1; - *page = pool->freelist[slindex].page; - *offset = pool->freelist[slindex].offset; - return slindex; - } - - /* Now do a full two-level bitmap search to find next nearest fit */ - flindex = slindex / BITS_PER_LONG; - - flbitmap = (pool->flbitmap) >> (flindex + 1); - if (!flbitmap) - return 0; - - flindex += __ffs(flbitmap) + 1; - slbitmap = pool->slbitmap[flindex]; - slindex = (flindex * BITS_PER_LONG) + __ffs(slbitmap); - *page = pool->freelist[slindex].page; - *offset = pool->freelist[slindex].offset; - - return slindex; -} - -/* - * Insert block at in freelist of given pool. - * freelist used depends on block size. - */ -static void insert_block(struct xv_pool *pool, struct page *page, u32 offset, - struct block_header *block) -{ - u32 flindex, slindex; - struct block_header *nextblock; - - slindex = get_index_for_insert(block->size); - flindex = slindex / BITS_PER_LONG; - - block->link.prev_page = NULL; - block->link.prev_offset = 0; - block->link.next_page = pool->freelist[slindex].page; - block->link.next_offset = pool->freelist[slindex].offset; - pool->freelist[slindex].page = page; - pool->freelist[slindex].offset = offset; - - if (block->link.next_page) { - nextblock = get_ptr_atomic(block->link.next_page, - block->link.next_offset); - nextblock->link.prev_page = page; - nextblock->link.prev_offset = offset; - put_ptr_atomic(nextblock); - /* If there was a next page then the free bits are set. */ - return; - } - - __set_bit(slindex % BITS_PER_LONG, &pool->slbitmap[flindex]); - __set_bit(flindex, &pool->flbitmap); -} - -/* - * Remove block from freelist. Index 'slindex' identifies the freelist. - */ -static void remove_block(struct xv_pool *pool, struct page *page, u32 offset, - struct block_header *block, u32 slindex) -{ - u32 flindex = slindex / BITS_PER_LONG; - struct block_header *tmpblock; - - if (block->link.prev_page) { - tmpblock = get_ptr_atomic(block->link.prev_page, - block->link.prev_offset); - tmpblock->link.next_page = block->link.next_page; - tmpblock->link.next_offset = block->link.next_offset; - put_ptr_atomic(tmpblock); - } - - if (block->link.next_page) { - tmpblock = get_ptr_atomic(block->link.next_page, - block->link.next_offset); - tmpblock->link.prev_page = block->link.prev_page; - tmpblock->link.prev_offset = block->link.prev_offset; - put_ptr_atomic(tmpblock); - } - - /* Is this block is at the head of the freelist? */ - if (pool->freelist[slindex].page == page - && pool->freelist[slindex].offset == offset) { - - pool->freelist[slindex].page = block->link.next_page; - pool->freelist[slindex].offset = block->link.next_offset; - - if (pool->freelist[slindex].page) { - struct block_header *tmpblock; - tmpblock = get_ptr_atomic(pool->freelist[slindex].page, - pool->freelist[slindex].offset); - tmpblock->link.prev_page = NULL; - tmpblock->link.prev_offset = 0; - put_ptr_atomic(tmpblock); - } else { - /* This freelist bucket is empty */ - __clear_bit(slindex % BITS_PER_LONG, - &pool->slbitmap[flindex]); - if (!pool->slbitmap[flindex]) - __clear_bit(flindex, &pool->flbitmap); - } - } - - block->link.prev_page = NULL; - block->link.prev_offset = 0; - block->link.next_page = NULL; - block->link.next_offset = 0; -} - -/* - * Allocate a page and add it to freelist of given pool. - */ -static int grow_pool(struct xv_pool *pool, gfp_t flags) -{ - struct page *page; - struct block_header *block; - - page = alloc_page(flags); - if (unlikely(!page)) - return -ENOMEM; - - stat_inc(&pool->total_pages); - - spin_lock(&pool->lock); - block = get_ptr_atomic(page, 0); - - block->size = PAGE_SIZE - XV_ALIGN; - set_flag(block, BLOCK_FREE); - clear_flag(block, PREV_FREE); - set_blockprev(block, 0); - - insert_block(pool, page, 0, block); - - put_ptr_atomic(block); - spin_unlock(&pool->lock); - - return 0; -} - -/* - * Create a memory pool. Allocates freelist, bitmaps and other - * per-pool metadata. - */ -struct xv_pool *xv_create_pool(void) -{ - u32 ovhd_size; - struct xv_pool *pool; - - ovhd_size = roundup(sizeof(*pool), PAGE_SIZE); - pool = kzalloc(ovhd_size, GFP_KERNEL); - if (!pool) - return NULL; - - spin_lock_init(&pool->lock); - - return pool; -} -EXPORT_SYMBOL_GPL(xv_create_pool); - -void xv_destroy_pool(struct xv_pool *pool) -{ - kfree(pool); -} -EXPORT_SYMBOL_GPL(xv_destroy_pool); - -/** - * xv_malloc - Allocate block of given size from pool. - * @pool: pool to allocate from - * @size: size of block to allocate - * @page: page no. that holds the object - * @offset: location of object within page - * - * On success, identifies block allocated - * and 0 is returned. On failure, is set to - * 0 and -ENOMEM is returned. - * - * Allocation requests with size > XV_MAX_ALLOC_SIZE will fail. - */ -int xv_malloc(struct xv_pool *pool, u32 size, struct page **page, - u32 *offset, gfp_t flags) -{ - int error; - u32 index, tmpsize, origsize, tmpoffset; - struct block_header *block, *tmpblock; - - *page = NULL; - *offset = 0; - origsize = size; - - if (unlikely(!size || size > XV_MAX_ALLOC_SIZE)) - return -ENOMEM; - - size = ALIGN(size, XV_ALIGN); - - spin_lock(&pool->lock); - - index = find_block(pool, size, page, offset); - - if (!*page) { - spin_unlock(&pool->lock); - if (flags & GFP_NOWAIT) - return -ENOMEM; - error = grow_pool(pool, flags); - if (unlikely(error)) - return error; - - spin_lock(&pool->lock); - index = find_block(pool, size, page, offset); - } - - if (!*page) { - spin_unlock(&pool->lock); - return -ENOMEM; - } - - block = get_ptr_atomic(*page, *offset); - - remove_block(pool, *page, *offset, block, index); - - /* Split the block if required */ - tmpoffset = *offset + size + XV_ALIGN; - tmpsize = block->size - size; - tmpblock = (struct block_header *)((char *)block + size + XV_ALIGN); - if (tmpsize) { - tmpblock->size = tmpsize - XV_ALIGN; - set_flag(tmpblock, BLOCK_FREE); - clear_flag(tmpblock, PREV_FREE); - - set_blockprev(tmpblock, *offset); - if (tmpblock->size >= XV_MIN_ALLOC_SIZE) - insert_block(pool, *page, tmpoffset, tmpblock); - - if (tmpoffset + XV_ALIGN + tmpblock->size != PAGE_SIZE) { - tmpblock = BLOCK_NEXT(tmpblock); - set_blockprev(tmpblock, tmpoffset); - } - } else { - /* This block is exact fit */ - if (tmpoffset != PAGE_SIZE) - clear_flag(tmpblock, PREV_FREE); - } - - block->size = origsize; - clear_flag(block, BLOCK_FREE); - - put_ptr_atomic(block); - spin_unlock(&pool->lock); - - *offset += XV_ALIGN; - - return 0; -} -EXPORT_SYMBOL_GPL(xv_malloc); - -/* - * Free block identified with - */ -void xv_free(struct xv_pool *pool, struct page *page, u32 offset) -{ - void *page_start; - struct block_header *block, *tmpblock; - - offset -= XV_ALIGN; - - spin_lock(&pool->lock); - - page_start = get_ptr_atomic(page, 0); - block = (struct block_header *)((char *)page_start + offset); - - /* Catch double free bugs */ - BUG_ON(test_flag(block, BLOCK_FREE)); - - block->size = ALIGN(block->size, XV_ALIGN); - - tmpblock = BLOCK_NEXT(block); - if (offset + block->size + XV_ALIGN == PAGE_SIZE) - tmpblock = NULL; - - /* Merge next block if its free */ - if (tmpblock && test_flag(tmpblock, BLOCK_FREE)) { - /* - * Blocks smaller than XV_MIN_ALLOC_SIZE - * are not inserted in any free list. - */ - if (tmpblock->size >= XV_MIN_ALLOC_SIZE) { - remove_block(pool, page, - offset + block->size + XV_ALIGN, tmpblock, - get_index_for_insert(tmpblock->size)); - } - block->size += tmpblock->size + XV_ALIGN; - } - - /* Merge previous block if its free */ - if (test_flag(block, PREV_FREE)) { - tmpblock = (struct block_header *)((char *)(page_start) + - get_blockprev(block)); - offset = offset - tmpblock->size - XV_ALIGN; - - if (tmpblock->size >= XV_MIN_ALLOC_SIZE) - remove_block(pool, page, offset, tmpblock, - get_index_for_insert(tmpblock->size)); - - tmpblock->size += block->size + XV_ALIGN; - block = tmpblock; - } - - /* No used objects in this page. Free it. */ - if (block->size == PAGE_SIZE - XV_ALIGN) { - put_ptr_atomic(page_start); - spin_unlock(&pool->lock); - - __free_page(page); - stat_dec(&pool->total_pages); - return; - } - - set_flag(block, BLOCK_FREE); - if (block->size >= XV_MIN_ALLOC_SIZE) - insert_block(pool, page, offset, block); - - if (offset + block->size + XV_ALIGN != PAGE_SIZE) { - tmpblock = BLOCK_NEXT(block); - set_flag(tmpblock, PREV_FREE); - set_blockprev(tmpblock, offset); - } - - put_ptr_atomic(page_start); - spin_unlock(&pool->lock); -} -EXPORT_SYMBOL_GPL(xv_free); - -u32 xv_get_object_size(void *obj) -{ - struct block_header *blk; - - blk = (struct block_header *)((char *)(obj) - XV_ALIGN); - return blk->size; -} -EXPORT_SYMBOL_GPL(xv_get_object_size); - -/* - * Returns total memory used by allocator (userdata + metadata) - */ -u64 xv_get_total_size_bytes(struct xv_pool *pool) -{ - return pool->total_pages << PAGE_SHIFT; -} -EXPORT_SYMBOL_GPL(xv_get_total_size_bytes); diff --git a/drivers/staging/ramster/xvmalloc.h b/drivers/staging/ramster/xvmalloc.h deleted file mode 100644 index 5b1a81a..0000000 --- a/drivers/staging/ramster/xvmalloc.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * xvmalloc memory allocator - * - * Copyright (C) 2008, 2009, 2010 Nitin Gupta - * - * This code is released using a dual license strategy: BSD/GPL - * You can choose the licence that better fits your requirements. - * - * Released under the terms of 3-clause BSD License - * Released under the terms of GNU General Public License Version 2.0 - */ - -#ifndef _XV_MALLOC_H_ -#define _XV_MALLOC_H_ - -#include - -struct xv_pool; - -struct xv_pool *xv_create_pool(void); -void xv_destroy_pool(struct xv_pool *pool); - -int xv_malloc(struct xv_pool *pool, u32 size, struct page **page, - u32 *offset, gfp_t flags); -void xv_free(struct xv_pool *pool, struct page *page, u32 offset); - -u32 xv_get_object_size(void *obj); -u64 xv_get_total_size_bytes(struct xv_pool *pool); - -#endif diff --git a/drivers/staging/ramster/xvmalloc_int.h b/drivers/staging/ramster/xvmalloc_int.h deleted file mode 100644 index b5f1f7f..0000000 --- a/drivers/staging/ramster/xvmalloc_int.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * xvmalloc memory allocator - * - * Copyright (C) 2008, 2009, 2010 Nitin Gupta - * - * This code is released using a dual license strategy: BSD/GPL - * You can choose the licence that better fits your requirements. - * - * Released under the terms of 3-clause BSD License - * Released under the terms of GNU General Public License Version 2.0 - */ - -#ifndef _XV_MALLOC_INT_H_ -#define _XV_MALLOC_INT_H_ - -#include -#include - -/* User configurable params */ - -/* Must be power of two */ -#ifdef CONFIG_64BIT -#define XV_ALIGN_SHIFT 3 -#else -#define XV_ALIGN_SHIFT 2 -#endif -#define XV_ALIGN (1 << XV_ALIGN_SHIFT) -#define XV_ALIGN_MASK (XV_ALIGN - 1) - -/* This must be greater than sizeof(link_free) */ -#define XV_MIN_ALLOC_SIZE 32 -#define XV_MAX_ALLOC_SIZE (PAGE_SIZE - XV_ALIGN) - -/* - * Free lists are separated by FL_DELTA bytes - * This value is 3 for 4k pages and 4 for 64k pages, for any - * other page size, a conservative (PAGE_SHIFT - 9) is used. - */ -#if PAGE_SHIFT == 16 -#define FL_DELTA_SHIFT 4 -#else -#define FL_DELTA_SHIFT (PAGE_SHIFT - 9) -#endif -#define FL_DELTA (1 << FL_DELTA_SHIFT) -#define FL_DELTA_MASK (FL_DELTA - 1) -#define NUM_FREE_LISTS ((XV_MAX_ALLOC_SIZE - XV_MIN_ALLOC_SIZE) \ - / FL_DELTA + 1) - -#define MAX_FLI DIV_ROUND_UP(NUM_FREE_LISTS, BITS_PER_LONG) - -/* End of user params */ - -enum blockflags { - BLOCK_FREE, - PREV_FREE, - __NR_BLOCKFLAGS, -}; - -#define FLAGS_MASK XV_ALIGN_MASK -#define PREV_MASK (~FLAGS_MASK) - -struct freelist_entry { - struct page *page; - u16 offset; - u16 pad; -}; - -struct link_free { - struct page *prev_page; - struct page *next_page; - u16 prev_offset; - u16 next_offset; -}; - -struct block_header { - union { - /* This common header must be XV_ALIGN bytes */ - u8 common[XV_ALIGN]; - struct { - u16 size; - u16 prev; - }; - }; - struct link_free link; -}; - -struct xv_pool { - ulong flbitmap; - ulong slbitmap[MAX_FLI]; - u64 total_pages; /* stats */ - struct freelist_entry freelist[NUM_FREE_LISTS]; - spinlock_t lock; -}; - -#endif diff --git a/drivers/staging/ramster/zcache-main.c b/drivers/staging/ramster/zcache-main.c deleted file mode 100644 index d46764b..0000000 --- a/drivers/staging/ramster/zcache-main.c +++ /dev/null @@ -1,3320 +0,0 @@ -/* - * zcache.c - * - * Copyright (c) 2010-2012, Dan Magenheimer, Oracle Corp. - * Copyright (c) 2010,2011, Nitin Gupta - * - * Zcache provides an in-kernel "host implementation" for transcendent memory - * and, thus indirectly, for cleancache and frontswap. Zcache includes two - * page-accessible memory [1] interfaces, both utilizing lzo1x compression: - * 1) "compression buddies" ("zbud") is used for ephemeral pages - * 2) xvmalloc is used for persistent pages. - * Xvmalloc (based on the TLSF allocator) has very low fragmentation - * so maximizes space efficiency, while zbud allows pairs (and potentially, - * in the future, more than a pair of) compressed pages to be closely linked - * so that reclaiming can be done via the kernel's physical-page-oriented - * "shrinker" interface. - * - * [1] For a definition of page-accessible memory (aka PAM), see: - * http://marc.info/?l=linux-mm&m=127811271605009 - * RAMSTER TODO: - * - handle remotifying of buddied pages (see zbud_remotify_zbpg) - * - kernel boot params: nocleancache/nofrontswap don't always work?!? - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "tmem.h" -#include "zcache.h" -#include "ramster.h" -#include "cluster/tcp.h" - -#include "xvmalloc.h" /* temporary until change to zsmalloc */ - -#define RAMSTER_TESTING - -#if (!defined(CONFIG_CLEANCACHE) && !defined(CONFIG_FRONTSWAP)) -#error "ramster is useless without CONFIG_CLEANCACHE or CONFIG_FRONTSWAP" -#endif -#ifdef CONFIG_CLEANCACHE -#include -#endif -#ifdef CONFIG_FRONTSWAP -#include -#endif - -enum ramster_remotify_op { - RAMSTER_REMOTIFY_EPH_PUT, - RAMSTER_REMOTIFY_PERS_PUT, - RAMSTER_REMOTIFY_FLUSH_PAGE, - RAMSTER_REMOTIFY_FLUSH_OBJ, - RAMSTER_INTRANSIT_PERS -}; - -struct ramster_remotify_hdr { - enum ramster_remotify_op op; - struct list_head list; -}; - -#define ZBH_SENTINEL 0x43214321 -#define ZBPG_SENTINEL 0xdeadbeef - -#define ZBUD_MAX_BUDS 2 - -struct zbud_hdr { - struct ramster_remotify_hdr rem_op; - uint16_t client_id; - uint16_t pool_id; - struct tmem_oid oid; - uint32_t index; - uint16_t size; /* compressed size in bytes, zero means unused */ - DECL_SENTINEL -}; - -#define ZVH_SENTINEL 0x43214321 -static const int zv_max_page_size = (PAGE_SIZE / 8) * 7; - -struct zv_hdr { - struct ramster_remotify_hdr rem_op; - uint16_t client_id; - uint16_t pool_id; - struct tmem_oid oid; - uint32_t index; - DECL_SENTINEL -}; - -struct flushlist_node { - struct ramster_remotify_hdr rem_op; - struct tmem_xhandle xh; -}; - -union { - struct ramster_remotify_hdr rem_op; - struct zv_hdr zv; - struct zbud_hdr zbud; - struct flushlist_node flist; -} remotify_list_node; - -static LIST_HEAD(zcache_rem_op_list); -static DEFINE_SPINLOCK(zcache_rem_op_list_lock); - -#if 0 -/* this is more aggressive but may cause other problems? */ -#define ZCACHE_GFP_MASK (GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN) -#else -#define ZCACHE_GFP_MASK \ - (__GFP_FS | __GFP_NORETRY | __GFP_NOWARN | __GFP_NOMEMALLOC) -#endif - -#define MAX_POOLS_PER_CLIENT 16 - -#define MAX_CLIENTS 16 -#define LOCAL_CLIENT ((uint16_t)-1) - -MODULE_LICENSE("GPL"); - -struct zcache_client { - struct tmem_pool *tmem_pools[MAX_POOLS_PER_CLIENT]; - struct xv_pool *xvpool; - bool allocated; - atomic_t refcount; -}; - -static struct zcache_client zcache_host; -static struct zcache_client zcache_clients[MAX_CLIENTS]; - -static inline uint16_t get_client_id_from_client(struct zcache_client *cli) -{ - BUG_ON(cli == NULL); - if (cli == &zcache_host) - return LOCAL_CLIENT; - return cli - &zcache_clients[0]; -} - -static inline bool is_local_client(struct zcache_client *cli) -{ - return cli == &zcache_host; -} - -/********** - * Compression buddies ("zbud") provides for packing two (or, possibly - * in the future, more) compressed ephemeral pages into a single "raw" - * (physical) page and tracking them with data structures so that - * the raw pages can be easily reclaimed. - * - * A zbud page ("zbpg") is an aligned page containing a list_head, - * a lock, and two "zbud headers". The remainder of the physical - * page is divided up into aligned 64-byte "chunks" which contain - * the compressed data for zero, one, or two zbuds. Each zbpg - * resides on: (1) an "unused list" if it has no zbuds; (2) a - * "buddied" list if it is fully populated with two zbuds; or - * (3) one of PAGE_SIZE/64 "unbuddied" lists indexed by how many chunks - * the one unbuddied zbud uses. The data inside a zbpg cannot be - * read or written unless the zbpg's lock is held. - */ - -struct zbud_page { - struct list_head bud_list; - spinlock_t lock; - struct zbud_hdr buddy[ZBUD_MAX_BUDS]; - DECL_SENTINEL - /* followed by NUM_CHUNK aligned CHUNK_SIZE-byte chunks */ -}; - -#define CHUNK_SHIFT 6 -#define CHUNK_SIZE (1 << CHUNK_SHIFT) -#define CHUNK_MASK (~(CHUNK_SIZE-1)) -#define NCHUNKS (((PAGE_SIZE - sizeof(struct zbud_page)) & \ - CHUNK_MASK) >> CHUNK_SHIFT) -#define MAX_CHUNK (NCHUNKS-1) - -static struct { - struct list_head list; - unsigned count; -} zbud_unbuddied[NCHUNKS]; -/* list N contains pages with N chunks USED and NCHUNKS-N unused */ -/* element 0 is never used but optimizing that isn't worth it */ -static unsigned long zbud_cumul_chunk_counts[NCHUNKS]; - -struct list_head zbud_buddied_list; -static unsigned long zcache_zbud_buddied_count; - -/* protects the buddied list and all unbuddied lists */ -static DEFINE_SPINLOCK(zbud_budlists_spinlock); - -static atomic_t zcache_zbud_curr_raw_pages; -static atomic_t zcache_zbud_curr_zpages; -static unsigned long zcache_zbud_curr_zbytes; -static unsigned long zcache_zbud_cumul_zpages; -static unsigned long zcache_zbud_cumul_zbytes; -static unsigned long zcache_compress_poor; -static unsigned long zcache_policy_percent_exceeded; -static unsigned long zcache_mean_compress_poor; - -/* - * RAMster counters - * - Remote pages are pages with a local pampd but the data is remote - * - Foreign pages are pages stored locally but belonging to another node - */ -static atomic_t ramster_remote_pers_pages = ATOMIC_INIT(0); -static unsigned long ramster_pers_remotify_enable; -static unsigned long ramster_eph_remotify_enable; -static unsigned long ramster_eph_pages_remoted; -static unsigned long ramster_eph_pages_remote_failed; -static unsigned long ramster_pers_pages_remoted; -static unsigned long ramster_pers_pages_remote_failed; -static unsigned long ramster_pers_pages_remote_nomem; -static unsigned long ramster_remote_objects_flushed; -static unsigned long ramster_remote_object_flushes_failed; -static unsigned long ramster_remote_pages_flushed; -static unsigned long ramster_remote_page_flushes_failed; -static unsigned long ramster_remote_eph_pages_succ_get; -static unsigned long ramster_remote_pers_pages_succ_get; -static unsigned long ramster_remote_eph_pages_unsucc_get; -static unsigned long ramster_remote_pers_pages_unsucc_get; -static atomic_t ramster_curr_flnode_count = ATOMIC_INIT(0); -static unsigned long ramster_curr_flnode_count_max; -static atomic_t ramster_foreign_eph_pampd_count = ATOMIC_INIT(0); -static unsigned long ramster_foreign_eph_pampd_count_max; -static atomic_t ramster_foreign_pers_pampd_count = ATOMIC_INIT(0); -static unsigned long ramster_foreign_pers_pampd_count_max; - -/* forward references */ -static void *zcache_get_free_page(void); -static void zcache_free_page(void *p); - -/* - * zbud helper functions - */ - -static inline unsigned zbud_max_buddy_size(void) -{ - return MAX_CHUNK << CHUNK_SHIFT; -} - -static inline unsigned zbud_size_to_chunks(unsigned size) -{ - BUG_ON(size == 0 || size > zbud_max_buddy_size()); - return (size + CHUNK_SIZE - 1) >> CHUNK_SHIFT; -} - -static inline int zbud_budnum(struct zbud_hdr *zh) -{ - unsigned offset = (unsigned long)zh & (PAGE_SIZE - 1); - struct zbud_page *zbpg = NULL; - unsigned budnum = -1U; - int i; - - for (i = 0; i < ZBUD_MAX_BUDS; i++) - if (offset == offsetof(typeof(*zbpg), buddy[i])) { - budnum = i; - break; - } - BUG_ON(budnum == -1U); - return budnum; -} - -static char *zbud_data(struct zbud_hdr *zh, unsigned size) -{ - struct zbud_page *zbpg; - char *p; - unsigned budnum; - - ASSERT_SENTINEL(zh, ZBH); - budnum = zbud_budnum(zh); - BUG_ON(size == 0 || size > zbud_max_buddy_size()); - zbpg = container_of(zh, struct zbud_page, buddy[budnum]); - ASSERT_SPINLOCK(&zbpg->lock); - p = (char *)zbpg; - if (budnum == 0) - p += ((sizeof(struct zbud_page) + CHUNK_SIZE - 1) & - CHUNK_MASK); - else if (budnum == 1) - p += PAGE_SIZE - ((size + CHUNK_SIZE - 1) & CHUNK_MASK); - return p; -} - -static void zbud_copy_from_pampd(char *data, size_t *size, struct zbud_hdr *zh) -{ - struct zbud_page *zbpg; - char *p; - unsigned budnum; - - ASSERT_SENTINEL(zh, ZBH); - budnum = zbud_budnum(zh); - zbpg = container_of(zh, struct zbud_page, buddy[budnum]); - spin_lock(&zbpg->lock); - BUG_ON(zh->size > *size); - p = (char *)zbpg; - if (budnum == 0) - p += ((sizeof(struct zbud_page) + CHUNK_SIZE - 1) & - CHUNK_MASK); - else if (budnum == 1) - p += PAGE_SIZE - ((zh->size + CHUNK_SIZE - 1) & CHUNK_MASK); - /* client should be filled in by caller */ - memcpy(data, p, zh->size); - *size = zh->size; - spin_unlock(&zbpg->lock); -} - -/* - * zbud raw page management - */ - -static struct zbud_page *zbud_alloc_raw_page(void) -{ - struct zbud_page *zbpg = NULL; - struct zbud_hdr *zh0, *zh1; - zbpg = zcache_get_free_page(); - if (likely(zbpg != NULL)) { - INIT_LIST_HEAD(&zbpg->bud_list); - zh0 = &zbpg->buddy[0]; zh1 = &zbpg->buddy[1]; - spin_lock_init(&zbpg->lock); - atomic_inc(&zcache_zbud_curr_raw_pages); - INIT_LIST_HEAD(&zbpg->bud_list); - SET_SENTINEL(zbpg, ZBPG); - zh0->size = 0; zh1->size = 0; - tmem_oid_set_invalid(&zh0->oid); - tmem_oid_set_invalid(&zh1->oid); - } - return zbpg; -} - -static void zbud_free_raw_page(struct zbud_page *zbpg) -{ - struct zbud_hdr *zh0 = &zbpg->buddy[0], *zh1 = &zbpg->buddy[1]; - - ASSERT_SENTINEL(zbpg, ZBPG); - BUG_ON(!list_empty(&zbpg->bud_list)); - ASSERT_SPINLOCK(&zbpg->lock); - BUG_ON(zh0->size != 0 || tmem_oid_valid(&zh0->oid)); - BUG_ON(zh1->size != 0 || tmem_oid_valid(&zh1->oid)); - INVERT_SENTINEL(zbpg, ZBPG); - spin_unlock(&zbpg->lock); - atomic_dec(&zcache_zbud_curr_raw_pages); - zcache_free_page(zbpg); -} - -/* - * core zbud handling routines - */ - -static unsigned zbud_free(struct zbud_hdr *zh) -{ - unsigned size; - - ASSERT_SENTINEL(zh, ZBH); - BUG_ON(!tmem_oid_valid(&zh->oid)); - size = zh->size; - BUG_ON(zh->size == 0 || zh->size > zbud_max_buddy_size()); - zh->size = 0; - tmem_oid_set_invalid(&zh->oid); - INVERT_SENTINEL(zh, ZBH); - zcache_zbud_curr_zbytes -= size; - atomic_dec(&zcache_zbud_curr_zpages); - return size; -} - -static void zbud_free_and_delist(struct zbud_hdr *zh) -{ - unsigned chunks; - struct zbud_hdr *zh_other; - unsigned budnum = zbud_budnum(zh), size; - struct zbud_page *zbpg = - container_of(zh, struct zbud_page, buddy[budnum]); - - /* FIXME, should be BUG_ON, pool destruction path doesn't disable - * interrupts tmem_destroy_pool()->tmem_pampd_destroy_all_in_obj()-> - * tmem_objnode_node_destroy()-> zcache_pampd_free() */ - WARN_ON(!irqs_disabled()); - spin_lock(&zbpg->lock); - if (list_empty(&zbpg->bud_list)) { - /* ignore zombie page... see zbud_evict_pages() */ - spin_unlock(&zbpg->lock); - return; - } - size = zbud_free(zh); - ASSERT_SPINLOCK(&zbpg->lock); - zh_other = &zbpg->buddy[(budnum == 0) ? 1 : 0]; - if (zh_other->size == 0) { /* was unbuddied: unlist and free */ - chunks = zbud_size_to_chunks(size) ; - spin_lock(&zbud_budlists_spinlock); - BUG_ON(list_empty(&zbud_unbuddied[chunks].list)); - list_del_init(&zbpg->bud_list); - zbud_unbuddied[chunks].count--; - spin_unlock(&zbud_budlists_spinlock); - zbud_free_raw_page(zbpg); - } else { /* was buddied: move remaining buddy to unbuddied list */ - chunks = zbud_size_to_chunks(zh_other->size) ; - spin_lock(&zbud_budlists_spinlock); - list_del_init(&zbpg->bud_list); - zcache_zbud_buddied_count--; - list_add_tail(&zbpg->bud_list, &zbud_unbuddied[chunks].list); - zbud_unbuddied[chunks].count++; - spin_unlock(&zbud_budlists_spinlock); - spin_unlock(&zbpg->lock); - } -} - -static struct zbud_hdr *zbud_create(uint16_t client_id, uint16_t pool_id, - struct tmem_oid *oid, - uint32_t index, struct page *page, - void *cdata, unsigned size) -{ - struct zbud_hdr *zh0, *zh1, *zh = NULL; - struct zbud_page *zbpg = NULL, *ztmp; - unsigned nchunks; - char *to; - int i, found_good_buddy = 0; - - nchunks = zbud_size_to_chunks(size) ; - for (i = MAX_CHUNK - nchunks + 1; i > 0; i--) { - spin_lock(&zbud_budlists_spinlock); - if (!list_empty(&zbud_unbuddied[i].list)) { - list_for_each_entry_safe(zbpg, ztmp, - &zbud_unbuddied[i].list, bud_list) { - if (spin_trylock(&zbpg->lock)) { - found_good_buddy = i; - goto found_unbuddied; - } - } - } - spin_unlock(&zbud_budlists_spinlock); - } - /* didn't find a good buddy, try allocating a new page */ - zbpg = zbud_alloc_raw_page(); - if (unlikely(zbpg == NULL)) - goto out; - /* ok, have a page, now compress the data before taking locks */ - spin_lock(&zbud_budlists_spinlock); - spin_lock(&zbpg->lock); - list_add_tail(&zbpg->bud_list, &zbud_unbuddied[nchunks].list); - zbud_unbuddied[nchunks].count++; - zh = &zbpg->buddy[0]; - goto init_zh; - -found_unbuddied: - ASSERT_SPINLOCK(&zbpg->lock); - zh0 = &zbpg->buddy[0]; zh1 = &zbpg->buddy[1]; - BUG_ON(!((zh0->size == 0) ^ (zh1->size == 0))); - if (zh0->size != 0) { /* buddy0 in use, buddy1 is vacant */ - ASSERT_SENTINEL(zh0, ZBH); - zh = zh1; - } else if (zh1->size != 0) { /* buddy1 in use, buddy0 is vacant */ - ASSERT_SENTINEL(zh1, ZBH); - zh = zh0; - } else - BUG(); - list_del_init(&zbpg->bud_list); - zbud_unbuddied[found_good_buddy].count--; - list_add_tail(&zbpg->bud_list, &zbud_buddied_list); - zcache_zbud_buddied_count++; - -init_zh: - SET_SENTINEL(zh, ZBH); - zh->size = size; - zh->index = index; - zh->oid = *oid; - zh->pool_id = pool_id; - zh->client_id = client_id; - to = zbud_data(zh, size); - memcpy(to, cdata, size); - spin_unlock(&zbpg->lock); - spin_unlock(&zbud_budlists_spinlock); - zbud_cumul_chunk_counts[nchunks]++; - atomic_inc(&zcache_zbud_curr_zpages); - zcache_zbud_cumul_zpages++; - zcache_zbud_curr_zbytes += size; - zcache_zbud_cumul_zbytes += size; -out: - return zh; -} - -static int zbud_decompress(struct page *page, struct zbud_hdr *zh) -{ - struct zbud_page *zbpg; - unsigned budnum = zbud_budnum(zh); - size_t out_len = PAGE_SIZE; - char *to_va, *from_va; - unsigned size; - int ret = 0; - - zbpg = container_of(zh, struct zbud_page, buddy[budnum]); - spin_lock(&zbpg->lock); - if (list_empty(&zbpg->bud_list)) { - /* ignore zombie page... see zbud_evict_pages() */ - ret = -EINVAL; - goto out; - } - ASSERT_SENTINEL(zh, ZBH); - BUG_ON(zh->size == 0 || zh->size > zbud_max_buddy_size()); - to_va = kmap_atomic(page); - size = zh->size; - from_va = zbud_data(zh, size); - ret = lzo1x_decompress_safe(from_va, size, to_va, &out_len); - BUG_ON(ret != LZO_E_OK); - BUG_ON(out_len != PAGE_SIZE); - kunmap_atomic(to_va); -out: - spin_unlock(&zbpg->lock); - return ret; -} - -/* - * The following routines handle shrinking of ephemeral pages by evicting - * pages "least valuable" first. - */ - -static unsigned long zcache_evicted_raw_pages; -static unsigned long zcache_evicted_buddied_pages; -static unsigned long zcache_evicted_unbuddied_pages; - -static struct tmem_pool *zcache_get_pool_by_id(uint16_t cli_id, - uint16_t poolid); -static void zcache_put_pool(struct tmem_pool *pool); - -/* - * Flush and free all zbuds in a zbpg, then free the pageframe - */ -static void zbud_evict_zbpg(struct zbud_page *zbpg) -{ - struct zbud_hdr *zh; - int i, j; - uint32_t pool_id[ZBUD_MAX_BUDS], client_id[ZBUD_MAX_BUDS]; - uint32_t index[ZBUD_MAX_BUDS]; - struct tmem_oid oid[ZBUD_MAX_BUDS]; - struct tmem_pool *pool; - unsigned long flags; - - ASSERT_SPINLOCK(&zbpg->lock); - for (i = 0, j = 0; i < ZBUD_MAX_BUDS; i++) { - zh = &zbpg->buddy[i]; - if (zh->size) { - client_id[j] = zh->client_id; - pool_id[j] = zh->pool_id; - oid[j] = zh->oid; - index[j] = zh->index; - j++; - } - } - spin_unlock(&zbpg->lock); - for (i = 0; i < j; i++) { - pool = zcache_get_pool_by_id(client_id[i], pool_id[i]); - BUG_ON(pool == NULL); - local_irq_save(flags); - /* these flushes should dispose of any local storage */ - tmem_flush_page(pool, &oid[i], index[i]); - local_irq_restore(flags); - zcache_put_pool(pool); - } -} - -/* - * Free nr pages. This code is funky because we want to hold the locks - * protecting various lists for as short a time as possible, and in some - * circumstances the list may change asynchronously when the list lock is - * not held. In some cases we also trylock not only to avoid waiting on a - * page in use by another cpu, but also to avoid potential deadlock due to - * lock inversion. - */ -static void zbud_evict_pages(int nr) -{ - struct zbud_page *zbpg; - int i, newly_unused_pages = 0; - - - /* now try freeing unbuddied pages, starting with least space avail */ - for (i = 0; i < MAX_CHUNK; i++) { -retry_unbud_list_i: - spin_lock_bh(&zbud_budlists_spinlock); - if (list_empty(&zbud_unbuddied[i].list)) { - spin_unlock_bh(&zbud_budlists_spinlock); - continue; - } - list_for_each_entry(zbpg, &zbud_unbuddied[i].list, bud_list) { - if (unlikely(!spin_trylock(&zbpg->lock))) - continue; - zbud_unbuddied[i].count--; - spin_unlock(&zbud_budlists_spinlock); - zcache_evicted_unbuddied_pages++; - /* want budlists unlocked when doing zbpg eviction */ - zbud_evict_zbpg(zbpg); - newly_unused_pages++; - local_bh_enable(); - if (--nr <= 0) - goto evict_unused; - goto retry_unbud_list_i; - } - spin_unlock_bh(&zbud_budlists_spinlock); - } - - /* as a last resort, free buddied pages */ -retry_bud_list: - spin_lock_bh(&zbud_budlists_spinlock); - if (list_empty(&zbud_buddied_list)) { - spin_unlock_bh(&zbud_budlists_spinlock); - goto evict_unused; - } - list_for_each_entry(zbpg, &zbud_buddied_list, bud_list) { - if (unlikely(!spin_trylock(&zbpg->lock))) - continue; - zcache_zbud_buddied_count--; - spin_unlock(&zbud_budlists_spinlock); - zcache_evicted_buddied_pages++; - /* want budlists unlocked when doing zbpg eviction */ - zbud_evict_zbpg(zbpg); - newly_unused_pages++; - local_bh_enable(); - if (--nr <= 0) - goto evict_unused; - goto retry_bud_list; - } - spin_unlock_bh(&zbud_budlists_spinlock); - -evict_unused: - return; -} - -static DEFINE_PER_CPU(unsigned char *, zcache_remoteputmem); - -static int zbud_remotify_zbud(struct tmem_xhandle *xh, char *data, - size_t size) -{ - struct tmem_pool *pool; - int i, remotenode, ret = -1; - unsigned char cksum, *p; - unsigned long flags; - - for (p = data, cksum = 0, i = 0; i < size; i++) - cksum += *p; - ret = ramster_remote_put(xh, data, size, true, &remotenode); - if (ret == 0) { - /* data was successfully remoted so change the local version - * to point to the remote node where it landed */ - pool = zcache_get_pool_by_id(LOCAL_CLIENT, xh->pool_id); - BUG_ON(pool == NULL); - local_irq_save(flags); - /* tmem_replace will also free up any local space */ - (void)tmem_replace(pool, &xh->oid, xh->index, - pampd_make_remote(remotenode, size, cksum)); - local_irq_restore(flags); - zcache_put_pool(pool); - ramster_eph_pages_remoted++; - ret = 0; - } else - ramster_eph_pages_remote_failed++; - return ret; -} - -static int zbud_remotify_zbpg(struct zbud_page *zbpg) -{ - struct zbud_hdr *zh1, *zh2 = NULL; - struct tmem_xhandle xh1, xh2 = { 0 }; - char *data1 = NULL, *data2 = NULL; - size_t size1 = 0, size2 = 0; - int ret = 0; - unsigned char *tmpmem = __get_cpu_var(zcache_remoteputmem); - - ASSERT_SPINLOCK(&zbpg->lock); - if (zbpg->buddy[0].size == 0) - zh1 = &zbpg->buddy[1]; - else if (zbpg->buddy[1].size == 0) - zh1 = &zbpg->buddy[0]; - else { - zh1 = &zbpg->buddy[0]; - zh2 = &zbpg->buddy[1]; - } - /* don't remotify pages that are already remotified */ - if (zh1->client_id != LOCAL_CLIENT) - zh1 = NULL; - if ((zh2 != NULL) && (zh2->client_id != LOCAL_CLIENT)) - zh2 = NULL; - - /* copy the data and metadata so can release lock */ - if (zh1 != NULL) { - xh1.client_id = zh1->client_id; - xh1.pool_id = zh1->pool_id; - xh1.oid = zh1->oid; - xh1.index = zh1->index; - size1 = zh1->size; - data1 = zbud_data(zh1, size1); - memcpy(tmpmem, zbud_data(zh1, size1), size1); - data1 = tmpmem; - tmpmem += size1; - } - if (zh2 != NULL) { - xh2.client_id = zh2->client_id; - xh2.pool_id = zh2->pool_id; - xh2.oid = zh2->oid; - xh2.index = zh2->index; - size2 = zh2->size; - memcpy(tmpmem, zbud_data(zh2, size2), size2); - data2 = tmpmem; - } - spin_unlock(&zbpg->lock); - preempt_enable(); - - /* OK, no locks held anymore, remotify one or both zbuds */ - if (zh1 != NULL) - ret = zbud_remotify_zbud(&xh1, data1, size1); - if (zh2 != NULL) - ret |= zbud_remotify_zbud(&xh2, data2, size2); - return ret; -} - -void zbud_remotify_pages(int nr) -{ - struct zbud_page *zbpg; - int i, ret; - - /* - * for now just try remotifying unbuddied pages, starting with - * least space avail - */ - for (i = 0; i < MAX_CHUNK; i++) { -retry_unbud_list_i: - preempt_disable(); /* enable in zbud_remotify_zbpg */ - spin_lock_bh(&zbud_budlists_spinlock); - if (list_empty(&zbud_unbuddied[i].list)) { - spin_unlock_bh(&zbud_budlists_spinlock); - preempt_enable(); - continue; /* next i in for loop */ - } - list_for_each_entry(zbpg, &zbud_unbuddied[i].list, bud_list) { - if (unlikely(!spin_trylock(&zbpg->lock))) - continue; /* next list_for_each_entry */ - zbud_unbuddied[i].count--; - /* want budlists unlocked when doing zbpg remotify */ - spin_unlock_bh(&zbud_budlists_spinlock); - ret = zbud_remotify_zbpg(zbpg); - /* preemption is re-enabled in zbud_remotify_zbpg */ - if (ret == 0) { - if (--nr <= 0) - goto out; - goto retry_unbud_list_i; - } - /* if fail to remotify any page, quit */ - pr_err("TESTING zbud_remotify_pages failed on page," - " trying to re-add\n"); - spin_lock_bh(&zbud_budlists_spinlock); - spin_lock(&zbpg->lock); - list_add_tail(&zbpg->bud_list, &zbud_unbuddied[i].list); - zbud_unbuddied[i].count++; - spin_unlock(&zbpg->lock); - spin_unlock_bh(&zbud_budlists_spinlock); - pr_err("TESTING zbud_remotify_pages failed on page," - " finished re-add\n"); - goto out; - } - spin_unlock_bh(&zbud_budlists_spinlock); - preempt_enable(); - } - -next_buddied_zbpg: - preempt_disable(); /* enable in zbud_remotify_zbpg */ - spin_lock_bh(&zbud_budlists_spinlock); - if (list_empty(&zbud_buddied_list)) - goto unlock_out; - list_for_each_entry(zbpg, &zbud_buddied_list, bud_list) { - if (unlikely(!spin_trylock(&zbpg->lock))) - continue; /* next list_for_each_entry */ - zcache_zbud_buddied_count--; - /* want budlists unlocked when doing zbpg remotify */ - spin_unlock_bh(&zbud_budlists_spinlock); - ret = zbud_remotify_zbpg(zbpg); - /* preemption is re-enabled in zbud_remotify_zbpg */ - if (ret == 0) { - if (--nr <= 0) - goto out; - goto next_buddied_zbpg; - } - /* if fail to remotify any page, quit */ - pr_err("TESTING zbud_remotify_pages failed on BUDDIED page," - " trying to re-add\n"); - spin_lock_bh(&zbud_budlists_spinlock); - spin_lock(&zbpg->lock); - list_add_tail(&zbpg->bud_list, &zbud_buddied_list); - zcache_zbud_buddied_count++; - spin_unlock(&zbpg->lock); - spin_unlock_bh(&zbud_budlists_spinlock); - pr_err("TESTING zbud_remotify_pages failed on BUDDIED page," - " finished re-add\n"); - goto out; - } -unlock_out: - spin_unlock_bh(&zbud_budlists_spinlock); - preempt_enable(); -out: - return; -} - -/* the "flush list" asynchronously collects pages to remotely flush */ -#define FLUSH_ENTIRE_OBJECT ((uint32_t)-1) -static void ramster_flnode_free(struct flushlist_node *, - struct tmem_pool *); - -static void zcache_remote_flush_page(struct flushlist_node *flnode) -{ - struct tmem_xhandle *xh; - int remotenode, ret; - - preempt_disable(); - xh = &flnode->xh; - remotenode = flnode->xh.client_id; - ret = ramster_remote_flush(xh, remotenode); - if (ret >= 0) - ramster_remote_pages_flushed++; - else - ramster_remote_page_flushes_failed++; - preempt_enable_no_resched(); - ramster_flnode_free(flnode, NULL); -} - -static void zcache_remote_flush_object(struct flushlist_node *flnode) -{ - struct tmem_xhandle *xh; - int remotenode, ret; - - preempt_disable(); - xh = &flnode->xh; - remotenode = flnode->xh.client_id; - ret = ramster_remote_flush_object(xh, remotenode); - if (ret >= 0) - ramster_remote_objects_flushed++; - else - ramster_remote_object_flushes_failed++; - preempt_enable_no_resched(); - ramster_flnode_free(flnode, NULL); -} - -static void zcache_remote_eph_put(struct zbud_hdr *zbud) -{ - /* FIXME */ -} - -static void zcache_remote_pers_put(struct zv_hdr *zv) -{ - struct tmem_xhandle xh; - uint16_t size; - bool ephemeral; - int remotenode, ret = -1; - char *data; - struct tmem_pool *pool; - unsigned long flags; - unsigned char cksum; - char *p; - int i; - unsigned char *tmpmem = __get_cpu_var(zcache_remoteputmem); - - ASSERT_SENTINEL(zv, ZVH); - BUG_ON(zv->client_id != LOCAL_CLIENT); - local_bh_disable(); - xh.client_id = zv->client_id; - xh.pool_id = zv->pool_id; - xh.oid = zv->oid; - xh.index = zv->index; - size = xv_get_object_size(zv) - sizeof(*zv); - BUG_ON(size == 0 || size > zv_max_page_size); - data = (char *)zv + sizeof(*zv); - for (p = data, cksum = 0, i = 0; i < size; i++) - cksum += *p; - memcpy(tmpmem, data, size); - data = tmpmem; - pool = zcache_get_pool_by_id(zv->client_id, zv->pool_id); - ephemeral = is_ephemeral(pool); - zcache_put_pool(pool); - /* now OK to release lock set in caller */ - spin_unlock(&zcache_rem_op_list_lock); - local_bh_enable(); - preempt_disable(); - ret = ramster_remote_put(&xh, data, size, ephemeral, &remotenode); - preempt_enable_no_resched(); - if (ret != 0) { - /* - * This is some form of a memory leak... if the remote put - * fails, there will never be another attempt to remotify - * this page. But since we've dropped the zv pointer, - * the page may have been freed or the data replaced - * so we can't just "put it back" in the remote op list. - * Even if we could, not sure where to put it in the list - * because there may be flushes that must be strictly - * ordered vs the put. So leave this as a FIXME for now. - * But count them so we know if it becomes a problem. - */ - ramster_pers_pages_remote_failed++; - goto out; - } else - atomic_inc(&ramster_remote_pers_pages); - ramster_pers_pages_remoted++; - /* - * data was successfully remoted so change the local version to - * point to the remote node where it landed - */ - local_bh_disable(); - pool = zcache_get_pool_by_id(LOCAL_CLIENT, xh.pool_id); - local_irq_save(flags); - (void)tmem_replace(pool, &xh.oid, xh.index, - pampd_make_remote(remotenode, size, cksum)); - local_irq_restore(flags); - zcache_put_pool(pool); - local_bh_enable(); -out: - return; -} - -static void zcache_do_remotify_ops(int nr) -{ - struct ramster_remotify_hdr *rem_op; - union remotify_list_node *u; - - while (1) { - if (!nr) - goto out; - spin_lock(&zcache_rem_op_list_lock); - if (list_empty(&zcache_rem_op_list)) { - spin_unlock(&zcache_rem_op_list_lock); - goto out; - } - rem_op = list_first_entry(&zcache_rem_op_list, - struct ramster_remotify_hdr, list); - list_del_init(&rem_op->list); - if (rem_op->op != RAMSTER_REMOTIFY_PERS_PUT) - spin_unlock(&zcache_rem_op_list_lock); - u = (union remotify_list_node *)rem_op; - switch (rem_op->op) { - case RAMSTER_REMOTIFY_EPH_PUT: -BUG(); - zcache_remote_eph_put((struct zbud_hdr *)rem_op); - break; - case RAMSTER_REMOTIFY_PERS_PUT: - zcache_remote_pers_put((struct zv_hdr *)rem_op); - break; - case RAMSTER_REMOTIFY_FLUSH_PAGE: - zcache_remote_flush_page((struct flushlist_node *)u); - break; - case RAMSTER_REMOTIFY_FLUSH_OBJ: - zcache_remote_flush_object((struct flushlist_node *)u); - break; - default: - BUG(); - } - } -out: - return; -} - -/* - * Communicate interface revision with userspace - */ -#include "cluster/ramster_nodemanager.h" -static unsigned long ramster_interface_revision = R2NM_API_VERSION; - -/* - * For now, just push over a few pages every few seconds to - * ensure that it basically works - */ -static struct workqueue_struct *ramster_remotify_workqueue; -static void ramster_remotify_process(struct work_struct *work); -static DECLARE_DELAYED_WORK(ramster_remotify_worker, - ramster_remotify_process); - -static void ramster_remotify_queue_delayed_work(unsigned long delay) -{ - if (!queue_delayed_work(ramster_remotify_workqueue, - &ramster_remotify_worker, delay)) - pr_err("ramster_remotify: bad workqueue\n"); -} - - -static int use_frontswap; -static int use_cleancache; -static int ramster_remote_target_nodenum = -1; -static void ramster_remotify_process(struct work_struct *work) -{ - static bool remotify_in_progress; - - BUG_ON(irqs_disabled()); - if (remotify_in_progress) - ramster_remotify_queue_delayed_work(HZ); - else if (ramster_remote_target_nodenum != -1) { - remotify_in_progress = true; -#ifdef CONFIG_CLEANCACHE - if (use_cleancache && ramster_eph_remotify_enable) - zbud_remotify_pages(5000); /* FIXME is this a good number? */ -#endif -#ifdef CONFIG_FRONTSWAP - if (use_frontswap && ramster_pers_remotify_enable) - zcache_do_remotify_ops(500); /* FIXME is this a good number? */ -#endif - remotify_in_progress = false; - ramster_remotify_queue_delayed_work(HZ); - } -} - -static void ramster_remotify_init(void) -{ - unsigned long n = 60UL; - ramster_remotify_workqueue = - create_singlethread_workqueue("ramster_remotify"); - ramster_remotify_queue_delayed_work(n * HZ); -} - - -static void zbud_init(void) -{ - int i; - - INIT_LIST_HEAD(&zbud_buddied_list); - zcache_zbud_buddied_count = 0; - for (i = 0; i < NCHUNKS; i++) { - INIT_LIST_HEAD(&zbud_unbuddied[i].list); - zbud_unbuddied[i].count = 0; - } -} - -#ifdef CONFIG_SYSFS -/* - * These sysfs routines show a nice distribution of how many zbpg's are - * currently (and have ever been placed) in each unbuddied list. It's fun - * to watch but can probably go away before final merge. - */ -static int zbud_show_unbuddied_list_counts(char *buf) -{ - int i; - char *p = buf; - - for (i = 0; i < NCHUNKS; i++) - p += sprintf(p, "%u ", zbud_unbuddied[i].count); - return p - buf; -} - -static int zbud_show_cumul_chunk_counts(char *buf) -{ - unsigned long i, chunks = 0, total_chunks = 0, sum_total_chunks = 0; - unsigned long total_chunks_lte_21 = 0, total_chunks_lte_32 = 0; - unsigned long total_chunks_lte_42 = 0; - char *p = buf; - - for (i = 0; i < NCHUNKS; i++) { - p += sprintf(p, "%lu ", zbud_cumul_chunk_counts[i]); - chunks += zbud_cumul_chunk_counts[i]; - total_chunks += zbud_cumul_chunk_counts[i]; - sum_total_chunks += i * zbud_cumul_chunk_counts[i]; - if (i == 21) - total_chunks_lte_21 = total_chunks; - if (i == 32) - total_chunks_lte_32 = total_chunks; - if (i == 42) - total_chunks_lte_42 = total_chunks; - } - p += sprintf(p, "<=21:%lu <=32:%lu <=42:%lu, mean:%lu\n", - total_chunks_lte_21, total_chunks_lte_32, total_chunks_lte_42, - chunks == 0 ? 0 : sum_total_chunks / chunks); - return p - buf; -} -#endif - -/********** - * This "zv" PAM implementation combines the TLSF-based xvMalloc - * with lzo1x compression to maximize the amount of data that can - * be packed into a physical page. - * - * Zv represents a PAM page with the index and object (plus a "size" value - * necessary for decompression) immediately preceding the compressed data. - */ - -/* rudimentary policy limits */ -/* total number of persistent pages may not exceed this percentage */ -static unsigned int zv_page_count_policy_percent = 75; -/* - * byte count defining poor compression; pages with greater zsize will be - * rejected - */ -static unsigned int zv_max_zsize = (PAGE_SIZE / 8) * 7; -/* - * byte count defining poor *mean* compression; pages with greater zsize - * will be rejected until sufficient better-compressed pages are accepted - * driving the mean below this threshold - */ -static unsigned int zv_max_mean_zsize = (PAGE_SIZE / 8) * 5; - -static atomic_t zv_curr_dist_counts[NCHUNKS]; -static atomic_t zv_cumul_dist_counts[NCHUNKS]; - - -static struct zv_hdr *zv_create(struct zcache_client *cli, uint32_t pool_id, - struct tmem_oid *oid, uint32_t index, - void *cdata, unsigned clen) -{ - struct page *page; - struct zv_hdr *zv = NULL; - uint32_t offset; - int alloc_size = clen + sizeof(struct zv_hdr); - int chunks = (alloc_size + (CHUNK_SIZE - 1)) >> CHUNK_SHIFT; - int ret; - - BUG_ON(!irqs_disabled()); - BUG_ON(chunks >= NCHUNKS); - ret = xv_malloc(cli->xvpool, clen + sizeof(struct zv_hdr), - &page, &offset, ZCACHE_GFP_MASK); - if (unlikely(ret)) - goto out; - atomic_inc(&zv_curr_dist_counts[chunks]); - atomic_inc(&zv_cumul_dist_counts[chunks]); - zv = kmap_atomic(page) + offset; - zv->index = index; - zv->oid = *oid; - zv->pool_id = pool_id; - SET_SENTINEL(zv, ZVH); - INIT_LIST_HEAD(&zv->rem_op.list); - zv->client_id = get_client_id_from_client(cli); - zv->rem_op.op = RAMSTER_REMOTIFY_PERS_PUT; - if (zv->client_id == LOCAL_CLIENT) { - spin_lock(&zcache_rem_op_list_lock); - list_add_tail(&zv->rem_op.list, &zcache_rem_op_list); - spin_unlock(&zcache_rem_op_list_lock); - } - memcpy((char *)zv + sizeof(struct zv_hdr), cdata, clen); - kunmap_atomic(zv); -out: - return zv; -} - -/* similar to zv_create, but just reserve space, no data yet */ -static struct zv_hdr *zv_alloc(struct tmem_pool *pool, - struct tmem_oid *oid, uint32_t index, - unsigned clen) -{ - struct zcache_client *cli = pool->client; - struct page *page; - struct zv_hdr *zv = NULL; - uint32_t offset; - int ret; - - BUG_ON(!irqs_disabled()); - BUG_ON(!is_local_client(pool->client)); - ret = xv_malloc(cli->xvpool, clen + sizeof(struct zv_hdr), - &page, &offset, ZCACHE_GFP_MASK); - if (unlikely(ret)) - goto out; - zv = kmap_atomic(page) + offset; - SET_SENTINEL(zv, ZVH); - INIT_LIST_HEAD(&zv->rem_op.list); - zv->client_id = LOCAL_CLIENT; - zv->rem_op.op = RAMSTER_INTRANSIT_PERS; - zv->index = index; - zv->oid = *oid; - zv->pool_id = pool->pool_id; - kunmap_atomic(zv); -out: - return zv; -} - -static void zv_free(struct xv_pool *xvpool, struct zv_hdr *zv) -{ - unsigned long flags; - struct page *page; - uint32_t offset; - uint16_t size = xv_get_object_size(zv); - int chunks = (size + (CHUNK_SIZE - 1)) >> CHUNK_SHIFT; - - ASSERT_SENTINEL(zv, ZVH); - BUG_ON(chunks >= NCHUNKS); - atomic_dec(&zv_curr_dist_counts[chunks]); - size -= sizeof(*zv); - spin_lock(&zcache_rem_op_list_lock); - size = xv_get_object_size(zv) - sizeof(*zv); - BUG_ON(size == 0); - INVERT_SENTINEL(zv, ZVH); - if (!list_empty(&zv->rem_op.list)) - list_del_init(&zv->rem_op.list); - spin_unlock(&zcache_rem_op_list_lock); - page = virt_to_page(zv); - offset = (unsigned long)zv & ~PAGE_MASK; - local_irq_save(flags); - xv_free(xvpool, page, offset); - local_irq_restore(flags); -} - -static void zv_decompress(struct page *page, struct zv_hdr *zv) -{ - size_t clen = PAGE_SIZE; - char *to_va; - unsigned size; - int ret; - - ASSERT_SENTINEL(zv, ZVH); - size = xv_get_object_size(zv) - sizeof(*zv); - BUG_ON(size == 0); - to_va = kmap_atomic(page); - ret = lzo1x_decompress_safe((char *)zv + sizeof(*zv), - size, to_va, &clen); - kunmap_atomic(to_va); - BUG_ON(ret != LZO_E_OK); - BUG_ON(clen != PAGE_SIZE); -} - -static void zv_copy_from_pampd(char *data, size_t *bufsize, struct zv_hdr *zv) -{ - unsigned size; - - ASSERT_SENTINEL(zv, ZVH); - size = xv_get_object_size(zv) - sizeof(*zv); - BUG_ON(size == 0 || size > zv_max_page_size); - BUG_ON(size > *bufsize); - memcpy(data, (char *)zv + sizeof(*zv), size); - *bufsize = size; -} - -static void zv_copy_to_pampd(struct zv_hdr *zv, char *data, size_t size) -{ - unsigned zv_size; - - ASSERT_SENTINEL(zv, ZVH); - zv_size = xv_get_object_size(zv) - sizeof(*zv); - BUG_ON(zv_size != size); - BUG_ON(zv_size == 0 || zv_size > zv_max_page_size); - memcpy((char *)zv + sizeof(*zv), data, size); -} - -#ifdef CONFIG_SYSFS -/* - * show a distribution of compression stats for zv pages. - */ - -static int zv_curr_dist_counts_show(char *buf) -{ - unsigned long i, n, chunks = 0, sum_total_chunks = 0; - char *p = buf; - - for (i = 0; i < NCHUNKS; i++) { - n = atomic_read(&zv_curr_dist_counts[i]); - p += sprintf(p, "%lu ", n); - chunks += n; - sum_total_chunks += i * n; - } - p += sprintf(p, "mean:%lu\n", - chunks == 0 ? 0 : sum_total_chunks / chunks); - return p - buf; -} - -static int zv_cumul_dist_counts_show(char *buf) -{ - unsigned long i, n, chunks = 0, sum_total_chunks = 0; - char *p = buf; - - for (i = 0; i < NCHUNKS; i++) { - n = atomic_read(&zv_cumul_dist_counts[i]); - p += sprintf(p, "%lu ", n); - chunks += n; - sum_total_chunks += i * n; - } - p += sprintf(p, "mean:%lu\n", - chunks == 0 ? 0 : sum_total_chunks / chunks); - return p - buf; -} - -/* - * setting zv_max_zsize via sysfs causes all persistent (e.g. swap) - * pages that don't compress to less than this value (including metadata - * overhead) to be rejected. We don't allow the value to get too close - * to PAGE_SIZE. - */ -static ssize_t zv_max_zsize_show(struct kobject *kobj, - struct kobj_attribute *attr, - char *buf) -{ - return sprintf(buf, "%u\n", zv_max_zsize); -} - -static ssize_t zv_max_zsize_store(struct kobject *kobj, - struct kobj_attribute *attr, - const char *buf, size_t count) -{ - unsigned long val; - int err; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - err = kstrtoul(buf, 10, &val); - if (err || (val == 0) || (val > (PAGE_SIZE / 8) * 7)) - return -EINVAL; - zv_max_zsize = val; - return count; -} - -/* - * setting zv_max_mean_zsize via sysfs causes all persistent (e.g. swap) - * pages that don't compress to less than this value (including metadata - * overhead) to be rejected UNLESS the mean compression is also smaller - * than this value. In other words, we are load-balancing-by-zsize the - * accepted pages. Again, we don't allow the value to get too close - * to PAGE_SIZE. - */ -static ssize_t zv_max_mean_zsize_show(struct kobject *kobj, - struct kobj_attribute *attr, - char *buf) -{ - return sprintf(buf, "%u\n", zv_max_mean_zsize); -} - -static ssize_t zv_max_mean_zsize_store(struct kobject *kobj, - struct kobj_attribute *attr, - const char *buf, size_t count) -{ - unsigned long val; - int err; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - err = kstrtoul(buf, 10, &val); - if (err || (val == 0) || (val > (PAGE_SIZE / 8) * 7)) - return -EINVAL; - zv_max_mean_zsize = val; - return count; -} - -/* - * setting zv_page_count_policy_percent via sysfs sets an upper bound of - * persistent (e.g. swap) pages that will be retained according to: - * (zv_page_count_policy_percent * totalram_pages) / 100) - * when that limit is reached, further puts will be rejected (until - * some pages have been flushed). Note that, due to compression, - * this number may exceed 100; it defaults to 75 and we set an - * arbitrary limit of 150. A poor choice will almost certainly result - * in OOM's, so this value should only be changed prudently. - */ -static ssize_t zv_page_count_policy_percent_show(struct kobject *kobj, - struct kobj_attribute *attr, - char *buf) -{ - return sprintf(buf, "%u\n", zv_page_count_policy_percent); -} - -static ssize_t zv_page_count_policy_percent_store(struct kobject *kobj, - struct kobj_attribute *attr, - const char *buf, size_t count) -{ - unsigned long val; - int err; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - err = kstrtoul(buf, 10, &val); - if (err || (val == 0) || (val > 150)) - return -EINVAL; - zv_page_count_policy_percent = val; - return count; -} - -static struct kobj_attribute zcache_zv_max_zsize_attr = { - .attr = { .name = "zv_max_zsize", .mode = 0644 }, - .show = zv_max_zsize_show, - .store = zv_max_zsize_store, -}; - -static struct kobj_attribute zcache_zv_max_mean_zsize_attr = { - .attr = { .name = "zv_max_mean_zsize", .mode = 0644 }, - .show = zv_max_mean_zsize_show, - .store = zv_max_mean_zsize_store, -}; - -static struct kobj_attribute zcache_zv_page_count_policy_percent_attr = { - .attr = { .name = "zv_page_count_policy_percent", - .mode = 0644 }, - .show = zv_page_count_policy_percent_show, - .store = zv_page_count_policy_percent_store, -}; -#endif - -/* - * zcache core code starts here - */ - -/* useful stats not collected by cleancache or frontswap */ -static unsigned long zcache_flush_total; -static unsigned long zcache_flush_found; -static unsigned long zcache_flobj_total; -static unsigned long zcache_flobj_found; -static unsigned long zcache_failed_eph_puts; -static unsigned long zcache_nonactive_puts; -static unsigned long zcache_failed_pers_puts; - -/* - * Tmem operations assume the poolid implies the invoking client. - * Zcache only has one client (the kernel itself): LOCAL_CLIENT. - * RAMster has each client numbered by cluster node, and a KVM version - * of zcache would have one client per guest and each client might - * have a poolid==N. - */ -static struct tmem_pool *zcache_get_pool_by_id(uint16_t cli_id, uint16_t poolid) -{ - struct tmem_pool *pool = NULL; - struct zcache_client *cli = NULL; - - if (cli_id == LOCAL_CLIENT) - cli = &zcache_host; - else { - if (cli_id >= MAX_CLIENTS) - goto out; - cli = &zcache_clients[cli_id]; - if (cli == NULL) - goto out; - atomic_inc(&cli->refcount); - } - if (poolid < MAX_POOLS_PER_CLIENT) { - pool = cli->tmem_pools[poolid]; - if (pool != NULL) - atomic_inc(&pool->refcount); - } -out: - return pool; -} - -static void zcache_put_pool(struct tmem_pool *pool) -{ - struct zcache_client *cli = NULL; - - if (pool == NULL) - BUG(); - cli = pool->client; - atomic_dec(&pool->refcount); - atomic_dec(&cli->refcount); -} - -int zcache_new_client(uint16_t cli_id) -{ - struct zcache_client *cli = NULL; - int ret = -1; - - if (cli_id == LOCAL_CLIENT) - cli = &zcache_host; - else if ((unsigned int)cli_id < MAX_CLIENTS) - cli = &zcache_clients[cli_id]; - if (cli == NULL) - goto out; - if (cli->allocated) - goto out; - cli->allocated = 1; -#ifdef CONFIG_FRONTSWAP - cli->xvpool = xv_create_pool(); - if (cli->xvpool == NULL) - goto out; -#endif - ret = 0; -out: - return ret; -} - -/* counters for debugging */ -static unsigned long zcache_failed_get_free_pages; -static unsigned long zcache_failed_alloc; -static unsigned long zcache_put_to_flush; - -/* - * for now, used named slabs so can easily track usage; later can - * either just use kmalloc, or perhaps add a slab-like allocator - * to more carefully manage total memory utilization - */ -static struct kmem_cache *zcache_objnode_cache; -static struct kmem_cache *zcache_obj_cache; -static struct kmem_cache *ramster_flnode_cache; -static atomic_t zcache_curr_obj_count = ATOMIC_INIT(0); -static unsigned long zcache_curr_obj_count_max; -static atomic_t zcache_curr_objnode_count = ATOMIC_INIT(0); -static unsigned long zcache_curr_objnode_count_max; - -/* - * to avoid memory allocation recursion (e.g. due to direct reclaim), we - * preload all necessary data structures so the hostops callbacks never - * actually do a malloc - */ -struct zcache_preload { - void *page; - struct tmem_obj *obj; - int nr; - struct tmem_objnode *objnodes[OBJNODE_TREE_MAX_PATH]; - struct flushlist_node *flnode; -}; -static DEFINE_PER_CPU(struct zcache_preload, zcache_preloads) = { 0, }; - -static int zcache_do_preload(struct tmem_pool *pool) -{ - struct zcache_preload *kp; - struct tmem_objnode *objnode; - struct tmem_obj *obj; - struct flushlist_node *flnode; - void *page; - int ret = -ENOMEM; - - if (unlikely(zcache_objnode_cache == NULL)) - goto out; - if (unlikely(zcache_obj_cache == NULL)) - goto out; - preempt_disable(); - kp = &__get_cpu_var(zcache_preloads); - while (kp->nr < ARRAY_SIZE(kp->objnodes)) { - preempt_enable_no_resched(); - objnode = kmem_cache_alloc(zcache_objnode_cache, - ZCACHE_GFP_MASK); - if (unlikely(objnode == NULL)) { - zcache_failed_alloc++; - goto out; - } - preempt_disable(); - kp = &__get_cpu_var(zcache_preloads); - if (kp->nr < ARRAY_SIZE(kp->objnodes)) - kp->objnodes[kp->nr++] = objnode; - else - kmem_cache_free(zcache_objnode_cache, objnode); - } - preempt_enable_no_resched(); - obj = kmem_cache_alloc(zcache_obj_cache, ZCACHE_GFP_MASK); - if (unlikely(obj == NULL)) { - zcache_failed_alloc++; - goto out; - } - flnode = kmem_cache_alloc(ramster_flnode_cache, ZCACHE_GFP_MASK); - if (unlikely(flnode == NULL)) { - zcache_failed_alloc++; - goto out; - } - if (is_ephemeral(pool)) { - page = (void *)__get_free_page(ZCACHE_GFP_MASK); - if (unlikely(page == NULL)) { - zcache_failed_get_free_pages++; - kmem_cache_free(zcache_obj_cache, obj); - kmem_cache_free(ramster_flnode_cache, flnode); - goto out; - } - } - preempt_disable(); - kp = &__get_cpu_var(zcache_preloads); - if (kp->obj == NULL) - kp->obj = obj; - else - kmem_cache_free(zcache_obj_cache, obj); - if (kp->flnode == NULL) - kp->flnode = flnode; - else - kmem_cache_free(ramster_flnode_cache, flnode); - if (is_ephemeral(pool)) { - if (kp->page == NULL) - kp->page = page; - else - free_page((unsigned long)page); - } - ret = 0; -out: - return ret; -} - -static int ramster_do_preload_flnode_only(struct tmem_pool *pool) -{ - struct zcache_preload *kp; - struct flushlist_node *flnode; - int ret = -ENOMEM; - - BUG_ON(!irqs_disabled()); - if (unlikely(ramster_flnode_cache == NULL)) - BUG(); - kp = &__get_cpu_var(zcache_preloads); - flnode = kmem_cache_alloc(ramster_flnode_cache, GFP_ATOMIC); - if (unlikely(flnode == NULL) && kp->flnode == NULL) - BUG(); /* FIXME handle more gracefully, but how??? */ - else if (kp->flnode == NULL) - kp->flnode = flnode; - else - kmem_cache_free(ramster_flnode_cache, flnode); - return ret; -} - -static void *zcache_get_free_page(void) -{ - struct zcache_preload *kp; - void *page; - - kp = &__get_cpu_var(zcache_preloads); - page = kp->page; - BUG_ON(page == NULL); - kp->page = NULL; - return page; -} - -static void zcache_free_page(void *p) -{ - free_page((unsigned long)p); -} - -/* - * zcache implementation for tmem host ops - */ - -static struct tmem_objnode *zcache_objnode_alloc(struct tmem_pool *pool) -{ - struct tmem_objnode *objnode = NULL; - unsigned long count; - struct zcache_preload *kp; - - kp = &__get_cpu_var(zcache_preloads); - if (kp->nr <= 0) - goto out; - objnode = kp->objnodes[kp->nr - 1]; - BUG_ON(objnode == NULL); - kp->objnodes[kp->nr - 1] = NULL; - kp->nr--; - count = atomic_inc_return(&zcache_curr_objnode_count); - if (count > zcache_curr_objnode_count_max) - zcache_curr_objnode_count_max = count; -out: - return objnode; -} - -static void zcache_objnode_free(struct tmem_objnode *objnode, - struct tmem_pool *pool) -{ - atomic_dec(&zcache_curr_objnode_count); - BUG_ON(atomic_read(&zcache_curr_objnode_count) < 0); - kmem_cache_free(zcache_objnode_cache, objnode); -} - -static struct tmem_obj *zcache_obj_alloc(struct tmem_pool *pool) -{ - struct tmem_obj *obj = NULL; - unsigned long count; - struct zcache_preload *kp; - - kp = &__get_cpu_var(zcache_preloads); - obj = kp->obj; - BUG_ON(obj == NULL); - kp->obj = NULL; - count = atomic_inc_return(&zcache_curr_obj_count); - if (count > zcache_curr_obj_count_max) - zcache_curr_obj_count_max = count; - return obj; -} - -static void zcache_obj_free(struct tmem_obj *obj, struct tmem_pool *pool) -{ - atomic_dec(&zcache_curr_obj_count); - BUG_ON(atomic_read(&zcache_curr_obj_count) < 0); - kmem_cache_free(zcache_obj_cache, obj); -} - -static struct flushlist_node *ramster_flnode_alloc(struct tmem_pool *pool) -{ - struct flushlist_node *flnode = NULL; - struct zcache_preload *kp; - int count; - - kp = &__get_cpu_var(zcache_preloads); - flnode = kp->flnode; - BUG_ON(flnode == NULL); - kp->flnode = NULL; - count = atomic_inc_return(&ramster_curr_flnode_count); - if (count > ramster_curr_flnode_count_max) - ramster_curr_flnode_count_max = count; - return flnode; -} - -static void ramster_flnode_free(struct flushlist_node *flnode, - struct tmem_pool *pool) -{ - atomic_dec(&ramster_curr_flnode_count); - BUG_ON(atomic_read(&ramster_curr_flnode_count) < 0); - kmem_cache_free(ramster_flnode_cache, flnode); -} - -static struct tmem_hostops zcache_hostops = { - .obj_alloc = zcache_obj_alloc, - .obj_free = zcache_obj_free, - .objnode_alloc = zcache_objnode_alloc, - .objnode_free = zcache_objnode_free, -}; - -/* - * zcache implementations for PAM page descriptor ops - */ - - -static inline void dec_and_check(atomic_t *pvar) -{ - atomic_dec(pvar); - /* later when all accounting is fixed, make this a BUG */ - WARN_ON_ONCE(atomic_read(pvar) < 0); -} - -static atomic_t zcache_curr_eph_pampd_count = ATOMIC_INIT(0); -static unsigned long zcache_curr_eph_pampd_count_max; -static atomic_t zcache_curr_pers_pampd_count = ATOMIC_INIT(0); -static unsigned long zcache_curr_pers_pampd_count_max; - -/* forward reference */ -static int zcache_compress(struct page *from, void **out_va, size_t *out_len); - -static int zcache_pampd_eph_create(char *data, size_t size, bool raw, - struct tmem_pool *pool, struct tmem_oid *oid, - uint32_t index, void **pampd) -{ - int ret = -1; - void *cdata = data; - size_t clen = size; - struct zcache_client *cli = pool->client; - uint16_t client_id = get_client_id_from_client(cli); - struct page *page = NULL; - unsigned long count; - - if (!raw) { - page = virt_to_page(data); - ret = zcache_compress(page, &cdata, &clen); - if (ret == 0) - goto out; - if (clen == 0 || clen > zbud_max_buddy_size()) { - zcache_compress_poor++; - goto out; - } - } - *pampd = (void *)zbud_create(client_id, pool->pool_id, oid, - index, page, cdata, clen); - if (*pampd == NULL) { - ret = -ENOMEM; - goto out; - } - ret = 0; - count = atomic_inc_return(&zcache_curr_eph_pampd_count); - if (count > zcache_curr_eph_pampd_count_max) - zcache_curr_eph_pampd_count_max = count; - if (client_id != LOCAL_CLIENT) { - count = atomic_inc_return(&ramster_foreign_eph_pampd_count); - if (count > ramster_foreign_eph_pampd_count_max) - ramster_foreign_eph_pampd_count_max = count; - } -out: - return ret; -} - -static int zcache_pampd_pers_create(char *data, size_t size, bool raw, - struct tmem_pool *pool, struct tmem_oid *oid, - uint32_t index, void **pampd) -{ - int ret = -1; - void *cdata = data; - size_t clen = size; - struct zcache_client *cli = pool->client; - struct page *page; - unsigned long count; - unsigned long zv_mean_zsize; - struct zv_hdr *zv; - long curr_pers_pampd_count; - u64 total_zsize; -#ifdef RAMSTER_TESTING - static bool pampd_neg_warned; -#endif - - curr_pers_pampd_count = atomic_read(&zcache_curr_pers_pampd_count) - - atomic_read(&ramster_remote_pers_pages); -#ifdef RAMSTER_TESTING - /* should always be positive, but warn if accounting is off */ - if (!pampd_neg_warned) { - pr_warn("ramster: bad accounting for curr_pers_pampd_count\n"); - pampd_neg_warned = true; - } -#endif - if (curr_pers_pampd_count > - (zv_page_count_policy_percent * totalram_pages) / 100) { - zcache_policy_percent_exceeded++; - goto out; - } - if (raw) - goto ok_to_create; - page = virt_to_page(data); - if (zcache_compress(page, &cdata, &clen) == 0) - goto out; - /* reject if compression is too poor */ - if (clen > zv_max_zsize) { - zcache_compress_poor++; - goto out; - } - /* reject if mean compression is too poor */ - if ((clen > zv_max_mean_zsize) && (curr_pers_pampd_count > 0)) { - total_zsize = xv_get_total_size_bytes(cli->xvpool); - zv_mean_zsize = div_u64(total_zsize, curr_pers_pampd_count); - if (zv_mean_zsize > zv_max_mean_zsize) { - zcache_mean_compress_poor++; - goto out; - } - } -ok_to_create: - *pampd = (void *)zv_create(cli, pool->pool_id, oid, index, cdata, clen); - if (*pampd == NULL) { - ret = -ENOMEM; - goto out; - } - ret = 0; - count = atomic_inc_return(&zcache_curr_pers_pampd_count); - if (count > zcache_curr_pers_pampd_count_max) - zcache_curr_pers_pampd_count_max = count; - if (is_local_client(cli)) - goto out; - zv = *(struct zv_hdr **)pampd; - count = atomic_inc_return(&ramster_foreign_pers_pampd_count); - if (count > ramster_foreign_pers_pampd_count_max) - ramster_foreign_pers_pampd_count_max = count; -out: - return ret; -} - -static void *zcache_pampd_create(char *data, size_t size, bool raw, int eph, - struct tmem_pool *pool, struct tmem_oid *oid, - uint32_t index) -{ - void *pampd = NULL; - int ret; - bool ephemeral; - - BUG_ON(preemptible()); - ephemeral = (eph == 1) || ((eph == 0) && is_ephemeral(pool)); - if (ephemeral) - ret = zcache_pampd_eph_create(data, size, raw, pool, - oid, index, &pampd); - else - ret = zcache_pampd_pers_create(data, size, raw, pool, - oid, index, &pampd); - /* FIXME add some counters here for failed creates? */ - return pampd; -} - -/* - * fill the pageframe corresponding to the struct page with the data - * from the passed pampd - */ -static int zcache_pampd_get_data(char *data, size_t *bufsize, bool raw, - void *pampd, struct tmem_pool *pool, - struct tmem_oid *oid, uint32_t index) -{ - int ret = 0; - - BUG_ON(preemptible()); - BUG_ON(is_ephemeral(pool)); /* Fix later for shared pools? */ - BUG_ON(pampd_is_remote(pampd)); - if (raw) - zv_copy_from_pampd(data, bufsize, pampd); - else - zv_decompress(virt_to_page(data), pampd); - return ret; -} - -static int zcache_pampd_get_data_and_free(char *data, size_t *bufsize, bool raw, - void *pampd, struct tmem_pool *pool, - struct tmem_oid *oid, uint32_t index) -{ - int ret = 0; - unsigned long flags; - struct zcache_client *cli = pool->client; - - BUG_ON(preemptible()); - BUG_ON(pampd_is_remote(pampd)); - if (is_ephemeral(pool)) { - local_irq_save(flags); - if (raw) - zbud_copy_from_pampd(data, bufsize, pampd); - else - ret = zbud_decompress(virt_to_page(data), pampd); - zbud_free_and_delist((struct zbud_hdr *)pampd); - local_irq_restore(flags); - if (!is_local_client(cli)) - dec_and_check(&ramster_foreign_eph_pampd_count); - dec_and_check(&zcache_curr_eph_pampd_count); - } else { - if (is_local_client(cli)) - BUG(); - if (raw) - zv_copy_from_pampd(data, bufsize, pampd); - else - zv_decompress(virt_to_page(data), pampd); - zv_free(cli->xvpool, pampd); - if (!is_local_client(cli)) - dec_and_check(&ramster_foreign_pers_pampd_count); - dec_and_check(&zcache_curr_pers_pampd_count); - ret = 0; - } - return ret; -} - -static bool zcache_pampd_is_remote(void *pampd) -{ - return pampd_is_remote(pampd); -} - -/* - * free the pampd and remove it from any zcache lists - * pampd must no longer be pointed to from any tmem data structures! - */ -static void zcache_pampd_free(void *pampd, struct tmem_pool *pool, - struct tmem_oid *oid, uint32_t index, bool acct) -{ - struct zcache_client *cli = pool->client; - bool eph = is_ephemeral(pool); - struct zv_hdr *zv; - - BUG_ON(preemptible()); - if (pampd_is_remote(pampd)) { - WARN_ON(acct == false); - if (oid == NULL) { - /* - * a NULL oid means to ignore this pampd free - * as the remote freeing will be handled elsewhere - */ - } else if (eph) { - /* FIXME remote flush optional but probably good idea */ - /* FIXME get these working properly again */ - dec_and_check(&zcache_curr_eph_pampd_count); - } else if (pampd_is_intransit(pampd)) { - /* did a pers remote get_and_free, so just free local */ - pampd = pampd_mask_intransit_and_remote(pampd); - goto local_pers; - } else { - struct flushlist_node *flnode = - ramster_flnode_alloc(pool); - - flnode->xh.client_id = pampd_remote_node(pampd); - flnode->xh.pool_id = pool->pool_id; - flnode->xh.oid = *oid; - flnode->xh.index = index; - flnode->rem_op.op = RAMSTER_REMOTIFY_FLUSH_PAGE; - spin_lock(&zcache_rem_op_list_lock); - list_add(&flnode->rem_op.list, &zcache_rem_op_list); - spin_unlock(&zcache_rem_op_list_lock); - dec_and_check(&zcache_curr_pers_pampd_count); - dec_and_check(&ramster_remote_pers_pages); - } - } else if (eph) { - zbud_free_and_delist((struct zbud_hdr *)pampd); - if (!is_local_client(pool->client)) - dec_and_check(&ramster_foreign_eph_pampd_count); - if (acct) - /* FIXME get these working properly again */ - dec_and_check(&zcache_curr_eph_pampd_count); - } else { -local_pers: - zv = (struct zv_hdr *)pampd; - if (!is_local_client(pool->client)) - dec_and_check(&ramster_foreign_pers_pampd_count); - zv_free(cli->xvpool, zv); - if (acct) - /* FIXME get these working properly again */ - dec_and_check(&zcache_curr_pers_pampd_count); - } -} - -static void zcache_pampd_free_obj(struct tmem_pool *pool, - struct tmem_obj *obj) -{ - struct flushlist_node *flnode; - - BUG_ON(preemptible()); - if (obj->extra == NULL) - return; - BUG_ON(!pampd_is_remote(obj->extra)); - flnode = ramster_flnode_alloc(pool); - flnode->xh.client_id = pampd_remote_node(obj->extra); - flnode->xh.pool_id = pool->pool_id; - flnode->xh.oid = obj->oid; - flnode->xh.index = FLUSH_ENTIRE_OBJECT; - flnode->rem_op.op = RAMSTER_REMOTIFY_FLUSH_OBJ; - spin_lock(&zcache_rem_op_list_lock); - list_add(&flnode->rem_op.list, &zcache_rem_op_list); - spin_unlock(&zcache_rem_op_list_lock); -} - -void zcache_pampd_new_obj(struct tmem_obj *obj) -{ - obj->extra = NULL; -} - -int zcache_pampd_replace_in_obj(void *new_pampd, struct tmem_obj *obj) -{ - int ret = -1; - - if (new_pampd != NULL) { - if (obj->extra == NULL) - obj->extra = new_pampd; - /* enforce that all remote pages in an object reside - * in the same node! */ - else if (pampd_remote_node(new_pampd) != - pampd_remote_node((void *)(obj->extra))) - BUG(); - ret = 0; - } - return ret; -} - -/* - * Called by the message handler after a (still compressed) page has been - * fetched from the remote machine in response to an "is_remote" tmem_get - * or persistent tmem_localify. For a tmem_get, "extra" is the address of - * the page that is to be filled to successfully resolve the tmem_get; for - * a (persistent) tmem_localify, "extra" is NULL (as the data is placed only - * in the local zcache). "data" points to "size" bytes of (compressed) data - * passed in the message. In the case of a persistent remote get, if - * pre-allocation was successful (see zcache_repatriate_preload), the page - * is placed into both local zcache and at "extra". - */ -int zcache_localify(int pool_id, struct tmem_oid *oidp, - uint32_t index, char *data, size_t size, - void *extra) -{ - int ret = -ENOENT; - unsigned long flags; - struct tmem_pool *pool; - bool ephemeral, delete = false; - size_t clen = PAGE_SIZE; - void *pampd, *saved_hb; - struct tmem_obj *obj; - - pool = zcache_get_pool_by_id(LOCAL_CLIENT, pool_id); - if (unlikely(pool == NULL)) - /* pool doesn't exist anymore */ - goto out; - ephemeral = is_ephemeral(pool); - local_irq_save(flags); /* FIXME: maybe only disable softirqs? */ - pampd = tmem_localify_get_pampd(pool, oidp, index, &obj, &saved_hb); - if (pampd == NULL) { - /* hmmm... must have been a flush while waiting */ -#ifdef RAMSTER_TESTING - pr_err("UNTESTED pampd==NULL in zcache_localify\n"); -#endif - if (ephemeral) - ramster_remote_eph_pages_unsucc_get++; - else - ramster_remote_pers_pages_unsucc_get++; - obj = NULL; - goto finish; - } else if (unlikely(!pampd_is_remote(pampd))) { - /* hmmm... must have been a dup put while waiting */ -#ifdef RAMSTER_TESTING - pr_err("UNTESTED dup while waiting in zcache_localify\n"); -#endif - if (ephemeral) - ramster_remote_eph_pages_unsucc_get++; - else - ramster_remote_pers_pages_unsucc_get++; - obj = NULL; - pampd = NULL; - ret = -EEXIST; - goto finish; - } else if (size == 0) { - /* no remote data, delete the local is_remote pampd */ - pampd = NULL; - if (ephemeral) - ramster_remote_eph_pages_unsucc_get++; - else - BUG(); - delete = true; - goto finish; - } - if (!ephemeral && pampd_is_intransit(pampd)) { - /* localify to zcache */ - pampd = pampd_mask_intransit_and_remote(pampd); - zv_copy_to_pampd(pampd, data, size); - } else { - pampd = NULL; - obj = NULL; - } - if (extra != NULL) { - /* decompress direct-to-memory to complete remotify */ - ret = lzo1x_decompress_safe((char *)data, size, - (char *)extra, &clen); - BUG_ON(ret != LZO_E_OK); - BUG_ON(clen != PAGE_SIZE); - } - if (ephemeral) - ramster_remote_eph_pages_succ_get++; - else - ramster_remote_pers_pages_succ_get++; - ret = 0; -finish: - tmem_localify_finish(obj, index, pampd, saved_hb, delete); - zcache_put_pool(pool); - local_irq_restore(flags); -out: - return ret; -} - -/* - * Called on a remote persistent tmem_get to attempt to preallocate - * local storage for the data contained in the remote persistent page. - * If successfully preallocated, returns the pampd, marked as remote and - * in_transit. Else returns NULL. Note that the appropriate tmem data - * structure must be locked. - */ -static void *zcache_pampd_repatriate_preload(void *pampd, - struct tmem_pool *pool, - struct tmem_oid *oid, - uint32_t index, - bool *intransit) -{ - int clen = pampd_remote_size(pampd); - void *ret_pampd = NULL; - unsigned long flags; - - if (!pampd_is_remote(pampd)) - BUG(); - if (is_ephemeral(pool)) - BUG(); - if (pampd_is_intransit(pampd)) { - /* - * to avoid multiple allocations (and maybe a memory leak) - * don't preallocate if already in the process of being - * repatriated - */ - *intransit = true; - goto out; - } - *intransit = false; - local_irq_save(flags); - ret_pampd = (void *)zv_alloc(pool, oid, index, clen); - if (ret_pampd != NULL) { - /* - * a pampd is marked intransit if it is remote and space has - * been allocated for it locally (note, only happens for - * persistent pages, in which case the remote copy is freed) - */ - ret_pampd = pampd_mark_intransit(ret_pampd); - dec_and_check(&ramster_remote_pers_pages); - } else - ramster_pers_pages_remote_nomem++; - local_irq_restore(flags); -out: - return ret_pampd; -} - -/* - * Called on a remote tmem_get to invoke a message to fetch the page. - * Might sleep so no tmem locks can be held. "extra" is passed - * all the way through the round-trip messaging to zcache_localify. - */ -static int zcache_pampd_repatriate(void *fake_pampd, void *real_pampd, - struct tmem_pool *pool, - struct tmem_oid *oid, uint32_t index, - bool free, void *extra) -{ - struct tmem_xhandle xh; - int ret; - - if (pampd_is_intransit(real_pampd)) - /* have local space pre-reserved, so free remote copy */ - free = true; - xh = tmem_xhandle_fill(LOCAL_CLIENT, pool, oid, index); - /* unreliable request/response for now */ - ret = ramster_remote_async_get(&xh, free, - pampd_remote_node(fake_pampd), - pampd_remote_size(fake_pampd), - pampd_remote_cksum(fake_pampd), - extra); -#ifdef RAMSTER_TESTING - if (ret != 0 && ret != -ENOENT) - pr_err("TESTING zcache_pampd_repatriate returns, ret=%d\n", - ret); -#endif - return ret; -} - -static struct tmem_pamops zcache_pamops = { - .create = zcache_pampd_create, - .get_data = zcache_pampd_get_data, - .free = zcache_pampd_free, - .get_data_and_free = zcache_pampd_get_data_and_free, - .free_obj = zcache_pampd_free_obj, - .is_remote = zcache_pampd_is_remote, - .repatriate_preload = zcache_pampd_repatriate_preload, - .repatriate = zcache_pampd_repatriate, - .new_obj = zcache_pampd_new_obj, - .replace_in_obj = zcache_pampd_replace_in_obj, -}; - -/* - * zcache compression/decompression and related per-cpu stuff - */ - -#define LZO_WORKMEM_BYTES LZO1X_1_MEM_COMPRESS -#define LZO_DSTMEM_PAGE_ORDER 1 -static DEFINE_PER_CPU(unsigned char *, zcache_workmem); -static DEFINE_PER_CPU(unsigned char *, zcache_dstmem); - -static int zcache_compress(struct page *from, void **out_va, size_t *out_len) -{ - int ret = 0; - unsigned char *dmem = __get_cpu_var(zcache_dstmem); - unsigned char *wmem = __get_cpu_var(zcache_workmem); - char *from_va; - - BUG_ON(!irqs_disabled()); - if (unlikely(dmem == NULL || wmem == NULL)) - goto out; /* no buffer, so can't compress */ - from_va = kmap_atomic(from); - mb(); - ret = lzo1x_1_compress(from_va, PAGE_SIZE, dmem, out_len, wmem); - BUG_ON(ret != LZO_E_OK); - *out_va = dmem; - kunmap_atomic(from_va); - ret = 1; -out: - return ret; -} - - -static int zcache_cpu_notifier(struct notifier_block *nb, - unsigned long action, void *pcpu) -{ - int cpu = (long)pcpu; - struct zcache_preload *kp; - - switch (action) { - case CPU_UP_PREPARE: - per_cpu(zcache_dstmem, cpu) = (void *)__get_free_pages( - GFP_KERNEL | __GFP_REPEAT, - LZO_DSTMEM_PAGE_ORDER), - per_cpu(zcache_workmem, cpu) = - kzalloc(LZO1X_MEM_COMPRESS, - GFP_KERNEL | __GFP_REPEAT); - per_cpu(zcache_remoteputmem, cpu) = - kzalloc(PAGE_SIZE, GFP_KERNEL | __GFP_REPEAT); - break; - case CPU_DEAD: - case CPU_UP_CANCELED: - kfree(per_cpu(zcache_remoteputmem, cpu)); - per_cpu(zcache_remoteputmem, cpu) = NULL; - free_pages((unsigned long)per_cpu(zcache_dstmem, cpu), - LZO_DSTMEM_PAGE_ORDER); - per_cpu(zcache_dstmem, cpu) = NULL; - kfree(per_cpu(zcache_workmem, cpu)); - per_cpu(zcache_workmem, cpu) = NULL; - kp = &per_cpu(zcache_preloads, cpu); - while (kp->nr) { - kmem_cache_free(zcache_objnode_cache, - kp->objnodes[kp->nr - 1]); - kp->objnodes[kp->nr - 1] = NULL; - kp->nr--; - } - if (kp->obj) { - kmem_cache_free(zcache_obj_cache, kp->obj); - kp->obj = NULL; - } - if (kp->flnode) { - kmem_cache_free(ramster_flnode_cache, kp->flnode); - kp->flnode = NULL; - } - if (kp->page) { - free_page((unsigned long)kp->page); - kp->page = NULL; - } - break; - default: - break; - } - return NOTIFY_OK; -} - -static struct notifier_block zcache_cpu_notifier_block = { - .notifier_call = zcache_cpu_notifier -}; - -#ifdef CONFIG_SYSFS -#define ZCACHE_SYSFS_RO(_name) \ - static ssize_t zcache_##_name##_show(struct kobject *kobj, \ - struct kobj_attribute *attr, char *buf) \ - { \ - return sprintf(buf, "%lu\n", zcache_##_name); \ - } \ - static struct kobj_attribute zcache_##_name##_attr = { \ - .attr = { .name = __stringify(_name), .mode = 0444 }, \ - .show = zcache_##_name##_show, \ - } - -#define ZCACHE_SYSFS_RO_ATOMIC(_name) \ - static ssize_t zcache_##_name##_show(struct kobject *kobj, \ - struct kobj_attribute *attr, char *buf) \ - { \ - return sprintf(buf, "%d\n", atomic_read(&zcache_##_name)); \ - } \ - static struct kobj_attribute zcache_##_name##_attr = { \ - .attr = { .name = __stringify(_name), .mode = 0444 }, \ - .show = zcache_##_name##_show, \ - } - -#define ZCACHE_SYSFS_RO_CUSTOM(_name, _func) \ - static ssize_t zcache_##_name##_show(struct kobject *kobj, \ - struct kobj_attribute *attr, char *buf) \ - { \ - return _func(buf); \ - } \ - static struct kobj_attribute zcache_##_name##_attr = { \ - .attr = { .name = __stringify(_name), .mode = 0444 }, \ - .show = zcache_##_name##_show, \ - } - -ZCACHE_SYSFS_RO(curr_obj_count_max); -ZCACHE_SYSFS_RO(curr_objnode_count_max); -ZCACHE_SYSFS_RO(flush_total); -ZCACHE_SYSFS_RO(flush_found); -ZCACHE_SYSFS_RO(flobj_total); -ZCACHE_SYSFS_RO(flobj_found); -ZCACHE_SYSFS_RO(failed_eph_puts); -ZCACHE_SYSFS_RO(nonactive_puts); -ZCACHE_SYSFS_RO(failed_pers_puts); -ZCACHE_SYSFS_RO(zbud_curr_zbytes); -ZCACHE_SYSFS_RO(zbud_cumul_zpages); -ZCACHE_SYSFS_RO(zbud_cumul_zbytes); -ZCACHE_SYSFS_RO(zbud_buddied_count); -ZCACHE_SYSFS_RO(evicted_raw_pages); -ZCACHE_SYSFS_RO(evicted_unbuddied_pages); -ZCACHE_SYSFS_RO(evicted_buddied_pages); -ZCACHE_SYSFS_RO(failed_get_free_pages); -ZCACHE_SYSFS_RO(failed_alloc); -ZCACHE_SYSFS_RO(put_to_flush); -ZCACHE_SYSFS_RO(compress_poor); -ZCACHE_SYSFS_RO(mean_compress_poor); -ZCACHE_SYSFS_RO(policy_percent_exceeded); -ZCACHE_SYSFS_RO_ATOMIC(zbud_curr_raw_pages); -ZCACHE_SYSFS_RO_ATOMIC(zbud_curr_zpages); -ZCACHE_SYSFS_RO_ATOMIC(curr_obj_count); -ZCACHE_SYSFS_RO_ATOMIC(curr_objnode_count); -ZCACHE_SYSFS_RO_CUSTOM(zbud_unbuddied_list_counts, - zbud_show_unbuddied_list_counts); -ZCACHE_SYSFS_RO_CUSTOM(zbud_cumul_chunk_counts, - zbud_show_cumul_chunk_counts); -ZCACHE_SYSFS_RO_CUSTOM(zv_curr_dist_counts, - zv_curr_dist_counts_show); -ZCACHE_SYSFS_RO_CUSTOM(zv_cumul_dist_counts, - zv_cumul_dist_counts_show); - -static struct attribute *zcache_attrs[] = { - &zcache_curr_obj_count_attr.attr, - &zcache_curr_obj_count_max_attr.attr, - &zcache_curr_objnode_count_attr.attr, - &zcache_curr_objnode_count_max_attr.attr, - &zcache_flush_total_attr.attr, - &zcache_flobj_total_attr.attr, - &zcache_flush_found_attr.attr, - &zcache_flobj_found_attr.attr, - &zcache_failed_eph_puts_attr.attr, - &zcache_nonactive_puts_attr.attr, - &zcache_failed_pers_puts_attr.attr, - &zcache_policy_percent_exceeded_attr.attr, - &zcache_compress_poor_attr.attr, - &zcache_mean_compress_poor_attr.attr, - &zcache_zbud_curr_raw_pages_attr.attr, - &zcache_zbud_curr_zpages_attr.attr, - &zcache_zbud_curr_zbytes_attr.attr, - &zcache_zbud_cumul_zpages_attr.attr, - &zcache_zbud_cumul_zbytes_attr.attr, - &zcache_zbud_buddied_count_attr.attr, - &zcache_evicted_raw_pages_attr.attr, - &zcache_evicted_unbuddied_pages_attr.attr, - &zcache_evicted_buddied_pages_attr.attr, - &zcache_failed_get_free_pages_attr.attr, - &zcache_failed_alloc_attr.attr, - &zcache_put_to_flush_attr.attr, - &zcache_zbud_unbuddied_list_counts_attr.attr, - &zcache_zbud_cumul_chunk_counts_attr.attr, - &zcache_zv_curr_dist_counts_attr.attr, - &zcache_zv_cumul_dist_counts_attr.attr, - &zcache_zv_max_zsize_attr.attr, - &zcache_zv_max_mean_zsize_attr.attr, - &zcache_zv_page_count_policy_percent_attr.attr, - NULL, -}; - -static struct attribute_group zcache_attr_group = { - .attrs = zcache_attrs, - .name = "zcache", -}; - -#define RAMSTER_SYSFS_RO(_name) \ - static ssize_t ramster_##_name##_show(struct kobject *kobj, \ - struct kobj_attribute *attr, char *buf) \ - { \ - return sprintf(buf, "%lu\n", ramster_##_name); \ - } \ - static struct kobj_attribute ramster_##_name##_attr = { \ - .attr = { .name = __stringify(_name), .mode = 0444 }, \ - .show = ramster_##_name##_show, \ - } - -#define RAMSTER_SYSFS_RW(_name) \ - static ssize_t ramster_##_name##_show(struct kobject *kobj, \ - struct kobj_attribute *attr, char *buf) \ - { \ - return sprintf(buf, "%lu\n", ramster_##_name); \ - } \ - static ssize_t ramster_##_name##_store(struct kobject *kobj, \ - struct kobj_attribute *attr, const char *buf, size_t count) \ - { \ - int err; \ - unsigned long enable; \ - err = kstrtoul(buf, 10, &enable); \ - if (err) \ - return -EINVAL; \ - ramster_##_name = enable; \ - return count; \ - } \ - static struct kobj_attribute ramster_##_name##_attr = { \ - .attr = { .name = __stringify(_name), .mode = 0644 }, \ - .show = ramster_##_name##_show, \ - .store = ramster_##_name##_store, \ - } - -#define RAMSTER_SYSFS_RO_ATOMIC(_name) \ - static ssize_t ramster_##_name##_show(struct kobject *kobj, \ - struct kobj_attribute *attr, char *buf) \ - { \ - return sprintf(buf, "%d\n", atomic_read(&ramster_##_name)); \ - } \ - static struct kobj_attribute ramster_##_name##_attr = { \ - .attr = { .name = __stringify(_name), .mode = 0444 }, \ - .show = ramster_##_name##_show, \ - } - -RAMSTER_SYSFS_RO(interface_revision); -RAMSTER_SYSFS_RO_ATOMIC(remote_pers_pages); -RAMSTER_SYSFS_RW(pers_remotify_enable); -RAMSTER_SYSFS_RW(eph_remotify_enable); -RAMSTER_SYSFS_RO(eph_pages_remoted); -RAMSTER_SYSFS_RO(eph_pages_remote_failed); -RAMSTER_SYSFS_RO(pers_pages_remoted); -RAMSTER_SYSFS_RO(pers_pages_remote_failed); -RAMSTER_SYSFS_RO(pers_pages_remote_nomem); -RAMSTER_SYSFS_RO(remote_pages_flushed); -RAMSTER_SYSFS_RO(remote_page_flushes_failed); -RAMSTER_SYSFS_RO(remote_objects_flushed); -RAMSTER_SYSFS_RO(remote_object_flushes_failed); -RAMSTER_SYSFS_RO(remote_eph_pages_succ_get); -RAMSTER_SYSFS_RO(remote_eph_pages_unsucc_get); -RAMSTER_SYSFS_RO(remote_pers_pages_succ_get); -RAMSTER_SYSFS_RO(remote_pers_pages_unsucc_get); -RAMSTER_SYSFS_RO_ATOMIC(foreign_eph_pampd_count); -RAMSTER_SYSFS_RO(foreign_eph_pampd_count_max); -RAMSTER_SYSFS_RO_ATOMIC(foreign_pers_pampd_count); -RAMSTER_SYSFS_RO(foreign_pers_pampd_count_max); -RAMSTER_SYSFS_RO_ATOMIC(curr_flnode_count); -RAMSTER_SYSFS_RO(curr_flnode_count_max); - -#define MANUAL_NODES 8 -static bool ramster_nodes_manual_up[MANUAL_NODES]; -static ssize_t ramster_manual_node_up_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - int i; - char *p = buf; - for (i = 0; i < MANUAL_NODES; i++) - if (ramster_nodes_manual_up[i]) - p += sprintf(p, "%d ", i); - p += sprintf(p, "\n"); - return p - buf; -} - -static ssize_t ramster_manual_node_up_store(struct kobject *kobj, - struct kobj_attribute *attr, const char *buf, size_t count) -{ - int err; - unsigned long node_num; - - err = kstrtoul(buf, 10, &node_num); - if (err) { - pr_err("ramster: bad strtoul?\n"); - return -EINVAL; - } - if (node_num >= MANUAL_NODES) { - pr_err("ramster: bad node_num=%lu?\n", node_num); - return -EINVAL; - } - if (ramster_nodes_manual_up[node_num]) { - pr_err("ramster: node %d already up, ignoring\n", - (int)node_num); - } else { - ramster_nodes_manual_up[node_num] = true; - r2net_hb_node_up_manual((int)node_num); - } - return count; -} - -static struct kobj_attribute ramster_manual_node_up_attr = { - .attr = { .name = "manual_node_up", .mode = 0644 }, - .show = ramster_manual_node_up_show, - .store = ramster_manual_node_up_store, -}; - -static ssize_t ramster_remote_target_nodenum_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - if (ramster_remote_target_nodenum == -1UL) - return sprintf(buf, "unset\n"); - else - return sprintf(buf, "%d\n", ramster_remote_target_nodenum); -} - -static ssize_t ramster_remote_target_nodenum_store(struct kobject *kobj, - struct kobj_attribute *attr, const char *buf, size_t count) -{ - int err; - unsigned long node_num; - - err = kstrtoul(buf, 10, &node_num); - if (err) { - pr_err("ramster: bad strtoul?\n"); - return -EINVAL; - } else if (node_num == -1UL) { - pr_err("ramster: disabling all remotification, " - "data may still reside on remote nodes however\n"); - return -EINVAL; - } else if (node_num >= MANUAL_NODES) { - pr_err("ramster: bad node_num=%lu?\n", node_num); - return -EINVAL; - } else if (!ramster_nodes_manual_up[node_num]) { - pr_err("ramster: node %d not up, ignoring setting " - "of remotification target\n", (int)node_num); - } else if (r2net_remote_target_node_set((int)node_num) >= 0) { - pr_info("ramster: node %d set as remotification target\n", - (int)node_num); - ramster_remote_target_nodenum = (int)node_num; - } else { - pr_err("ramster: bad num to node node_num=%d?\n", - (int)node_num); - return -EINVAL; - } - return count; -} - -static struct kobj_attribute ramster_remote_target_nodenum_attr = { - .attr = { .name = "remote_target_nodenum", .mode = 0644 }, - .show = ramster_remote_target_nodenum_show, - .store = ramster_remote_target_nodenum_store, -}; - - -static struct attribute *ramster_attrs[] = { - &ramster_interface_revision_attr.attr, - &ramster_pers_remotify_enable_attr.attr, - &ramster_eph_remotify_enable_attr.attr, - &ramster_remote_pers_pages_attr.attr, - &ramster_eph_pages_remoted_attr.attr, - &ramster_eph_pages_remote_failed_attr.attr, - &ramster_pers_pages_remoted_attr.attr, - &ramster_pers_pages_remote_failed_attr.attr, - &ramster_pers_pages_remote_nomem_attr.attr, - &ramster_remote_pages_flushed_attr.attr, - &ramster_remote_page_flushes_failed_attr.attr, - &ramster_remote_objects_flushed_attr.attr, - &ramster_remote_object_flushes_failed_attr.attr, - &ramster_remote_eph_pages_succ_get_attr.attr, - &ramster_remote_eph_pages_unsucc_get_attr.attr, - &ramster_remote_pers_pages_succ_get_attr.attr, - &ramster_remote_pers_pages_unsucc_get_attr.attr, - &ramster_foreign_eph_pampd_count_attr.attr, - &ramster_foreign_eph_pampd_count_max_attr.attr, - &ramster_foreign_pers_pampd_count_attr.attr, - &ramster_foreign_pers_pampd_count_max_attr.attr, - &ramster_curr_flnode_count_attr.attr, - &ramster_curr_flnode_count_max_attr.attr, - &ramster_manual_node_up_attr.attr, - &ramster_remote_target_nodenum_attr.attr, - NULL, -}; - -static struct attribute_group ramster_attr_group = { - .attrs = ramster_attrs, - .name = "ramster", -}; - -#endif /* CONFIG_SYSFS */ -/* - * When zcache is disabled ("frozen"), pools can be created and destroyed, - * but all puts (and thus all other operations that require memory allocation) - * must fail. If zcache is unfrozen, accepts puts, then frozen again, - * data consistency requires all puts while frozen to be converted into - * flushes. - */ -static bool zcache_freeze; - -/* - * zcache shrinker interface (only useful for ephemeral pages, so zbud only) - */ -static int shrink_zcache_memory(struct shrinker *shrink, - struct shrink_control *sc) -{ - int ret = -1; - int nr = sc->nr_to_scan; - gfp_t gfp_mask = sc->gfp_mask; - - if (nr >= 0) { - if (!(gfp_mask & __GFP_FS)) - /* does this case really need to be skipped? */ - goto out; - zbud_evict_pages(nr); - } - ret = (int)atomic_read(&zcache_zbud_curr_raw_pages); -out: - return ret; -} - -static struct shrinker zcache_shrinker = { - .shrink = shrink_zcache_memory, - .seeks = DEFAULT_SEEKS, -}; - -/* - * zcache shims between cleancache/frontswap ops and tmem - */ - -int zcache_put(int cli_id, int pool_id, struct tmem_oid *oidp, - uint32_t index, char *data, size_t size, - bool raw, int ephemeral) -{ - struct tmem_pool *pool; - int ret = -1; - - BUG_ON(!irqs_disabled()); - pool = zcache_get_pool_by_id(cli_id, pool_id); - if (unlikely(pool == NULL)) - goto out; - if (!zcache_freeze && zcache_do_preload(pool) == 0) { - /* preload does preempt_disable on success */ - ret = tmem_put(pool, oidp, index, data, size, raw, ephemeral); - if (ret < 0) { - if (is_ephemeral(pool)) - zcache_failed_eph_puts++; - else - zcache_failed_pers_puts++; - } - zcache_put_pool(pool); - preempt_enable_no_resched(); - } else { - zcache_put_to_flush++; - if (atomic_read(&pool->obj_count) > 0) - /* the put fails whether the flush succeeds or not */ - (void)tmem_flush_page(pool, oidp, index); - zcache_put_pool(pool); - } -out: - return ret; -} - -int zcache_get(int cli_id, int pool_id, struct tmem_oid *oidp, - uint32_t index, char *data, size_t *sizep, - bool raw, int get_and_free) -{ - struct tmem_pool *pool; - int ret = -1; - bool eph; - - if (!raw) { - BUG_ON(irqs_disabled()); - BUG_ON(in_softirq()); - } - pool = zcache_get_pool_by_id(cli_id, pool_id); - eph = is_ephemeral(pool); - if (likely(pool != NULL)) { - if (atomic_read(&pool->obj_count) > 0) - ret = tmem_get(pool, oidp, index, data, sizep, - raw, get_and_free); - zcache_put_pool(pool); - } - WARN_ONCE((!eph && (ret != 0)), "zcache_get fails on persistent pool, " - "bad things are very likely to happen soon\n"); -#ifdef RAMSTER_TESTING - if (ret != 0 && ret != -1 && !(ret == -EINVAL && is_ephemeral(pool))) - pr_err("TESTING zcache_get tmem_get returns ret=%d\n", ret); -#endif - if (ret == -EAGAIN) - BUG(); /* FIXME... don't need this anymore??? let's ensure */ - return ret; -} - -int zcache_flush(int cli_id, int pool_id, - struct tmem_oid *oidp, uint32_t index) -{ - struct tmem_pool *pool; - int ret = -1; - unsigned long flags; - - local_irq_save(flags); - zcache_flush_total++; - pool = zcache_get_pool_by_id(cli_id, pool_id); - ramster_do_preload_flnode_only(pool); - if (likely(pool != NULL)) { - if (atomic_read(&pool->obj_count) > 0) - ret = tmem_flush_page(pool, oidp, index); - zcache_put_pool(pool); - } - if (ret >= 0) - zcache_flush_found++; - local_irq_restore(flags); - return ret; -} - -int zcache_flush_object(int cli_id, int pool_id, struct tmem_oid *oidp) -{ - struct tmem_pool *pool; - int ret = -1; - unsigned long flags; - - local_irq_save(flags); - zcache_flobj_total++; - pool = zcache_get_pool_by_id(cli_id, pool_id); - ramster_do_preload_flnode_only(pool); - if (likely(pool != NULL)) { - if (atomic_read(&pool->obj_count) > 0) - ret = tmem_flush_object(pool, oidp); - zcache_put_pool(pool); - } - if (ret >= 0) - zcache_flobj_found++; - local_irq_restore(flags); - return ret; -} - -int zcache_client_destroy_pool(int cli_id, int pool_id) -{ - struct tmem_pool *pool = NULL; - struct zcache_client *cli = NULL; - int ret = -1; - - if (pool_id < 0) - goto out; - if (cli_id == LOCAL_CLIENT) - cli = &zcache_host; - else if ((unsigned int)cli_id < MAX_CLIENTS) - cli = &zcache_clients[cli_id]; - if (cli == NULL) - goto out; - atomic_inc(&cli->refcount); - pool = cli->tmem_pools[pool_id]; - if (pool == NULL) - goto out; - cli->tmem_pools[pool_id] = NULL; - /* wait for pool activity on other cpus to quiesce */ - while (atomic_read(&pool->refcount) != 0) - ; - atomic_dec(&cli->refcount); - local_bh_disable(); - ret = tmem_destroy_pool(pool); - local_bh_enable(); - kfree(pool); - pr_info("ramster: destroyed pool id=%d cli_id=%d\n", pool_id, cli_id); -out: - return ret; -} - -static int zcache_destroy_pool(int pool_id) -{ - return zcache_client_destroy_pool(LOCAL_CLIENT, pool_id); -} - -int zcache_new_pool(uint16_t cli_id, uint32_t flags) -{ - int poolid = -1; - struct tmem_pool *pool; - struct zcache_client *cli = NULL; - - if (cli_id == LOCAL_CLIENT) - cli = &zcache_host; - else if ((unsigned int)cli_id < MAX_CLIENTS) - cli = &zcache_clients[cli_id]; - if (cli == NULL) - goto out; - atomic_inc(&cli->refcount); - pool = kmalloc(sizeof(struct tmem_pool), GFP_ATOMIC); - if (pool == NULL) { - pr_info("ramster: pool creation failed: out of memory\n"); - goto out; - } - - for (poolid = 0; poolid < MAX_POOLS_PER_CLIENT; poolid++) - if (cli->tmem_pools[poolid] == NULL) - break; - if (poolid >= MAX_POOLS_PER_CLIENT) { - pr_info("ramster: pool creation failed: max exceeded\n"); - kfree(pool); - poolid = -1; - goto out; - } - atomic_set(&pool->refcount, 0); - pool->client = cli; - pool->pool_id = poolid; - tmem_new_pool(pool, flags); - cli->tmem_pools[poolid] = pool; - if (cli_id == LOCAL_CLIENT) - pr_info("ramster: created %s tmem pool, id=%d, local client\n", - flags & TMEM_POOL_PERSIST ? "persistent" : "ephemeral", - poolid); - else - pr_info("ramster: created %s tmem pool, id=%d, client=%d\n", - flags & TMEM_POOL_PERSIST ? "persistent" : "ephemeral", - poolid, cli_id); -out: - if (cli != NULL) - atomic_dec(&cli->refcount); - return poolid; -} - -static int zcache_local_new_pool(uint32_t flags) -{ - return zcache_new_pool(LOCAL_CLIENT, flags); -} - -int zcache_autocreate_pool(int cli_id, int pool_id, bool ephemeral) -{ - struct tmem_pool *pool; - struct zcache_client *cli = NULL; - uint32_t flags = ephemeral ? 0 : TMEM_POOL_PERSIST; - int ret = -1; - - if (cli_id == LOCAL_CLIENT) - goto out; - if (pool_id >= MAX_POOLS_PER_CLIENT) - goto out; - else if ((unsigned int)cli_id < MAX_CLIENTS) - cli = &zcache_clients[cli_id]; - if ((ephemeral && !use_cleancache) || (!ephemeral && !use_frontswap)) - BUG(); /* FIXME, handle more gracefully later */ - if (!cli->allocated) { - if (zcache_new_client(cli_id)) - BUG(); /* FIXME, handle more gracefully later */ - cli = &zcache_clients[cli_id]; - } - atomic_inc(&cli->refcount); - pool = cli->tmem_pools[pool_id]; - if (pool != NULL) { - if (pool->persistent && ephemeral) { - pr_err("zcache_autocreate_pool: type mismatch\n"); - goto out; - } - ret = 0; - goto out; - } - pool = kmalloc(sizeof(struct tmem_pool), GFP_KERNEL); - if (pool == NULL) { - pr_info("ramster: pool creation failed: out of memory\n"); - goto out; - } - atomic_set(&pool->refcount, 0); - pool->client = cli; - pool->pool_id = pool_id; - tmem_new_pool(pool, flags); - cli->tmem_pools[pool_id] = pool; - pr_info("ramster: AUTOcreated %s tmem poolid=%d, for remote client=%d\n", - flags & TMEM_POOL_PERSIST ? "persistent" : "ephemeral", - pool_id, cli_id); - ret = 0; -out: - if (cli == NULL) - BUG(); /* FIXME, handle more gracefully later */ - /* pr_err("zcache_autocreate_pool: failed\n"); */ - if (cli != NULL) - atomic_dec(&cli->refcount); - return ret; -} - -/********** - * Two kernel functionalities currently can be layered on top of tmem. - * These are "cleancache" which is used as a second-chance cache for clean - * page cache pages; and "frontswap" which is used for swap pages - * to avoid writes to disk. A generic "shim" is provided here for each - * to translate in-kernel semantics to zcache semantics. - */ - -#ifdef CONFIG_CLEANCACHE -static void zcache_cleancache_put_page(int pool_id, - struct cleancache_filekey key, - pgoff_t index, struct page *page) -{ - u32 ind = (u32) index; - struct tmem_oid oid = *(struct tmem_oid *)&key; - -#ifdef __PG_WAS_ACTIVE - if (!PageWasActive(page)) { - zcache_nonactive_puts++; - return; - } -#endif - if (likely(ind == index)) { - char *kva = page_address(page); - - (void)zcache_put(LOCAL_CLIENT, pool_id, &oid, index, - kva, PAGE_SIZE, 0, 1); - } -} - -static int zcache_cleancache_get_page(int pool_id, - struct cleancache_filekey key, - pgoff_t index, struct page *page) -{ - u32 ind = (u32) index; - struct tmem_oid oid = *(struct tmem_oid *)&key; - int ret = -1; - - preempt_disable(); - if (likely(ind == index)) { - char *kva = page_address(page); - size_t size = PAGE_SIZE; - - ret = zcache_get(LOCAL_CLIENT, pool_id, &oid, index, - kva, &size, 0, 0); -#ifdef __PG_WAS_ACTIVE - if (ret == 0) - SetPageWasActive(page); -#endif - } - preempt_enable(); - return ret; -} - -static void zcache_cleancache_flush_page(int pool_id, - struct cleancache_filekey key, - pgoff_t index) -{ - u32 ind = (u32) index; - struct tmem_oid oid = *(struct tmem_oid *)&key; - - if (likely(ind == index)) - (void)zcache_flush(LOCAL_CLIENT, pool_id, &oid, ind); -} - -static void zcache_cleancache_flush_inode(int pool_id, - struct cleancache_filekey key) -{ - struct tmem_oid oid = *(struct tmem_oid *)&key; - - (void)zcache_flush_object(LOCAL_CLIENT, pool_id, &oid); -} - -static void zcache_cleancache_flush_fs(int pool_id) -{ - if (pool_id >= 0) - (void)zcache_destroy_pool(pool_id); -} - -static int zcache_cleancache_init_fs(size_t pagesize) -{ - BUG_ON(sizeof(struct cleancache_filekey) != - sizeof(struct tmem_oid)); - BUG_ON(pagesize != PAGE_SIZE); - return zcache_local_new_pool(0); -} - -static int zcache_cleancache_init_shared_fs(char *uuid, size_t pagesize) -{ - /* shared pools are unsupported and map to private */ - BUG_ON(sizeof(struct cleancache_filekey) != - sizeof(struct tmem_oid)); - BUG_ON(pagesize != PAGE_SIZE); - return zcache_local_new_pool(0); -} - -static struct cleancache_ops zcache_cleancache_ops = { - .put_page = zcache_cleancache_put_page, - .get_page = zcache_cleancache_get_page, - .invalidate_page = zcache_cleancache_flush_page, - .invalidate_inode = zcache_cleancache_flush_inode, - .invalidate_fs = zcache_cleancache_flush_fs, - .init_shared_fs = zcache_cleancache_init_shared_fs, - .init_fs = zcache_cleancache_init_fs -}; - -struct cleancache_ops zcache_cleancache_register_ops(void) -{ - struct cleancache_ops old_ops = - cleancache_register_ops(&zcache_cleancache_ops); - - return old_ops; -} -#endif - -#ifdef CONFIG_FRONTSWAP -/* a single tmem poolid is used for all frontswap "types" (swapfiles) */ -static int zcache_frontswap_poolid = -1; - -/* - * Swizzling increases objects per swaptype, increasing tmem concurrency - * for heavy swaploads. Later, larger nr_cpus -> larger SWIZ_BITS - */ -#define SWIZ_BITS 8 -#define SWIZ_MASK ((1 << SWIZ_BITS) - 1) -#define _oswiz(_type, _ind) ((_type << SWIZ_BITS) | (_ind & SWIZ_MASK)) -#define iswiz(_ind) (_ind >> SWIZ_BITS) - -static inline struct tmem_oid oswiz(unsigned type, u32 ind) -{ - struct tmem_oid oid = { .oid = { 0 } }; - oid.oid[0] = _oswiz(type, ind); - return oid; -} - -static int zcache_frontswap_store(unsigned type, pgoff_t offset, - struct page *page) -{ - u64 ind64 = (u64)offset; - u32 ind = (u32)offset; - struct tmem_oid oid = oswiz(type, ind); - int ret = -1; - unsigned long flags; - char *kva; - - BUG_ON(!PageLocked(page)); - if (likely(ind64 == ind)) { - local_irq_save(flags); - kva = page_address(page); - ret = zcache_put(LOCAL_CLIENT, zcache_frontswap_poolid, - &oid, iswiz(ind), kva, PAGE_SIZE, 0, 0); - local_irq_restore(flags); - } - return ret; -} - -/* returns 0 if the page was successfully gotten from frontswap, -1 if - * was not present (should never happen!) */ -static int zcache_frontswap_load(unsigned type, pgoff_t offset, - struct page *page) -{ - u64 ind64 = (u64)offset; - u32 ind = (u32)offset; - struct tmem_oid oid = oswiz(type, ind); - int ret = -1; - - preempt_disable(); /* FIXME, remove this? */ - BUG_ON(!PageLocked(page)); - if (likely(ind64 == ind)) { - char *kva = page_address(page); - size_t size = PAGE_SIZE; - - ret = zcache_get(LOCAL_CLIENT, zcache_frontswap_poolid, - &oid, iswiz(ind), kva, &size, 0, -1); - } - preempt_enable(); /* FIXME, remove this? */ - return ret; -} - -/* flush a single page from frontswap */ -static void zcache_frontswap_flush_page(unsigned type, pgoff_t offset) -{ - u64 ind64 = (u64)offset; - u32 ind = (u32)offset; - struct tmem_oid oid = oswiz(type, ind); - - if (likely(ind64 == ind)) - (void)zcache_flush(LOCAL_CLIENT, zcache_frontswap_poolid, - &oid, iswiz(ind)); -} - -/* flush all pages from the passed swaptype */ -static void zcache_frontswap_flush_area(unsigned type) -{ - struct tmem_oid oid; - int ind; - - for (ind = SWIZ_MASK; ind >= 0; ind--) { - oid = oswiz(type, ind); - (void)zcache_flush_object(LOCAL_CLIENT, - zcache_frontswap_poolid, &oid); - } -} - -static void zcache_frontswap_init(unsigned ignored) -{ - /* a single tmem poolid is used for all frontswap "types" (swapfiles) */ - if (zcache_frontswap_poolid < 0) - zcache_frontswap_poolid = - zcache_local_new_pool(TMEM_POOL_PERSIST); -} - -static struct frontswap_ops zcache_frontswap_ops = { - .store = zcache_frontswap_store, - .load = zcache_frontswap_load, - .invalidate_page = zcache_frontswap_flush_page, - .invalidate_area = zcache_frontswap_flush_area, - .init = zcache_frontswap_init -}; - -struct frontswap_ops zcache_frontswap_register_ops(void) -{ - struct frontswap_ops old_ops = - frontswap_register_ops(&zcache_frontswap_ops); - - return old_ops; -} -#endif - -/* - * frontswap selfshrinking - */ - -#ifdef CONFIG_FRONTSWAP -/* In HZ, controls frequency of worker invocation. */ -static unsigned int selfshrink_interval __read_mostly = 5; - -static void selfshrink_process(struct work_struct *work); -static DECLARE_DELAYED_WORK(selfshrink_worker, selfshrink_process); - -/* Enable/disable with sysfs. */ -static bool frontswap_selfshrinking __read_mostly; - -/* Enable/disable with kernel boot option. */ -static bool use_frontswap_selfshrink __initdata = true; - -/* - * The default values for the following parameters were deemed reasonable - * by experimentation, may be workload-dependent, and can all be - * adjusted via sysfs. - */ - -/* Control rate for frontswap shrinking. Higher hysteresis is slower. */ -static unsigned int frontswap_hysteresis __read_mostly = 20; - -/* - * Number of selfshrink worker invocations to wait before observing that - * frontswap selfshrinking should commence. Note that selfshrinking does - * not use a separate worker thread. - */ -static unsigned int frontswap_inertia __read_mostly = 3; - -/* Countdown to next invocation of frontswap_shrink() */ -static unsigned long frontswap_inertia_counter; - -/* - * Invoked by the selfshrink worker thread, uses current number of pages - * in frontswap (frontswap_curr_pages()), previous status, and control - * values (hysteresis and inertia) to determine if frontswap should be - * shrunk and what the new frontswap size should be. Note that - * frontswap_shrink is essentially a partial swapoff that immediately - * transfers pages from the "swap device" (frontswap) back into kernel - * RAM; despite the name, frontswap "shrinking" is very different from - * the "shrinker" interface used by the kernel MM subsystem to reclaim - * memory. - */ -static void frontswap_selfshrink(void) -{ - static unsigned long cur_frontswap_pages; - static unsigned long last_frontswap_pages; - static unsigned long tgt_frontswap_pages; - - last_frontswap_pages = cur_frontswap_pages; - cur_frontswap_pages = frontswap_curr_pages(); - if (!cur_frontswap_pages || - (cur_frontswap_pages > last_frontswap_pages)) { - frontswap_inertia_counter = frontswap_inertia; - return; - } - if (frontswap_inertia_counter && --frontswap_inertia_counter) - return; - if (cur_frontswap_pages <= frontswap_hysteresis) - tgt_frontswap_pages = 0; - else - tgt_frontswap_pages = cur_frontswap_pages - - (cur_frontswap_pages / frontswap_hysteresis); - frontswap_shrink(tgt_frontswap_pages); -} - -static int __init ramster_nofrontswap_selfshrink_setup(char *s) -{ - use_frontswap_selfshrink = false; - return 1; -} - -__setup("noselfshrink", ramster_nofrontswap_selfshrink_setup); - -static void selfshrink_process(struct work_struct *work) -{ - if (frontswap_selfshrinking && frontswap_enabled) { - frontswap_selfshrink(); - schedule_delayed_work(&selfshrink_worker, - selfshrink_interval * HZ); - } -} - -static int ramster_enabled; - -static int __init ramster_selfshrink_init(void) -{ - frontswap_selfshrinking = ramster_enabled && use_frontswap_selfshrink; - if (frontswap_selfshrinking) - pr_info("ramster: Initializing frontswap " - "selfshrinking driver.\n"); - else - return -ENODEV; - - schedule_delayed_work(&selfshrink_worker, selfshrink_interval * HZ); - - return 0; -} - -subsys_initcall(ramster_selfshrink_init); -#endif - -/* - * zcache initialization - * NOTE FOR NOW ramster MUST BE PROVIDED AS A KERNEL BOOT PARAMETER OR - * NOTHING HAPPENS! - */ - -static int ramster_enabled; - -static int __init enable_ramster(char *s) -{ - ramster_enabled = 1; - return 1; -} -__setup("ramster", enable_ramster); - -/* allow independent dynamic disabling of cleancache and frontswap */ - -static int use_cleancache = 1; - -static int __init no_cleancache(char *s) -{ - pr_info("INIT no_cleancache called\n"); - use_cleancache = 0; - return 1; -} - -/* - * FIXME: need to guarantee this gets checked before zcache_init is called - * What is the correct way to achieve this? - */ -early_param("nocleancache", no_cleancache); - -static int use_frontswap = 1; - -static int __init no_frontswap(char *s) -{ - pr_info("INIT no_frontswap called\n"); - use_frontswap = 0; - return 1; -} - -__setup("nofrontswap", no_frontswap); - -static int __init zcache_init(void) -{ - int ret = 0; - -#ifdef CONFIG_SYSFS - ret = sysfs_create_group(mm_kobj, &zcache_attr_group); - ret = sysfs_create_group(mm_kobj, &ramster_attr_group); - if (ret) { - pr_err("ramster: can't create sysfs\n"); - goto out; - } -#endif /* CONFIG_SYSFS */ -#if defined(CONFIG_CLEANCACHE) || defined(CONFIG_FRONTSWAP) - if (ramster_enabled) { - unsigned int cpu; - - (void)r2net_register_handlers(); - tmem_register_hostops(&zcache_hostops); - tmem_register_pamops(&zcache_pamops); - ret = register_cpu_notifier(&zcache_cpu_notifier_block); - if (ret) { - pr_err("ramster: can't register cpu notifier\n"); - goto out; - } - for_each_online_cpu(cpu) { - void *pcpu = (void *)(long)cpu; - zcache_cpu_notifier(&zcache_cpu_notifier_block, - CPU_UP_PREPARE, pcpu); - } - } - zcache_objnode_cache = kmem_cache_create("zcache_objnode", - sizeof(struct tmem_objnode), 0, 0, NULL); - zcache_obj_cache = kmem_cache_create("zcache_obj", - sizeof(struct tmem_obj), 0, 0, NULL); - ramster_flnode_cache = kmem_cache_create("ramster_flnode", - sizeof(struct flushlist_node), 0, 0, NULL); -#endif -#ifdef CONFIG_CLEANCACHE - pr_info("INIT ramster_enabled=%d use_cleancache=%d\n", - ramster_enabled, use_cleancache); - if (ramster_enabled && use_cleancache) { - struct cleancache_ops old_ops; - - zbud_init(); - register_shrinker(&zcache_shrinker); - old_ops = zcache_cleancache_register_ops(); - pr_info("ramster: cleancache enabled using kernel " - "transcendent memory and compression buddies\n"); - if (old_ops.init_fs != NULL) - pr_warning("ramster: cleancache_ops overridden"); - } -#endif -#ifdef CONFIG_FRONTSWAP - pr_info("INIT ramster_enabled=%d use_frontswap=%d\n", - ramster_enabled, use_frontswap); - if (ramster_enabled && use_frontswap) { - struct frontswap_ops old_ops; - - zcache_new_client(LOCAL_CLIENT); - old_ops = zcache_frontswap_register_ops(); - pr_info("ramster: frontswap enabled using kernel " - "transcendent memory and xvmalloc\n"); - if (old_ops.init != NULL) - pr_warning("ramster: frontswap_ops overridden"); - } - if (ramster_enabled && (use_frontswap || use_cleancache)) - ramster_remotify_init(); -#endif -out: - return ret; -} - -module_init(zcache_init) diff --git a/drivers/staging/ramster/zcache.h b/drivers/staging/ramster/zcache.h deleted file mode 100644 index 250b121..0000000 --- a/drivers/staging/ramster/zcache.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * zcache.h - * - * External zcache functions - * - * Copyright (c) 2009-2012, Dan Magenheimer, Oracle Corp. - */ - -#ifndef _ZCACHE_H_ -#define _ZCACHE_H_ - -extern int zcache_put(int, int, struct tmem_oid *, uint32_t, - char *, size_t, bool, int); -extern int zcache_autocreate_pool(int, int, bool); -extern int zcache_get(int, int, struct tmem_oid *, uint32_t, - char *, size_t *, bool, int); -extern int zcache_flush(int, int, struct tmem_oid *, uint32_t); -extern int zcache_flush_object(int, int, struct tmem_oid *); -extern int zcache_localify(int, struct tmem_oid *, uint32_t, - char *, size_t, void *); - -#endif /* _ZCACHE_H */ -- cgit v0.10.2 From faca2ef77abf1983e87d36b14bc181efb983979a Mon Sep 17 00:00:00 2001 From: Dan Magenheimer Date: Wed, 5 Sep 2012 13:45:00 -0700 Subject: staging: ramster: move to new zcache2 codebase [V2: rebased to apply to 20120905 staging-next, no other changes] The original zcache in staging is a "demo" version, and this is a massive rewrite. This was intended to result in a merged zcache and ramster, but that option has been blocked so, to continue forward progress on ramster and future related projects, only ramster moves to the new codebase. To differentiate between the old demo zcache and the rewrite, we refer to the latter as zcache2, config'd as CONFIG_ZCACHE2. Zcache and zcache2 cannot be built in the same kernel, so CONFIG_ZCACHE2 implies !CONFIG_ZCACHE. This developer still has hope that zcache and zcache2 will be merged into one codebase. Until then, zcache2 can be considered a one-node version of ramster. No history of changes was recorded during the zcache2 rewrite and recreating a sane one would be a Sisyphean task but, since ramster is still in staging and has been unchanged since it was merged, presumably this is acceptable. This commit also provides the hooks in zcache2 for ramster, but all ramster-specific code is provided in a separate commit. Some of the highlights of this rewritten codebase for zcache2: (Note: If you are not familiar with the tmem terminology, you can review it here: http://lwn.net/Articles/454795/ ) 1. Merge of "demo" zcache and the v1.1 version of zcache in ramster. Zcache and ramster had a great deal of duplicate code which is now merged. In essence, zcache2 *is* ramster but with no remote machine available, but !CONFIG_RAMSTER will avoid compiling lots of ramster-specific code. 2. Allocator. Previously, persistent pools used zsmalloc and ephemeral pools used zbud. Now a completely rewritten zbud is used for both. Notably this zbud maintains all persistent (frontswap) and ephemeral (cleancache) pageframes in separate queues in LRU order. 3. Interaction with page allocator. Zbud does no page allocation/freeing, it is done entirely in zcache2 where it can be tracked more effectively. 4. Better pre-allocation. Previously, on put, if a new pageframe could not be pre-allocated, the put would fail, even if the allocator had plenty of partial pages where the data could be stored; this is now fixed. 5. Ouroboros ("eating its own tail") allocation. If no pageframe can be allocated AND no partial pages are available, the least-recently-used ephemeral pageframe is reclaimed immediately (including flushing tmem pointers to it) and re-used. This ensures that most-recently-used cleancache pages are more likely to be retained than LRU pages and also that, as in the core mm subsystem, anonymous pages have a higher priority than clean page cache pages. 6. Zcache and zbud now use debugfs instead of sysfs. Ramster uses debugfs where possible and sysfs where necessary. (Some ramster configuration is done from userspace so some sysfs is necessary.) 7. Modularization. As some have observed, the monolithic zcache-main.c code included zbud code, which has now been separated into its own code module. Much ramster-specific code in the old ramster zcache-main.c has also been moved into ramster.c so that it does not get compiled with !CONFIG_RAMSTER. 8. Rebased to 3.5. This new codebase also provides hooks for several future new features: A. WasActive patch, requires some mm/frontswap changes previously posted. A new version of this patch will be provided separately. See ifdef __PG_WAS_ACTIVE B. Exclusive gets. It seems tmem _can_ support exclusive gets with a minor change to both zcache2 and a small backwards-compatible change to frontswap.c. Explanation and frontswap patch will be provided separately. See ifdef FRONTSWAP_HAS_EXCLUSIVE_GETS C. Ouroboros writeback. Since persistent (frontswap) pages may now also be reclaimed in LRU order, the foundation is in place to properly writeback these pages back into the swap cache and then the swap disk. This is still under development and requires some other mm changes which are prototyped. See ifdef FRONTSWAP_HAS_UNUSE. A new feature that desperately needs attention (if someone is looking for a way to contribute) is kernel module support. A preliminary version of a patch was posted by Erlangen University and needs to be integrated and tested for zcache2 and brought up to kernel standards. If anybody is interested on helping out with any of these, let me know! Acked-by: Konrad Rzeszutek Wilk Signed-off-by: Dan Magenheimer Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index e25e1e1..e12f5a3 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -134,4 +134,6 @@ source "drivers/staging/csr/Kconfig" source "drivers/staging/omap-thermal/Kconfig" +source "drivers/staging/ramster/Kconfig" + endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 7ab2d51..ce42832 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -59,3 +59,4 @@ obj-$(CONFIG_USB_G_CCG) += ccg/ obj-$(CONFIG_WIMAX_GDM72XX) += gdm72xx/ obj-$(CONFIG_CSR_WIFI) += csr/ obj-$(CONFIG_OMAP_BANDGAP) += omap-thermal/ +obj-$(CONFIG_ZCACHE2) += ramster/ diff --git a/drivers/staging/ramster/Kconfig b/drivers/staging/ramster/Kconfig new file mode 100644 index 0000000..7db0592 --- /dev/null +++ b/drivers/staging/ramster/Kconfig @@ -0,0 +1,16 @@ +config ZCACHE2 + bool "Dynamic compression of swap pages and clean pagecache pages" + depends on CRYPTO=y && SWAP=y && CLEANCACHE && FRONTSWAP && !ZCACHE + select CRYPTO_LZO + default n + help + Zcache2 doubles RAM efficiency while providing a significant + performance boosts on many workloads. Zcache2 uses + compression and an in-kernel implementation of transcendent + memory to store clean page cache pages and swap in RAM, + providing a noticeable reduction in disk I/O. Zcache2 + is a complete rewrite of the older zcache; it was intended to + be a merge but that has been blocked due to political and + technical disagreements. It is intended that they will merge + again in the future. Until then, zcache2 is a single-node + version of ramster. diff --git a/drivers/staging/ramster/Makefile b/drivers/staging/ramster/Makefile new file mode 100644 index 0000000..800e70c --- /dev/null +++ b/drivers/staging/ramster/Makefile @@ -0,0 +1,3 @@ +zcache-y := zcache-main.o tmem.o zbud.o + +obj-$(CONFIG_ZCACHE2) += zcache.o diff --git a/drivers/staging/ramster/ramster.h b/drivers/staging/ramster/ramster.h new file mode 100644 index 0000000..1b71aea --- /dev/null +++ b/drivers/staging/ramster/ramster.h @@ -0,0 +1,59 @@ + +/* + * zcache/ramster.h + * + * Placeholder to resolve ramster references when !CONFIG_RAMSTER + * Real ramster.h lives in ramster subdirectory. + * + * Copyright (c) 2009-2012, Dan Magenheimer, Oracle Corp. + */ + +#ifndef _ZCACHE_RAMSTER_H_ +#define _ZCACHE_RAMSTER_H_ + +#ifdef CONFIG_RAMSTER +#include "ramster/ramster.h" +#else +static inline void ramster_init(bool x, bool y, bool z) +{ +} + +static inline void ramster_register_pamops(struct tmem_pamops *p) +{ +} + +static inline int ramster_remotify_pageframe(bool b) +{ + return 0; +} + +static inline void *ramster_pampd_free(void *v, struct tmem_pool *p, + struct tmem_oid *o, uint32_t u, bool b) +{ + return NULL; +} + +static inline int ramster_do_preload_flnode(struct tmem_pool *p) +{ + return -1; +} + +static inline bool pampd_is_remote(void *v) +{ + return false; +} + +static inline void ramster_count_foreign_pages(bool b, int i) +{ +} + +static inline void ramster_cpu_up(int cpu) +{ +} + +static inline void ramster_cpu_down(int cpu) +{ +} +#endif + +#endif /* _ZCACHE_RAMSTER_H */ diff --git a/drivers/staging/ramster/tmem.c b/drivers/staging/ramster/tmem.c new file mode 100644 index 0000000..a2b7e03 --- /dev/null +++ b/drivers/staging/ramster/tmem.c @@ -0,0 +1,894 @@ +/* + * In-kernel transcendent memory (generic implementation) + * + * Copyright (c) 2009-2012, Dan Magenheimer, Oracle Corp. + * + * The primary purpose of Transcedent Memory ("tmem") is to map object-oriented + * "handles" (triples containing a pool id, and object id, and an index), to + * pages in a page-accessible memory (PAM). Tmem references the PAM pages via + * an abstract "pampd" (PAM page-descriptor), which can be operated on by a + * set of functions (pamops). Each pampd contains some representation of + * PAGE_SIZE bytes worth of data. For those familiar with key-value stores, + * the tmem handle is a three-level hierarchical key, and the value is always + * reconstituted (but not necessarily stored) as PAGE_SIZE bytes and is + * referenced in the datastore by the pampd. The hierarchy is required + * to ensure that certain invalidation functions can be performed efficiently + * (i.e. flush all indexes associated with this object_id, or + * flush all objects associated with this pool). + * + * Tmem must support potentially millions of pages and must be able to insert, + * find, and delete these pages at a potential frequency of thousands per + * second concurrently across many CPUs, (and, if used with KVM, across many + * vcpus across many guests). Tmem is tracked with a hierarchy of data + * structures, organized by the elements in the handle-tuple: pool_id, + * object_id, and page index. One or more "clients" (e.g. guests) each + * provide one or more tmem_pools. Each pool, contains a hash table of + * rb_trees of tmem_objs. Each tmem_obj contains a radix-tree-like tree + * of pointers, with intermediate nodes called tmem_objnodes. Each leaf + * pointer in this tree points to a pampd, which is accessible only through + * a small set of callbacks registered by the PAM implementation (see + * tmem_register_pamops). Tmem only needs to memory allocation for objs + * and objnodes and this is done via a set of callbacks that must be + * registered by the tmem host implementation (e.g. see tmem_register_hostops). + */ + +#include +#include +#include +#ifdef CONFIG_RAMSTER +#include +#endif + +#include "tmem.h" + +/* data structure sentinels used for debugging... see tmem.h */ +#define POOL_SENTINEL 0x87658765 +#define OBJ_SENTINEL 0x12345678 +#define OBJNODE_SENTINEL 0xfedcba09 + +/* + * A tmem host implementation must use this function to register callbacks + * for memory allocation. + */ +static struct tmem_hostops tmem_hostops; + +static void tmem_objnode_tree_init(void); + +void tmem_register_hostops(struct tmem_hostops *m) +{ + tmem_objnode_tree_init(); + tmem_hostops = *m; +} + +/* + * A tmem host implementation must use this function to register + * callbacks for a page-accessible memory (PAM) implementation. + */ +static struct tmem_pamops tmem_pamops; + +void tmem_register_pamops(struct tmem_pamops *m) +{ + tmem_pamops = *m; +} + +/* + * Oid's are potentially very sparse and tmem_objs may have an indeterminately + * short life, being added and deleted at a relatively high frequency. + * So an rb_tree is an ideal data structure to manage tmem_objs. But because + * of the potentially huge number of tmem_objs, each pool manages a hashtable + * of rb_trees to reduce search, insert, delete, and rebalancing time. + * Each hashbucket also has a lock to manage concurrent access and no + * searches, inserts, or deletions can be performed unless the lock is held. + * As a result, care must be taken to ensure tmem routines are not called + * recursively; the vast majority of the time, a recursive call may work + * but a deadlock will occur a small fraction of the time due to the + * hashbucket lock. + * + * The following routines manage tmem_objs. In all of these routines, + * the hashbucket lock is already held. + */ + +/* Search for object==oid in pool, returns object if found. */ +static struct tmem_obj *__tmem_obj_find(struct tmem_hashbucket *hb, + struct tmem_oid *oidp, + struct rb_node **parent, + struct rb_node ***link) +{ + struct rb_node *_parent = NULL, **rbnode; + struct tmem_obj *obj = NULL; + + rbnode = &hb->obj_rb_root.rb_node; + while (*rbnode) { + BUG_ON(RB_EMPTY_NODE(*rbnode)); + _parent = *rbnode; + obj = rb_entry(*rbnode, struct tmem_obj, + rb_tree_node); + switch (tmem_oid_compare(oidp, &obj->oid)) { + case 0: /* equal */ + goto out; + case -1: + rbnode = &(*rbnode)->rb_left; + break; + case 1: + rbnode = &(*rbnode)->rb_right; + break; + } + } + + if (parent) + *parent = _parent; + if (link) + *link = rbnode; + obj = NULL; +out: + return obj; +} + +static struct tmem_obj *tmem_obj_find(struct tmem_hashbucket *hb, + struct tmem_oid *oidp) +{ + return __tmem_obj_find(hb, oidp, NULL, NULL); +} + +static void tmem_pampd_destroy_all_in_obj(struct tmem_obj *, bool); + +/* Free an object that has no more pampds in it. */ +static void tmem_obj_free(struct tmem_obj *obj, struct tmem_hashbucket *hb) +{ + struct tmem_pool *pool; + + BUG_ON(obj == NULL); + ASSERT_SENTINEL(obj, OBJ); + BUG_ON(obj->pampd_count > 0); + pool = obj->pool; + BUG_ON(pool == NULL); + if (obj->objnode_tree_root != NULL) /* may be "stump" with no leaves */ + tmem_pampd_destroy_all_in_obj(obj, false); + BUG_ON(obj->objnode_tree_root != NULL); + BUG_ON((long)obj->objnode_count != 0); + atomic_dec(&pool->obj_count); + BUG_ON(atomic_read(&pool->obj_count) < 0); + INVERT_SENTINEL(obj, OBJ); + obj->pool = NULL; + tmem_oid_set_invalid(&obj->oid); + rb_erase(&obj->rb_tree_node, &hb->obj_rb_root); +} + +/* + * Initialize, and insert an tmem_object_root (called only if find failed). + */ +static void tmem_obj_init(struct tmem_obj *obj, struct tmem_hashbucket *hb, + struct tmem_pool *pool, + struct tmem_oid *oidp) +{ + struct rb_root *root = &hb->obj_rb_root; + struct rb_node **new = NULL, *parent = NULL; + + BUG_ON(pool == NULL); + atomic_inc(&pool->obj_count); + obj->objnode_tree_height = 0; + obj->objnode_tree_root = NULL; + obj->pool = pool; + obj->oid = *oidp; + obj->objnode_count = 0; + obj->pampd_count = 0; +#ifdef CONFIG_RAMSTER + if (tmem_pamops.new_obj != NULL) + (*tmem_pamops.new_obj)(obj); +#endif + SET_SENTINEL(obj, OBJ); + + if (__tmem_obj_find(hb, oidp, &parent, &new)) + BUG(); + + rb_link_node(&obj->rb_tree_node, parent, new); + rb_insert_color(&obj->rb_tree_node, root); +} + +/* + * Tmem is managed as a set of tmem_pools with certain attributes, such as + * "ephemeral" vs "persistent". These attributes apply to all tmem_objs + * and all pampds that belong to a tmem_pool. A tmem_pool is created + * or deleted relatively rarely (for example, when a filesystem is + * mounted or unmounted). + */ + +/* flush all data from a pool and, optionally, free it */ +static void tmem_pool_flush(struct tmem_pool *pool, bool destroy) +{ + struct rb_node *rbnode; + struct tmem_obj *obj; + struct tmem_hashbucket *hb = &pool->hashbucket[0]; + int i; + + BUG_ON(pool == NULL); + for (i = 0; i < TMEM_HASH_BUCKETS; i++, hb++) { + spin_lock(&hb->lock); + rbnode = rb_first(&hb->obj_rb_root); + while (rbnode != NULL) { + obj = rb_entry(rbnode, struct tmem_obj, rb_tree_node); + rbnode = rb_next(rbnode); + tmem_pampd_destroy_all_in_obj(obj, true); + tmem_obj_free(obj, hb); + (*tmem_hostops.obj_free)(obj, pool); + } + spin_unlock(&hb->lock); + } + if (destroy) + list_del(&pool->pool_list); +} + +/* + * A tmem_obj contains a radix-tree-like tree in which the intermediate + * nodes are called tmem_objnodes. (The kernel lib/radix-tree.c implementation + * is very specialized and tuned for specific uses and is not particularly + * suited for use from this code, though some code from the core algorithms has + * been reused, thus the copyright notices below). Each tmem_objnode contains + * a set of pointers which point to either a set of intermediate tmem_objnodes + * or a set of of pampds. + * + * Portions Copyright (C) 2001 Momchil Velikov + * Portions Copyright (C) 2001 Christoph Hellwig + * Portions Copyright (C) 2005 SGI, Christoph Lameter + */ + +struct tmem_objnode_tree_path { + struct tmem_objnode *objnode; + int offset; +}; + +/* objnode height_to_maxindex translation */ +static unsigned long tmem_objnode_tree_h2max[OBJNODE_TREE_MAX_PATH + 1]; + +static void tmem_objnode_tree_init(void) +{ + unsigned int ht, tmp; + + for (ht = 0; ht < ARRAY_SIZE(tmem_objnode_tree_h2max); ht++) { + tmp = ht * OBJNODE_TREE_MAP_SHIFT; + if (tmp >= OBJNODE_TREE_INDEX_BITS) + tmem_objnode_tree_h2max[ht] = ~0UL; + else + tmem_objnode_tree_h2max[ht] = + (~0UL >> (OBJNODE_TREE_INDEX_BITS - tmp - 1)) >> 1; + } +} + +static struct tmem_objnode *tmem_objnode_alloc(struct tmem_obj *obj) +{ + struct tmem_objnode *objnode; + + ASSERT_SENTINEL(obj, OBJ); + BUG_ON(obj->pool == NULL); + ASSERT_SENTINEL(obj->pool, POOL); + objnode = (*tmem_hostops.objnode_alloc)(obj->pool); + if (unlikely(objnode == NULL)) + goto out; + objnode->obj = obj; + SET_SENTINEL(objnode, OBJNODE); + memset(&objnode->slots, 0, sizeof(objnode->slots)); + objnode->slots_in_use = 0; + obj->objnode_count++; +out: + return objnode; +} + +static void tmem_objnode_free(struct tmem_objnode *objnode) +{ + struct tmem_pool *pool; + int i; + + BUG_ON(objnode == NULL); + for (i = 0; i < OBJNODE_TREE_MAP_SIZE; i++) + BUG_ON(objnode->slots[i] != NULL); + ASSERT_SENTINEL(objnode, OBJNODE); + INVERT_SENTINEL(objnode, OBJNODE); + BUG_ON(objnode->obj == NULL); + ASSERT_SENTINEL(objnode->obj, OBJ); + pool = objnode->obj->pool; + BUG_ON(pool == NULL); + ASSERT_SENTINEL(pool, POOL); + objnode->obj->objnode_count--; + objnode->obj = NULL; + (*tmem_hostops.objnode_free)(objnode, pool); +} + +/* + * Lookup index in object and return associated pampd (or NULL if not found). + */ +static void **__tmem_pampd_lookup_in_obj(struct tmem_obj *obj, uint32_t index) +{ + unsigned int height, shift; + struct tmem_objnode **slot = NULL; + + BUG_ON(obj == NULL); + ASSERT_SENTINEL(obj, OBJ); + BUG_ON(obj->pool == NULL); + ASSERT_SENTINEL(obj->pool, POOL); + + height = obj->objnode_tree_height; + if (index > tmem_objnode_tree_h2max[obj->objnode_tree_height]) + goto out; + if (height == 0 && obj->objnode_tree_root) { + slot = &obj->objnode_tree_root; + goto out; + } + shift = (height-1) * OBJNODE_TREE_MAP_SHIFT; + slot = &obj->objnode_tree_root; + while (height > 0) { + if (*slot == NULL) + goto out; + slot = (struct tmem_objnode **) + ((*slot)->slots + + ((index >> shift) & OBJNODE_TREE_MAP_MASK)); + shift -= OBJNODE_TREE_MAP_SHIFT; + height--; + } +out: + return slot != NULL ? (void **)slot : NULL; +} + +static void *tmem_pampd_lookup_in_obj(struct tmem_obj *obj, uint32_t index) +{ + struct tmem_objnode **slot; + + slot = (struct tmem_objnode **)__tmem_pampd_lookup_in_obj(obj, index); + return slot != NULL ? *slot : NULL; +} + +#ifdef CONFIG_RAMSTER +static void *tmem_pampd_replace_in_obj(struct tmem_obj *obj, uint32_t index, + void *new_pampd, bool no_free) +{ + struct tmem_objnode **slot; + void *ret = NULL; + + slot = (struct tmem_objnode **)__tmem_pampd_lookup_in_obj(obj, index); + if ((slot != NULL) && (*slot != NULL)) { + void *old_pampd = *(void **)slot; + *(void **)slot = new_pampd; + if (!no_free) + (*tmem_pamops.free)(old_pampd, obj->pool, + NULL, 0, false); + ret = new_pampd; + } + return ret; +} +#endif + +static int tmem_pampd_add_to_obj(struct tmem_obj *obj, uint32_t index, + void *pampd) +{ + int ret = 0; + struct tmem_objnode *objnode = NULL, *newnode, *slot; + unsigned int height, shift; + int offset = 0; + + /* if necessary, extend the tree to be higher */ + if (index > tmem_objnode_tree_h2max[obj->objnode_tree_height]) { + height = obj->objnode_tree_height + 1; + if (index > tmem_objnode_tree_h2max[height]) + while (index > tmem_objnode_tree_h2max[height]) + height++; + if (obj->objnode_tree_root == NULL) { + obj->objnode_tree_height = height; + goto insert; + } + do { + newnode = tmem_objnode_alloc(obj); + if (!newnode) { + ret = -ENOMEM; + goto out; + } + newnode->slots[0] = obj->objnode_tree_root; + newnode->slots_in_use = 1; + obj->objnode_tree_root = newnode; + obj->objnode_tree_height++; + } while (height > obj->objnode_tree_height); + } +insert: + slot = obj->objnode_tree_root; + height = obj->objnode_tree_height; + shift = (height-1) * OBJNODE_TREE_MAP_SHIFT; + while (height > 0) { + if (slot == NULL) { + /* add a child objnode. */ + slot = tmem_objnode_alloc(obj); + if (!slot) { + ret = -ENOMEM; + goto out; + } + if (objnode) { + + objnode->slots[offset] = slot; + objnode->slots_in_use++; + } else + obj->objnode_tree_root = slot; + } + /* go down a level */ + offset = (index >> shift) & OBJNODE_TREE_MAP_MASK; + objnode = slot; + slot = objnode->slots[offset]; + shift -= OBJNODE_TREE_MAP_SHIFT; + height--; + } + BUG_ON(slot != NULL); + if (objnode) { + objnode->slots_in_use++; + objnode->slots[offset] = pampd; + } else + obj->objnode_tree_root = pampd; + obj->pampd_count++; +out: + return ret; +} + +static void *tmem_pampd_delete_from_obj(struct tmem_obj *obj, uint32_t index) +{ + struct tmem_objnode_tree_path path[OBJNODE_TREE_MAX_PATH + 1]; + struct tmem_objnode_tree_path *pathp = path; + struct tmem_objnode *slot = NULL; + unsigned int height, shift; + int offset; + + BUG_ON(obj == NULL); + ASSERT_SENTINEL(obj, OBJ); + BUG_ON(obj->pool == NULL); + ASSERT_SENTINEL(obj->pool, POOL); + height = obj->objnode_tree_height; + if (index > tmem_objnode_tree_h2max[height]) + goto out; + slot = obj->objnode_tree_root; + if (height == 0 && obj->objnode_tree_root) { + obj->objnode_tree_root = NULL; + goto out; + } + shift = (height - 1) * OBJNODE_TREE_MAP_SHIFT; + pathp->objnode = NULL; + do { + if (slot == NULL) + goto out; + pathp++; + offset = (index >> shift) & OBJNODE_TREE_MAP_MASK; + pathp->offset = offset; + pathp->objnode = slot; + slot = slot->slots[offset]; + shift -= OBJNODE_TREE_MAP_SHIFT; + height--; + } while (height > 0); + if (slot == NULL) + goto out; + while (pathp->objnode) { + pathp->objnode->slots[pathp->offset] = NULL; + pathp->objnode->slots_in_use--; + if (pathp->objnode->slots_in_use) { + if (pathp->objnode == obj->objnode_tree_root) { + while (obj->objnode_tree_height > 0 && + obj->objnode_tree_root->slots_in_use == 1 && + obj->objnode_tree_root->slots[0]) { + struct tmem_objnode *to_free = + obj->objnode_tree_root; + + obj->objnode_tree_root = + to_free->slots[0]; + obj->objnode_tree_height--; + to_free->slots[0] = NULL; + to_free->slots_in_use = 0; + tmem_objnode_free(to_free); + } + } + goto out; + } + tmem_objnode_free(pathp->objnode); /* 0 slots used, free it */ + pathp--; + } + obj->objnode_tree_height = 0; + obj->objnode_tree_root = NULL; + +out: + if (slot != NULL) + obj->pampd_count--; + BUG_ON(obj->pampd_count < 0); + return slot; +} + +/* Recursively walk the objnode_tree destroying pampds and objnodes. */ +static void tmem_objnode_node_destroy(struct tmem_obj *obj, + struct tmem_objnode *objnode, + unsigned int ht) +{ + int i; + + if (ht == 0) + return; + for (i = 0; i < OBJNODE_TREE_MAP_SIZE; i++) { + if (objnode->slots[i]) { + if (ht == 1) { + obj->pampd_count--; + (*tmem_pamops.free)(objnode->slots[i], + obj->pool, NULL, 0, true); + objnode->slots[i] = NULL; + continue; + } + tmem_objnode_node_destroy(obj, objnode->slots[i], ht-1); + tmem_objnode_free(objnode->slots[i]); + objnode->slots[i] = NULL; + } + } +} + +static void tmem_pampd_destroy_all_in_obj(struct tmem_obj *obj, + bool pool_destroy) +{ + if (obj->objnode_tree_root == NULL) + return; + if (obj->objnode_tree_height == 0) { + obj->pampd_count--; + (*tmem_pamops.free)(obj->objnode_tree_root, + obj->pool, NULL, 0, true); + } else { + tmem_objnode_node_destroy(obj, obj->objnode_tree_root, + obj->objnode_tree_height); + tmem_objnode_free(obj->objnode_tree_root); + obj->objnode_tree_height = 0; + } + obj->objnode_tree_root = NULL; +#ifdef CONFIG_RAMSTER + if (tmem_pamops.free_obj != NULL) + (*tmem_pamops.free_obj)(obj->pool, obj, pool_destroy); +#endif +} + +/* + * Tmem is operated on by a set of well-defined actions: + * "put", "get", "flush", "flush_object", "new pool" and "destroy pool". + * (The tmem ABI allows for subpages and exchanges but these operations + * are not included in this implementation.) + * + * These "tmem core" operations are implemented in the following functions. + */ + +/* + * "Put" a page, e.g. associate the passed pampd with the passed handle. + * Tmem_put is complicated by a corner case: What if a page with matching + * handle already exists in tmem? To guarantee coherency, one of two + * actions is necessary: Either the data for the page must be overwritten, + * or the page must be "flushed" so that the data is not accessible to a + * subsequent "get". Since these "duplicate puts" are relatively rare, + * this implementation always flushes for simplicity. + */ +int tmem_put(struct tmem_pool *pool, struct tmem_oid *oidp, uint32_t index, + bool raw, void *pampd_to_use) +{ + struct tmem_obj *obj = NULL, *objfound = NULL, *objnew = NULL; + void *pampd = NULL, *pampd_del = NULL; + int ret = -ENOMEM; + struct tmem_hashbucket *hb; + + hb = &pool->hashbucket[tmem_oid_hash(oidp)]; + spin_lock(&hb->lock); + obj = objfound = tmem_obj_find(hb, oidp); + if (obj != NULL) { + pampd = tmem_pampd_lookup_in_obj(objfound, index); + if (pampd != NULL) { + /* if found, is a dup put, flush the old one */ + pampd_del = tmem_pampd_delete_from_obj(obj, index); + BUG_ON(pampd_del != pampd); + (*tmem_pamops.free)(pampd, pool, oidp, index, true); + if (obj->pampd_count == 0) { + objnew = obj; + objfound = NULL; + } + pampd = NULL; + } + } else { + obj = objnew = (*tmem_hostops.obj_alloc)(pool); + if (unlikely(obj == NULL)) { + ret = -ENOMEM; + goto out; + } + tmem_obj_init(obj, hb, pool, oidp); + } + BUG_ON(obj == NULL); + BUG_ON(((objnew != obj) && (objfound != obj)) || (objnew == objfound)); + pampd = pampd_to_use; + BUG_ON(pampd_to_use == NULL); + ret = tmem_pampd_add_to_obj(obj, index, pampd); + if (unlikely(ret == -ENOMEM)) + /* may have partially built objnode tree ("stump") */ + goto delete_and_free; + (*tmem_pamops.create_finish)(pampd, is_ephemeral(pool)); + goto out; + +delete_and_free: + (void)tmem_pampd_delete_from_obj(obj, index); + if (pampd) + (*tmem_pamops.free)(pampd, pool, NULL, 0, true); + if (objnew) { + tmem_obj_free(objnew, hb); + (*tmem_hostops.obj_free)(objnew, pool); + } +out: + spin_unlock(&hb->lock); + return ret; +} + +#ifdef CONFIG_RAMSTER +/* + * For ramster only: The following routines provide a two-step sequence + * to allow the caller to replace a pampd in the tmem data structures with + * another pampd. Here, we lookup the passed handle and, if found, return the + * associated pampd and object, leaving the hashbucket locked and returning + * a reference to it. The caller is expected to immediately call the + * matching tmem_localify_finish routine which will handles the replacement + * and unlocks the hashbucket. + */ +void *tmem_localify_get_pampd(struct tmem_pool *pool, struct tmem_oid *oidp, + uint32_t index, struct tmem_obj **ret_obj, + void **saved_hb) +{ + struct tmem_hashbucket *hb; + struct tmem_obj *obj = NULL; + void *pampd = NULL; + + hb = &pool->hashbucket[tmem_oid_hash(oidp)]; + spin_lock(&hb->lock); + obj = tmem_obj_find(hb, oidp); + if (likely(obj != NULL)) + pampd = tmem_pampd_lookup_in_obj(obj, index); + *ret_obj = obj; + *saved_hb = (void *)hb; + /* note, hashbucket remains locked */ + return pampd; +} + +void tmem_localify_finish(struct tmem_obj *obj, uint32_t index, + void *pampd, void *saved_hb, bool delete) +{ + struct tmem_hashbucket *hb = (struct tmem_hashbucket *)saved_hb; + + BUG_ON(!spin_is_locked(&hb->lock)); + if (pampd != NULL) { + BUG_ON(obj == NULL); + (void)tmem_pampd_replace_in_obj(obj, index, pampd, 1); + (*tmem_pamops.create_finish)(pampd, is_ephemeral(obj->pool)); + } else if (delete) { + BUG_ON(obj == NULL); + (void)tmem_pampd_delete_from_obj(obj, index); + } + spin_unlock(&hb->lock); +} + +/* + * For ramster only. Helper function to support asynchronous tmem_get. + */ +static int tmem_repatriate(void **ppampd, struct tmem_hashbucket *hb, + struct tmem_pool *pool, struct tmem_oid *oidp, + uint32_t index, bool free, char *data) +{ + void *old_pampd = *ppampd, *new_pampd = NULL; + bool intransit = false; + int ret = 0; + + if (!is_ephemeral(pool)) + new_pampd = (*tmem_pamops.repatriate_preload)( + old_pampd, pool, oidp, index, &intransit); + if (intransit) + ret = -EAGAIN; + else if (new_pampd != NULL) + *ppampd = new_pampd; + /* must release the hb->lock else repatriate can't sleep */ + spin_unlock(&hb->lock); + if (!intransit) + ret = (*tmem_pamops.repatriate)(old_pampd, new_pampd, pool, + oidp, index, free, data); + if (ret == -EAGAIN) { + /* rare I think, but should cond_resched()??? */ + usleep_range(10, 1000); + } else if (ret == -ENOTCONN || ret == -EHOSTDOWN) { + ret = -1; + } else if (ret != 0 && ret != -ENOENT) { + ret = -1; + } + /* note hb->lock has now been unlocked */ + return ret; +} + +/* + * For ramster only. If a page in tmem matches the handle, replace the + * page so that any subsequent "get" gets the new page. Returns 0 if + * there was a page to replace, else returns -1. + */ +int tmem_replace(struct tmem_pool *pool, struct tmem_oid *oidp, + uint32_t index, void *new_pampd) +{ + struct tmem_obj *obj; + int ret = -1; + struct tmem_hashbucket *hb; + + hb = &pool->hashbucket[tmem_oid_hash(oidp)]; + spin_lock(&hb->lock); + obj = tmem_obj_find(hb, oidp); + if (obj == NULL) + goto out; + new_pampd = tmem_pampd_replace_in_obj(obj, index, new_pampd, 0); + /* if we bug here, pamops wasn't properly set up for ramster */ + BUG_ON(tmem_pamops.replace_in_obj == NULL); + ret = (*tmem_pamops.replace_in_obj)(new_pampd, obj); +out: + spin_unlock(&hb->lock); + return ret; +} +#endif + +/* + * "Get" a page, e.g. if a pampd can be found matching the passed handle, + * use a pamops callback to recreated the page from the pampd with the + * matching handle. By tmem definition, when a "get" is successful on + * an ephemeral page, the page is "flushed", and when a "get" is successful + * on a persistent page, the page is retained in tmem. Note that to preserve + * coherency, "get" can never be skipped if tmem contains the data. + * That is, if a get is done with a certain handle and fails, any + * subsequent "get" must also fail (unless of course there is a + * "put" done with the same handle). + */ +int tmem_get(struct tmem_pool *pool, struct tmem_oid *oidp, uint32_t index, + char *data, size_t *sizep, bool raw, int get_and_free) +{ + struct tmem_obj *obj; + void *pampd = NULL; + bool ephemeral = is_ephemeral(pool); + int ret = -1; + struct tmem_hashbucket *hb; + bool free = (get_and_free == 1) || ((get_and_free == 0) && ephemeral); + bool lock_held = false; + void **ppampd; + + do { + hb = &pool->hashbucket[tmem_oid_hash(oidp)]; + spin_lock(&hb->lock); + lock_held = true; + obj = tmem_obj_find(hb, oidp); + if (obj == NULL) + goto out; + ppampd = __tmem_pampd_lookup_in_obj(obj, index); + if (ppampd == NULL) + goto out; +#ifdef CONFIG_RAMSTER + if ((tmem_pamops.is_remote != NULL) && + tmem_pamops.is_remote(*ppampd)) { + ret = tmem_repatriate(ppampd, hb, pool, oidp, + index, free, data); + /* tmem_repatriate releases hb->lock */ + lock_held = false; + *sizep = PAGE_SIZE; + if (ret != -EAGAIN) + goto out; + } +#endif + } while (ret == -EAGAIN); + if (free) + pampd = tmem_pampd_delete_from_obj(obj, index); + else + pampd = tmem_pampd_lookup_in_obj(obj, index); + if (pampd == NULL) + goto out; + if (free) { + if (obj->pampd_count == 0) { + tmem_obj_free(obj, hb); + (*tmem_hostops.obj_free)(obj, pool); + obj = NULL; + } + } + if (free) + ret = (*tmem_pamops.get_data_and_free)( + data, sizep, raw, pampd, pool, oidp, index); + else + ret = (*tmem_pamops.get_data)( + data, sizep, raw, pampd, pool, oidp, index); + if (ret < 0) + goto out; + ret = 0; +out: + if (lock_held) + spin_unlock(&hb->lock); + return ret; +} + +/* + * If a page in tmem matches the handle, "flush" this page from tmem such + * that any subsequent "get" does not succeed (unless, of course, there + * was another "put" with the same handle). + */ +int tmem_flush_page(struct tmem_pool *pool, + struct tmem_oid *oidp, uint32_t index) +{ + struct tmem_obj *obj; + void *pampd; + int ret = -1; + struct tmem_hashbucket *hb; + + hb = &pool->hashbucket[tmem_oid_hash(oidp)]; + spin_lock(&hb->lock); + obj = tmem_obj_find(hb, oidp); + if (obj == NULL) + goto out; + pampd = tmem_pampd_delete_from_obj(obj, index); + if (pampd == NULL) + goto out; + (*tmem_pamops.free)(pampd, pool, oidp, index, true); + if (obj->pampd_count == 0) { + tmem_obj_free(obj, hb); + (*tmem_hostops.obj_free)(obj, pool); + } + ret = 0; + +out: + spin_unlock(&hb->lock); + return ret; +} + +/* + * "Flush" all pages in tmem matching this oid. + */ +int tmem_flush_object(struct tmem_pool *pool, struct tmem_oid *oidp) +{ + struct tmem_obj *obj; + struct tmem_hashbucket *hb; + int ret = -1; + + hb = &pool->hashbucket[tmem_oid_hash(oidp)]; + spin_lock(&hb->lock); + obj = tmem_obj_find(hb, oidp); + if (obj == NULL) + goto out; + tmem_pampd_destroy_all_in_obj(obj, false); + tmem_obj_free(obj, hb); + (*tmem_hostops.obj_free)(obj, pool); + ret = 0; + +out: + spin_unlock(&hb->lock); + return ret; +} + +/* + * "Flush" all pages (and tmem_objs) from this tmem_pool and disable + * all subsequent access to this tmem_pool. + */ +int tmem_destroy_pool(struct tmem_pool *pool) +{ + int ret = -1; + + if (pool == NULL) + goto out; + tmem_pool_flush(pool, 1); + ret = 0; +out: + return ret; +} + +static LIST_HEAD(tmem_global_pool_list); + +/* + * Create a new tmem_pool with the provided flag and return + * a pool id provided by the tmem host implementation. + */ +void tmem_new_pool(struct tmem_pool *pool, uint32_t flags) +{ + int persistent = flags & TMEM_POOL_PERSIST; + int shared = flags & TMEM_POOL_SHARED; + struct tmem_hashbucket *hb = &pool->hashbucket[0]; + int i; + + for (i = 0; i < TMEM_HASH_BUCKETS; i++, hb++) { + hb->obj_rb_root = RB_ROOT; + spin_lock_init(&hb->lock); + } + INIT_LIST_HEAD(&pool->pool_list); + atomic_set(&pool->obj_count, 0); + SET_SENTINEL(pool, POOL); + list_add_tail(&pool->pool_list, &tmem_global_pool_list); + pool->persistent = persistent; + pool->shared = shared; +} diff --git a/drivers/staging/ramster/tmem.h b/drivers/staging/ramster/tmem.h new file mode 100644 index 0000000..adbe5a8 --- /dev/null +++ b/drivers/staging/ramster/tmem.h @@ -0,0 +1,259 @@ +/* + * tmem.h + * + * Transcendent memory + * + * Copyright (c) 2009-2012, Dan Magenheimer, Oracle Corp. + */ + +#ifndef _TMEM_H_ +#define _TMEM_H_ + +#include +#include +#include +#include + +/* + * These are defined by the Xen<->Linux ABI so should remain consistent + */ +#define TMEM_POOL_PERSIST 1 +#define TMEM_POOL_SHARED 2 +#define TMEM_POOL_PRECOMPRESSED 4 +#define TMEM_POOL_PAGESIZE_SHIFT 4 +#define TMEM_POOL_PAGESIZE_MASK 0xf +#define TMEM_POOL_RESERVED_BITS 0x00ffff00 + +/* + * sentinels have proven very useful for debugging but can be removed + * or disabled before final merge. + */ +#undef SENTINELS +#ifdef SENTINELS +#define DECL_SENTINEL uint32_t sentinel; +#define SET_SENTINEL(_x, _y) (_x->sentinel = _y##_SENTINEL) +#define INVERT_SENTINEL(_x, _y) (_x->sentinel = ~_y##_SENTINEL) +#define ASSERT_SENTINEL(_x, _y) WARN_ON(_x->sentinel != _y##_SENTINEL) +#define ASSERT_INVERTED_SENTINEL(_x, _y) WARN_ON(_x->sentinel != ~_y##_SENTINEL) +#else +#define DECL_SENTINEL +#define SET_SENTINEL(_x, _y) do { } while (0) +#define INVERT_SENTINEL(_x, _y) do { } while (0) +#define ASSERT_SENTINEL(_x, _y) do { } while (0) +#define ASSERT_INVERTED_SENTINEL(_x, _y) do { } while (0) +#endif + +#define ASSERT_SPINLOCK(_l) lockdep_assert_held(_l) + +/* + * A pool is the highest-level data structure managed by tmem and + * usually corresponds to a large independent set of pages such as + * a filesystem. Each pool has an id, and certain attributes and counters. + * It also contains a set of hash buckets, each of which contains an rbtree + * of objects and a lock to manage concurrency within the pool. + */ + +#define TMEM_HASH_BUCKET_BITS 8 +#define TMEM_HASH_BUCKETS (1<persistent) +#define is_ephemeral(_p) (!(_p->persistent)) + +/* + * An object id ("oid") is large: 192-bits (to ensure, for example, files + * in a modern filesystem can be uniquely identified). + */ + +struct tmem_oid { + uint64_t oid[3]; +}; + +static inline void tmem_oid_set_invalid(struct tmem_oid *oidp) +{ + oidp->oid[0] = oidp->oid[1] = oidp->oid[2] = -1UL; +} + +static inline bool tmem_oid_valid(struct tmem_oid *oidp) +{ + return oidp->oid[0] != -1UL || oidp->oid[1] != -1UL || + oidp->oid[2] != -1UL; +} + +static inline int tmem_oid_compare(struct tmem_oid *left, + struct tmem_oid *right) +{ + int ret; + + if (left->oid[2] == right->oid[2]) { + if (left->oid[1] == right->oid[1]) { + if (left->oid[0] == right->oid[0]) + ret = 0; + else if (left->oid[0] < right->oid[0]) + ret = -1; + else + return 1; + } else if (left->oid[1] < right->oid[1]) + ret = -1; + else + ret = 1; + } else if (left->oid[2] < right->oid[2]) + ret = -1; + else + ret = 1; + return ret; +} + +static inline unsigned tmem_oid_hash(struct tmem_oid *oidp) +{ + return hash_long(oidp->oid[0] ^ oidp->oid[1] ^ oidp->oid[2], + TMEM_HASH_BUCKET_BITS); +} + +#ifdef CONFIG_RAMSTER +struct tmem_xhandle { + uint8_t client_id; + uint8_t xh_data_cksum; + uint16_t xh_data_size; + uint16_t pool_id; + struct tmem_oid oid; + uint32_t index; + void *extra; +}; + +static inline struct tmem_xhandle tmem_xhandle_fill(uint16_t client_id, + struct tmem_pool *pool, + struct tmem_oid *oidp, + uint32_t index) +{ + struct tmem_xhandle xh; + xh.client_id = client_id; + xh.xh_data_cksum = (uint8_t)-1; + xh.xh_data_size = (uint16_t)-1; + xh.pool_id = pool->pool_id; + xh.oid = *oidp; + xh.index = index; + return xh; +} +#endif + + +/* + * A tmem_obj contains an identifier (oid), pointers to the parent + * pool and the rb_tree to which it belongs, counters, and an ordered + * set of pampds, structured in a radix-tree-like tree. The intermediate + * nodes of the tree are called tmem_objnodes. + */ + +struct tmem_objnode; + +struct tmem_obj { + struct tmem_oid oid; + struct tmem_pool *pool; + struct rb_node rb_tree_node; + struct tmem_objnode *objnode_tree_root; + unsigned int objnode_tree_height; + unsigned long objnode_count; + long pampd_count; +#ifdef CONFIG_RAMSTER + /* + * for current design of ramster, all pages belonging to + * an object reside on the same remotenode and extra is + * used to record the number of the remotenode so a + * flush-object operation can specify it + */ + void *extra; /* for private use by pampd implementation */ +#endif + DECL_SENTINEL +}; + +#define OBJNODE_TREE_MAP_SHIFT 6 +#define OBJNODE_TREE_MAP_SIZE (1UL << OBJNODE_TREE_MAP_SHIFT) +#define OBJNODE_TREE_MAP_MASK (OBJNODE_TREE_MAP_SIZE-1) +#define OBJNODE_TREE_INDEX_BITS (8 /* CHAR_BIT */ * sizeof(unsigned long)) +#define OBJNODE_TREE_MAX_PATH \ + (OBJNODE_TREE_INDEX_BITS/OBJNODE_TREE_MAP_SHIFT + 2) + +struct tmem_objnode { + struct tmem_obj *obj; + DECL_SENTINEL + void *slots[OBJNODE_TREE_MAP_SIZE]; + unsigned int slots_in_use; +}; + +struct tmem_handle { + struct tmem_oid oid; /* 24 bytes */ + uint32_t index; + uint16_t pool_id; + uint16_t client_id; +}; + + +/* pampd abstract datatype methods provided by the PAM implementation */ +struct tmem_pamops { + void (*create_finish)(void *, bool); + int (*get_data)(char *, size_t *, bool, void *, struct tmem_pool *, + struct tmem_oid *, uint32_t); + int (*get_data_and_free)(char *, size_t *, bool, void *, + struct tmem_pool *, struct tmem_oid *, + uint32_t); + void (*free)(void *, struct tmem_pool *, + struct tmem_oid *, uint32_t, bool); +#ifdef CONFIG_RAMSTER + void (*new_obj)(struct tmem_obj *); + void (*free_obj)(struct tmem_pool *, struct tmem_obj *, bool); + void *(*repatriate_preload)(void *, struct tmem_pool *, + struct tmem_oid *, uint32_t, bool *); + int (*repatriate)(void *, void *, struct tmem_pool *, + struct tmem_oid *, uint32_t, bool, void *); + bool (*is_remote)(void *); + int (*replace_in_obj)(void *, struct tmem_obj *); +#endif +}; +extern void tmem_register_pamops(struct tmem_pamops *m); + +/* memory allocation methods provided by the host implementation */ +struct tmem_hostops { + struct tmem_obj *(*obj_alloc)(struct tmem_pool *); + void (*obj_free)(struct tmem_obj *, struct tmem_pool *); + struct tmem_objnode *(*objnode_alloc)(struct tmem_pool *); + void (*objnode_free)(struct tmem_objnode *, struct tmem_pool *); +}; +extern void tmem_register_hostops(struct tmem_hostops *m); + +/* core tmem accessor functions */ +extern int tmem_put(struct tmem_pool *, struct tmem_oid *, uint32_t index, + bool, void *); +extern int tmem_get(struct tmem_pool *, struct tmem_oid *, uint32_t index, + char *, size_t *, bool, int); +extern int tmem_flush_page(struct tmem_pool *, struct tmem_oid *, + uint32_t index); +extern int tmem_flush_object(struct tmem_pool *, struct tmem_oid *); +extern int tmem_destroy_pool(struct tmem_pool *); +extern void tmem_new_pool(struct tmem_pool *, uint32_t); +#ifdef CONFIG_RAMSTER +extern int tmem_replace(struct tmem_pool *, struct tmem_oid *, uint32_t index, + void *); +extern void *tmem_localify_get_pampd(struct tmem_pool *, struct tmem_oid *, + uint32_t index, struct tmem_obj **, + void **); +extern void tmem_localify_finish(struct tmem_obj *, uint32_t index, + void *, void *, bool); +#endif +#endif /* _TMEM_H */ diff --git a/drivers/staging/ramster/zbud.c b/drivers/staging/ramster/zbud.c new file mode 100644 index 0000000..a7c4361 --- /dev/null +++ b/drivers/staging/ramster/zbud.c @@ -0,0 +1,1060 @@ +/* + * zbud.c - Compression buddies allocator + * + * Copyright (c) 2010-2012, Dan Magenheimer, Oracle Corp. + * + * Compression buddies ("zbud") provides for efficiently packing two + * (or, possibly in the future, more) compressed pages ("zpages") into + * a single "raw" pageframe and for tracking both zpages and pageframes + * so that whole pageframes can be easily reclaimed in LRU-like order. + * It is designed to be used in conjunction with transcendent memory + * ("tmem"); for example separate LRU lists are maintained for persistent + * vs. ephemeral pages. + * + * A zbudpage is an overlay for a struct page and thus each zbudpage + * refers to a physical pageframe of RAM. When the caller passes a + * struct page from the kernel's page allocator, zbud "transforms" it + * to a zbudpage which sets/uses a different set of fields than the + * struct-page and thus must "untransform" it back by reinitializing + * certain fields before the struct-page can be freed. The fields + * of a zbudpage include a page lock for controlling access to the + * corresponding pageframe, and there is a size field for each zpage. + * Each zbudpage also lives on two linked lists: a "budlist" which is + * used to support efficient buddying of zpages; and an "lru" which + * is used for reclaiming pageframes in approximately least-recently-used + * order. + * + * A zbudpageframe is a pageframe divided up into aligned 64-byte "chunks" + * which contain the compressed data for zero, one, or two zbuds. Contained + * with the compressed data is a tmem_handle which is a key to allow + * the same data to be found via the tmem interface so the zpage can + * be invalidated (for ephemeral pages) or repatriated to the swap cache + * (for persistent pages). The contents of a zbudpageframe must never + * be accessed without holding the page lock for the corresponding + * zbudpage and, to accomodate highmem machines, the contents may + * only be examined or changes when kmapped. Thus, when in use, a + * kmapped zbudpageframe is referred to in the zbud code as "void *zbpg". + * + * Note that the term "zbud" refers to the combination of a zpage and + * a tmem_handle that is stored as one of possibly two "buddied" zpages; + * it also generically refers to this allocator... sorry for any confusion. + * + * A zbudref is a pointer to a struct zbudpage (which can be cast to a + * struct page), with the LSB either cleared or set to indicate, respectively, + * the first or second zpage in the zbudpageframe. Since a zbudref can be + * cast to a pointer, it is used as the tmem "pampd" pointer and uniquely + * references a stored tmem page and so is the only zbud data structure + * externally visible to zbud.c/zbud.h. + * + * Since we wish to reclaim entire pageframes but zpages may be randomly + * added and deleted to any given pageframe, we approximate LRU by + * promoting a pageframe to MRU when a zpage is added to it, but + * leaving it at the current place in the list when a zpage is deleted + * from it. As a side effect, zpages that are difficult to buddy (e.g. + * very large paages) will be reclaimed faster than average, which seems + * reasonable. + * + * In the current implementation, no more than two zpages may be stored in + * any pageframe and no zpage ever crosses a pageframe boundary. While + * other zpage allocation mechanisms may allow greater density, this two + * zpage-per-pageframe limit both ensures simple reclaim of pageframes + * (including garbage collection of references to the contents of those + * pageframes from tmem data structures) AND avoids the need for compaction. + * With additional complexity, zbud could be modified to support storing + * up to three zpages per pageframe or, to handle larger average zpages, + * up to three zpages per pair of pageframes, but it is not clear if the + * additional complexity would be worth it. So consider it an exercise + * for future developers. + * + * Note also that zbud does no page allocation or freeing. This is so + * that the caller has complete control over and, for accounting, visibility + * into if/when pages are allocated and freed. + * + * Finally, note that zbud limits the size of zpages it can store; the + * caller must check the zpage size with zbud_max_buddy_size before + * storing it, else BUGs will result. User beware. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "tmem.h" +#include "zcache.h" +#include "zbud.h" + +/* + * We need to ensure that a struct zbudpage is never larger than a + * struct page. This is checked with a BUG_ON in zbud_init. + * + * The unevictable field indicates that a zbud is being added to the + * zbudpage. Since this is a two-phase process (due to tmem locking), + * this field locks the zbudpage against eviction when a zbud match + * or creation is in process. Since this addition process may occur + * in parallel for two zbuds in one zbudpage, the field is a counter + * that must not exceed two. + */ +struct zbudpage { + union { + struct page page; + struct { + unsigned long space_for_flags; + struct { + unsigned zbud0_size:12; + unsigned zbud1_size:12; + unsigned unevictable:2; + }; + struct list_head budlist; + struct list_head lru; + }; + }; +}; + +struct zbudref { + union { + struct zbudpage *zbudpage; + unsigned long zbudref; + }; +}; + +#define CHUNK_SHIFT 6 +#define CHUNK_SIZE (1 << CHUNK_SHIFT) +#define CHUNK_MASK (~(CHUNK_SIZE-1)) +#define NCHUNKS (PAGE_SIZE >> CHUNK_SHIFT) +#define MAX_CHUNK (NCHUNKS-1) + +/* + * The following functions deal with the difference between struct + * page and struct zbudpage. Note the hack of using the pageflags + * from struct page; this is to avoid duplicating all the complex + * pageflag macros. + */ +static inline void zbudpage_spin_lock(struct zbudpage *zbudpage) +{ + struct page *page = (struct page *)zbudpage; + + while (unlikely(test_and_set_bit_lock(PG_locked, &page->flags))) { + do { + cpu_relax(); + } while (test_bit(PG_locked, &page->flags)); + } +} + +static inline void zbudpage_spin_unlock(struct zbudpage *zbudpage) +{ + struct page *page = (struct page *)zbudpage; + + clear_bit(PG_locked, &page->flags); +} + +static inline int zbudpage_spin_trylock(struct zbudpage *zbudpage) +{ + return trylock_page((struct page *)zbudpage); +} + +static inline int zbudpage_is_locked(struct zbudpage *zbudpage) +{ + return PageLocked((struct page *)zbudpage); +} + +static inline void *kmap_zbudpage_atomic(struct zbudpage *zbudpage) +{ + return kmap_atomic((struct page *)zbudpage); +} + +/* + * A dying zbudpage is an ephemeral page in the process of being evicted. + * Any data contained in the zbudpage is invalid and we are just waiting for + * the tmem pampds to be invalidated before freeing the page + */ +static inline int zbudpage_is_dying(struct zbudpage *zbudpage) +{ + struct page *page = (struct page *)zbudpage; + + return test_bit(PG_reclaim, &page->flags); +} + +static inline void zbudpage_set_dying(struct zbudpage *zbudpage) +{ + struct page *page = (struct page *)zbudpage; + + set_bit(PG_reclaim, &page->flags); +} + +static inline void zbudpage_clear_dying(struct zbudpage *zbudpage) +{ + struct page *page = (struct page *)zbudpage; + + clear_bit(PG_reclaim, &page->flags); +} + +/* + * A zombie zbudpage is a persistent page in the process of being evicted. + * The data contained in the zbudpage is valid and we are just waiting for + * the tmem pampds to be invalidated before freeing the page + */ +static inline int zbudpage_is_zombie(struct zbudpage *zbudpage) +{ + struct page *page = (struct page *)zbudpage; + + return test_bit(PG_dirty, &page->flags); +} + +static inline void zbudpage_set_zombie(struct zbudpage *zbudpage) +{ + struct page *page = (struct page *)zbudpage; + + set_bit(PG_dirty, &page->flags); +} + +static inline void zbudpage_clear_zombie(struct zbudpage *zbudpage) +{ + struct page *page = (struct page *)zbudpage; + + clear_bit(PG_dirty, &page->flags); +} + +static inline void kunmap_zbudpage_atomic(void *zbpg) +{ + kunmap_atomic(zbpg); +} + +/* + * zbud "translation" and helper functions + */ + +static inline struct zbudpage *zbudref_to_zbudpage(struct zbudref *zref) +{ + unsigned long zbud = (unsigned long)zref; + zbud &= ~1UL; + return (struct zbudpage *)zbud; +} + +static inline struct zbudref *zbudpage_to_zbudref(struct zbudpage *zbudpage, + unsigned budnum) +{ + unsigned long zbud = (unsigned long)zbudpage; + BUG_ON(budnum > 1); + zbud |= budnum; + return (struct zbudref *)zbud; +} + +static inline int zbudref_budnum(struct zbudref *zbudref) +{ + unsigned long zbud = (unsigned long)zbudref; + return zbud & 1UL; +} + +static inline unsigned zbud_max_size(void) +{ + return MAX_CHUNK << CHUNK_SHIFT; +} + +static inline unsigned zbud_size_to_chunks(unsigned size) +{ + BUG_ON(size == 0 || size > zbud_max_size()); + return (size + CHUNK_SIZE - 1) >> CHUNK_SHIFT; +} + +/* can only be used between kmap_zbudpage_atomic/kunmap_zbudpage_atomic! */ +static inline char *zbud_data(void *zbpg, + unsigned budnum, unsigned size) +{ + char *p; + + BUG_ON(size == 0 || size > zbud_max_size()); + p = (char *)zbpg; + if (budnum == 1) + p += PAGE_SIZE - ((size + CHUNK_SIZE - 1) & CHUNK_MASK); + return p; +} + +/* + * These are all informative and exposed through debugfs... except for + * the arrays... anyone know how to do that? To avoid confusion for + * debugfs viewers, some of these should also be atomic_long_t, but + * I don't know how to expose atomics via debugfs either... + */ +static unsigned long zbud_eph_pageframes; +static unsigned long zbud_pers_pageframes; +static unsigned long zbud_eph_zpages; +static unsigned long zbud_pers_zpages; +static u64 zbud_eph_zbytes; +static u64 zbud_pers_zbytes; +static unsigned long zbud_eph_evicted_pageframes; +static unsigned long zbud_pers_evicted_pageframes; +static unsigned long zbud_eph_cumul_zpages; +static unsigned long zbud_pers_cumul_zpages; +static u64 zbud_eph_cumul_zbytes; +static u64 zbud_pers_cumul_zbytes; +static unsigned long zbud_eph_cumul_chunk_counts[NCHUNKS]; +static unsigned long zbud_pers_cumul_chunk_counts[NCHUNKS]; +static unsigned long zbud_eph_buddied_count; +static unsigned long zbud_pers_buddied_count; +static unsigned long zbud_eph_unbuddied_count; +static unsigned long zbud_pers_unbuddied_count; +static unsigned long zbud_eph_zombie_count; +static unsigned long zbud_pers_zombie_count; +static atomic_t zbud_eph_zombie_atomic; +static atomic_t zbud_pers_zombie_atomic; + +#ifdef CONFIG_DEBUG_FS +#include +#define zdfs debugfs_create_size_t +#define zdfs64 debugfs_create_u64 +static int zbud_debugfs_init(void) +{ + struct dentry *root = debugfs_create_dir("zbud", NULL); + if (root == NULL) + return -ENXIO; + + /* + * would be nice to dump the sizes of the unbuddied + * arrays, like was done with sysfs, but it doesn't + * look like debugfs is flexible enough to do that + */ + zdfs64("eph_zbytes", S_IRUGO, root, &zbud_eph_zbytes); + zdfs64("eph_cumul_zbytes", S_IRUGO, root, &zbud_eph_cumul_zbytes); + zdfs64("pers_zbytes", S_IRUGO, root, &zbud_pers_zbytes); + zdfs64("pers_cumul_zbytes", S_IRUGO, root, &zbud_pers_cumul_zbytes); + zdfs("eph_cumul_zpages", S_IRUGO, root, &zbud_eph_cumul_zpages); + zdfs("eph_evicted_pageframes", S_IRUGO, root, + &zbud_eph_evicted_pageframes); + zdfs("eph_zpages", S_IRUGO, root, &zbud_eph_zpages); + zdfs("eph_pageframes", S_IRUGO, root, &zbud_eph_pageframes); + zdfs("eph_buddied_count", S_IRUGO, root, &zbud_eph_buddied_count); + zdfs("eph_unbuddied_count", S_IRUGO, root, &zbud_eph_unbuddied_count); + zdfs("pers_cumul_zpages", S_IRUGO, root, &zbud_pers_cumul_zpages); + zdfs("pers_evicted_pageframes", S_IRUGO, root, + &zbud_pers_evicted_pageframes); + zdfs("pers_zpages", S_IRUGO, root, &zbud_pers_zpages); + zdfs("pers_pageframes", S_IRUGO, root, &zbud_pers_pageframes); + zdfs("pers_buddied_count", S_IRUGO, root, &zbud_pers_buddied_count); + zdfs("pers_unbuddied_count", S_IRUGO, root, &zbud_pers_unbuddied_count); + zdfs("pers_zombie_count", S_IRUGO, root, &zbud_pers_zombie_count); + return 0; +} +#undef zdfs +#undef zdfs64 +#endif + +/* protects the buddied list and all unbuddied lists */ +static DEFINE_SPINLOCK(zbud_eph_lists_lock); +static DEFINE_SPINLOCK(zbud_pers_lists_lock); + +struct zbud_unbuddied { + struct list_head list; + unsigned count; +}; + +/* list N contains pages with N chunks USED and NCHUNKS-N unused */ +/* element 0 is never used but optimizing that isn't worth it */ +static struct zbud_unbuddied zbud_eph_unbuddied[NCHUNKS]; +static struct zbud_unbuddied zbud_pers_unbuddied[NCHUNKS]; +static LIST_HEAD(zbud_eph_lru_list); +static LIST_HEAD(zbud_pers_lru_list); +static LIST_HEAD(zbud_eph_buddied_list); +static LIST_HEAD(zbud_pers_buddied_list); +static LIST_HEAD(zbud_eph_zombie_list); +static LIST_HEAD(zbud_pers_zombie_list); + +/* + * Given a struct page, transform it to a zbudpage so that it can be + * used by zbud and initialize fields as necessary. + */ +static inline struct zbudpage *zbud_init_zbudpage(struct page *page, bool eph) +{ + struct zbudpage *zbudpage = (struct zbudpage *)page; + + BUG_ON(page == NULL); + INIT_LIST_HEAD(&zbudpage->budlist); + INIT_LIST_HEAD(&zbudpage->lru); + zbudpage->zbud0_size = 0; + zbudpage->zbud1_size = 0; + zbudpage->unevictable = 0; + if (eph) + zbud_eph_pageframes++; + else + zbud_pers_pageframes++; + return zbudpage; +} + +/* "Transform" a zbudpage back to a struct page suitable to free. */ +static inline struct page *zbud_unuse_zbudpage(struct zbudpage *zbudpage, + bool eph) +{ + struct page *page = (struct page *)zbudpage; + + BUG_ON(!list_empty(&zbudpage->budlist)); + BUG_ON(!list_empty(&zbudpage->lru)); + BUG_ON(zbudpage->zbud0_size != 0); + BUG_ON(zbudpage->zbud1_size != 0); + BUG_ON(!PageLocked(page)); + BUG_ON(zbudpage->unevictable != 0); + BUG_ON(zbudpage_is_dying(zbudpage)); + BUG_ON(zbudpage_is_zombie(zbudpage)); + if (eph) + zbud_eph_pageframes--; + else + zbud_pers_pageframes--; + zbudpage_spin_unlock(zbudpage); + reset_page_mapcount(page); + init_page_count(page); + page->index = 0; + return page; +} + +/* Mark a zbud as unused and do accounting */ +static inline void zbud_unuse_zbud(struct zbudpage *zbudpage, + int budnum, bool eph) +{ + unsigned size; + + BUG_ON(!zbudpage_is_locked(zbudpage)); + if (budnum == 0) { + size = zbudpage->zbud0_size; + zbudpage->zbud0_size = 0; + } else { + size = zbudpage->zbud1_size; + zbudpage->zbud1_size = 0; + } + if (eph) { + zbud_eph_zbytes -= size; + zbud_eph_zpages--; + } else { + zbud_pers_zbytes -= size; + zbud_pers_zpages--; + } +} + +/* + * Given a zbudpage/budnum/size, a tmem handle, and a kmapped pointer + * to some data, set up the zbud appropriately including data copying + * and accounting. Note that if cdata is NULL, the data copying is + * skipped. (This is useful for lazy writes such as for RAMster.) + */ +static void zbud_init_zbud(struct zbudpage *zbudpage, struct tmem_handle *th, + bool eph, void *cdata, + unsigned budnum, unsigned size) +{ + char *to; + void *zbpg; + struct tmem_handle *to_th; + unsigned nchunks = zbud_size_to_chunks(size); + + BUG_ON(!zbudpage_is_locked(zbudpage)); + zbpg = kmap_zbudpage_atomic(zbudpage); + to = zbud_data(zbpg, budnum, size); + to_th = (struct tmem_handle *)to; + to_th->index = th->index; + to_th->oid = th->oid; + to_th->pool_id = th->pool_id; + to_th->client_id = th->client_id; + to += sizeof(struct tmem_handle); + if (cdata != NULL) + memcpy(to, cdata, size - sizeof(struct tmem_handle)); + kunmap_zbudpage_atomic(zbpg); + if (budnum == 0) + zbudpage->zbud0_size = size; + else + zbudpage->zbud1_size = size; + if (eph) { + zbud_eph_cumul_chunk_counts[nchunks]++; + zbud_eph_zpages++; + zbud_eph_cumul_zpages++; + zbud_eph_zbytes += size; + zbud_eph_cumul_zbytes += size; + } else { + zbud_pers_cumul_chunk_counts[nchunks]++; + zbud_pers_zpages++; + zbud_pers_cumul_zpages++; + zbud_pers_zbytes += size; + zbud_pers_cumul_zbytes += size; + } +} + +/* + * Given a locked dying zbudpage, read out the tmem handles from the data, + * unlock the page, then use the handles to tell tmem to flush out its + * references + */ +static void zbud_evict_tmem(struct zbudpage *zbudpage) +{ + int i, j; + uint32_t pool_id[2], client_id[2]; + uint32_t index[2]; + struct tmem_oid oid[2]; + struct tmem_pool *pool; + void *zbpg; + struct tmem_handle *th; + unsigned size; + + /* read out the tmem handles from the data and set aside */ + zbpg = kmap_zbudpage_atomic(zbudpage); + for (i = 0, j = 0; i < 2; i++) { + size = (i == 0) ? zbudpage->zbud0_size : zbudpage->zbud1_size; + if (size) { + th = (struct tmem_handle *)zbud_data(zbpg, i, size); + client_id[j] = th->client_id; + pool_id[j] = th->pool_id; + oid[j] = th->oid; + index[j] = th->index; + j++; + zbud_unuse_zbud(zbudpage, i, true); + } + } + kunmap_zbudpage_atomic(zbpg); + zbudpage_spin_unlock(zbudpage); + /* zbudpage is now an unlocked dying... tell tmem to flush pointers */ + for (i = 0; i < j; i++) { + pool = zcache_get_pool_by_id(client_id[i], pool_id[i]); + if (pool != NULL) { + tmem_flush_page(pool, &oid[i], index[i]); + zcache_put_pool(pool); + } + } +} + +/* + * Externally callable zbud handling routines. + */ + +/* + * Return the maximum size compressed page that can be stored (secretly + * setting aside space for the tmem handle. + */ +unsigned int zbud_max_buddy_size(void) +{ + return zbud_max_size() - sizeof(struct tmem_handle); +} + +/* + * Given a zbud reference, free the corresponding zbud from all lists, + * mark it as unused, do accounting, and if the freeing of the zbud + * frees up an entire pageframe, return it to the caller (else NULL). + */ +struct page *zbud_free_and_delist(struct zbudref *zref, bool eph, + unsigned int *zsize, unsigned int *zpages) +{ + unsigned long budnum = zbudref_budnum(zref); + struct zbudpage *zbudpage = zbudref_to_zbudpage(zref); + struct page *page = NULL; + unsigned chunks, bud_size, other_bud_size; + spinlock_t *lists_lock = + eph ? &zbud_eph_lists_lock : &zbud_pers_lists_lock; + struct zbud_unbuddied *unbud = + eph ? zbud_eph_unbuddied : zbud_pers_unbuddied; + + + spin_lock(lists_lock); + zbudpage_spin_lock(zbudpage); + if (zbudpage_is_dying(zbudpage)) { + /* ignore dying zbudpage... see zbud_evict_pageframe_lru() */ + zbudpage_spin_unlock(zbudpage); + spin_unlock(lists_lock); + *zpages = 0; + *zsize = 0; + goto out; + } + if (budnum == 0) { + bud_size = zbudpage->zbud0_size; + other_bud_size = zbudpage->zbud1_size; + } else { + bud_size = zbudpage->zbud1_size; + other_bud_size = zbudpage->zbud0_size; + } + *zsize = bud_size - sizeof(struct tmem_handle); + *zpages = 1; + zbud_unuse_zbud(zbudpage, budnum, eph); + if (other_bud_size == 0) { /* was unbuddied: unlist and free */ + chunks = zbud_size_to_chunks(bud_size) ; + if (zbudpage_is_zombie(zbudpage)) { + if (eph) + zbud_pers_zombie_count = + atomic_dec_return(&zbud_eph_zombie_atomic); + else + zbud_pers_zombie_count = + atomic_dec_return(&zbud_pers_zombie_atomic); + zbudpage_clear_zombie(zbudpage); + } else { + BUG_ON(list_empty(&unbud[chunks].list)); + list_del_init(&zbudpage->budlist); + unbud[chunks].count--; + } + list_del_init(&zbudpage->lru); + spin_unlock(lists_lock); + if (eph) + zbud_eph_unbuddied_count--; + else + zbud_pers_unbuddied_count--; + page = zbud_unuse_zbudpage(zbudpage, eph); + } else { /* was buddied: move remaining buddy to unbuddied list */ + chunks = zbud_size_to_chunks(other_bud_size) ; + if (!zbudpage_is_zombie(zbudpage)) { + list_del_init(&zbudpage->budlist); + list_add_tail(&zbudpage->budlist, &unbud[chunks].list); + unbud[chunks].count++; + } + if (eph) { + zbud_eph_buddied_count--; + zbud_eph_unbuddied_count++; + } else { + zbud_pers_unbuddied_count++; + zbud_pers_buddied_count--; + } + /* don't mess with lru, no need to move it */ + zbudpage_spin_unlock(zbudpage); + spin_unlock(lists_lock); + } +out: + return page; +} + +/* + * Given a tmem handle, and a kmapped pointer to compressed data of + * the given size, try to find an unbuddied zbudpage in which to + * create a zbud. If found, put it there, mark the zbudpage unevictable, + * and return a zbudref to it. Else return NULL. + */ +struct zbudref *zbud_match_prep(struct tmem_handle *th, bool eph, + void *cdata, unsigned size) +{ + struct zbudpage *zbudpage = NULL, *zbudpage2; + unsigned long budnum = 0UL; + unsigned nchunks; + int i, found_good_buddy = 0; + spinlock_t *lists_lock = + eph ? &zbud_eph_lists_lock : &zbud_pers_lists_lock; + struct zbud_unbuddied *unbud = + eph ? zbud_eph_unbuddied : zbud_pers_unbuddied; + + size += sizeof(struct tmem_handle); + nchunks = zbud_size_to_chunks(size); + for (i = MAX_CHUNK - nchunks + 1; i > 0; i--) { + spin_lock(lists_lock); + if (!list_empty(&unbud[i].list)) { + list_for_each_entry_safe(zbudpage, zbudpage2, + &unbud[i].list, budlist) { + if (zbudpage_spin_trylock(zbudpage)) { + found_good_buddy = i; + goto found_unbuddied; + } + } + } + spin_unlock(lists_lock); + } + zbudpage = NULL; + goto out; + +found_unbuddied: + BUG_ON(!zbudpage_is_locked(zbudpage)); + BUG_ON(!((zbudpage->zbud0_size == 0) ^ (zbudpage->zbud1_size == 0))); + if (zbudpage->zbud0_size == 0) + budnum = 0UL; + else if (zbudpage->zbud1_size == 0) + budnum = 1UL; + list_del_init(&zbudpage->budlist); + if (eph) { + list_add_tail(&zbudpage->budlist, &zbud_eph_buddied_list); + unbud[found_good_buddy].count--; + zbud_eph_unbuddied_count--; + zbud_eph_buddied_count++; + /* "promote" raw zbudpage to most-recently-used */ + list_del_init(&zbudpage->lru); + list_add_tail(&zbudpage->lru, &zbud_eph_lru_list); + } else { + list_add_tail(&zbudpage->budlist, &zbud_pers_buddied_list); + unbud[found_good_buddy].count--; + zbud_pers_unbuddied_count--; + zbud_pers_buddied_count++; + /* "promote" raw zbudpage to most-recently-used */ + list_del_init(&zbudpage->lru); + list_add_tail(&zbudpage->lru, &zbud_pers_lru_list); + } + zbud_init_zbud(zbudpage, th, eph, cdata, budnum, size); + zbudpage->unevictable++; + BUG_ON(zbudpage->unevictable == 3); + zbudpage_spin_unlock(zbudpage); + spin_unlock(lists_lock); +out: + return zbudpage_to_zbudref(zbudpage, budnum); + +} + +/* + * Given a tmem handle, and a kmapped pointer to compressed data of + * the given size, and a newly allocated struct page, create an unevictable + * zbud in that new page and return a zbudref to it. + */ +struct zbudref *zbud_create_prep(struct tmem_handle *th, bool eph, + void *cdata, unsigned size, + struct page *newpage) +{ + struct zbudpage *zbudpage; + unsigned long budnum = 0; + unsigned nchunks; + spinlock_t *lists_lock = + eph ? &zbud_eph_lists_lock : &zbud_pers_lists_lock; + struct zbud_unbuddied *unbud = + eph ? zbud_eph_unbuddied : zbud_pers_unbuddied; + +#if 0 + /* this may be worth it later to support decompress-in-place? */ + static unsigned long counter; + budnum = counter++ & 1; /* alternate using zbud0 and zbud1 */ +#endif + + if (size > zbud_max_buddy_size()) + return NULL; + if (newpage == NULL) + return NULL; + + size += sizeof(struct tmem_handle); + nchunks = zbud_size_to_chunks(size) ; + spin_lock(lists_lock); + zbudpage = zbud_init_zbudpage(newpage, eph); + zbudpage_spin_lock(zbudpage); + list_add_tail(&zbudpage->budlist, &unbud[nchunks].list); + if (eph) { + list_add_tail(&zbudpage->lru, &zbud_eph_lru_list); + zbud_eph_unbuddied_count++; + } else { + list_add_tail(&zbudpage->lru, &zbud_pers_lru_list); + zbud_pers_unbuddied_count++; + } + unbud[nchunks].count++; + zbud_init_zbud(zbudpage, th, eph, cdata, budnum, size); + zbudpage->unevictable++; + BUG_ON(zbudpage->unevictable == 3); + zbudpage_spin_unlock(zbudpage); + spin_unlock(lists_lock); + return zbudpage_to_zbudref(zbudpage, budnum); +} + +/* + * Finish creation of a zbud by, assuming another zbud isn't being created + * in parallel, marking it evictable. + */ +void zbud_create_finish(struct zbudref *zref, bool eph) +{ + struct zbudpage *zbudpage = zbudref_to_zbudpage(zref); + spinlock_t *lists_lock = + eph ? &zbud_eph_lists_lock : &zbud_pers_lists_lock; + + spin_lock(lists_lock); + zbudpage_spin_lock(zbudpage); + BUG_ON(zbudpage_is_dying(zbudpage)); + zbudpage->unevictable--; + BUG_ON((int)zbudpage->unevictable < 0); + zbudpage_spin_unlock(zbudpage); + spin_unlock(lists_lock); +} + +/* + * Given a zbudref and a struct page, decompress the data from + * the zbud into the physical page represented by the struct page + * by upcalling to zcache_decompress + */ +int zbud_decompress(struct page *data_page, struct zbudref *zref, bool eph, + void (*decompress)(char *, unsigned int, char *)) +{ + struct zbudpage *zbudpage = zbudref_to_zbudpage(zref); + unsigned long budnum = zbudref_budnum(zref); + void *zbpg; + char *to_va, *from_va; + unsigned size; + int ret = -1; + spinlock_t *lists_lock = + eph ? &zbud_eph_lists_lock : &zbud_pers_lists_lock; + + spin_lock(lists_lock); + zbudpage_spin_lock(zbudpage); + if (zbudpage_is_dying(zbudpage)) { + /* ignore dying zbudpage... see zbud_evict_pageframe_lru() */ + goto out; + } + zbpg = kmap_zbudpage_atomic(zbudpage); + to_va = kmap_atomic(data_page); + if (budnum == 0) + size = zbudpage->zbud0_size; + else + size = zbudpage->zbud1_size; + BUG_ON(size == 0 || size > zbud_max_size()); + from_va = zbud_data(zbpg, budnum, size); + from_va += sizeof(struct tmem_handle); + size -= sizeof(struct tmem_handle); + decompress(from_va, size, to_va); + kunmap_atomic(to_va); + kunmap_zbudpage_atomic(zbpg); + ret = 0; +out: + zbudpage_spin_unlock(zbudpage); + spin_unlock(lists_lock); + return ret; +} + +/* + * Given a zbudref and a kernel pointer, copy the data from + * the zbud to the kernel pointer. + */ +int zbud_copy_from_zbud(char *to_va, struct zbudref *zref, + size_t *sizep, bool eph) +{ + struct zbudpage *zbudpage = zbudref_to_zbudpage(zref); + unsigned long budnum = zbudref_budnum(zref); + void *zbpg; + char *from_va; + unsigned size; + int ret = -1; + spinlock_t *lists_lock = + eph ? &zbud_eph_lists_lock : &zbud_pers_lists_lock; + + spin_lock(lists_lock); + zbudpage_spin_lock(zbudpage); + if (zbudpage_is_dying(zbudpage)) { + /* ignore dying zbudpage... see zbud_evict_pageframe_lru() */ + goto out; + } + zbpg = kmap_zbudpage_atomic(zbudpage); + if (budnum == 0) + size = zbudpage->zbud0_size; + else + size = zbudpage->zbud1_size; + BUG_ON(size == 0 || size > zbud_max_size()); + from_va = zbud_data(zbpg, budnum, size); + from_va += sizeof(struct tmem_handle); + size -= sizeof(struct tmem_handle); + *sizep = size; + memcpy(to_va, from_va, size); + + kunmap_zbudpage_atomic(zbpg); + ret = 0; +out: + zbudpage_spin_unlock(zbudpage); + spin_unlock(lists_lock); + return ret; +} + +/* + * Given a zbudref and a kernel pointer, copy the data from + * the kernel pointer to the zbud. + */ +int zbud_copy_to_zbud(struct zbudref *zref, char *from_va, bool eph) +{ + struct zbudpage *zbudpage = zbudref_to_zbudpage(zref); + unsigned long budnum = zbudref_budnum(zref); + void *zbpg; + char *to_va; + unsigned size; + int ret = -1; + spinlock_t *lists_lock = + eph ? &zbud_eph_lists_lock : &zbud_pers_lists_lock; + + spin_lock(lists_lock); + zbudpage_spin_lock(zbudpage); + if (zbudpage_is_dying(zbudpage)) { + /* ignore dying zbudpage... see zbud_evict_pageframe_lru() */ + goto out; + } + zbpg = kmap_zbudpage_atomic(zbudpage); + if (budnum == 0) + size = zbudpage->zbud0_size; + else + size = zbudpage->zbud1_size; + BUG_ON(size == 0 || size > zbud_max_size()); + to_va = zbud_data(zbpg, budnum, size); + to_va += sizeof(struct tmem_handle); + size -= sizeof(struct tmem_handle); + memcpy(to_va, from_va, size); + + kunmap_zbudpage_atomic(zbpg); + ret = 0; +out: + zbudpage_spin_unlock(zbudpage); + spin_unlock(lists_lock); + return ret; +} + +/* + * Choose an ephemeral LRU zbudpage that is evictable (not locked), ensure + * there are no references to it remaining, and return the now unused + * (and re-init'ed) struct page and the total amount of compressed + * data that was evicted. + */ +struct page *zbud_evict_pageframe_lru(unsigned int *zsize, unsigned int *zpages) +{ + struct zbudpage *zbudpage = NULL, *zbudpage2; + struct zbud_unbuddied *unbud = zbud_eph_unbuddied; + struct page *page = NULL; + bool irqs_disabled = irqs_disabled(); + + /* + * Since this can be called indirectly from cleancache_put, which + * has interrupts disabled, as well as frontswap_put, which does not, + * we need to be able to handle both cases, even though it is ugly. + */ + if (irqs_disabled) + spin_lock(&zbud_eph_lists_lock); + else + spin_lock_bh(&zbud_eph_lists_lock); + *zsize = 0; + if (list_empty(&zbud_eph_lru_list)) + goto unlock_out; + list_for_each_entry_safe(zbudpage, zbudpage2, &zbud_eph_lru_list, lru) { + /* skip a locked zbudpage */ + if (unlikely(!zbudpage_spin_trylock(zbudpage))) + continue; + /* skip an unevictable zbudpage */ + if (unlikely(zbudpage->unevictable != 0)) { + zbudpage_spin_unlock(zbudpage); + continue; + } + /* got a locked evictable page */ + goto evict_page; + + } +unlock_out: + /* no unlocked evictable pages, give up */ + if (irqs_disabled) + spin_unlock(&zbud_eph_lists_lock); + else + spin_unlock_bh(&zbud_eph_lists_lock); + goto out; + +evict_page: + list_del_init(&zbudpage->budlist); + list_del_init(&zbudpage->lru); + zbudpage_set_dying(zbudpage); + /* + * the zbudpage is now "dying" and attempts to read, write, + * or delete data from it will be ignored + */ + if (zbudpage->zbud0_size != 0 && zbudpage->zbud1_size != 0) { + *zsize = zbudpage->zbud0_size + zbudpage->zbud1_size - + (2 * sizeof(struct tmem_handle)); + *zpages = 2; + } else if (zbudpage->zbud0_size != 0) { + unbud[zbud_size_to_chunks(zbudpage->zbud0_size)].count--; + *zsize = zbudpage->zbud0_size - sizeof(struct tmem_handle); + *zpages = 1; + } else if (zbudpage->zbud1_size != 0) { + unbud[zbud_size_to_chunks(zbudpage->zbud1_size)].count--; + *zsize = zbudpage->zbud1_size - sizeof(struct tmem_handle); + *zpages = 1; + } else { + BUG(); + } + spin_unlock(&zbud_eph_lists_lock); + zbud_eph_evicted_pageframes++; + if (*zpages == 1) + zbud_eph_unbuddied_count--; + else + zbud_eph_buddied_count--; + zbud_evict_tmem(zbudpage); + zbudpage_spin_lock(zbudpage); + zbudpage_clear_dying(zbudpage); + page = zbud_unuse_zbudpage(zbudpage, true); + if (!irqs_disabled) + local_bh_enable(); +out: + return page; +} + +/* + * Choose a persistent LRU zbudpage that is evictable (not locked), zombify it, + * read the tmem_handle(s) out of it into the passed array, and return the + * number of zbuds. Caller must perform necessary tmem functions and, + * indirectly, zbud functions to fetch any valid data and cause the + * now-zombified zbudpage to eventually be freed. We track the zombified + * zbudpage count so it is possible to observe if there is a leak. + FIXME: describe (ramster) case where data pointers are passed in for memcpy + */ +unsigned int zbud_make_zombie_lru(struct tmem_handle *th, unsigned char **data, + unsigned int *zsize, bool eph) +{ + struct zbudpage *zbudpage = NULL, *zbudpag2; + struct tmem_handle *thfrom; + char *from_va; + void *zbpg; + unsigned size; + int ret = 0, i; + spinlock_t *lists_lock = + eph ? &zbud_eph_lists_lock : &zbud_pers_lists_lock; + struct list_head *lru_list = + eph ? &zbud_eph_lru_list : &zbud_pers_lru_list; + + spin_lock_bh(lists_lock); + if (list_empty(lru_list)) + goto out; + list_for_each_entry_safe(zbudpage, zbudpag2, lru_list, lru) { + /* skip a locked zbudpage */ + if (unlikely(!zbudpage_spin_trylock(zbudpage))) + continue; + /* skip an unevictable zbudpage */ + if (unlikely(zbudpage->unevictable != 0)) { + zbudpage_spin_unlock(zbudpage); + continue; + } + /* got a locked evictable page */ + goto zombify_page; + } + /* no unlocked evictable pages, give up */ + goto out; + +zombify_page: + /* got an unlocked evictable page, zombify it */ + list_del_init(&zbudpage->budlist); + zbudpage_set_zombie(zbudpage); + /* FIXME what accounting do I need to do here? */ + list_del_init(&zbudpage->lru); + if (eph) { + list_add_tail(&zbudpage->lru, &zbud_eph_zombie_list); + zbud_eph_zombie_count = + atomic_inc_return(&zbud_eph_zombie_atomic); + } else { + list_add_tail(&zbudpage->lru, &zbud_pers_zombie_list); + zbud_pers_zombie_count = + atomic_inc_return(&zbud_pers_zombie_atomic); + } + /* FIXME what accounting do I need to do here? */ + zbpg = kmap_zbudpage_atomic(zbudpage); + for (i = 0; i < 2; i++) { + size = (i == 0) ? zbudpage->zbud0_size : zbudpage->zbud1_size; + if (size) { + from_va = zbud_data(zbpg, i, size); + thfrom = (struct tmem_handle *)from_va; + from_va += sizeof(struct tmem_handle); + size -= sizeof(struct tmem_handle); + if (th != NULL) + th[ret] = *thfrom; + if (data != NULL) + memcpy(data[ret], from_va, size); + if (zsize != NULL) + *zsize++ = size; + ret++; + } + } + kunmap_zbudpage_atomic(zbpg); + zbudpage_spin_unlock(zbudpage); +out: + spin_unlock_bh(lists_lock); + return ret; +} + +void __init zbud_init(void) +{ + int i; + +#ifdef CONFIG_DEBUG_FS + zbud_debugfs_init(); +#endif + BUG_ON((sizeof(struct tmem_handle) * 2 > CHUNK_SIZE)); + BUG_ON(sizeof(struct zbudpage) > sizeof(struct page)); + for (i = 0; i < NCHUNKS; i++) { + INIT_LIST_HEAD(&zbud_eph_unbuddied[i].list); + INIT_LIST_HEAD(&zbud_pers_unbuddied[i].list); + } +} diff --git a/drivers/staging/ramster/zbud.h b/drivers/staging/ramster/zbud.h new file mode 100644 index 0000000..891e8a7 --- /dev/null +++ b/drivers/staging/ramster/zbud.h @@ -0,0 +1,33 @@ +/* + * zbud.h + * + * Copyright (c) 2010-2012, Dan Magenheimer, Oracle Corp. + * + */ + +#ifndef _ZBUD_H_ +#define _ZBUD_H_ + +#include "tmem.h" + +struct zbudref; + +extern unsigned int zbud_max_buddy_size(void); +extern struct zbudref *zbud_match_prep(struct tmem_handle *th, bool eph, + void *cdata, unsigned size); +extern struct zbudref *zbud_create_prep(struct tmem_handle *th, bool eph, + void *cdata, unsigned size, + struct page *newpage); +extern void zbud_create_finish(struct zbudref *, bool); +extern int zbud_decompress(struct page *, struct zbudref *, bool, + void (*func)(char *, unsigned int, char *)); +extern int zbud_copy_from_zbud(char *, struct zbudref *, size_t *, bool); +extern int zbud_copy_to_zbud(struct zbudref *, char *, bool); +extern struct page *zbud_free_and_delist(struct zbudref *, bool eph, + unsigned int *, unsigned int *); +extern struct page *zbud_evict_pageframe_lru(unsigned int *, unsigned int *); +extern unsigned int zbud_make_zombie_lru(struct tmem_handle *, unsigned char **, + unsigned int *, bool); +extern void zbud_init(void); + +#endif /* _ZBUD_H_ */ diff --git a/drivers/staging/ramster/zcache-main.c b/drivers/staging/ramster/zcache-main.c new file mode 100644 index 0000000..24b3d4a --- /dev/null +++ b/drivers/staging/ramster/zcache-main.c @@ -0,0 +1,1812 @@ +/* + * zcache.c + * + * Copyright (c) 2010-2012, Dan Magenheimer, Oracle Corp. + * Copyright (c) 2010,2011, Nitin Gupta + * + * Zcache provides an in-kernel "host implementation" for transcendent memory + * ("tmem") and, thus indirectly, for cleancache and frontswap. Zcache uses + * lzo1x compression to improve density and an embedded allocator called + * "zbud" which "buddies" two compressed pages semi-optimally in each physical + * pageframe. Zbud is integrally tied into tmem to allow pageframes to + * be "reclaimed" efficiently. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "tmem.h" +#include "zcache.h" +#include "zbud.h" +#include "ramster.h" +#ifdef CONFIG_RAMSTER +static int ramster_enabled; +#else +#define ramster_enabled 0 +#endif + +#ifndef __PG_WAS_ACTIVE +static inline bool PageWasActive(struct page *page) +{ + return true; +} + +static inline void SetPageWasActive(struct page *page) +{ +} +#endif + +#ifdef FRONTSWAP_HAS_EXCLUSIVE_GETS +static bool frontswap_has_exclusive_gets __read_mostly = true; +#else +static bool frontswap_has_exclusive_gets __read_mostly; +static inline void frontswap_tmem_exclusive_gets(bool b) +{ +} +#endif + +static int zcache_enabled __read_mostly; +static int disable_cleancache __read_mostly; +static int disable_frontswap __read_mostly; +static int disable_frontswap_ignore_nonactive __read_mostly; +static int disable_cleancache_ignore_nonactive __read_mostly; +static char *namestr __read_mostly = "zcache"; + +#define ZCACHE_GFP_MASK \ + (__GFP_FS | __GFP_NORETRY | __GFP_NOWARN | __GFP_NOMEMALLOC) + +MODULE_LICENSE("GPL"); + +/* crypto API for zcache */ +#define ZCACHE_COMP_NAME_SZ CRYPTO_MAX_ALG_NAME +static char zcache_comp_name[ZCACHE_COMP_NAME_SZ] __read_mostly; +static struct crypto_comp * __percpu *zcache_comp_pcpu_tfms __read_mostly; + +enum comp_op { + ZCACHE_COMPOP_COMPRESS, + ZCACHE_COMPOP_DECOMPRESS +}; + +static inline int zcache_comp_op(enum comp_op op, + const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen) +{ + struct crypto_comp *tfm; + int ret = -1; + + BUG_ON(!zcache_comp_pcpu_tfms); + tfm = *per_cpu_ptr(zcache_comp_pcpu_tfms, get_cpu()); + BUG_ON(!tfm); + switch (op) { + case ZCACHE_COMPOP_COMPRESS: + ret = crypto_comp_compress(tfm, src, slen, dst, dlen); + break; + case ZCACHE_COMPOP_DECOMPRESS: + ret = crypto_comp_decompress(tfm, src, slen, dst, dlen); + break; + default: + ret = -EINVAL; + } + put_cpu(); + return ret; +} + +/* + * policy parameters + */ + +/* + * byte count defining poor compression; pages with greater zsize will be + * rejected + */ +static unsigned int zbud_max_zsize __read_mostly = (PAGE_SIZE / 8) * 7; +/* + * byte count defining poor *mean* compression; pages with greater zsize + * will be rejected until sufficient better-compressed pages are accepted + * driving the mean below this threshold + */ +static unsigned int zbud_max_mean_zsize __read_mostly = (PAGE_SIZE / 8) * 5; + +/* + * for now, used named slabs so can easily track usage; later can + * either just use kmalloc, or perhaps add a slab-like allocator + * to more carefully manage total memory utilization + */ +static struct kmem_cache *zcache_objnode_cache; +static struct kmem_cache *zcache_obj_cache; + +static DEFINE_PER_CPU(struct zcache_preload, zcache_preloads) = { 0, }; + +/* we try to keep these statistics SMP-consistent */ +static long zcache_obj_count; +static atomic_t zcache_obj_atomic = ATOMIC_INIT(0); +static long zcache_obj_count_max; +static long zcache_objnode_count; +static atomic_t zcache_objnode_atomic = ATOMIC_INIT(0); +static long zcache_objnode_count_max; +static u64 zcache_eph_zbytes; +static atomic_long_t zcache_eph_zbytes_atomic = ATOMIC_INIT(0); +static u64 zcache_eph_zbytes_max; +static u64 zcache_pers_zbytes; +static atomic_long_t zcache_pers_zbytes_atomic = ATOMIC_INIT(0); +static u64 zcache_pers_zbytes_max; +static long zcache_eph_pageframes; +static atomic_t zcache_eph_pageframes_atomic = ATOMIC_INIT(0); +static long zcache_eph_pageframes_max; +static long zcache_pers_pageframes; +static atomic_t zcache_pers_pageframes_atomic = ATOMIC_INIT(0); +static long zcache_pers_pageframes_max; +static long zcache_pageframes_alloced; +static atomic_t zcache_pageframes_alloced_atomic = ATOMIC_INIT(0); +static long zcache_pageframes_freed; +static atomic_t zcache_pageframes_freed_atomic = ATOMIC_INIT(0); +static long zcache_eph_zpages; +static atomic_t zcache_eph_zpages_atomic = ATOMIC_INIT(0); +static long zcache_eph_zpages_max; +static long zcache_pers_zpages; +static atomic_t zcache_pers_zpages_atomic = ATOMIC_INIT(0); +static long zcache_pers_zpages_max; + +/* but for the rest of these, counting races are ok */ +static unsigned long zcache_flush_total; +static unsigned long zcache_flush_found; +static unsigned long zcache_flobj_total; +static unsigned long zcache_flobj_found; +static unsigned long zcache_failed_eph_puts; +static unsigned long zcache_failed_pers_puts; +static unsigned long zcache_failed_getfreepages; +static unsigned long zcache_failed_alloc; +static unsigned long zcache_put_to_flush; +static unsigned long zcache_compress_poor; +static unsigned long zcache_mean_compress_poor; +static unsigned long zcache_eph_ate_tail; +static unsigned long zcache_eph_ate_tail_failed; +static unsigned long zcache_pers_ate_eph; +static unsigned long zcache_pers_ate_eph_failed; +static unsigned long zcache_evicted_eph_zpages; +static unsigned long zcache_evicted_eph_pageframes; +static unsigned long zcache_last_active_file_pageframes; +static unsigned long zcache_last_inactive_file_pageframes; +static unsigned long zcache_last_active_anon_pageframes; +static unsigned long zcache_last_inactive_anon_pageframes; +static unsigned long zcache_eph_nonactive_puts_ignored; +static unsigned long zcache_pers_nonactive_puts_ignored; + +#ifdef CONFIG_DEBUG_FS +#include +#define zdfs debugfs_create_size_t +#define zdfs64 debugfs_create_u64 +static int zcache_debugfs_init(void) +{ + struct dentry *root = debugfs_create_dir("zcache", NULL); + if (root == NULL) + return -ENXIO; + + zdfs("obj_count", S_IRUGO, root, &zcache_obj_count); + zdfs("obj_count_max", S_IRUGO, root, &zcache_obj_count_max); + zdfs("objnode_count", S_IRUGO, root, &zcache_objnode_count); + zdfs("objnode_count_max", S_IRUGO, root, &zcache_objnode_count_max); + zdfs("flush_total", S_IRUGO, root, &zcache_flush_total); + zdfs("flush_found", S_IRUGO, root, &zcache_flush_found); + zdfs("flobj_total", S_IRUGO, root, &zcache_flobj_total); + zdfs("flobj_found", S_IRUGO, root, &zcache_flobj_found); + zdfs("failed_eph_puts", S_IRUGO, root, &zcache_failed_eph_puts); + zdfs("failed_pers_puts", S_IRUGO, root, &zcache_failed_pers_puts); + zdfs("failed_get_free_pages", S_IRUGO, root, + &zcache_failed_getfreepages); + zdfs("failed_alloc", S_IRUGO, root, &zcache_failed_alloc); + zdfs("put_to_flush", S_IRUGO, root, &zcache_put_to_flush); + zdfs("compress_poor", S_IRUGO, root, &zcache_compress_poor); + zdfs("mean_compress_poor", S_IRUGO, root, &zcache_mean_compress_poor); + zdfs("eph_ate_tail", S_IRUGO, root, &zcache_eph_ate_tail); + zdfs("eph_ate_tail_failed", S_IRUGO, root, &zcache_eph_ate_tail_failed); + zdfs("pers_ate_eph", S_IRUGO, root, &zcache_pers_ate_eph); + zdfs("pers_ate_eph_failed", S_IRUGO, root, &zcache_pers_ate_eph_failed); + zdfs("evicted_eph_zpages", S_IRUGO, root, &zcache_evicted_eph_zpages); + zdfs("evicted_eph_pageframes", S_IRUGO, root, + &zcache_evicted_eph_pageframes); + zdfs("eph_pageframes", S_IRUGO, root, &zcache_eph_pageframes); + zdfs("eph_pageframes_max", S_IRUGO, root, &zcache_eph_pageframes_max); + zdfs("pers_pageframes", S_IRUGO, root, &zcache_pers_pageframes); + zdfs("pers_pageframes_max", S_IRUGO, root, &zcache_pers_pageframes_max); + zdfs("eph_zpages", S_IRUGO, root, &zcache_eph_zpages); + zdfs("eph_zpages_max", S_IRUGO, root, &zcache_eph_zpages_max); + zdfs("pers_zpages", S_IRUGO, root, &zcache_pers_zpages); + zdfs("pers_zpages_max", S_IRUGO, root, &zcache_pers_zpages_max); + zdfs("last_active_file_pageframes", S_IRUGO, root, + &zcache_last_active_file_pageframes); + zdfs("last_inactive_file_pageframes", S_IRUGO, root, + &zcache_last_inactive_file_pageframes); + zdfs("last_active_anon_pageframes", S_IRUGO, root, + &zcache_last_active_anon_pageframes); + zdfs("last_inactive_anon_pageframes", S_IRUGO, root, + &zcache_last_inactive_anon_pageframes); + zdfs("eph_nonactive_puts_ignored", S_IRUGO, root, + &zcache_eph_nonactive_puts_ignored); + zdfs("pers_nonactive_puts_ignored", S_IRUGO, root, + &zcache_pers_nonactive_puts_ignored); + zdfs64("eph_zbytes", S_IRUGO, root, &zcache_eph_zbytes); + zdfs64("eph_zbytes_max", S_IRUGO, root, &zcache_eph_zbytes_max); + zdfs64("pers_zbytes", S_IRUGO, root, &zcache_pers_zbytes); + zdfs64("pers_zbytes_max", S_IRUGO, root, &zcache_pers_zbytes_max); + return 0; +} +#undef zdebugfs +#undef zdfs64 +#endif + +#define ZCACHE_DEBUG +#ifdef ZCACHE_DEBUG +/* developers can call this in case of ooms, e.g. to find memory leaks */ +void zcache_dump(void) +{ + pr_info("zcache: obj_count=%lu\n", zcache_obj_count); + pr_info("zcache: obj_count_max=%lu\n", zcache_obj_count_max); + pr_info("zcache: objnode_count=%lu\n", zcache_objnode_count); + pr_info("zcache: objnode_count_max=%lu\n", zcache_objnode_count_max); + pr_info("zcache: flush_total=%lu\n", zcache_flush_total); + pr_info("zcache: flush_found=%lu\n", zcache_flush_found); + pr_info("zcache: flobj_total=%lu\n", zcache_flobj_total); + pr_info("zcache: flobj_found=%lu\n", zcache_flobj_found); + pr_info("zcache: failed_eph_puts=%lu\n", zcache_failed_eph_puts); + pr_info("zcache: failed_pers_puts=%lu\n", zcache_failed_pers_puts); + pr_info("zcache: failed_get_free_pages=%lu\n", + zcache_failed_getfreepages); + pr_info("zcache: failed_alloc=%lu\n", zcache_failed_alloc); + pr_info("zcache: put_to_flush=%lu\n", zcache_put_to_flush); + pr_info("zcache: compress_poor=%lu\n", zcache_compress_poor); + pr_info("zcache: mean_compress_poor=%lu\n", + zcache_mean_compress_poor); + pr_info("zcache: eph_ate_tail=%lu\n", zcache_eph_ate_tail); + pr_info("zcache: eph_ate_tail_failed=%lu\n", + zcache_eph_ate_tail_failed); + pr_info("zcache: pers_ate_eph=%lu\n", zcache_pers_ate_eph); + pr_info("zcache: pers_ate_eph_failed=%lu\n", + zcache_pers_ate_eph_failed); + pr_info("zcache: evicted_eph_zpages=%lu\n", zcache_evicted_eph_zpages); + pr_info("zcache: evicted_eph_pageframes=%lu\n", + zcache_evicted_eph_pageframes); + pr_info("zcache: eph_pageframes=%lu\n", zcache_eph_pageframes); + pr_info("zcache: eph_pageframes_max=%lu\n", zcache_eph_pageframes_max); + pr_info("zcache: pers_pageframes=%lu\n", zcache_pers_pageframes); + pr_info("zcache: pers_pageframes_max=%lu\n", + zcache_pers_pageframes_max); + pr_info("zcache: eph_zpages=%lu\n", zcache_eph_zpages); + pr_info("zcache: eph_zpages_max=%lu\n", zcache_eph_zpages_max); + pr_info("zcache: pers_zpages=%lu\n", zcache_pers_zpages); + pr_info("zcache: pers_zpages_max=%lu\n", zcache_pers_zpages_max); + pr_info("zcache: eph_zbytes=%llu\n", + (unsigned long long)zcache_eph_zbytes); + pr_info("zcache: eph_zbytes_max=%llu\n", + (unsigned long long)zcache_eph_zbytes_max); + pr_info("zcache: pers_zbytes=%llu\n", + (unsigned long long)zcache_pers_zbytes); + pr_info("zcache: pers_zbytes_max=%llu\n", + (unsigned long long)zcache_pers_zbytes_max); +} +#endif + +/* + * zcache core code starts here + */ + +static struct zcache_client zcache_host; +static struct zcache_client zcache_clients[MAX_CLIENTS]; + +static inline bool is_local_client(struct zcache_client *cli) +{ + return cli == &zcache_host; +} + +static struct zcache_client *zcache_get_client_by_id(uint16_t cli_id) +{ + struct zcache_client *cli = &zcache_host; + + if (cli_id != LOCAL_CLIENT) { + if (cli_id >= MAX_CLIENTS) + goto out; + cli = &zcache_clients[cli_id]; + } +out: + return cli; +} + +/* + * Tmem operations assume the poolid implies the invoking client. + * Zcache only has one client (the kernel itself): LOCAL_CLIENT. + * RAMster has each client numbered by cluster node, and a KVM version + * of zcache would have one client per guest and each client might + * have a poolid==N. + */ +struct tmem_pool *zcache_get_pool_by_id(uint16_t cli_id, uint16_t poolid) +{ + struct tmem_pool *pool = NULL; + struct zcache_client *cli = NULL; + + cli = zcache_get_client_by_id(cli_id); + if (cli == NULL) + goto out; + if (!is_local_client(cli)) + atomic_inc(&cli->refcount); + if (poolid < MAX_POOLS_PER_CLIENT) { + pool = cli->tmem_pools[poolid]; + if (pool != NULL) + atomic_inc(&pool->refcount); + } +out: + return pool; +} + +void zcache_put_pool(struct tmem_pool *pool) +{ + struct zcache_client *cli = NULL; + + if (pool == NULL) + BUG(); + cli = pool->client; + atomic_dec(&pool->refcount); + if (!is_local_client(cli)) + atomic_dec(&cli->refcount); +} + +int zcache_new_client(uint16_t cli_id) +{ + struct zcache_client *cli; + int ret = -1; + + cli = zcache_get_client_by_id(cli_id); + if (cli == NULL) + goto out; + if (cli->allocated) + goto out; + cli->allocated = 1; + ret = 0; +out: + return ret; +} + +/* + * zcache implementation for tmem host ops + */ + +static struct tmem_objnode *zcache_objnode_alloc(struct tmem_pool *pool) +{ + struct tmem_objnode *objnode = NULL; + struct zcache_preload *kp; + int i; + + kp = &__get_cpu_var(zcache_preloads); + for (i = 0; i < ARRAY_SIZE(kp->objnodes); i++) { + objnode = kp->objnodes[i]; + if (objnode != NULL) { + kp->objnodes[i] = NULL; + break; + } + } + BUG_ON(objnode == NULL); + zcache_objnode_count = atomic_inc_return(&zcache_objnode_atomic); + if (zcache_objnode_count > zcache_objnode_count_max) + zcache_objnode_count_max = zcache_objnode_count; + return objnode; +} + +static void zcache_objnode_free(struct tmem_objnode *objnode, + struct tmem_pool *pool) +{ + zcache_objnode_count = + atomic_dec_return(&zcache_objnode_atomic); + BUG_ON(zcache_objnode_count < 0); + kmem_cache_free(zcache_objnode_cache, objnode); +} + +static struct tmem_obj *zcache_obj_alloc(struct tmem_pool *pool) +{ + struct tmem_obj *obj = NULL; + struct zcache_preload *kp; + + kp = &__get_cpu_var(zcache_preloads); + obj = kp->obj; + BUG_ON(obj == NULL); + kp->obj = NULL; + zcache_obj_count = atomic_inc_return(&zcache_obj_atomic); + if (zcache_obj_count > zcache_obj_count_max) + zcache_obj_count_max = zcache_obj_count; + return obj; +} + +static void zcache_obj_free(struct tmem_obj *obj, struct tmem_pool *pool) +{ + zcache_obj_count = + atomic_dec_return(&zcache_obj_atomic); + BUG_ON(zcache_obj_count < 0); + kmem_cache_free(zcache_obj_cache, obj); +} + +static struct tmem_hostops zcache_hostops = { + .obj_alloc = zcache_obj_alloc, + .obj_free = zcache_obj_free, + .objnode_alloc = zcache_objnode_alloc, + .objnode_free = zcache_objnode_free, +}; + +static struct page *zcache_alloc_page(void) +{ + struct page *page = alloc_page(ZCACHE_GFP_MASK); + + if (page != NULL) + zcache_pageframes_alloced = + atomic_inc_return(&zcache_pageframes_alloced_atomic); + return page; +} + +static void zcache_unacct_page(void) +{ + zcache_pageframes_freed = + atomic_inc_return(&zcache_pageframes_freed_atomic); +} + +static void zcache_free_page(struct page *page) +{ + long curr_pageframes; + static long max_pageframes, min_pageframes, total_freed; + + if (page == NULL) + BUG(); + __free_page(page); + zcache_pageframes_freed = + atomic_inc_return(&zcache_pageframes_freed_atomic); + curr_pageframes = zcache_pageframes_alloced - + atomic_read(&zcache_pageframes_freed_atomic) - + atomic_read(&zcache_eph_pageframes_atomic) - + atomic_read(&zcache_pers_pageframes_atomic); + if (curr_pageframes > max_pageframes) + max_pageframes = curr_pageframes; + if (curr_pageframes < min_pageframes) + min_pageframes = curr_pageframes; +#ifdef ZCACHE_DEBUG + if (curr_pageframes > 2L || curr_pageframes < -2L) { + /* pr_info here */ + } +#endif +} + +/* + * zcache implementations for PAM page descriptor ops + */ + +/* forward reference */ +static void zcache_compress(struct page *from, + void **out_va, unsigned *out_len); + +static struct page *zcache_evict_eph_pageframe(void); + +static void *zcache_pampd_eph_create(char *data, size_t size, bool raw, + struct tmem_handle *th) +{ + void *pampd = NULL, *cdata = data; + unsigned clen = size; + struct page *page = (struct page *)(data), *newpage; + + if (!raw) { + zcache_compress(page, &cdata, &clen); + if (clen > zbud_max_buddy_size()) { + zcache_compress_poor++; + goto out; + } + } else { + BUG_ON(clen > zbud_max_buddy_size()); + } + + /* look for space via an existing match first */ + pampd = (void *)zbud_match_prep(th, true, cdata, clen); + if (pampd != NULL) + goto got_pampd; + + /* no match, now we need to find (or free up) a full page */ + newpage = zcache_alloc_page(); + if (newpage != NULL) + goto create_in_new_page; + + zcache_failed_getfreepages++; + /* can't allocate a page, evict an ephemeral page via LRU */ + newpage = zcache_evict_eph_pageframe(); + if (newpage == NULL) { + zcache_eph_ate_tail_failed++; + goto out; + } + zcache_eph_ate_tail++; + +create_in_new_page: + pampd = (void *)zbud_create_prep(th, true, cdata, clen, newpage); + BUG_ON(pampd == NULL); + zcache_eph_pageframes = + atomic_inc_return(&zcache_eph_pageframes_atomic); + if (zcache_eph_pageframes > zcache_eph_pageframes_max) + zcache_eph_pageframes_max = zcache_eph_pageframes; + +got_pampd: + zcache_eph_zbytes = + atomic_long_add_return(clen, &zcache_eph_zbytes_atomic); + if (zcache_eph_zbytes > zcache_eph_zbytes_max) + zcache_eph_zbytes_max = zcache_eph_zbytes; + zcache_eph_zpages = atomic_inc_return(&zcache_eph_zpages_atomic); + if (zcache_eph_zpages > zcache_eph_zpages_max) + zcache_eph_zpages_max = zcache_eph_zpages; + if (ramster_enabled && raw) + ramster_count_foreign_pages(true, 1); +out: + return pampd; +} + +static void *zcache_pampd_pers_create(char *data, size_t size, bool raw, + struct tmem_handle *th) +{ + void *pampd = NULL, *cdata = data; + unsigned clen = size; + struct page *page = (struct page *)(data), *newpage; + unsigned long zbud_mean_zsize; + unsigned long curr_pers_zpages, total_zsize; + + if (data == NULL) { + BUG_ON(!ramster_enabled); + goto create_pampd; + } + curr_pers_zpages = zcache_pers_zpages; +/* FIXME CONFIG_RAMSTER... subtract atomic remote_pers_pages here? */ + if (!raw) + zcache_compress(page, &cdata, &clen); + /* reject if compression is too poor */ + if (clen > zbud_max_zsize) { + zcache_compress_poor++; + goto out; + } + /* reject if mean compression is too poor */ + if ((clen > zbud_max_mean_zsize) && (curr_pers_zpages > 0)) { + total_zsize = zcache_pers_zbytes; + if ((long)total_zsize < 0) + total_zsize = 0; + zbud_mean_zsize = div_u64(total_zsize, + curr_pers_zpages); + if (zbud_mean_zsize > zbud_max_mean_zsize) { + zcache_mean_compress_poor++; + goto out; + } + } + +create_pampd: + /* look for space via an existing match first */ + pampd = (void *)zbud_match_prep(th, false, cdata, clen); + if (pampd != NULL) + goto got_pampd; + + /* no match, now we need to find (or free up) a full page */ + newpage = zcache_alloc_page(); + if (newpage != NULL) + goto create_in_new_page; + /* + * FIXME do the following only if eph is oversized? + * if (zcache_eph_pageframes > + * (global_page_state(NR_LRU_BASE + LRU_ACTIVE_FILE) + + * global_page_state(NR_LRU_BASE + LRU_INACTIVE_FILE))) + */ + zcache_failed_getfreepages++; + /* can't allocate a page, evict an ephemeral page via LRU */ + newpage = zcache_evict_eph_pageframe(); + if (newpage == NULL) { + zcache_pers_ate_eph_failed++; + goto out; + } + zcache_pers_ate_eph++; + +create_in_new_page: + pampd = (void *)zbud_create_prep(th, false, cdata, clen, newpage); + BUG_ON(pampd == NULL); + zcache_pers_pageframes = + atomic_inc_return(&zcache_pers_pageframes_atomic); + if (zcache_pers_pageframes > zcache_pers_pageframes_max) + zcache_pers_pageframes_max = zcache_pers_pageframes; + +got_pampd: + zcache_pers_zpages = atomic_inc_return(&zcache_pers_zpages_atomic); + if (zcache_pers_zpages > zcache_pers_zpages_max) + zcache_pers_zpages_max = zcache_pers_zpages; + zcache_pers_zbytes = + atomic_long_add_return(clen, &zcache_pers_zbytes_atomic); + if (zcache_pers_zbytes > zcache_pers_zbytes_max) + zcache_pers_zbytes_max = zcache_pers_zbytes; + if (ramster_enabled && raw) + ramster_count_foreign_pages(false, 1); +out: + return pampd; +} + +/* + * This is called directly from zcache_put_page to pre-allocate space + * to store a zpage. + */ +void *zcache_pampd_create(char *data, unsigned int size, bool raw, + int eph, struct tmem_handle *th) +{ + void *pampd = NULL; + struct zcache_preload *kp; + struct tmem_objnode *objnode; + struct tmem_obj *obj; + int i; + + BUG_ON(!irqs_disabled()); + /* pre-allocate per-cpu metadata */ + BUG_ON(zcache_objnode_cache == NULL); + BUG_ON(zcache_obj_cache == NULL); + kp = &__get_cpu_var(zcache_preloads); + for (i = 0; i < ARRAY_SIZE(kp->objnodes); i++) { + objnode = kp->objnodes[i]; + if (objnode == NULL) { + objnode = kmem_cache_alloc(zcache_objnode_cache, + ZCACHE_GFP_MASK); + if (unlikely(objnode == NULL)) { + zcache_failed_alloc++; + goto out; + } + kp->objnodes[i] = objnode; + } + } + if (kp->obj == NULL) { + obj = kmem_cache_alloc(zcache_obj_cache, ZCACHE_GFP_MASK); + kp->obj = obj; + } + if (unlikely(kp->obj == NULL)) { + zcache_failed_alloc++; + goto out; + } + /* + * ok, have all the metadata pre-allocated, now do the data + * but since how we allocate the data is dependent on ephemeral + * or persistent, we split the call here to different sub-functions + */ + if (eph) + pampd = zcache_pampd_eph_create(data, size, raw, th); + else + pampd = zcache_pampd_pers_create(data, size, raw, th); +out: + return pampd; +} + +/* + * This is a pamops called via tmem_put and is necessary to "finish" + * a pampd creation. + */ +void zcache_pampd_create_finish(void *pampd, bool eph) +{ + zbud_create_finish((struct zbudref *)pampd, eph); +} + +/* + * This is passed as a function parameter to zbud_decompress so that + * zbud need not be familiar with the details of crypto. It assumes that + * the bytes from_va and to_va through from_va+size-1 and to_va+size-1 are + * kmapped. It must be successful, else there is a logic bug somewhere. + */ +static void zcache_decompress(char *from_va, unsigned int size, char *to_va) +{ + int ret; + unsigned int outlen = PAGE_SIZE; + + ret = zcache_comp_op(ZCACHE_COMPOP_DECOMPRESS, from_va, size, + to_va, &outlen); + BUG_ON(ret); + BUG_ON(outlen != PAGE_SIZE); +} + +/* + * Decompress from the kernel va to a pageframe + */ +void zcache_decompress_to_page(char *from_va, unsigned int size, + struct page *to_page) +{ + char *to_va = kmap_atomic(to_page); + zcache_decompress(from_va, size, to_va); + kunmap_atomic(to_va); +} + +/* + * fill the pageframe corresponding to the struct page with the data + * from the passed pampd + */ +static int zcache_pampd_get_data(char *data, size_t *sizep, bool raw, + void *pampd, struct tmem_pool *pool, + struct tmem_oid *oid, uint32_t index) +{ + int ret; + bool eph = !is_persistent(pool); + + BUG_ON(preemptible()); + BUG_ON(eph); /* fix later if shared pools get implemented */ + BUG_ON(pampd_is_remote(pampd)); + if (raw) + ret = zbud_copy_from_zbud(data, (struct zbudref *)pampd, + sizep, eph); + else { + ret = zbud_decompress((struct page *)(data), + (struct zbudref *)pampd, false, + zcache_decompress); + *sizep = PAGE_SIZE; + } + return ret; +} + +/* + * fill the pageframe corresponding to the struct page with the data + * from the passed pampd + */ +static int zcache_pampd_get_data_and_free(char *data, size_t *sizep, bool raw, + void *pampd, struct tmem_pool *pool, + struct tmem_oid *oid, uint32_t index) +{ + int ret; + bool eph = !is_persistent(pool); + struct page *page = NULL; + unsigned int zsize, zpages; + + BUG_ON(preemptible()); + BUG_ON(pampd_is_remote(pampd)); + if (raw) + ret = zbud_copy_from_zbud(data, (struct zbudref *)pampd, + sizep, eph); + else { + ret = zbud_decompress((struct page *)(data), + (struct zbudref *)pampd, eph, + zcache_decompress); + *sizep = PAGE_SIZE; + } + page = zbud_free_and_delist((struct zbudref *)pampd, eph, + &zsize, &zpages); + if (eph) { + if (page) + zcache_eph_pageframes = + atomic_dec_return(&zcache_eph_pageframes_atomic); + zcache_eph_zpages = + atomic_sub_return(zpages, &zcache_eph_zpages_atomic); + zcache_eph_zbytes = + atomic_long_sub_return(zsize, &zcache_eph_zbytes_atomic); + } else { + if (page) + zcache_pers_pageframes = + atomic_dec_return(&zcache_pers_pageframes_atomic); + zcache_pers_zpages = + atomic_sub_return(zpages, &zcache_pers_zpages_atomic); + zcache_pers_zbytes = + atomic_long_sub_return(zsize, &zcache_pers_zbytes_atomic); + } + if (!is_local_client(pool->client)) + ramster_count_foreign_pages(eph, -1); + if (page) + zcache_free_page(page); + return ret; +} + +/* + * free the pampd and remove it from any zcache lists + * pampd must no longer be pointed to from any tmem data structures! + */ +static void zcache_pampd_free(void *pampd, struct tmem_pool *pool, + struct tmem_oid *oid, uint32_t index, bool acct) +{ + struct page *page = NULL; + unsigned int zsize, zpages; + + BUG_ON(preemptible()); + if (pampd_is_remote(pampd)) { + BUG_ON(!ramster_enabled); + pampd = ramster_pampd_free(pampd, pool, oid, index, acct); + if (pampd == NULL) + return; + } + if (is_ephemeral(pool)) { + page = zbud_free_and_delist((struct zbudref *)pampd, + true, &zsize, &zpages); + if (page) + zcache_eph_pageframes = + atomic_dec_return(&zcache_eph_pageframes_atomic); + zcache_eph_zpages = + atomic_sub_return(zpages, &zcache_eph_zpages_atomic); + zcache_eph_zbytes = + atomic_long_sub_return(zsize, &zcache_eph_zbytes_atomic); + /* FIXME CONFIG_RAMSTER... check acct parameter? */ + } else { + page = zbud_free_and_delist((struct zbudref *)pampd, + false, &zsize, &zpages); + if (page) + zcache_pers_pageframes = + atomic_dec_return(&zcache_pers_pageframes_atomic); + zcache_pers_zpages = + atomic_sub_return(zpages, &zcache_pers_zpages_atomic); + zcache_pers_zbytes = + atomic_long_sub_return(zsize, &zcache_pers_zbytes_atomic); + } + if (!is_local_client(pool->client)) + ramster_count_foreign_pages(is_ephemeral(pool), -1); + if (page) + zcache_free_page(page); +} + +static struct tmem_pamops zcache_pamops = { + .create_finish = zcache_pampd_create_finish, + .get_data = zcache_pampd_get_data, + .get_data_and_free = zcache_pampd_get_data_and_free, + .free = zcache_pampd_free, +}; + +/* + * zcache compression/decompression and related per-cpu stuff + */ + +static DEFINE_PER_CPU(unsigned char *, zcache_dstmem); +#define ZCACHE_DSTMEM_ORDER 1 + +static void zcache_compress(struct page *from, void **out_va, unsigned *out_len) +{ + int ret; + unsigned char *dmem = __get_cpu_var(zcache_dstmem); + char *from_va; + + BUG_ON(!irqs_disabled()); + /* no buffer or no compressor so can't compress */ + BUG_ON(dmem == NULL); + *out_len = PAGE_SIZE << ZCACHE_DSTMEM_ORDER; + from_va = kmap_atomic(from); + mb(); + ret = zcache_comp_op(ZCACHE_COMPOP_COMPRESS, from_va, PAGE_SIZE, dmem, + out_len); + BUG_ON(ret); + *out_va = dmem; + kunmap_atomic(from_va); +} + +static int zcache_comp_cpu_up(int cpu) +{ + struct crypto_comp *tfm; + + tfm = crypto_alloc_comp(zcache_comp_name, 0, 0); + if (IS_ERR(tfm)) + return NOTIFY_BAD; + *per_cpu_ptr(zcache_comp_pcpu_tfms, cpu) = tfm; + return NOTIFY_OK; +} + +static void zcache_comp_cpu_down(int cpu) +{ + struct crypto_comp *tfm; + + tfm = *per_cpu_ptr(zcache_comp_pcpu_tfms, cpu); + crypto_free_comp(tfm); + *per_cpu_ptr(zcache_comp_pcpu_tfms, cpu) = NULL; +} + +static int zcache_cpu_notifier(struct notifier_block *nb, + unsigned long action, void *pcpu) +{ + int ret, i, cpu = (long)pcpu; + struct zcache_preload *kp; + + switch (action) { + case CPU_UP_PREPARE: + ret = zcache_comp_cpu_up(cpu); + if (ret != NOTIFY_OK) { + pr_err("%s: can't allocate compressor xform\n", + namestr); + return ret; + } + per_cpu(zcache_dstmem, cpu) = (void *)__get_free_pages( + GFP_KERNEL | __GFP_REPEAT, ZCACHE_DSTMEM_ORDER); + if (ramster_enabled) + ramster_cpu_up(cpu); + break; + case CPU_DEAD: + case CPU_UP_CANCELED: + zcache_comp_cpu_down(cpu); + free_pages((unsigned long)per_cpu(zcache_dstmem, cpu), + ZCACHE_DSTMEM_ORDER); + per_cpu(zcache_dstmem, cpu) = NULL; + kp = &per_cpu(zcache_preloads, cpu); + for (i = 0; i < ARRAY_SIZE(kp->objnodes); i++) { + if (kp->objnodes[i]) + kmem_cache_free(zcache_objnode_cache, + kp->objnodes[i]); + } + if (kp->obj) { + kmem_cache_free(zcache_obj_cache, kp->obj); + kp->obj = NULL; + } + if (ramster_enabled) + ramster_cpu_down(cpu); + break; + default: + break; + } + return NOTIFY_OK; +} + +static struct notifier_block zcache_cpu_notifier_block = { + .notifier_call = zcache_cpu_notifier +}; + +/* + * The following code interacts with the zbud eviction and zbud + * zombify code to access LRU pages + */ + +static struct page *zcache_evict_eph_pageframe(void) +{ + struct page *page; + unsigned int zsize = 0, zpages = 0; + + page = zbud_evict_pageframe_lru(&zsize, &zpages); + if (page == NULL) + goto out; + zcache_eph_zbytes = atomic_long_sub_return(zsize, + &zcache_eph_zbytes_atomic); + zcache_eph_zpages = atomic_sub_return(zpages, + &zcache_eph_zpages_atomic); + zcache_evicted_eph_zpages++; + zcache_eph_pageframes = + atomic_dec_return(&zcache_eph_pageframes_atomic); + zcache_evicted_eph_pageframes++; +out: + return page; +} + +static void unswiz(struct tmem_oid oid, u32 index, + unsigned *type, pgoff_t *offset); +#ifdef FRONTSWAP_HAS_UNUSE +/* + * Choose an LRU persistent pageframe and attempt to "unuse" it by + * calling frontswap_unuse on both zpages. + * + * This is work-in-progress. + */ + +static int zcache_frontswap_unuse(void) +{ + struct tmem_handle th[2]; + int ret = -ENOMEM; + int nzbuds, unuse_ret; + unsigned type; + struct page *newpage1 = NULL, *newpage2 = NULL; + struct page *evictpage1 = NULL, *evictpage2 = NULL; + pgoff_t offset; + + newpage1 = alloc_page(ZCACHE_GFP_MASK); + newpage2 = alloc_page(ZCACHE_GFP_MASK); + if (newpage1 == NULL) + evictpage1 = zcache_evict_eph_pageframe(); + if (newpage2 == NULL) + evictpage2 = zcache_evict_eph_pageframe(); + if (evictpage1 == NULL || evictpage2 == NULL) + goto free_and_out; + /* ok, we have two pages pre-allocated */ + nzbuds = zbud_make_zombie_lru(&th[0], NULL, NULL, false); + if (nzbuds == 0) { + ret = -ENOENT; + goto free_and_out; + } + unswiz(th[0].oid, th[0].index, &type, &offset); + unuse_ret = frontswap_unuse(type, offset, + newpage1 != NULL ? newpage1 : evictpage1, + ZCACHE_GFP_MASK); + if (unuse_ret != 0) + goto free_and_out; + else if (evictpage1 != NULL) + zcache_unacct_page(); + newpage1 = NULL; + evictpage1 = NULL; + if (nzbuds == 2) { + unswiz(th[1].oid, th[1].index, &type, &offset); + unuse_ret = frontswap_unuse(type, offset, + newpage2 != NULL ? newpage2 : evictpage2, + ZCACHE_GFP_MASK); + if (unuse_ret != 0) { + goto free_and_out; + } else if (evictpage2 != NULL) { + zcache_unacct_page(); + } + } + ret = 0; + goto out; + +free_and_out: + if (newpage1 != NULL) + __free_page(newpage1); + if (newpage2 != NULL) + __free_page(newpage2); + if (evictpage1 != NULL) + zcache_free_page(evictpage1); + if (evictpage2 != NULL) + zcache_free_page(evictpage2); +out: + return ret; +} +#endif + +/* + * When zcache is disabled ("frozen"), pools can be created and destroyed, + * but all puts (and thus all other operations that require memory allocation) + * must fail. If zcache is unfrozen, accepts puts, then frozen again, + * data consistency requires all puts while frozen to be converted into + * flushes. + */ +static bool zcache_freeze; + +/* + * This zcache shrinker interface reduces the number of ephemeral pageframes + * used by zcache to approximately the same as the total number of LRU_FILE + * pageframes in use. + */ +static int shrink_zcache_memory(struct shrinker *shrink, + struct shrink_control *sc) +{ + static bool in_progress; + int ret = -1; + int nr = sc->nr_to_scan; + int nr_evict = 0; + int nr_unuse = 0; + struct page *page; + int unuse_ret; + + if (nr <= 0) + goto skip_evict; + + /* don't allow more than one eviction thread at a time */ + if (in_progress) + goto skip_evict; + + in_progress = true; + + /* we are going to ignore nr, and target a different value */ + zcache_last_active_file_pageframes = + global_page_state(NR_LRU_BASE + LRU_ACTIVE_FILE); + zcache_last_inactive_file_pageframes = + global_page_state(NR_LRU_BASE + LRU_INACTIVE_FILE); + nr_evict = zcache_eph_pageframes - zcache_last_active_file_pageframes + + zcache_last_inactive_file_pageframes; + while (nr_evict-- > 0) { + page = zcache_evict_eph_pageframe(); + if (page == NULL) + break; + zcache_free_page(page); + } + + zcache_last_active_anon_pageframes = + global_page_state(NR_LRU_BASE + LRU_ACTIVE_ANON); + zcache_last_inactive_anon_pageframes = + global_page_state(NR_LRU_BASE + LRU_INACTIVE_ANON); + nr_unuse = zcache_pers_pageframes - zcache_last_active_anon_pageframes + + zcache_last_inactive_anon_pageframes; +#ifdef FRONTSWAP_HAS_UNUSE + /* rate limit for testing */ + if (nr_unuse > 32) + nr_unuse = 32; + while (nr_unuse-- > 0) { + unuse_ret = zcache_frontswap_unuse(); + if (unuse_ret == -ENOMEM) + break; + } +#endif + in_progress = false; + +skip_evict: + /* resample: has changed, but maybe not all the way yet */ + zcache_last_active_file_pageframes = + global_page_state(NR_LRU_BASE + LRU_ACTIVE_FILE); + zcache_last_inactive_file_pageframes = + global_page_state(NR_LRU_BASE + LRU_INACTIVE_FILE); + ret = zcache_eph_pageframes - zcache_last_active_file_pageframes + + zcache_last_inactive_file_pageframes; + if (ret < 0) + ret = 0; + return ret; +} + +static struct shrinker zcache_shrinker = { + .shrink = shrink_zcache_memory, + .seeks = DEFAULT_SEEKS, +}; + +/* + * zcache shims between cleancache/frontswap ops and tmem + */ + +/* FIXME rename these core routines to zcache_tmemput etc? */ +int zcache_put_page(int cli_id, int pool_id, struct tmem_oid *oidp, + uint32_t index, void *page, + unsigned int size, bool raw, int ephemeral) +{ + struct tmem_pool *pool; + struct tmem_handle th; + int ret = -1; + void *pampd = NULL; + + BUG_ON(!irqs_disabled()); + pool = zcache_get_pool_by_id(cli_id, pool_id); + if (unlikely(pool == NULL)) + goto out; + if (!zcache_freeze) { + ret = 0; + th.client_id = cli_id; + th.pool_id = pool_id; + th.oid = *oidp; + th.index = index; + pampd = zcache_pampd_create((char *)page, size, raw, + ephemeral, &th); + if (pampd == NULL) { + ret = -ENOMEM; + if (ephemeral) + zcache_failed_eph_puts++; + else + zcache_failed_pers_puts++; + } else { + if (ramster_enabled) + ramster_do_preload_flnode(pool); + ret = tmem_put(pool, oidp, index, 0, pampd); + if (ret < 0) + BUG(); + } + zcache_put_pool(pool); + } else { + zcache_put_to_flush++; + if (ramster_enabled) + ramster_do_preload_flnode(pool); + if (atomic_read(&pool->obj_count) > 0) + /* the put fails whether the flush succeeds or not */ + (void)tmem_flush_page(pool, oidp, index); + zcache_put_pool(pool); + } +out: + return ret; +} + +int zcache_get_page(int cli_id, int pool_id, struct tmem_oid *oidp, + uint32_t index, void *page, + size_t *sizep, bool raw, int get_and_free) +{ + struct tmem_pool *pool; + int ret = -1; + bool eph; + + if (!raw) { + BUG_ON(irqs_disabled()); + BUG_ON(in_softirq()); + } + pool = zcache_get_pool_by_id(cli_id, pool_id); + eph = is_ephemeral(pool); + if (likely(pool != NULL)) { + if (atomic_read(&pool->obj_count) > 0) + ret = tmem_get(pool, oidp, index, (char *)(page), + sizep, raw, get_and_free); + zcache_put_pool(pool); + } + WARN_ONCE((!is_ephemeral(pool) && (ret != 0)), + "zcache_get fails on persistent pool, " + "bad things are very likely to happen soon\n"); +#ifdef RAMSTER_TESTING + if (ret != 0 && ret != -1 && !(ret == -EINVAL && is_ephemeral(pool))) + pr_err("TESTING zcache_get tmem_get returns ret=%d\n", ret); +#endif + return ret; +} + +int zcache_flush_page(int cli_id, int pool_id, + struct tmem_oid *oidp, uint32_t index) +{ + struct tmem_pool *pool; + int ret = -1; + unsigned long flags; + + local_irq_save(flags); + zcache_flush_total++; + pool = zcache_get_pool_by_id(cli_id, pool_id); + if (ramster_enabled) + ramster_do_preload_flnode(pool); + if (likely(pool != NULL)) { + if (atomic_read(&pool->obj_count) > 0) + ret = tmem_flush_page(pool, oidp, index); + zcache_put_pool(pool); + } + if (ret >= 0) + zcache_flush_found++; + local_irq_restore(flags); + return ret; +} + +int zcache_flush_object(int cli_id, int pool_id, + struct tmem_oid *oidp) +{ + struct tmem_pool *pool; + int ret = -1; + unsigned long flags; + + local_irq_save(flags); + zcache_flobj_total++; + pool = zcache_get_pool_by_id(cli_id, pool_id); + if (ramster_enabled) + ramster_do_preload_flnode(pool); + if (likely(pool != NULL)) { + if (atomic_read(&pool->obj_count) > 0) + ret = tmem_flush_object(pool, oidp); + zcache_put_pool(pool); + } + if (ret >= 0) + zcache_flobj_found++; + local_irq_restore(flags); + return ret; +} + +static int zcache_client_destroy_pool(int cli_id, int pool_id) +{ + struct tmem_pool *pool = NULL; + struct zcache_client *cli = NULL; + int ret = -1; + + if (pool_id < 0) + goto out; + if (cli_id == LOCAL_CLIENT) + cli = &zcache_host; + else if ((unsigned int)cli_id < MAX_CLIENTS) + cli = &zcache_clients[cli_id]; + if (cli == NULL) + goto out; + atomic_inc(&cli->refcount); + pool = cli->tmem_pools[pool_id]; + if (pool == NULL) + goto out; + cli->tmem_pools[pool_id] = NULL; + /* wait for pool activity on other cpus to quiesce */ + while (atomic_read(&pool->refcount) != 0) + ; + atomic_dec(&cli->refcount); + local_bh_disable(); + ret = tmem_destroy_pool(pool); + local_bh_enable(); + kfree(pool); + if (cli_id == LOCAL_CLIENT) + pr_info("%s: destroyed local pool id=%d\n", namestr, pool_id); + else + pr_info("%s: destroyed pool id=%d, client=%d\n", + namestr, pool_id, cli_id); +out: + return ret; +} + +int zcache_new_pool(uint16_t cli_id, uint32_t flags) +{ + int poolid = -1; + struct tmem_pool *pool; + struct zcache_client *cli = NULL; + + if (cli_id == LOCAL_CLIENT) + cli = &zcache_host; + else if ((unsigned int)cli_id < MAX_CLIENTS) + cli = &zcache_clients[cli_id]; + if (cli == NULL) + goto out; + atomic_inc(&cli->refcount); + pool = kmalloc(sizeof(struct tmem_pool), GFP_ATOMIC); + if (pool == NULL) { + pr_info("%s: pool creation failed: out of memory\n", namestr); + goto out; + } + + for (poolid = 0; poolid < MAX_POOLS_PER_CLIENT; poolid++) + if (cli->tmem_pools[poolid] == NULL) + break; + if (poolid >= MAX_POOLS_PER_CLIENT) { + pr_info("%s: pool creation failed: max exceeded\n", namestr); + kfree(pool); + poolid = -1; + goto out; + } + atomic_set(&pool->refcount, 0); + pool->client = cli; + pool->pool_id = poolid; + tmem_new_pool(pool, flags); + cli->tmem_pools[poolid] = pool; + if (cli_id == LOCAL_CLIENT) + pr_info("%s: created %s local tmem pool, id=%d\n", namestr, + flags & TMEM_POOL_PERSIST ? "persistent" : "ephemeral", + poolid); + else + pr_info("%s: created %s tmem pool, id=%d, client=%d\n", namestr, + flags & TMEM_POOL_PERSIST ? "persistent" : "ephemeral", + poolid, cli_id); +out: + if (cli != NULL) + atomic_dec(&cli->refcount); + return poolid; +} + +static int zcache_local_new_pool(uint32_t flags) +{ + return zcache_new_pool(LOCAL_CLIENT, flags); +} + +int zcache_autocreate_pool(int cli_id, int pool_id, bool eph) +{ + struct tmem_pool *pool; + struct zcache_client *cli = NULL; + uint32_t flags = eph ? 0 : TMEM_POOL_PERSIST; + int ret = -1; + + BUG_ON(!ramster_enabled); + if (cli_id == LOCAL_CLIENT) + goto out; + if (pool_id >= MAX_POOLS_PER_CLIENT) + goto out; + else if ((unsigned int)cli_id < MAX_CLIENTS) + cli = &zcache_clients[cli_id]; + if ((eph && disable_cleancache) || (!eph && disable_frontswap)) { + pr_err("zcache_autocreate_pool: pool type disabled\n"); + goto out; + } + if (!cli->allocated) { + if (zcache_new_client(cli_id)) { + pr_err("zcache_autocreate_pool: can't create client\n"); + goto out; + } + cli = &zcache_clients[cli_id]; + } + atomic_inc(&cli->refcount); + pool = cli->tmem_pools[pool_id]; + if (pool != NULL) { + if (pool->persistent && eph) { + pr_err("zcache_autocreate_pool: type mismatch\n"); + goto out; + } + ret = 0; + goto out; + } + pool = kmalloc(sizeof(struct tmem_pool), GFP_KERNEL); + if (pool == NULL) { + pr_info("%s: pool creation failed: out of memory\n", namestr); + goto out; + } + atomic_set(&pool->refcount, 0); + pool->client = cli; + pool->pool_id = pool_id; + tmem_new_pool(pool, flags); + cli->tmem_pools[pool_id] = pool; + pr_info("%s: AUTOcreated %s tmem poolid=%d, for remote client=%d\n", + namestr, flags & TMEM_POOL_PERSIST ? "persistent" : "ephemeral", + pool_id, cli_id); + ret = 0; +out: + if (cli != NULL) + atomic_dec(&cli->refcount); + return ret; +} + +/********** + * Two kernel functionalities currently can be layered on top of tmem. + * These are "cleancache" which is used as a second-chance cache for clean + * page cache pages; and "frontswap" which is used for swap pages + * to avoid writes to disk. A generic "shim" is provided here for each + * to translate in-kernel semantics to zcache semantics. + */ + +static void zcache_cleancache_put_page(int pool_id, + struct cleancache_filekey key, + pgoff_t index, struct page *page) +{ + u32 ind = (u32) index; + struct tmem_oid oid = *(struct tmem_oid *)&key; + + if (!disable_cleancache_ignore_nonactive && !PageWasActive(page)) { + zcache_eph_nonactive_puts_ignored++; + return; + } + if (likely(ind == index)) + (void)zcache_put_page(LOCAL_CLIENT, pool_id, &oid, index, + page, PAGE_SIZE, false, 1); +} + +static int zcache_cleancache_get_page(int pool_id, + struct cleancache_filekey key, + pgoff_t index, struct page *page) +{ + u32 ind = (u32) index; + struct tmem_oid oid = *(struct tmem_oid *)&key; + size_t size; + int ret = -1; + + if (likely(ind == index)) { + ret = zcache_get_page(LOCAL_CLIENT, pool_id, &oid, index, + page, &size, false, 0); + BUG_ON(ret >= 0 && size != PAGE_SIZE); + if (ret == 0) + SetPageWasActive(page); + } + return ret; +} + +static void zcache_cleancache_flush_page(int pool_id, + struct cleancache_filekey key, + pgoff_t index) +{ + u32 ind = (u32) index; + struct tmem_oid oid = *(struct tmem_oid *)&key; + + if (likely(ind == index)) + (void)zcache_flush_page(LOCAL_CLIENT, pool_id, &oid, ind); +} + +static void zcache_cleancache_flush_inode(int pool_id, + struct cleancache_filekey key) +{ + struct tmem_oid oid = *(struct tmem_oid *)&key; + + (void)zcache_flush_object(LOCAL_CLIENT, pool_id, &oid); +} + +static void zcache_cleancache_flush_fs(int pool_id) +{ + if (pool_id >= 0) + (void)zcache_client_destroy_pool(LOCAL_CLIENT, pool_id); +} + +static int zcache_cleancache_init_fs(size_t pagesize) +{ + BUG_ON(sizeof(struct cleancache_filekey) != + sizeof(struct tmem_oid)); + BUG_ON(pagesize != PAGE_SIZE); + return zcache_local_new_pool(0); +} + +static int zcache_cleancache_init_shared_fs(char *uuid, size_t pagesize) +{ + /* shared pools are unsupported and map to private */ + BUG_ON(sizeof(struct cleancache_filekey) != + sizeof(struct tmem_oid)); + BUG_ON(pagesize != PAGE_SIZE); + return zcache_local_new_pool(0); +} + +static struct cleancache_ops zcache_cleancache_ops = { + .put_page = zcache_cleancache_put_page, + .get_page = zcache_cleancache_get_page, + .invalidate_page = zcache_cleancache_flush_page, + .invalidate_inode = zcache_cleancache_flush_inode, + .invalidate_fs = zcache_cleancache_flush_fs, + .init_shared_fs = zcache_cleancache_init_shared_fs, + .init_fs = zcache_cleancache_init_fs +}; + +struct cleancache_ops zcache_cleancache_register_ops(void) +{ + struct cleancache_ops old_ops = + cleancache_register_ops(&zcache_cleancache_ops); + + return old_ops; +} + +/* a single tmem poolid is used for all frontswap "types" (swapfiles) */ +static int zcache_frontswap_poolid __read_mostly = -1; + +/* + * Swizzling increases objects per swaptype, increasing tmem concurrency + * for heavy swaploads. Later, larger nr_cpus -> larger SWIZ_BITS + * Setting SWIZ_BITS to 27 basically reconstructs the swap entry from + * frontswap_get_page(), but has side-effects. Hence using 8. + */ +#define SWIZ_BITS 8 +#define SWIZ_MASK ((1 << SWIZ_BITS) - 1) +#define _oswiz(_type, _ind) ((_type << SWIZ_BITS) | (_ind & SWIZ_MASK)) +#define iswiz(_ind) (_ind >> SWIZ_BITS) + +static inline struct tmem_oid oswiz(unsigned type, u32 ind) +{ + struct tmem_oid oid = { .oid = { 0 } }; + oid.oid[0] = _oswiz(type, ind); + return oid; +} + +static void unswiz(struct tmem_oid oid, u32 index, + unsigned *type, pgoff_t *offset) +{ + *type = (unsigned)(oid.oid[0] >> SWIZ_BITS); + *offset = (pgoff_t)((index << SWIZ_BITS) | + (oid.oid[0] & SWIZ_MASK)); +} + +static int zcache_frontswap_put_page(unsigned type, pgoff_t offset, + struct page *page) +{ + u64 ind64 = (u64)offset; + u32 ind = (u32)offset; + struct tmem_oid oid = oswiz(type, ind); + int ret = -1; + unsigned long flags; + int unuse_ret; + + BUG_ON(!PageLocked(page)); + if (!disable_frontswap_ignore_nonactive && !PageWasActive(page)) { + zcache_pers_nonactive_puts_ignored++; + ret = -ERANGE; + goto out; + } + if (likely(ind64 == ind)) { + local_irq_save(flags); + ret = zcache_put_page(LOCAL_CLIENT, zcache_frontswap_poolid, + &oid, iswiz(ind), + page, PAGE_SIZE, false, 0); + local_irq_restore(flags); + } +out: + return ret; +} + +/* returns 0 if the page was successfully gotten from frontswap, -1 if + * was not present (should never happen!) */ +static int zcache_frontswap_get_page(unsigned type, pgoff_t offset, + struct page *page) +{ + u64 ind64 = (u64)offset; + u32 ind = (u32)offset; + struct tmem_oid oid = oswiz(type, ind); + size_t size; + int ret = -1, get_and_free; + + if (frontswap_has_exclusive_gets) + get_and_free = 1; + else + get_and_free = -1; + BUG_ON(!PageLocked(page)); + if (likely(ind64 == ind)) { + ret = zcache_get_page(LOCAL_CLIENT, zcache_frontswap_poolid, + &oid, iswiz(ind), + page, &size, false, get_and_free); + BUG_ON(ret >= 0 && size != PAGE_SIZE); + } + return ret; +} + +/* flush a single page from frontswap */ +static void zcache_frontswap_flush_page(unsigned type, pgoff_t offset) +{ + u64 ind64 = (u64)offset; + u32 ind = (u32)offset; + struct tmem_oid oid = oswiz(type, ind); + + if (likely(ind64 == ind)) + (void)zcache_flush_page(LOCAL_CLIENT, zcache_frontswap_poolid, + &oid, iswiz(ind)); +} + +/* flush all pages from the passed swaptype */ +static void zcache_frontswap_flush_area(unsigned type) +{ + struct tmem_oid oid; + int ind; + + for (ind = SWIZ_MASK; ind >= 0; ind--) { + oid = oswiz(type, ind); + (void)zcache_flush_object(LOCAL_CLIENT, + zcache_frontswap_poolid, &oid); + } +} + +static void zcache_frontswap_init(unsigned ignored) +{ + /* a single tmem poolid is used for all frontswap "types" (swapfiles) */ + if (zcache_frontswap_poolid < 0) + zcache_frontswap_poolid = + zcache_local_new_pool(TMEM_POOL_PERSIST); +} + +static struct frontswap_ops zcache_frontswap_ops = { + .store = zcache_frontswap_put_page, + .load = zcache_frontswap_get_page, + .invalidate_page = zcache_frontswap_flush_page, + .invalidate_area = zcache_frontswap_flush_area, + .init = zcache_frontswap_init +}; + +struct frontswap_ops zcache_frontswap_register_ops(void) +{ + struct frontswap_ops old_ops = + frontswap_register_ops(&zcache_frontswap_ops); + + return old_ops; +} + +/* + * zcache initialization + * NOTE FOR NOW zcache or ramster MUST BE PROVIDED AS A KERNEL BOOT PARAMETER + * OR NOTHING HAPPENS! + */ + +static int __init enable_zcache(char *s) +{ + zcache_enabled = 1; + return 1; +} +__setup("zcache", enable_zcache); + +static int __init enable_ramster(char *s) +{ + zcache_enabled = 1; +#ifdef CONFIG_RAMSTER + ramster_enabled = 1; +#endif + return 1; +} +__setup("ramster", enable_ramster); + +/* allow independent dynamic disabling of cleancache and frontswap */ + +static int __init no_cleancache(char *s) +{ + disable_cleancache = 1; + return 1; +} + +__setup("nocleancache", no_cleancache); + +static int __init no_frontswap(char *s) +{ + disable_frontswap = 1; + return 1; +} + +__setup("nofrontswap", no_frontswap); + +static int __init no_frontswap_exclusive_gets(char *s) +{ + frontswap_has_exclusive_gets = false; + return 1; +} + +__setup("nofrontswapexclusivegets", no_frontswap_exclusive_gets); + +static int __init no_frontswap_ignore_nonactive(char *s) +{ + disable_frontswap_ignore_nonactive = 1; + return 1; +} + +__setup("nofrontswapignorenonactive", no_frontswap_ignore_nonactive); + +static int __init no_cleancache_ignore_nonactive(char *s) +{ + disable_cleancache_ignore_nonactive = 1; + return 1; +} + +__setup("nocleancacheignorenonactive", no_cleancache_ignore_nonactive); + +static int __init enable_zcache_compressor(char *s) +{ + strncpy(zcache_comp_name, s, ZCACHE_COMP_NAME_SZ); + zcache_enabled = 1; + return 1; +} +__setup("zcache=", enable_zcache_compressor); + + +static int __init zcache_comp_init(void) +{ + int ret = 0; + + /* check crypto algorithm */ + if (*zcache_comp_name != '\0') { + ret = crypto_has_comp(zcache_comp_name, 0, 0); + if (!ret) + pr_info("zcache: %s not supported\n", + zcache_comp_name); + } + if (!ret) + strcpy(zcache_comp_name, "lzo"); + ret = crypto_has_comp(zcache_comp_name, 0, 0); + if (!ret) { + ret = 1; + goto out; + } + pr_info("zcache: using %s compressor\n", zcache_comp_name); + + /* alloc percpu transforms */ + ret = 0; + zcache_comp_pcpu_tfms = alloc_percpu(struct crypto_comp *); + if (!zcache_comp_pcpu_tfms) + ret = 1; +out: + return ret; +} + +static int __init zcache_init(void) +{ + int ret = 0; + + if (ramster_enabled) { + namestr = "ramster"; + ramster_register_pamops(&zcache_pamops); + } +#ifdef CONFIG_DEBUG_FS + zcache_debugfs_init(); +#endif + if (zcache_enabled) { + unsigned int cpu; + + tmem_register_hostops(&zcache_hostops); + tmem_register_pamops(&zcache_pamops); + ret = register_cpu_notifier(&zcache_cpu_notifier_block); + if (ret) { + pr_err("%s: can't register cpu notifier\n", namestr); + goto out; + } + ret = zcache_comp_init(); + if (ret) { + pr_err("%s: compressor initialization failed\n", + namestr); + goto out; + } + for_each_online_cpu(cpu) { + void *pcpu = (void *)(long)cpu; + zcache_cpu_notifier(&zcache_cpu_notifier_block, + CPU_UP_PREPARE, pcpu); + } + } + zcache_objnode_cache = kmem_cache_create("zcache_objnode", + sizeof(struct tmem_objnode), 0, 0, NULL); + zcache_obj_cache = kmem_cache_create("zcache_obj", + sizeof(struct tmem_obj), 0, 0, NULL); + ret = zcache_new_client(LOCAL_CLIENT); + if (ret) { + pr_err("%s: can't create client\n", namestr); + goto out; + } + zbud_init(); + if (zcache_enabled && !disable_cleancache) { + struct cleancache_ops old_ops; + + register_shrinker(&zcache_shrinker); + old_ops = zcache_cleancache_register_ops(); + pr_info("%s: cleancache enabled using kernel transcendent " + "memory and compression buddies\n", namestr); +#ifdef ZCACHE_DEBUG + pr_info("%s: cleancache: ignorenonactive = %d\n", + namestr, !disable_cleancache_ignore_nonactive); +#endif + if (old_ops.init_fs != NULL) + pr_warn("%s: cleancache_ops overridden\n", namestr); + } + if (zcache_enabled && !disable_frontswap) { + struct frontswap_ops old_ops; + + old_ops = zcache_frontswap_register_ops(); + if (frontswap_has_exclusive_gets) + frontswap_tmem_exclusive_gets(true); + pr_info("%s: frontswap enabled using kernel transcendent " + "memory and compression buddies\n", namestr); +#ifdef ZCACHE_DEBUG + pr_info("%s: frontswap: excl gets = %d active only = %d\n", + namestr, frontswap_has_exclusive_gets, + !disable_frontswap_ignore_nonactive); +#endif + if (old_ops.init != NULL) + pr_warn("%s: frontswap_ops overridden\n", namestr); + } + if (ramster_enabled) + ramster_init(!disable_cleancache, !disable_frontswap, + frontswap_has_exclusive_gets); +out: + return ret; +} + +late_initcall(zcache_init); diff --git a/drivers/staging/ramster/zcache.h b/drivers/staging/ramster/zcache.h new file mode 100644 index 0000000..c59666e --- /dev/null +++ b/drivers/staging/ramster/zcache.h @@ -0,0 +1,53 @@ + +/* + * zcache.h + * + * Copyright (c) 2012, Dan Magenheimer, Oracle Corp. + */ + +#ifndef _ZCACHE_H_ +#define _ZCACHE_H_ + +struct zcache_preload { + struct tmem_obj *obj; + struct tmem_objnode *objnodes[OBJNODE_TREE_MAX_PATH]; +}; + +struct tmem_pool; + +#define MAX_POOLS_PER_CLIENT 16 + +#define MAX_CLIENTS 16 +#define LOCAL_CLIENT ((uint16_t)-1) + +struct zcache_client { + struct tmem_pool *tmem_pools[MAX_POOLS_PER_CLIENT]; + bool allocated; + atomic_t refcount; +}; + +extern struct tmem_pool *zcache_get_pool_by_id(uint16_t cli_id, + uint16_t poolid); +extern void zcache_put_pool(struct tmem_pool *pool); + +extern int zcache_put_page(int, int, struct tmem_oid *, + uint32_t, void *, + unsigned int, bool, int); +extern int zcache_get_page(int, int, struct tmem_oid *, uint32_t, + void *, size_t *, bool, int); +extern int zcache_flush_page(int, int, struct tmem_oid *, uint32_t); +extern int zcache_flush_object(int, int, struct tmem_oid *); +extern void zcache_decompress_to_page(char *, unsigned int, struct page *); + +#ifdef CONFIG_RAMSTER +extern void *zcache_pampd_create(char *, unsigned int, bool, int, + struct tmem_handle *); +extern int zcache_autocreate_pool(int, int, bool); +#endif + +#define MAX_POOLS_PER_CLIENT 16 + +#define MAX_CLIENTS 16 +#define LOCAL_CLIENT ((uint16_t)-1) + +#endif /* _ZCACHE_H_ */ -- cgit v0.10.2 From 14c9fda5c477305ccf0d82ccbdfd47f66a557d65 Mon Sep 17 00:00:00 2001 From: Dan Magenheimer Date: Wed, 5 Sep 2012 13:45:01 -0700 Subject: staging: ramster: place ramster codebase on top of new zcache2 codebase [V2: rebased to apply to 20120905 staging-next, no other changes] This slightly modified ramster codebase is now built entirely on zcache2 and all ramster-specific code is fully contained in a subdirectory. Ramster extends zcache2 to allow pages compressed via zcache2 to be "load-balanced" across machines in a cluster. Control and data communication is done via kernel sockets, and cluster configuration and management is heavily leveraged from the ocfs2 cluster filesystem. There are no new features since the codebase introduced into staging at 3.4. Some cleanup was performed though: 1) Interfaces directly with new zbud 2) Debugfs now used instead of sysfs where possible. Sysfs still used where necessary for userland cluster configuration. Ramster is very much a work-in-progress but also does really work! RAMSTER HIGH LEVEL OVERVIEW (from original V5 posting in Feb 2012) RAMster implements peer-to-peer transcendent memory, allowing a "cluster" of kernels to dynamically pool their RAM so that a RAM-hungry workload on one machine can temporarily and transparently utilize RAM on another machine which is presumably idle or running a non-RAM-hungry workload. Other than the already-merged cleancache patchset and frontswap patchset, no core kernel changes are currently required. (Note that, unlike previous public descriptions of RAMster, this implementation does NOT require synchronous "gets" or core networking changes. As of V5, it also co-exists with ocfs2.) RAMster combines a clustering and messaging foundation based on the ocfs2 cluster layer with the in-kernel compression implementation of zcache2, and adds code to glue them together. When a page is "put" to RAMster, it is compressed and stored locally. Periodically, a thread will "remotify" these pages by sending them via messages to a remote machine. When the page is later needed as indicated by a page fault, a "get" is issued. If the data is local, it is uncompressed and the fault is resolved. If the data is remote, a message is sent to fetch the data and the faulting thread sleeps; when the data arrives, the thread awakens, the data is decompressed and the fault is resolved. As of V5, clusters up to eight nodes are supported; each node can remotify pages to one specified node, so clusters can be configured as clients to a "memory server". Some simple policy is in place that will need to be refined over time. Larger clusters and fault-resistant protocols can also be added over time. A HOW-TO is available at: http://oss.oracle.com/projects/tmem/dist/files/RAMster/HOWTO-120817 Acked-by: Konrad Rzeszutek Wilk Signed-off-by: Dan Magenheimer Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ramster/Kconfig b/drivers/staging/ramster/Kconfig index 7db0592..843c541 100644 --- a/drivers/staging/ramster/Kconfig +++ b/drivers/staging/ramster/Kconfig @@ -14,3 +14,17 @@ config ZCACHE2 technical disagreements. It is intended that they will merge again in the future. Until then, zcache2 is a single-node version of ramster. + +config RAMSTER + bool "Cross-machine RAM capacity sharing, aka peer-to-peer tmem" + depends on CONFIGFS_FS=y && SYSFS=y && !HIGHMEM && ZCACHE2=y + # must ensure struct page is 8-byte aligned + select HAVE_ALIGNED_STRUCT_PAGE if !64_BIT + default n + help + RAMster allows RAM on other machines in a cluster to be utilized + dynamically and symmetrically instead of swapping to a local swap + disk, thus improving performance on memory-constrained workloads + while minimizing total RAM across the cluster. RAMster, like + zcache2, compresses swap pages into local RAM, but then remotifies + the compressed pages to another node in the RAMster cluster. diff --git a/drivers/staging/ramster/Makefile b/drivers/staging/ramster/Makefile index 800e70c..2d8b9d0 100644 --- a/drivers/staging/ramster/Makefile +++ b/drivers/staging/ramster/Makefile @@ -1,3 +1,6 @@ zcache-y := zcache-main.o tmem.o zbud.o +zcache-$(CONFIG_RAMSTER) += ramster/ramster.o ramster/r2net.o +zcache-$(CONFIG_RAMSTER) += ramster/nodemanager.o ramster/tcp.o +zcache-$(CONFIG_RAMSTER) += ramster/heartbeat.o ramster/masklog.o obj-$(CONFIG_ZCACHE2) += zcache.o diff --git a/drivers/staging/ramster/ramster/heartbeat.c b/drivers/staging/ramster/ramster/heartbeat.c new file mode 100644 index 0000000..75d3fe8 --- /dev/null +++ b/drivers/staging/ramster/ramster/heartbeat.c @@ -0,0 +1,462 @@ +/* -*- mode: c; c-basic-offset: 8; -*- + * vim: noexpandtab sw=8 ts=8 sts=0: + * + * Copyright (C) 2004, 2005, 2012 Oracle. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + */ + +#include +#include +#include + +#include "heartbeat.h" +#include "tcp.h" +#include "nodemanager.h" + +#include "masklog.h" + +/* + * The first heartbeat pass had one global thread that would serialize all hb + * callback calls. This global serializing sem should only be removed once + * we've made sure that all callees can deal with being called concurrently + * from multiple hb region threads. + */ +static DECLARE_RWSEM(r2hb_callback_sem); + +/* + * multiple hb threads are watching multiple regions. A node is live + * whenever any of the threads sees activity from the node in its region. + */ +static DEFINE_SPINLOCK(r2hb_live_lock); +static unsigned long r2hb_live_node_bitmap[BITS_TO_LONGS(R2NM_MAX_NODES)]; + +static struct r2hb_callback { + struct list_head list; +} r2hb_callbacks[R2HB_NUM_CB]; + +enum r2hb_heartbeat_modes { + R2HB_HEARTBEAT_LOCAL = 0, + R2HB_HEARTBEAT_GLOBAL, + R2HB_HEARTBEAT_NUM_MODES, +}; + +char *r2hb_heartbeat_mode_desc[R2HB_HEARTBEAT_NUM_MODES] = { + "local", /* R2HB_HEARTBEAT_LOCAL */ + "global", /* R2HB_HEARTBEAT_GLOBAL */ +}; + +unsigned int r2hb_dead_threshold = R2HB_DEFAULT_DEAD_THRESHOLD; +unsigned int r2hb_heartbeat_mode = R2HB_HEARTBEAT_LOCAL; + +/* Only sets a new threshold if there are no active regions. + * + * No locking or otherwise interesting code is required for reading + * r2hb_dead_threshold as it can't change once regions are active and + * it's not interesting to anyone until then anyway. */ +static void r2hb_dead_threshold_set(unsigned int threshold) +{ + if (threshold > R2HB_MIN_DEAD_THRESHOLD) { + spin_lock(&r2hb_live_lock); + r2hb_dead_threshold = threshold; + spin_unlock(&r2hb_live_lock); + } +} + +static int r2hb_global_hearbeat_mode_set(unsigned int hb_mode) +{ + int ret = -1; + + if (hb_mode < R2HB_HEARTBEAT_NUM_MODES) { + spin_lock(&r2hb_live_lock); + r2hb_heartbeat_mode = hb_mode; + ret = 0; + spin_unlock(&r2hb_live_lock); + } + + return ret; +} + +void r2hb_exit(void) +{ +} + +int r2hb_init(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(r2hb_callbacks); i++) + INIT_LIST_HEAD(&r2hb_callbacks[i].list); + + memset(r2hb_live_node_bitmap, 0, sizeof(r2hb_live_node_bitmap)); + + return 0; +} + +/* if we're already in a callback then we're already serialized by the sem */ +static void r2hb_fill_node_map_from_callback(unsigned long *map, + unsigned bytes) +{ + BUG_ON(bytes < (BITS_TO_LONGS(R2NM_MAX_NODES) * sizeof(unsigned long))); + + memcpy(map, &r2hb_live_node_bitmap, bytes); +} + +/* + * get a map of all nodes that are heartbeating in any regions + */ +void r2hb_fill_node_map(unsigned long *map, unsigned bytes) +{ + /* callers want to serialize this map and callbacks so that they + * can trust that they don't miss nodes coming to the party */ + down_read(&r2hb_callback_sem); + spin_lock(&r2hb_live_lock); + r2hb_fill_node_map_from_callback(map, bytes); + spin_unlock(&r2hb_live_lock); + up_read(&r2hb_callback_sem); +} +EXPORT_SYMBOL_GPL(r2hb_fill_node_map); + +/* + * heartbeat configfs bits. The heartbeat set is a default set under + * the cluster set in nodemanager.c. + */ + +/* heartbeat set */ + +struct r2hb_hb_group { + struct config_group hs_group; + /* some stuff? */ +}; + +static struct r2hb_hb_group *to_r2hb_hb_group(struct config_group *group) +{ + return group ? + container_of(group, struct r2hb_hb_group, hs_group) + : NULL; +} + +static struct config_item r2hb_config_item; + +static struct config_item *r2hb_hb_group_make_item(struct config_group *group, + const char *name) +{ + int ret; + + if (strlen(name) > R2HB_MAX_REGION_NAME_LEN) { + ret = -ENAMETOOLONG; + goto free; + } + + config_item_put(&r2hb_config_item); + + return &r2hb_config_item; +free: + return ERR_PTR(ret); +} + +static void r2hb_hb_group_drop_item(struct config_group *group, + struct config_item *item) +{ + if (r2hb_global_heartbeat_active()) { + pr_notice("ramster: Heartbeat %s on region %s (%s)\n", + "stopped/aborted", config_item_name(item), + "no region"); + } + + config_item_put(item); +} + +struct r2hb_hb_group_attribute { + struct configfs_attribute attr; + ssize_t (*show)(struct r2hb_hb_group *, char *); + ssize_t (*store)(struct r2hb_hb_group *, const char *, size_t); +}; + +static ssize_t r2hb_hb_group_show(struct config_item *item, + struct configfs_attribute *attr, + char *page) +{ + struct r2hb_hb_group *reg = to_r2hb_hb_group(to_config_group(item)); + struct r2hb_hb_group_attribute *r2hb_hb_group_attr = + container_of(attr, struct r2hb_hb_group_attribute, attr); + ssize_t ret = 0; + + if (r2hb_hb_group_attr->show) + ret = r2hb_hb_group_attr->show(reg, page); + return ret; +} + +static ssize_t r2hb_hb_group_store(struct config_item *item, + struct configfs_attribute *attr, + const char *page, size_t count) +{ + struct r2hb_hb_group *reg = to_r2hb_hb_group(to_config_group(item)); + struct r2hb_hb_group_attribute *r2hb_hb_group_attr = + container_of(attr, struct r2hb_hb_group_attribute, attr); + ssize_t ret = -EINVAL; + + if (r2hb_hb_group_attr->store) + ret = r2hb_hb_group_attr->store(reg, page, count); + return ret; +} + +static ssize_t r2hb_hb_group_threshold_show(struct r2hb_hb_group *group, + char *page) +{ + return sprintf(page, "%u\n", r2hb_dead_threshold); +} + +static ssize_t r2hb_hb_group_threshold_store(struct r2hb_hb_group *group, + const char *page, + size_t count) +{ + unsigned long tmp; + char *p = (char *)page; + int err; + + err = kstrtoul(p, 10, &tmp); + if (err) + return err; + + /* this will validate ranges for us. */ + r2hb_dead_threshold_set((unsigned int) tmp); + + return count; +} + +static +ssize_t r2hb_hb_group_mode_show(struct r2hb_hb_group *group, + char *page) +{ + return sprintf(page, "%s\n", + r2hb_heartbeat_mode_desc[r2hb_heartbeat_mode]); +} + +static +ssize_t r2hb_hb_group_mode_store(struct r2hb_hb_group *group, + const char *page, size_t count) +{ + unsigned int i; + int ret; + size_t len; + + len = (page[count - 1] == '\n') ? count - 1 : count; + if (!len) + return -EINVAL; + + for (i = 0; i < R2HB_HEARTBEAT_NUM_MODES; ++i) { + if (strnicmp(page, r2hb_heartbeat_mode_desc[i], len)) + continue; + + ret = r2hb_global_hearbeat_mode_set(i); + if (!ret) + pr_notice("ramster: Heartbeat mode set to %s\n", + r2hb_heartbeat_mode_desc[i]); + return count; + } + + return -EINVAL; + +} + +static struct r2hb_hb_group_attribute r2hb_hb_group_attr_threshold = { + .attr = { .ca_owner = THIS_MODULE, + .ca_name = "dead_threshold", + .ca_mode = S_IRUGO | S_IWUSR }, + .show = r2hb_hb_group_threshold_show, + .store = r2hb_hb_group_threshold_store, +}; + +static struct r2hb_hb_group_attribute r2hb_hb_group_attr_mode = { + .attr = { .ca_owner = THIS_MODULE, + .ca_name = "mode", + .ca_mode = S_IRUGO | S_IWUSR }, + .show = r2hb_hb_group_mode_show, + .store = r2hb_hb_group_mode_store, +}; + +static struct configfs_attribute *r2hb_hb_group_attrs[] = { + &r2hb_hb_group_attr_threshold.attr, + &r2hb_hb_group_attr_mode.attr, + NULL, +}; + +static struct configfs_item_operations r2hb_hearbeat_group_item_ops = { + .show_attribute = r2hb_hb_group_show, + .store_attribute = r2hb_hb_group_store, +}; + +static struct configfs_group_operations r2hb_hb_group_group_ops = { + .make_item = r2hb_hb_group_make_item, + .drop_item = r2hb_hb_group_drop_item, +}; + +static struct config_item_type r2hb_hb_group_type = { + .ct_group_ops = &r2hb_hb_group_group_ops, + .ct_item_ops = &r2hb_hearbeat_group_item_ops, + .ct_attrs = r2hb_hb_group_attrs, + .ct_owner = THIS_MODULE, +}; + +/* this is just here to avoid touching group in heartbeat.h which the + * entire damn world #includes */ +struct config_group *r2hb_alloc_hb_set(void) +{ + struct r2hb_hb_group *hs = NULL; + struct config_group *ret = NULL; + + hs = kzalloc(sizeof(struct r2hb_hb_group), GFP_KERNEL); + if (hs == NULL) + goto out; + + config_group_init_type_name(&hs->hs_group, "heartbeat", + &r2hb_hb_group_type); + + ret = &hs->hs_group; +out: + if (ret == NULL) + kfree(hs); + return ret; +} + +void r2hb_free_hb_set(struct config_group *group) +{ + struct r2hb_hb_group *hs = to_r2hb_hb_group(group); + kfree(hs); +} + +/* hb callback registration and issuing */ + +static struct r2hb_callback *hbcall_from_type(enum r2hb_callback_type type) +{ + if (type == R2HB_NUM_CB) + return ERR_PTR(-EINVAL); + + return &r2hb_callbacks[type]; +} + +void r2hb_setup_callback(struct r2hb_callback_func *hc, + enum r2hb_callback_type type, + r2hb_cb_func *func, + void *data, + int priority) +{ + INIT_LIST_HEAD(&hc->hc_item); + hc->hc_func = func; + hc->hc_data = data; + hc->hc_priority = priority; + hc->hc_type = type; + hc->hc_magic = R2HB_CB_MAGIC; +} +EXPORT_SYMBOL_GPL(r2hb_setup_callback); + +int r2hb_register_callback(const char *region_uuid, + struct r2hb_callback_func *hc) +{ + struct r2hb_callback_func *tmp; + struct list_head *iter; + struct r2hb_callback *hbcall; + int ret; + + BUG_ON(hc->hc_magic != R2HB_CB_MAGIC); + BUG_ON(!list_empty(&hc->hc_item)); + + hbcall = hbcall_from_type(hc->hc_type); + if (IS_ERR(hbcall)) { + ret = PTR_ERR(hbcall); + goto out; + } + + down_write(&r2hb_callback_sem); + + list_for_each(iter, &hbcall->list) { + tmp = list_entry(iter, struct r2hb_callback_func, hc_item); + if (hc->hc_priority < tmp->hc_priority) { + list_add_tail(&hc->hc_item, iter); + break; + } + } + if (list_empty(&hc->hc_item)) + list_add_tail(&hc->hc_item, &hbcall->list); + + up_write(&r2hb_callback_sem); + ret = 0; +out: + mlog(ML_CLUSTER, "returning %d on behalf of %p for funcs %p\n", + ret, __builtin_return_address(0), hc); + return ret; +} +EXPORT_SYMBOL_GPL(r2hb_register_callback); + +void r2hb_unregister_callback(const char *region_uuid, + struct r2hb_callback_func *hc) +{ + BUG_ON(hc->hc_magic != R2HB_CB_MAGIC); + + mlog(ML_CLUSTER, "on behalf of %p for funcs %p\n", + __builtin_return_address(0), hc); + + /* XXX Can this happen _with_ a region reference? */ + if (list_empty(&hc->hc_item)) + return; + + down_write(&r2hb_callback_sem); + + list_del_init(&hc->hc_item); + + up_write(&r2hb_callback_sem); +} +EXPORT_SYMBOL_GPL(r2hb_unregister_callback); + +int r2hb_check_node_heartbeating_from_callback(u8 node_num) +{ + unsigned long testing_map[BITS_TO_LONGS(R2NM_MAX_NODES)]; + + r2hb_fill_node_map_from_callback(testing_map, sizeof(testing_map)); + if (!test_bit(node_num, testing_map)) { + mlog(ML_HEARTBEAT, + "node (%u) does not have heartbeating enabled.\n", + node_num); + return 0; + } + + return 1; +} +EXPORT_SYMBOL_GPL(r2hb_check_node_heartbeating_from_callback); + +void r2hb_stop_all_regions(void) +{ +} +EXPORT_SYMBOL_GPL(r2hb_stop_all_regions); + +/* + * this is just a hack until we get the plumbing which flips file systems + * read only and drops the hb ref instead of killing the node dead. + */ +int r2hb_global_heartbeat_active(void) +{ + return (r2hb_heartbeat_mode == R2HB_HEARTBEAT_GLOBAL); +} +EXPORT_SYMBOL(r2hb_global_heartbeat_active); + +/* added for RAMster */ +void r2hb_manual_set_node_heartbeating(int node_num) +{ + if (node_num < R2NM_MAX_NODES) + set_bit(node_num, r2hb_live_node_bitmap); +} +EXPORT_SYMBOL(r2hb_manual_set_node_heartbeating); diff --git a/drivers/staging/ramster/ramster/heartbeat.h b/drivers/staging/ramster/ramster/heartbeat.h new file mode 100644 index 0000000..6cbc775 --- /dev/null +++ b/drivers/staging/ramster/ramster/heartbeat.h @@ -0,0 +1,87 @@ +/* -*- mode: c; c-basic-offset: 8; -*- + * vim: noexpandtab sw=8 ts=8 sts=0: + * + * heartbeat.h + * + * Function prototypes + * + * Copyright (C) 2004 Oracle. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + * + */ + +#ifndef R2CLUSTER_HEARTBEAT_H +#define R2CLUSTER_HEARTBEAT_H + +#define R2HB_REGION_TIMEOUT_MS 2000 + +#define R2HB_MAX_REGION_NAME_LEN 32 + +/* number of changes to be seen as live */ +#define R2HB_LIVE_THRESHOLD 2 +/* number of equal samples to be seen as dead */ +extern unsigned int r2hb_dead_threshold; +#define R2HB_DEFAULT_DEAD_THRESHOLD 31 +/* Otherwise MAX_WRITE_TIMEOUT will be zero... */ +#define R2HB_MIN_DEAD_THRESHOLD 2 +#define R2HB_MAX_WRITE_TIMEOUT_MS \ + (R2HB_REGION_TIMEOUT_MS * (r2hb_dead_threshold - 1)) + +#define R2HB_CB_MAGIC 0x51d1e4ec + +/* callback stuff */ +enum r2hb_callback_type { + R2HB_NODE_DOWN_CB = 0, + R2HB_NODE_UP_CB, + R2HB_NUM_CB +}; + +struct r2nm_node; +typedef void (r2hb_cb_func)(struct r2nm_node *, int, void *); + +struct r2hb_callback_func { + u32 hc_magic; + struct list_head hc_item; + r2hb_cb_func *hc_func; + void *hc_data; + int hc_priority; + enum r2hb_callback_type hc_type; +}; + +struct config_group *r2hb_alloc_hb_set(void); +void r2hb_free_hb_set(struct config_group *group); + +void r2hb_setup_callback(struct r2hb_callback_func *hc, + enum r2hb_callback_type type, + r2hb_cb_func *func, + void *data, + int priority); +int r2hb_register_callback(const char *region_uuid, + struct r2hb_callback_func *hc); +void r2hb_unregister_callback(const char *region_uuid, + struct r2hb_callback_func *hc); +void r2hb_fill_node_map(unsigned long *map, + unsigned bytes); +void r2hb_exit(void); +int r2hb_init(void); +int r2hb_check_node_heartbeating_from_callback(u8 node_num); +void r2hb_stop_all_regions(void); +int r2hb_get_all_regions(char *region_uuids, u8 numregions); +int r2hb_global_heartbeat_active(void); +void r2hb_manual_set_node_heartbeating(int); + +#endif /* R2CLUSTER_HEARTBEAT_H */ diff --git a/drivers/staging/ramster/ramster/masklog.c b/drivers/staging/ramster/ramster/masklog.c new file mode 100644 index 0000000..1261d85 --- /dev/null +++ b/drivers/staging/ramster/ramster/masklog.c @@ -0,0 +1,155 @@ +/* -*- mode: c; c-basic-offset: 8; -*- + * vim: noexpandtab sw=8 ts=8 sts=0: + * + * Copyright (C) 2004, 2005, 2012 Oracle. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + */ + +#include +#include +#include +#include +#include +#include + +#include "masklog.h" + +struct mlog_bits r2_mlog_and_bits = MLOG_BITS_RHS(MLOG_INITIAL_AND_MASK); +EXPORT_SYMBOL_GPL(r2_mlog_and_bits); +struct mlog_bits r2_mlog_not_bits = MLOG_BITS_RHS(0); +EXPORT_SYMBOL_GPL(r2_mlog_not_bits); + +static ssize_t mlog_mask_show(u64 mask, char *buf) +{ + char *state; + + if (__mlog_test_u64(mask, r2_mlog_and_bits)) + state = "allow"; + else if (__mlog_test_u64(mask, r2_mlog_not_bits)) + state = "deny"; + else + state = "off"; + + return snprintf(buf, PAGE_SIZE, "%s\n", state); +} + +static ssize_t mlog_mask_store(u64 mask, const char *buf, size_t count) +{ + if (!strnicmp(buf, "allow", 5)) { + __mlog_set_u64(mask, r2_mlog_and_bits); + __mlog_clear_u64(mask, r2_mlog_not_bits); + } else if (!strnicmp(buf, "deny", 4)) { + __mlog_set_u64(mask, r2_mlog_not_bits); + __mlog_clear_u64(mask, r2_mlog_and_bits); + } else if (!strnicmp(buf, "off", 3)) { + __mlog_clear_u64(mask, r2_mlog_not_bits); + __mlog_clear_u64(mask, r2_mlog_and_bits); + } else + return -EINVAL; + + return count; +} + +struct mlog_attribute { + struct attribute attr; + u64 mask; +}; + +#define to_mlog_attr(_attr) container_of(_attr, struct mlog_attribute, attr) + +#define define_mask(_name) { \ + .attr = { \ + .name = #_name, \ + .mode = S_IRUGO | S_IWUSR, \ + }, \ + .mask = ML_##_name, \ +} + +static struct mlog_attribute mlog_attrs[MLOG_MAX_BITS] = { + define_mask(TCP), + define_mask(MSG), + define_mask(SOCKET), + define_mask(HEARTBEAT), + define_mask(HB_BIO), + define_mask(DLMFS), + define_mask(DLM), + define_mask(DLM_DOMAIN), + define_mask(DLM_THREAD), + define_mask(DLM_MASTER), + define_mask(DLM_RECOVERY), + define_mask(DLM_GLUE), + define_mask(VOTE), + define_mask(CONN), + define_mask(QUORUM), + define_mask(BASTS), + define_mask(CLUSTER), + define_mask(ERROR), + define_mask(NOTICE), + define_mask(KTHREAD), +}; + +static struct attribute *mlog_attr_ptrs[MLOG_MAX_BITS] = {NULL, }; + +static ssize_t mlog_show(struct kobject *obj, struct attribute *attr, + char *buf) +{ + struct mlog_attribute *mlog_attr = to_mlog_attr(attr); + + return mlog_mask_show(mlog_attr->mask, buf); +} + +static ssize_t mlog_store(struct kobject *obj, struct attribute *attr, + const char *buf, size_t count) +{ + struct mlog_attribute *mlog_attr = to_mlog_attr(attr); + + return mlog_mask_store(mlog_attr->mask, buf, count); +} + +static const struct sysfs_ops mlog_attr_ops = { + .show = mlog_show, + .store = mlog_store, +}; + +static struct kobj_type mlog_ktype = { + .default_attrs = mlog_attr_ptrs, + .sysfs_ops = &mlog_attr_ops, +}; + +static struct kset mlog_kset = { + .kobj = {.ktype = &mlog_ktype}, +}; + +int r2_mlog_sys_init(struct kset *r2cb_kset) +{ + int i = 0; + + while (mlog_attrs[i].attr.mode) { + mlog_attr_ptrs[i] = &mlog_attrs[i].attr; + i++; + } + mlog_attr_ptrs[i] = NULL; + + kobject_set_name(&mlog_kset.kobj, "logmask"); + mlog_kset.kobj.kset = r2cb_kset; + return kset_register(&mlog_kset); +} + +void r2_mlog_sys_shutdown(void) +{ + kset_unregister(&mlog_kset); +} diff --git a/drivers/staging/ramster/ramster/masklog.h b/drivers/staging/ramster/ramster/masklog.h new file mode 100644 index 0000000..918ae11 --- /dev/null +++ b/drivers/staging/ramster/ramster/masklog.h @@ -0,0 +1,220 @@ +/* -*- mode: c; c-basic-offset: 8; -*- + * vim: noexpandtab sw=8 ts=8 sts=0: + * + * Copyright (C) 2005, 2012 Oracle. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + */ + +#ifndef R2CLUSTER_MASKLOG_H +#define R2CLUSTER_MASKLOG_H + +/* + * For now this is a trivial wrapper around printk() that gives the critical + * ability to enable sets of debugging output at run-time. In the future this + * will almost certainly be redirected to relayfs so that it can pay a + * substantially lower heisenberg tax. + * + * Callers associate the message with a bitmask and a global bitmask is + * maintained with help from /proc. If any of the bits match the message is + * output. + * + * We must have efficient bit tests on i386 and it seems gcc still emits crazy + * code for the 64bit compare. It emits very good code for the dual unsigned + * long tests, though, completely avoiding tests that can never pass if the + * caller gives a constant bitmask that fills one of the longs with all 0s. So + * the desire is to have almost all of the calls decided on by comparing just + * one of the longs. This leads to having infrequently given bits that are + * frequently matched in the high bits. + * + * _ERROR and _NOTICE are used for messages that always go to the console and + * have appropriate KERN_ prefixes. We wrap these in our function instead of + * just calling printk() so that this can eventually make its way through + * relayfs along with the debugging messages. Everything else gets KERN_DEBUG. + * The inline tests and macro dance give GCC the opportunity to quite cleverly + * only emit the appropriage printk() when the caller passes in a constant + * mask, as is almost always the case. + * + * All this bitmask nonsense is managed from the files under + * /sys/fs/r2cb/logmask/. Reading the files gives a straightforward + * indication of which bits are allowed (allow) or denied (off/deny). + * ENTRY deny + * EXIT deny + * TCP off + * MSG off + * SOCKET off + * ERROR allow + * NOTICE allow + * + * Writing changes the state of a given bit and requires a strictly formatted + * single write() call: + * + * write(fd, "allow", 5); + * + * Echoing allow/deny/off string into the logmask files can flip the bits + * on or off as expected; here is the bash script for example: + * + * log_mask="/sys/fs/r2cb/log_mask" + * for node in ENTRY EXIT TCP MSG SOCKET ERROR NOTICE; do + * echo allow >"$log_mask"/"$node" + * done + * + * The debugfs.ramster tool can also flip the bits with the -l option: + * + * debugfs.ramster -l TCP allow + */ + +/* for task_struct */ +#include + +/* bits that are frequently given and infrequently matched in the low word */ +/* NOTE: If you add a flag, you need to also update masklog.c! */ +#define ML_TCP 0x0000000000000001ULL /* net cluster/tcp.c */ +#define ML_MSG 0x0000000000000002ULL /* net network messages */ +#define ML_SOCKET 0x0000000000000004ULL /* net socket lifetime */ +#define ML_HEARTBEAT 0x0000000000000008ULL /* hb all heartbeat tracking */ +#define ML_HB_BIO 0x0000000000000010ULL /* hb io tracing */ +#define ML_DLMFS 0x0000000000000020ULL /* dlm user dlmfs */ +#define ML_DLM 0x0000000000000040ULL /* dlm general debugging */ +#define ML_DLM_DOMAIN 0x0000000000000080ULL /* dlm domain debugging */ +#define ML_DLM_THREAD 0x0000000000000100ULL /* dlm domain thread */ +#define ML_DLM_MASTER 0x0000000000000200ULL /* dlm master functions */ +#define ML_DLM_RECOVERY 0x0000000000000400ULL /* dlm master functions */ +#define ML_DLM_GLUE 0x0000000000000800ULL /* ramster dlm glue layer */ +#define ML_VOTE 0x0000000000001000ULL /* ramster node messaging */ +#define ML_CONN 0x0000000000002000ULL /* net connection management */ +#define ML_QUORUM 0x0000000000004000ULL /* net connection quorum */ +#define ML_BASTS 0x0000000000008000ULL /* dlmglue asts and basts */ +#define ML_CLUSTER 0x0000000000010000ULL /* cluster stack */ + +/* bits that are infrequently given and frequently matched in the high word */ +#define ML_ERROR 0x1000000000000000ULL /* sent to KERN_ERR */ +#define ML_NOTICE 0x2000000000000000ULL /* setn to KERN_NOTICE */ +#define ML_KTHREAD 0x4000000000000000ULL /* kernel thread activity */ + +#define MLOG_INITIAL_AND_MASK (ML_ERROR|ML_NOTICE) +#ifndef MLOG_MASK_PREFIX +#define MLOG_MASK_PREFIX 0 +#endif + +/* + * When logging is disabled, force the bit test to 0 for anything other + * than errors and notices, allowing gcc to remove the code completely. + * When enabled, allow all masks. + */ +#if defined(CONFIG_RAMSTER_DEBUG_MASKLOG) +#define ML_ALLOWED_BITS (~0) +#else +#define ML_ALLOWED_BITS (ML_ERROR|ML_NOTICE) +#endif + +#define MLOG_MAX_BITS 64 + +struct mlog_bits { + unsigned long words[MLOG_MAX_BITS / BITS_PER_LONG]; +}; + +extern struct mlog_bits r2_mlog_and_bits, r2_mlog_not_bits; + +#if BITS_PER_LONG == 32 + +#define __mlog_test_u64(mask, bits) \ + ((u32)(mask & 0xffffffff) & bits.words[0] || \ + ((u64)(mask) >> 32) & bits.words[1]) +#define __mlog_set_u64(mask, bits) do { \ + bits.words[0] |= (u32)(mask & 0xffffffff); \ + bits.words[1] |= (u64)(mask) >> 32; \ +} while (0) +#define __mlog_clear_u64(mask, bits) do { \ + bits.words[0] &= ~((u32)(mask & 0xffffffff)); \ + bits.words[1] &= ~((u64)(mask) >> 32); \ +} while (0) +#define MLOG_BITS_RHS(mask) { \ + { \ + [0] = (u32)(mask & 0xffffffff), \ + [1] = (u64)(mask) >> 32, \ + } \ +} + +#else /* 32bit long above, 64bit long below */ + +#define __mlog_test_u64(mask, bits) ((mask) & bits.words[0]) +#define __mlog_set_u64(mask, bits) do { \ + bits.words[0] |= (mask); \ +} while (0) +#define __mlog_clear_u64(mask, bits) do { \ + bits.words[0] &= ~(mask); \ +} while (0) +#define MLOG_BITS_RHS(mask) { { (mask) } } + +#endif + +/* + * smp_processor_id() "helpfully" screams when called outside preemptible + * regions in current kernels. sles doesn't have the variants that don't + * scream. just do this instead of trying to guess which we're building + * against.. *sigh*. + */ +#define __mlog_cpu_guess ({ \ + unsigned long _cpu = get_cpu(); \ + put_cpu(); \ + _cpu; \ +}) + +/* In the following two macros, the whitespace after the ',' just + * before ##args is intentional. Otherwise, gcc 2.95 will eat the + * previous token if args expands to nothing. + */ +#define __mlog_printk(level, fmt, args...) \ + printk(level "(%s,%u,%lu):%s:%d " fmt, current->comm, \ + task_pid_nr(current), __mlog_cpu_guess, \ + __PRETTY_FUNCTION__, __LINE__ , ##args) + +#define mlog(mask, fmt, args...) do { \ + u64 __m = MLOG_MASK_PREFIX | (mask); \ + if ((__m & ML_ALLOWED_BITS) && \ + __mlog_test_u64(__m, r2_mlog_and_bits) && \ + !__mlog_test_u64(__m, r2_mlog_not_bits)) { \ + if (__m & ML_ERROR) \ + __mlog_printk(KERN_ERR, "ERROR: "fmt , ##args); \ + else if (__m & ML_NOTICE) \ + __mlog_printk(KERN_NOTICE, fmt , ##args); \ + else \ + __mlog_printk(KERN_INFO, fmt , ##args); \ + } \ +} while (0) + +#define mlog_errno(st) do { \ + int _st = (st); \ + if (_st != -ERESTARTSYS && _st != -EINTR && \ + _st != AOP_TRUNCATED_PAGE && _st != -ENOSPC) \ + mlog(ML_ERROR, "status = %lld\n", (long long)_st); \ +} while (0) + +#define mlog_bug_on_msg(cond, fmt, args...) do { \ + if (cond) { \ + mlog(ML_ERROR, "bug expression: " #cond "\n"); \ + mlog(ML_ERROR, fmt, ##args); \ + BUG(); \ + } \ +} while (0) + +#include +#include +int r2_mlog_sys_init(struct kset *r2cb_subsys); +void r2_mlog_sys_shutdown(void); + +#endif /* R2CLUSTER_MASKLOG_H */ diff --git a/drivers/staging/ramster/ramster/nodemanager.c b/drivers/staging/ramster/ramster/nodemanager.c new file mode 100644 index 0000000..c0f4815 --- /dev/null +++ b/drivers/staging/ramster/ramster/nodemanager.c @@ -0,0 +1,995 @@ +/* -*- mode: c; c-basic-offset: 8; -*- + * vim: noexpandtab sw=8 ts=8 sts=0: + * + * Copyright (C) 2004, 2005, 2012 Oracle. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + */ + +#include +#include +#include +#include + +#include "tcp.h" +#include "nodemanager.h" +#include "heartbeat.h" +#include "masklog.h" + +/* for now we operate under the assertion that there can be only one + * cluster active at a time. Changing this will require trickling + * cluster references throughout where nodes are looked up */ +struct r2nm_cluster *r2nm_single_cluster; + +char *r2nm_fence_method_desc[R2NM_FENCE_METHODS] = { + "reset", /* R2NM_FENCE_RESET */ + "panic", /* R2NM_FENCE_PANIC */ +}; + +struct r2nm_node *r2nm_get_node_by_num(u8 node_num) +{ + struct r2nm_node *node = NULL; + + if (node_num >= R2NM_MAX_NODES || r2nm_single_cluster == NULL) + goto out; + + read_lock(&r2nm_single_cluster->cl_nodes_lock); + node = r2nm_single_cluster->cl_nodes[node_num]; + if (node) + config_item_get(&node->nd_item); + read_unlock(&r2nm_single_cluster->cl_nodes_lock); +out: + return node; +} +EXPORT_SYMBOL_GPL(r2nm_get_node_by_num); + +int r2nm_configured_node_map(unsigned long *map, unsigned bytes) +{ + struct r2nm_cluster *cluster = r2nm_single_cluster; + + BUG_ON(bytes < (sizeof(cluster->cl_nodes_bitmap))); + + if (cluster == NULL) + return -EINVAL; + + read_lock(&cluster->cl_nodes_lock); + memcpy(map, cluster->cl_nodes_bitmap, sizeof(cluster->cl_nodes_bitmap)); + read_unlock(&cluster->cl_nodes_lock); + + return 0; +} +EXPORT_SYMBOL_GPL(r2nm_configured_node_map); + +static struct r2nm_node *r2nm_node_ip_tree_lookup(struct r2nm_cluster *cluster, + __be32 ip_needle, + struct rb_node ***ret_p, + struct rb_node **ret_parent) +{ + struct rb_node **p = &cluster->cl_node_ip_tree.rb_node; + struct rb_node *parent = NULL; + struct r2nm_node *node, *ret = NULL; + + while (*p) { + int cmp; + + parent = *p; + node = rb_entry(parent, struct r2nm_node, nd_ip_node); + + cmp = memcmp(&ip_needle, &node->nd_ipv4_address, + sizeof(ip_needle)); + if (cmp < 0) + p = &(*p)->rb_left; + else if (cmp > 0) + p = &(*p)->rb_right; + else { + ret = node; + break; + } + } + + if (ret_p != NULL) + *ret_p = p; + if (ret_parent != NULL) + *ret_parent = parent; + + return ret; +} + +struct r2nm_node *r2nm_get_node_by_ip(__be32 addr) +{ + struct r2nm_node *node = NULL; + struct r2nm_cluster *cluster = r2nm_single_cluster; + + if (cluster == NULL) + goto out; + + read_lock(&cluster->cl_nodes_lock); + node = r2nm_node_ip_tree_lookup(cluster, addr, NULL, NULL); + if (node) + config_item_get(&node->nd_item); + read_unlock(&cluster->cl_nodes_lock); + +out: + return node; +} +EXPORT_SYMBOL_GPL(r2nm_get_node_by_ip); + +void r2nm_node_put(struct r2nm_node *node) +{ + config_item_put(&node->nd_item); +} +EXPORT_SYMBOL_GPL(r2nm_node_put); + +void r2nm_node_get(struct r2nm_node *node) +{ + config_item_get(&node->nd_item); +} +EXPORT_SYMBOL_GPL(r2nm_node_get); + +u8 r2nm_this_node(void) +{ + u8 node_num = R2NM_MAX_NODES; + + if (r2nm_single_cluster && r2nm_single_cluster->cl_has_local) + node_num = r2nm_single_cluster->cl_local_node; + + return node_num; +} +EXPORT_SYMBOL_GPL(r2nm_this_node); + +/* node configfs bits */ + +static struct r2nm_cluster *to_r2nm_cluster(struct config_item *item) +{ + return item ? + container_of(to_config_group(item), struct r2nm_cluster, + cl_group) + : NULL; +} + +static struct r2nm_node *to_r2nm_node(struct config_item *item) +{ + return item ? container_of(item, struct r2nm_node, nd_item) : NULL; +} + +static void r2nm_node_release(struct config_item *item) +{ + struct r2nm_node *node = to_r2nm_node(item); + kfree(node); +} + +static ssize_t r2nm_node_num_read(struct r2nm_node *node, char *page) +{ + return sprintf(page, "%d\n", node->nd_num); +} + +static struct r2nm_cluster *to_r2nm_cluster_from_node(struct r2nm_node *node) +{ + /* through the first node_set .parent + * mycluster/nodes/mynode == r2nm_cluster->r2nm_node_group->r2nm_node */ + return to_r2nm_cluster(node->nd_item.ci_parent->ci_parent); +} + +enum { + R2NM_NODE_ATTR_NUM = 0, + R2NM_NODE_ATTR_PORT, + R2NM_NODE_ATTR_ADDRESS, + R2NM_NODE_ATTR_LOCAL, +}; + +static ssize_t r2nm_node_num_write(struct r2nm_node *node, const char *page, + size_t count) +{ + struct r2nm_cluster *cluster = to_r2nm_cluster_from_node(node); + unsigned long tmp; + char *p = (char *)page; + int err; + + err = kstrtoul(p, 10, &tmp); + if (err) + return err; + + if (tmp >= R2NM_MAX_NODES) + return -ERANGE; + + /* once we're in the cl_nodes tree networking can look us up by + * node number and try to use our address and port attributes + * to connect to this node.. make sure that they've been set + * before writing the node attribute? */ + if (!test_bit(R2NM_NODE_ATTR_ADDRESS, &node->nd_set_attributes) || + !test_bit(R2NM_NODE_ATTR_PORT, &node->nd_set_attributes)) + return -EINVAL; /* XXX */ + + write_lock(&cluster->cl_nodes_lock); + if (cluster->cl_nodes[tmp]) + p = NULL; + else { + cluster->cl_nodes[tmp] = node; + node->nd_num = tmp; + set_bit(tmp, cluster->cl_nodes_bitmap); + } + write_unlock(&cluster->cl_nodes_lock); + if (p == NULL) + return -EEXIST; + + return count; +} +static ssize_t r2nm_node_ipv4_port_read(struct r2nm_node *node, char *page) +{ + return sprintf(page, "%u\n", ntohs(node->nd_ipv4_port)); +} + +static ssize_t r2nm_node_ipv4_port_write(struct r2nm_node *node, + const char *page, size_t count) +{ + unsigned long tmp; + char *p = (char *)page; + int err; + + err = kstrtoul(p, 10, &tmp); + if (err) + return err; + + if (tmp == 0) + return -EINVAL; + if (tmp >= (u16)-1) + return -ERANGE; + + node->nd_ipv4_port = htons(tmp); + + return count; +} + +static ssize_t r2nm_node_ipv4_address_read(struct r2nm_node *node, char *page) +{ + return sprintf(page, "%pI4\n", &node->nd_ipv4_address); +} + +static ssize_t r2nm_node_ipv4_address_write(struct r2nm_node *node, + const char *page, + size_t count) +{ + struct r2nm_cluster *cluster = to_r2nm_cluster_from_node(node); + int ret, i; + struct rb_node **p, *parent; + unsigned int octets[4]; + __be32 ipv4_addr = 0; + + ret = sscanf(page, "%3u.%3u.%3u.%3u", &octets[3], &octets[2], + &octets[1], &octets[0]); + if (ret != 4) + return -EINVAL; + + for (i = 0; i < ARRAY_SIZE(octets); i++) { + if (octets[i] > 255) + return -ERANGE; + be32_add_cpu(&ipv4_addr, octets[i] << (i * 8)); + } + + ret = 0; + write_lock(&cluster->cl_nodes_lock); + if (r2nm_node_ip_tree_lookup(cluster, ipv4_addr, &p, &parent)) + ret = -EEXIST; + else { + rb_link_node(&node->nd_ip_node, parent, p); + rb_insert_color(&node->nd_ip_node, &cluster->cl_node_ip_tree); + } + write_unlock(&cluster->cl_nodes_lock); + if (ret) + return ret; + + memcpy(&node->nd_ipv4_address, &ipv4_addr, sizeof(ipv4_addr)); + + return count; +} + +static ssize_t r2nm_node_local_read(struct r2nm_node *node, char *page) +{ + return sprintf(page, "%d\n", node->nd_local); +} + +static ssize_t r2nm_node_local_write(struct r2nm_node *node, const char *page, + size_t count) +{ + struct r2nm_cluster *cluster = to_r2nm_cluster_from_node(node); + unsigned long tmp; + char *p = (char *)page; + ssize_t ret; + int err; + + err = kstrtoul(p, 10, &tmp); + if (err) + return err; + + tmp = !!tmp; /* boolean of whether this node wants to be local */ + + /* setting local turns on networking rx for now so we require having + * set everything else first */ + if (!test_bit(R2NM_NODE_ATTR_ADDRESS, &node->nd_set_attributes) || + !test_bit(R2NM_NODE_ATTR_NUM, &node->nd_set_attributes) || + !test_bit(R2NM_NODE_ATTR_PORT, &node->nd_set_attributes)) + return -EINVAL; /* XXX */ + + /* the only failure case is trying to set a new local node + * when a different one is already set */ + if (tmp && tmp == cluster->cl_has_local && + cluster->cl_local_node != node->nd_num) + return -EBUSY; + + /* bring up the rx thread if we're setting the new local node. */ + if (tmp && !cluster->cl_has_local) { + ret = r2net_start_listening(node); + if (ret) + return ret; + } + + if (!tmp && cluster->cl_has_local && + cluster->cl_local_node == node->nd_num) { + r2net_stop_listening(node); + cluster->cl_local_node = R2NM_INVALID_NODE_NUM; + } + + node->nd_local = tmp; + if (node->nd_local) { + cluster->cl_has_local = tmp; + cluster->cl_local_node = node->nd_num; + } + + return count; +} + +struct r2nm_node_attribute { + struct configfs_attribute attr; + ssize_t (*show)(struct r2nm_node *, char *); + ssize_t (*store)(struct r2nm_node *, const char *, size_t); +}; + +static struct r2nm_node_attribute r2nm_node_attr_num = { + .attr = { .ca_owner = THIS_MODULE, + .ca_name = "num", + .ca_mode = S_IRUGO | S_IWUSR }, + .show = r2nm_node_num_read, + .store = r2nm_node_num_write, +}; + +static struct r2nm_node_attribute r2nm_node_attr_ipv4_port = { + .attr = { .ca_owner = THIS_MODULE, + .ca_name = "ipv4_port", + .ca_mode = S_IRUGO | S_IWUSR }, + .show = r2nm_node_ipv4_port_read, + .store = r2nm_node_ipv4_port_write, +}; + +static struct r2nm_node_attribute r2nm_node_attr_ipv4_address = { + .attr = { .ca_owner = THIS_MODULE, + .ca_name = "ipv4_address", + .ca_mode = S_IRUGO | S_IWUSR }, + .show = r2nm_node_ipv4_address_read, + .store = r2nm_node_ipv4_address_write, +}; + +static struct r2nm_node_attribute r2nm_node_attr_local = { + .attr = { .ca_owner = THIS_MODULE, + .ca_name = "local", + .ca_mode = S_IRUGO | S_IWUSR }, + .show = r2nm_node_local_read, + .store = r2nm_node_local_write, +}; + +static struct configfs_attribute *r2nm_node_attrs[] = { + [R2NM_NODE_ATTR_NUM] = &r2nm_node_attr_num.attr, + [R2NM_NODE_ATTR_PORT] = &r2nm_node_attr_ipv4_port.attr, + [R2NM_NODE_ATTR_ADDRESS] = &r2nm_node_attr_ipv4_address.attr, + [R2NM_NODE_ATTR_LOCAL] = &r2nm_node_attr_local.attr, + NULL, +}; + +static int r2nm_attr_index(struct configfs_attribute *attr) +{ + int i; + for (i = 0; i < ARRAY_SIZE(r2nm_node_attrs); i++) { + if (attr == r2nm_node_attrs[i]) + return i; + } + BUG(); + return 0; +} + +static ssize_t r2nm_node_show(struct config_item *item, + struct configfs_attribute *attr, + char *page) +{ + struct r2nm_node *node = to_r2nm_node(item); + struct r2nm_node_attribute *r2nm_node_attr = + container_of(attr, struct r2nm_node_attribute, attr); + ssize_t ret = 0; + + if (r2nm_node_attr->show) + ret = r2nm_node_attr->show(node, page); + return ret; +} + +static ssize_t r2nm_node_store(struct config_item *item, + struct configfs_attribute *attr, + const char *page, size_t count) +{ + struct r2nm_node *node = to_r2nm_node(item); + struct r2nm_node_attribute *r2nm_node_attr = + container_of(attr, struct r2nm_node_attribute, attr); + ssize_t ret; + int attr_index = r2nm_attr_index(attr); + + if (r2nm_node_attr->store == NULL) { + ret = -EINVAL; + goto out; + } + + if (test_bit(attr_index, &node->nd_set_attributes)) + return -EBUSY; + + ret = r2nm_node_attr->store(node, page, count); + if (ret < count) + goto out; + + set_bit(attr_index, &node->nd_set_attributes); +out: + return ret; +} + +static struct configfs_item_operations r2nm_node_item_ops = { + .release = r2nm_node_release, + .show_attribute = r2nm_node_show, + .store_attribute = r2nm_node_store, +}; + +static struct config_item_type r2nm_node_type = { + .ct_item_ops = &r2nm_node_item_ops, + .ct_attrs = r2nm_node_attrs, + .ct_owner = THIS_MODULE, +}; + +/* node set */ + +struct r2nm_node_group { + struct config_group ns_group; + /* some stuff? */ +}; + +#if 0 +static struct r2nm_node_group *to_r2nm_node_group(struct config_group *group) +{ + return group ? + container_of(group, struct r2nm_node_group, ns_group) + : NULL; +} +#endif + +struct r2nm_cluster_attribute { + struct configfs_attribute attr; + ssize_t (*show)(struct r2nm_cluster *, char *); + ssize_t (*store)(struct r2nm_cluster *, const char *, size_t); +}; + +static ssize_t r2nm_cluster_attr_write(const char *page, ssize_t count, + unsigned int *val) +{ + unsigned long tmp; + char *p = (char *)page; + int err; + + err = kstrtoul(p, 10, &tmp); + if (err) + return err; + + if (tmp == 0) + return -EINVAL; + if (tmp >= (u32)-1) + return -ERANGE; + + *val = tmp; + + return count; +} + +static ssize_t r2nm_cluster_attr_idle_timeout_ms_read( + struct r2nm_cluster *cluster, char *page) +{ + return sprintf(page, "%u\n", cluster->cl_idle_timeout_ms); +} + +static ssize_t r2nm_cluster_attr_idle_timeout_ms_write( + struct r2nm_cluster *cluster, const char *page, size_t count) +{ + ssize_t ret; + unsigned int val = 0; + + ret = r2nm_cluster_attr_write(page, count, &val); + + if (ret > 0) { + if (cluster->cl_idle_timeout_ms != val + && r2net_num_connected_peers()) { + mlog(ML_NOTICE, + "r2net: cannot change idle timeout after " + "the first peer has agreed to it." + " %d connected peers\n", + r2net_num_connected_peers()); + ret = -EINVAL; + } else if (val <= cluster->cl_keepalive_delay_ms) { + mlog(ML_NOTICE, + "r2net: idle timeout must be larger " + "than keepalive delay\n"); + ret = -EINVAL; + } else { + cluster->cl_idle_timeout_ms = val; + } + } + + return ret; +} + +static ssize_t r2nm_cluster_attr_keepalive_delay_ms_read( + struct r2nm_cluster *cluster, char *page) +{ + return sprintf(page, "%u\n", cluster->cl_keepalive_delay_ms); +} + +static ssize_t r2nm_cluster_attr_keepalive_delay_ms_write( + struct r2nm_cluster *cluster, const char *page, size_t count) +{ + ssize_t ret; + unsigned int val = 0; + + ret = r2nm_cluster_attr_write(page, count, &val); + + if (ret > 0) { + if (cluster->cl_keepalive_delay_ms != val + && r2net_num_connected_peers()) { + mlog(ML_NOTICE, + "r2net: cannot change keepalive delay after" + " the first peer has agreed to it." + " %d connected peers\n", + r2net_num_connected_peers()); + ret = -EINVAL; + } else if (val >= cluster->cl_idle_timeout_ms) { + mlog(ML_NOTICE, + "r2net: keepalive delay must be " + "smaller than idle timeout\n"); + ret = -EINVAL; + } else { + cluster->cl_keepalive_delay_ms = val; + } + } + + return ret; +} + +static ssize_t r2nm_cluster_attr_reconnect_delay_ms_read( + struct r2nm_cluster *cluster, char *page) +{ + return sprintf(page, "%u\n", cluster->cl_reconnect_delay_ms); +} + +static ssize_t r2nm_cluster_attr_reconnect_delay_ms_write( + struct r2nm_cluster *cluster, const char *page, size_t count) +{ + return r2nm_cluster_attr_write(page, count, + &cluster->cl_reconnect_delay_ms); +} + +static ssize_t r2nm_cluster_attr_fence_method_read( + struct r2nm_cluster *cluster, char *page) +{ + ssize_t ret = 0; + + if (cluster) + ret = sprintf(page, "%s\n", + r2nm_fence_method_desc[cluster->cl_fence_method]); + return ret; +} + +static ssize_t r2nm_cluster_attr_fence_method_write( + struct r2nm_cluster *cluster, const char *page, size_t count) +{ + unsigned int i; + + if (page[count - 1] != '\n') + goto bail; + + for (i = 0; i < R2NM_FENCE_METHODS; ++i) { + if (count != strlen(r2nm_fence_method_desc[i]) + 1) + continue; + if (strncasecmp(page, r2nm_fence_method_desc[i], count - 1)) + continue; + if (cluster->cl_fence_method != i) { + pr_info("ramster: Changing fence method to %s\n", + r2nm_fence_method_desc[i]); + cluster->cl_fence_method = i; + } + return count; + } + +bail: + return -EINVAL; +} + +static struct r2nm_cluster_attribute r2nm_cluster_attr_idle_timeout_ms = { + .attr = { .ca_owner = THIS_MODULE, + .ca_name = "idle_timeout_ms", + .ca_mode = S_IRUGO | S_IWUSR }, + .show = r2nm_cluster_attr_idle_timeout_ms_read, + .store = r2nm_cluster_attr_idle_timeout_ms_write, +}; + +static struct r2nm_cluster_attribute r2nm_cluster_attr_keepalive_delay_ms = { + .attr = { .ca_owner = THIS_MODULE, + .ca_name = "keepalive_delay_ms", + .ca_mode = S_IRUGO | S_IWUSR }, + .show = r2nm_cluster_attr_keepalive_delay_ms_read, + .store = r2nm_cluster_attr_keepalive_delay_ms_write, +}; + +static struct r2nm_cluster_attribute r2nm_cluster_attr_reconnect_delay_ms = { + .attr = { .ca_owner = THIS_MODULE, + .ca_name = "reconnect_delay_ms", + .ca_mode = S_IRUGO | S_IWUSR }, + .show = r2nm_cluster_attr_reconnect_delay_ms_read, + .store = r2nm_cluster_attr_reconnect_delay_ms_write, +}; + +static struct r2nm_cluster_attribute r2nm_cluster_attr_fence_method = { + .attr = { .ca_owner = THIS_MODULE, + .ca_name = "fence_method", + .ca_mode = S_IRUGO | S_IWUSR }, + .show = r2nm_cluster_attr_fence_method_read, + .store = r2nm_cluster_attr_fence_method_write, +}; + +static struct configfs_attribute *r2nm_cluster_attrs[] = { + &r2nm_cluster_attr_idle_timeout_ms.attr, + &r2nm_cluster_attr_keepalive_delay_ms.attr, + &r2nm_cluster_attr_reconnect_delay_ms.attr, + &r2nm_cluster_attr_fence_method.attr, + NULL, +}; +static ssize_t r2nm_cluster_show(struct config_item *item, + struct configfs_attribute *attr, + char *page) +{ + struct r2nm_cluster *cluster = to_r2nm_cluster(item); + struct r2nm_cluster_attribute *r2nm_cluster_attr = + container_of(attr, struct r2nm_cluster_attribute, attr); + ssize_t ret = 0; + + if (r2nm_cluster_attr->show) + ret = r2nm_cluster_attr->show(cluster, page); + return ret; +} + +static ssize_t r2nm_cluster_store(struct config_item *item, + struct configfs_attribute *attr, + const char *page, size_t count) +{ + struct r2nm_cluster *cluster = to_r2nm_cluster(item); + struct r2nm_cluster_attribute *r2nm_cluster_attr = + container_of(attr, struct r2nm_cluster_attribute, attr); + ssize_t ret; + + if (r2nm_cluster_attr->store == NULL) { + ret = -EINVAL; + goto out; + } + + ret = r2nm_cluster_attr->store(cluster, page, count); + if (ret < count) + goto out; +out: + return ret; +} + +static struct config_item *r2nm_node_group_make_item(struct config_group *group, + const char *name) +{ + struct r2nm_node *node = NULL; + + if (strlen(name) > R2NM_MAX_NAME_LEN) + return ERR_PTR(-ENAMETOOLONG); + + node = kzalloc(sizeof(struct r2nm_node), GFP_KERNEL); + if (node == NULL) + return ERR_PTR(-ENOMEM); + + strcpy(node->nd_name, name); /* use item.ci_namebuf instead? */ + config_item_init_type_name(&node->nd_item, name, &r2nm_node_type); + spin_lock_init(&node->nd_lock); + + mlog(ML_CLUSTER, "r2nm: Registering node %s\n", name); + + return &node->nd_item; +} + +static void r2nm_node_group_drop_item(struct config_group *group, + struct config_item *item) +{ + struct r2nm_node *node = to_r2nm_node(item); + struct r2nm_cluster *cluster = + to_r2nm_cluster(group->cg_item.ci_parent); + + r2net_disconnect_node(node); + + if (cluster->cl_has_local && + (cluster->cl_local_node == node->nd_num)) { + cluster->cl_has_local = 0; + cluster->cl_local_node = R2NM_INVALID_NODE_NUM; + r2net_stop_listening(node); + } + + /* XXX call into net to stop this node from trading messages */ + + write_lock(&cluster->cl_nodes_lock); + + /* XXX sloppy */ + if (node->nd_ipv4_address) + rb_erase(&node->nd_ip_node, &cluster->cl_node_ip_tree); + + /* nd_num might be 0 if the node number hasn't been set.. */ + if (cluster->cl_nodes[node->nd_num] == node) { + cluster->cl_nodes[node->nd_num] = NULL; + clear_bit(node->nd_num, cluster->cl_nodes_bitmap); + } + write_unlock(&cluster->cl_nodes_lock); + + mlog(ML_CLUSTER, "r2nm: Unregistered node %s\n", + config_item_name(&node->nd_item)); + + config_item_put(item); +} + +static struct configfs_group_operations r2nm_node_group_group_ops = { + .make_item = r2nm_node_group_make_item, + .drop_item = r2nm_node_group_drop_item, +}; + +static struct config_item_type r2nm_node_group_type = { + .ct_group_ops = &r2nm_node_group_group_ops, + .ct_owner = THIS_MODULE, +}; + +/* cluster */ + +static void r2nm_cluster_release(struct config_item *item) +{ + struct r2nm_cluster *cluster = to_r2nm_cluster(item); + + kfree(cluster->cl_group.default_groups); + kfree(cluster); +} + +static struct configfs_item_operations r2nm_cluster_item_ops = { + .release = r2nm_cluster_release, + .show_attribute = r2nm_cluster_show, + .store_attribute = r2nm_cluster_store, +}; + +static struct config_item_type r2nm_cluster_type = { + .ct_item_ops = &r2nm_cluster_item_ops, + .ct_attrs = r2nm_cluster_attrs, + .ct_owner = THIS_MODULE, +}; + +/* cluster set */ + +struct r2nm_cluster_group { + struct configfs_subsystem cs_subsys; + /* some stuff? */ +}; + +#if 0 +static struct r2nm_cluster_group * +to_r2nm_cluster_group(struct config_group *group) +{ + return group ? + container_of(to_configfs_subsystem(group), + struct r2nm_cluster_group, cs_subsys) + : NULL; +} +#endif + +static struct config_group * +r2nm_cluster_group_make_group(struct config_group *group, + const char *name) +{ + struct r2nm_cluster *cluster = NULL; + struct r2nm_node_group *ns = NULL; + struct config_group *r2hb_group = NULL, *ret = NULL; + void *defs = NULL; + + /* this runs under the parent dir's i_mutex; there can be only + * one caller in here at a time */ + if (r2nm_single_cluster) + return ERR_PTR(-ENOSPC); + + cluster = kzalloc(sizeof(struct r2nm_cluster), GFP_KERNEL); + ns = kzalloc(sizeof(struct r2nm_node_group), GFP_KERNEL); + defs = kcalloc(3, sizeof(struct config_group *), GFP_KERNEL); + r2hb_group = r2hb_alloc_hb_set(); + if (cluster == NULL || ns == NULL || r2hb_group == NULL || defs == NULL) + goto out; + + config_group_init_type_name(&cluster->cl_group, name, + &r2nm_cluster_type); + config_group_init_type_name(&ns->ns_group, "node", + &r2nm_node_group_type); + + cluster->cl_group.default_groups = defs; + cluster->cl_group.default_groups[0] = &ns->ns_group; + cluster->cl_group.default_groups[1] = r2hb_group; + cluster->cl_group.default_groups[2] = NULL; + rwlock_init(&cluster->cl_nodes_lock); + cluster->cl_node_ip_tree = RB_ROOT; + cluster->cl_reconnect_delay_ms = R2NET_RECONNECT_DELAY_MS_DEFAULT; + cluster->cl_idle_timeout_ms = R2NET_IDLE_TIMEOUT_MS_DEFAULT; + cluster->cl_keepalive_delay_ms = R2NET_KEEPALIVE_DELAY_MS_DEFAULT; + cluster->cl_fence_method = R2NM_FENCE_RESET; + + ret = &cluster->cl_group; + r2nm_single_cluster = cluster; + +out: + if (ret == NULL) { + kfree(cluster); + kfree(ns); + r2hb_free_hb_set(r2hb_group); + kfree(defs); + ret = ERR_PTR(-ENOMEM); + } + + return ret; +} + +static void r2nm_cluster_group_drop_item(struct config_group *group, + struct config_item *item) +{ + struct r2nm_cluster *cluster = to_r2nm_cluster(item); + int i; + struct config_item *killme; + + BUG_ON(r2nm_single_cluster != cluster); + r2nm_single_cluster = NULL; + + for (i = 0; cluster->cl_group.default_groups[i]; i++) { + killme = &cluster->cl_group.default_groups[i]->cg_item; + cluster->cl_group.default_groups[i] = NULL; + config_item_put(killme); + } + + config_item_put(item); +} + +static struct configfs_group_operations r2nm_cluster_group_group_ops = { + .make_group = r2nm_cluster_group_make_group, + .drop_item = r2nm_cluster_group_drop_item, +}; + +static struct config_item_type r2nm_cluster_group_type = { + .ct_group_ops = &r2nm_cluster_group_group_ops, + .ct_owner = THIS_MODULE, +}; + +static struct r2nm_cluster_group r2nm_cluster_group = { + .cs_subsys = { + .su_group = { + .cg_item = { + .ci_namebuf = "cluster", + .ci_type = &r2nm_cluster_group_type, + }, + }, + }, +}; + +int r2nm_depend_item(struct config_item *item) +{ + return configfs_depend_item(&r2nm_cluster_group.cs_subsys, item); +} + +void r2nm_undepend_item(struct config_item *item) +{ + configfs_undepend_item(&r2nm_cluster_group.cs_subsys, item); +} + +int r2nm_depend_this_node(void) +{ + int ret = 0; + struct r2nm_node *local_node; + + local_node = r2nm_get_node_by_num(r2nm_this_node()); + if (!local_node) { + ret = -EINVAL; + goto out; + } + + ret = r2nm_depend_item(&local_node->nd_item); + r2nm_node_put(local_node); + +out: + return ret; +} + +void r2nm_undepend_this_node(void) +{ + struct r2nm_node *local_node; + + local_node = r2nm_get_node_by_num(r2nm_this_node()); + BUG_ON(!local_node); + + r2nm_undepend_item(&local_node->nd_item); + r2nm_node_put(local_node); +} + + +static void __exit exit_r2nm(void) +{ + /* XXX sync with hb callbacks and shut down hb? */ + r2net_unregister_hb_callbacks(); + configfs_unregister_subsystem(&r2nm_cluster_group.cs_subsys); + + r2net_exit(); + r2hb_exit(); +} + +static int __init init_r2nm(void) +{ + int ret = -1; + + ret = r2hb_init(); + if (ret) + goto out; + + ret = r2net_init(); + if (ret) + goto out_r2hb; + + ret = r2net_register_hb_callbacks(); + if (ret) + goto out_r2net; + + config_group_init(&r2nm_cluster_group.cs_subsys.su_group); + mutex_init(&r2nm_cluster_group.cs_subsys.su_mutex); + ret = configfs_register_subsystem(&r2nm_cluster_group.cs_subsys); + if (ret) { + pr_err("nodemanager: Registration returned %d\n", ret); + goto out_callbacks; + } + + if (!ret) + goto out; + + configfs_unregister_subsystem(&r2nm_cluster_group.cs_subsys); +out_callbacks: + r2net_unregister_hb_callbacks(); +out_r2net: + r2net_exit(); +out_r2hb: + r2hb_exit(); +out: + return ret; +} + +MODULE_AUTHOR("Oracle"); +MODULE_LICENSE("GPL"); + +/* module_init(init_r2nm) */ +late_initcall(init_r2nm); +/* module_exit(exit_r2nm) */ diff --git a/drivers/staging/ramster/ramster/nodemanager.h b/drivers/staging/ramster/ramster/nodemanager.h new file mode 100644 index 0000000..41a04df --- /dev/null +++ b/drivers/staging/ramster/ramster/nodemanager.h @@ -0,0 +1,88 @@ +/* -*- mode: c; c-basic-offset: 8; -*- + * vim: noexpandtab sw=8 ts=8 sts=0: + * + * nodemanager.h + * + * Function prototypes + * + * Copyright (C) 2004 Oracle. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + * + */ + +#ifndef R2CLUSTER_NODEMANAGER_H +#define R2CLUSTER_NODEMANAGER_H + +#include "ramster_nodemanager.h" + +/* This totally doesn't belong here. */ +#include +#include + +enum r2nm_fence_method { + R2NM_FENCE_RESET = 0, + R2NM_FENCE_PANIC, + R2NM_FENCE_METHODS, /* Number of fence methods */ +}; + +struct r2nm_node { + spinlock_t nd_lock; + struct config_item nd_item; + char nd_name[R2NM_MAX_NAME_LEN+1]; /* replace? */ + __u8 nd_num; + /* only one address per node, as attributes, for now. */ + __be32 nd_ipv4_address; + __be16 nd_ipv4_port; + struct rb_node nd_ip_node; + /* there can be only one local node for now */ + int nd_local; + + unsigned long nd_set_attributes; +}; + +struct r2nm_cluster { + struct config_group cl_group; + unsigned cl_has_local:1; + u8 cl_local_node; + rwlock_t cl_nodes_lock; + struct r2nm_node *cl_nodes[R2NM_MAX_NODES]; + struct rb_root cl_node_ip_tree; + unsigned int cl_idle_timeout_ms; + unsigned int cl_keepalive_delay_ms; + unsigned int cl_reconnect_delay_ms; + enum r2nm_fence_method cl_fence_method; + + /* part of a hack for disk bitmap.. will go eventually. - zab */ + unsigned long cl_nodes_bitmap[BITS_TO_LONGS(R2NM_MAX_NODES)]; +}; + +extern struct r2nm_cluster *r2nm_single_cluster; + +u8 r2nm_this_node(void); + +int r2nm_configured_node_map(unsigned long *map, unsigned bytes); +struct r2nm_node *r2nm_get_node_by_num(u8 node_num); +struct r2nm_node *r2nm_get_node_by_ip(__be32 addr); +void r2nm_node_get(struct r2nm_node *node); +void r2nm_node_put(struct r2nm_node *node); + +int r2nm_depend_item(struct config_item *item); +void r2nm_undepend_item(struct config_item *item); +int r2nm_depend_this_node(void); +void r2nm_undepend_this_node(void); + +#endif /* R2CLUSTER_NODEMANAGER_H */ diff --git a/drivers/staging/ramster/ramster/r2net.c b/drivers/staging/ramster/ramster/r2net.c new file mode 100644 index 0000000..34818dc --- /dev/null +++ b/drivers/staging/ramster/ramster/r2net.c @@ -0,0 +1,414 @@ +/* + * r2net.c + * + * Copyright (c) 2011-2012, Dan Magenheimer, Oracle Corp. + * + * Ramster_r2net provides an interface between zcache and r2net. + * + * FIXME: support more than two nodes + */ + +#include +#include "tcp.h" +#include "nodemanager.h" +#include "../tmem.h" +#include "../zcache.h" +#include "ramster.h" + +#define RAMSTER_TESTING + +#define RMSTR_KEY 0x77347734 + +enum { + RMSTR_TMEM_PUT_EPH = 100, + RMSTR_TMEM_PUT_PERS, + RMSTR_TMEM_ASYNC_GET_REQUEST, + RMSTR_TMEM_ASYNC_GET_AND_FREE_REQUEST, + RMSTR_TMEM_ASYNC_GET_REPLY, + RMSTR_TMEM_FLUSH, + RMSTR_TMEM_FLOBJ, + RMSTR_TMEM_DESTROY_POOL, +}; + +#define RMSTR_R2NET_MAX_LEN \ + (R2NET_MAX_PAYLOAD_BYTES - sizeof(struct tmem_xhandle)) + +#include "tcp_internal.h" + +static struct r2nm_node *r2net_target_node; +static int r2net_target_nodenum; + +int r2net_remote_target_node_set(int node_num) +{ + int ret = -1; + + r2net_target_node = r2nm_get_node_by_num(node_num); + if (r2net_target_node != NULL) { + r2net_target_nodenum = node_num; + r2nm_node_put(r2net_target_node); + ret = 0; + } + return ret; +} + +/* FIXME following buffer should be per-cpu, protected by preempt_disable */ +static char ramster_async_get_buf[R2NET_MAX_PAYLOAD_BYTES]; + +static int ramster_remote_async_get_request_handler(struct r2net_msg *msg, + u32 len, void *data, void **ret_data) +{ + char *pdata; + struct tmem_xhandle xh; + int found; + size_t size = RMSTR_R2NET_MAX_LEN; + u16 msgtype = be16_to_cpu(msg->msg_type); + bool get_and_free = (msgtype == RMSTR_TMEM_ASYNC_GET_AND_FREE_REQUEST); + unsigned long flags; + + xh = *(struct tmem_xhandle *)msg->buf; + if (xh.xh_data_size > RMSTR_R2NET_MAX_LEN) + BUG(); + pdata = ramster_async_get_buf; + *(struct tmem_xhandle *)pdata = xh; + pdata += sizeof(struct tmem_xhandle); + local_irq_save(flags); + found = zcache_get_page(xh.client_id, xh.pool_id, &xh.oid, xh.index, + pdata, &size, true, get_and_free ? 1 : -1); + local_irq_restore(flags); + if (found < 0) { + /* a zero size indicates the get failed */ + size = 0; + } + if (size > RMSTR_R2NET_MAX_LEN) + BUG(); + *ret_data = pdata - sizeof(struct tmem_xhandle); + /* now make caller (r2net_process_message) handle specially */ + r2net_force_data_magic(msg, RMSTR_TMEM_ASYNC_GET_REPLY, RMSTR_KEY); + return size + sizeof(struct tmem_xhandle); +} + +static int ramster_remote_async_get_reply_handler(struct r2net_msg *msg, + u32 len, void *data, void **ret_data) +{ + char *in = (char *)msg->buf; + int datalen = len - sizeof(struct r2net_msg); + int ret = -1; + struct tmem_xhandle *xh = (struct tmem_xhandle *)in; + + in += sizeof(struct tmem_xhandle); + datalen -= sizeof(struct tmem_xhandle); + BUG_ON(datalen < 0 || datalen > PAGE_SIZE); + ret = ramster_localify(xh->pool_id, &xh->oid, xh->index, + in, datalen, xh->extra); +#ifdef RAMSTER_TESTING + if (ret == -EEXIST) + pr_err("TESTING ArrgREP, aborted overwrite on racy put\n"); +#endif + return ret; +} + +int ramster_remote_put_handler(struct r2net_msg *msg, + u32 len, void *data, void **ret_data) +{ + struct tmem_xhandle *xh; + char *p = (char *)msg->buf; + int datalen = len - sizeof(struct r2net_msg) - + sizeof(struct tmem_xhandle); + u16 msgtype = be16_to_cpu(msg->msg_type); + bool ephemeral = (msgtype == RMSTR_TMEM_PUT_EPH); + unsigned long flags; + int ret; + + xh = (struct tmem_xhandle *)p; + p += sizeof(struct tmem_xhandle); + zcache_autocreate_pool(xh->client_id, xh->pool_id, ephemeral); + local_irq_save(flags); + ret = zcache_put_page(xh->client_id, xh->pool_id, &xh->oid, xh->index, + p, datalen, true, ephemeral); + local_irq_restore(flags); + return ret; +} + +int ramster_remote_flush_handler(struct r2net_msg *msg, + u32 len, void *data, void **ret_data) +{ + struct tmem_xhandle *xh; + char *p = (char *)msg->buf; + + xh = (struct tmem_xhandle *)p; + p += sizeof(struct tmem_xhandle); + (void)zcache_flush_page(xh->client_id, xh->pool_id, + &xh->oid, xh->index); + return 0; +} + +int ramster_remote_flobj_handler(struct r2net_msg *msg, + u32 len, void *data, void **ret_data) +{ + struct tmem_xhandle *xh; + char *p = (char *)msg->buf; + + xh = (struct tmem_xhandle *)p; + p += sizeof(struct tmem_xhandle); + (void)zcache_flush_object(xh->client_id, xh->pool_id, &xh->oid); + return 0; +} + +int r2net_remote_async_get(struct tmem_xhandle *xh, bool free, int remotenode, + size_t expect_size, uint8_t expect_cksum, + void *extra) +{ + int nodenum, ret = -1, status; + struct r2nm_node *node = NULL; + struct kvec vec[1]; + size_t veclen = 1; + u32 msg_type; + struct r2net_node *nn; + + node = r2nm_get_node_by_num(remotenode); + if (node == NULL) + goto out; + xh->client_id = r2nm_this_node(); /* which node is getting */ + xh->xh_data_cksum = expect_cksum; + xh->xh_data_size = expect_size; + xh->extra = extra; + vec[0].iov_len = sizeof(*xh); + vec[0].iov_base = xh; + + node = r2net_target_node; + if (!node) + goto out; + + nodenum = r2net_target_nodenum; + + r2nm_node_get(node); + nn = r2net_nn_from_num(nodenum); + if (nn->nn_persistent_error || !nn->nn_sc_valid) { + ret = -ENOTCONN; + r2nm_node_put(node); + goto out; + } + + if (free) + msg_type = RMSTR_TMEM_ASYNC_GET_AND_FREE_REQUEST; + else + msg_type = RMSTR_TMEM_ASYNC_GET_REQUEST; + ret = r2net_send_message_vec(msg_type, RMSTR_KEY, + vec, veclen, remotenode, &status); + r2nm_node_put(node); + if (ret < 0) { + if (ret == -ENOTCONN || ret == -EHOSTDOWN) + goto out; + if (ret == -EAGAIN) + goto out; + /* FIXME handle bad message possibilities here? */ + pr_err("UNTESTED ret<0 in ramster_remote_async_get: ret=%d\n", + ret); + } + ret = status; +out: + return ret; +} + +#ifdef RAMSTER_TESTING +/* leave me here to see if it catches a weird crash */ +static void ramster_check_irq_counts(void) +{ + static int last_hardirq_cnt, last_softirq_cnt, last_preempt_cnt; + int cur_hardirq_cnt, cur_softirq_cnt, cur_preempt_cnt; + + cur_hardirq_cnt = hardirq_count() >> HARDIRQ_SHIFT; + if (cur_hardirq_cnt > last_hardirq_cnt) { + last_hardirq_cnt = cur_hardirq_cnt; + if (!(last_hardirq_cnt&(last_hardirq_cnt-1))) + pr_err("RAMSTER TESTING RRP hardirq_count=%d\n", + last_hardirq_cnt); + } + cur_softirq_cnt = softirq_count() >> SOFTIRQ_SHIFT; + if (cur_softirq_cnt > last_softirq_cnt) { + last_softirq_cnt = cur_softirq_cnt; + if (!(last_softirq_cnt&(last_softirq_cnt-1))) + pr_err("RAMSTER TESTING RRP softirq_count=%d\n", + last_softirq_cnt); + } + cur_preempt_cnt = preempt_count() & PREEMPT_MASK; + if (cur_preempt_cnt > last_preempt_cnt) { + last_preempt_cnt = cur_preempt_cnt; + if (!(last_preempt_cnt&(last_preempt_cnt-1))) + pr_err("RAMSTER TESTING RRP preempt_count=%d\n", + last_preempt_cnt); + } +} +#endif + +int r2net_remote_put(struct tmem_xhandle *xh, char *data, size_t size, + bool ephemeral, int *remotenode) +{ + int nodenum, ret = -1, status; + struct r2nm_node *node = NULL; + struct kvec vec[2]; + size_t veclen = 2; + u32 msg_type; + struct r2net_node *nn; + + BUG_ON(size > RMSTR_R2NET_MAX_LEN); + xh->client_id = r2nm_this_node(); /* which node is putting */ + vec[0].iov_len = sizeof(*xh); + vec[0].iov_base = xh; + vec[1].iov_len = size; + vec[1].iov_base = data; + + node = r2net_target_node; + if (!node) + goto out; + + nodenum = r2net_target_nodenum; + + r2nm_node_get(node); + + nn = r2net_nn_from_num(nodenum); + if (nn->nn_persistent_error || !nn->nn_sc_valid) { + ret = -ENOTCONN; + r2nm_node_put(node); + goto out; + } + + if (ephemeral) + msg_type = RMSTR_TMEM_PUT_EPH; + else + msg_type = RMSTR_TMEM_PUT_PERS; +#ifdef RAMSTER_TESTING + /* leave me here to see if it catches a weird crash */ + ramster_check_irq_counts(); +#endif + + ret = r2net_send_message_vec(msg_type, RMSTR_KEY, vec, veclen, + nodenum, &status); + if (ret < 0) + ret = -1; + else { + ret = status; + *remotenode = nodenum; + } + + r2nm_node_put(node); +out: + return ret; +} + +int r2net_remote_flush(struct tmem_xhandle *xh, int remotenode) +{ + int ret = -1, status; + struct r2nm_node *node = NULL; + struct kvec vec[1]; + size_t veclen = 1; + + node = r2nm_get_node_by_num(remotenode); + BUG_ON(node == NULL); + xh->client_id = r2nm_this_node(); /* which node is flushing */ + vec[0].iov_len = sizeof(*xh); + vec[0].iov_base = xh; + BUG_ON(irqs_disabled()); + BUG_ON(in_softirq()); + ret = r2net_send_message_vec(RMSTR_TMEM_FLUSH, RMSTR_KEY, + vec, veclen, remotenode, &status); + r2nm_node_put(node); + return ret; +} + +int r2net_remote_flush_object(struct tmem_xhandle *xh, int remotenode) +{ + int ret = -1, status; + struct r2nm_node *node = NULL; + struct kvec vec[1]; + size_t veclen = 1; + + node = r2nm_get_node_by_num(remotenode); + BUG_ON(node == NULL); + xh->client_id = r2nm_this_node(); /* which node is flobjing */ + vec[0].iov_len = sizeof(*xh); + vec[0].iov_base = xh; + ret = r2net_send_message_vec(RMSTR_TMEM_FLOBJ, RMSTR_KEY, + vec, veclen, remotenode, &status); + r2nm_node_put(node); + return ret; +} + +/* + * Handler registration + */ + +static LIST_HEAD(r2net_unreg_list); + +static void r2net_unregister_handlers(void) +{ + r2net_unregister_handler_list(&r2net_unreg_list); +} + +int r2net_register_handlers(void) +{ + int status; + + status = r2net_register_handler(RMSTR_TMEM_PUT_EPH, RMSTR_KEY, + RMSTR_R2NET_MAX_LEN, + ramster_remote_put_handler, + NULL, NULL, &r2net_unreg_list); + if (status) + goto bail; + + status = r2net_register_handler(RMSTR_TMEM_PUT_PERS, RMSTR_KEY, + RMSTR_R2NET_MAX_LEN, + ramster_remote_put_handler, + NULL, NULL, &r2net_unreg_list); + if (status) + goto bail; + + status = r2net_register_handler(RMSTR_TMEM_ASYNC_GET_REQUEST, RMSTR_KEY, + RMSTR_R2NET_MAX_LEN, + ramster_remote_async_get_request_handler, + NULL, NULL, + &r2net_unreg_list); + if (status) + goto bail; + + status = r2net_register_handler(RMSTR_TMEM_ASYNC_GET_AND_FREE_REQUEST, + RMSTR_KEY, RMSTR_R2NET_MAX_LEN, + ramster_remote_async_get_request_handler, + NULL, NULL, + &r2net_unreg_list); + if (status) + goto bail; + + status = r2net_register_handler(RMSTR_TMEM_ASYNC_GET_REPLY, RMSTR_KEY, + RMSTR_R2NET_MAX_LEN, + ramster_remote_async_get_reply_handler, + NULL, NULL, + &r2net_unreg_list); + if (status) + goto bail; + + status = r2net_register_handler(RMSTR_TMEM_FLUSH, RMSTR_KEY, + RMSTR_R2NET_MAX_LEN, + ramster_remote_flush_handler, + NULL, NULL, + &r2net_unreg_list); + if (status) + goto bail; + + status = r2net_register_handler(RMSTR_TMEM_FLOBJ, RMSTR_KEY, + RMSTR_R2NET_MAX_LEN, + ramster_remote_flobj_handler, + NULL, NULL, + &r2net_unreg_list); + if (status) + goto bail; + + pr_info("ramster: r2net handlers registered\n"); + +bail: + if (status) { + r2net_unregister_handlers(); + pr_err("ramster: couldn't register r2net handlers\n"); + } + return status; +} diff --git a/drivers/staging/ramster/ramster/ramster.c b/drivers/staging/ramster/ramster/ramster.c new file mode 100644 index 0000000..c06709f --- /dev/null +++ b/drivers/staging/ramster/ramster/ramster.c @@ -0,0 +1,985 @@ +/* + * ramster.c + * + * Copyright (c) 2010-2012, Dan Magenheimer, Oracle Corp. + * + * RAMster implements peer-to-peer transcendent memory, allowing a "cluster" of + * kernels to dynamically pool their RAM so that a RAM-hungry workload on one + * machine can temporarily and transparently utilize RAM on another machine + * which is presumably idle or running a non-RAM-hungry workload. + * + * RAMster combines a clustering and messaging foundation based on the ocfs2 + * cluster layer with the in-kernel compression implementation of zcache, and + * adds code to glue them together. When a page is "put" to RAMster, it is + * compressed and stored locally. Periodically, a thread will "remotify" these + * pages by sending them via messages to a remote machine. When the page is + * later needed as indicated by a page fault, a "get" is issued. If the data + * is local, it is uncompressed and the fault is resolved. If the data is + * remote, a message is sent to fetch the data and the faulting thread sleeps; + * when the data arrives, the thread awakens, the data is decompressed and + * the fault is resolved. + + * As of V5, clusters up to eight nodes are supported; each node can remotify + * pages to one specified node, so clusters can be configured as clients to + * a "memory server". Some simple policy is in place that will need to be + * refined over time. Larger clusters and fault-resistant protocols can also + * be added over time. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../tmem.h" +#include "../zcache.h" +#include "../zbud.h" +#include "ramster.h" +#include "ramster_nodemanager.h" +#include "tcp.h" + +#define RAMSTER_TESTING + +#ifndef CONFIG_SYSFS +#error "ramster needs sysfs to define cluster nodes to use" +#endif + +static bool use_cleancache __read_mostly; +static bool use_frontswap __read_mostly; +static bool use_frontswap_exclusive_gets __read_mostly; + +/* These must be sysfs not debugfs as they are checked/used by userland!! */ +static unsigned long ramster_interface_revision __read_mostly = + R2NM_API_VERSION; /* interface revision must match userspace! */ +static unsigned long ramster_pers_remotify_enable __read_mostly; +static unsigned long ramster_eph_remotify_enable __read_mostly; +static atomic_t ramster_remote_pers_pages = ATOMIC_INIT(0); +#define MANUAL_NODES 8 +static bool ramster_nodes_manual_up[MANUAL_NODES] __read_mostly; +static int ramster_remote_target_nodenum __read_mostly = -1; + +/* these counters are made available via debugfs */ +static long ramster_flnodes; +static atomic_t ramster_flnodes_atomic = ATOMIC_INIT(0); +static unsigned long ramster_flnodes_max; +static long ramster_foreign_eph_pages; +static atomic_t ramster_foreign_eph_pages_atomic = ATOMIC_INIT(0); +static unsigned long ramster_foreign_eph_pages_max; +static long ramster_foreign_pers_pages; +static atomic_t ramster_foreign_pers_pages_atomic = ATOMIC_INIT(0); +static unsigned long ramster_foreign_pers_pages_max; +static unsigned long ramster_eph_pages_remoted; +static unsigned long ramster_pers_pages_remoted; +static unsigned long ramster_eph_pages_remote_failed; +static unsigned long ramster_pers_pages_remote_failed; +static unsigned long ramster_remote_eph_pages_succ_get; +static unsigned long ramster_remote_pers_pages_succ_get; +static unsigned long ramster_remote_eph_pages_unsucc_get; +static unsigned long ramster_remote_pers_pages_unsucc_get; +static unsigned long ramster_pers_pages_remote_nomem; +static unsigned long ramster_remote_objects_flushed; +static unsigned long ramster_remote_object_flushes_failed; +static unsigned long ramster_remote_pages_flushed; +static unsigned long ramster_remote_page_flushes_failed; +/* FIXME frontswap selfshrinking knobs in debugfs? */ + +#ifdef CONFIG_DEBUG_FS +#include +#define zdfs debugfs_create_size_t +#define zdfs64 debugfs_create_u64 +static int __init ramster_debugfs_init(void) +{ + struct dentry *root = debugfs_create_dir("ramster", NULL); + if (root == NULL) + return -ENXIO; + + zdfs("eph_pages_remoted", S_IRUGO, root, &ramster_eph_pages_remoted); + zdfs("pers_pages_remoted", S_IRUGO, root, &ramster_pers_pages_remoted); + zdfs("eph_pages_remote_failed", S_IRUGO, root, + &ramster_eph_pages_remote_failed); + zdfs("pers_pages_remote_failed", S_IRUGO, root, + &ramster_pers_pages_remote_failed); + zdfs("remote_eph_pages_succ_get", S_IRUGO, root, + &ramster_remote_eph_pages_succ_get); + zdfs("remote_pers_pages_succ_get", S_IRUGO, root, + &ramster_remote_pers_pages_succ_get); + zdfs("remote_eph_pages_unsucc_get", S_IRUGO, root, + &ramster_remote_eph_pages_unsucc_get); + zdfs("remote_pers_pages_unsucc_get", S_IRUGO, root, + &ramster_remote_pers_pages_unsucc_get); + zdfs("pers_pages_remote_nomem", S_IRUGO, root, + &ramster_pers_pages_remote_nomem); + zdfs("remote_objects_flushed", S_IRUGO, root, + &ramster_remote_objects_flushed); + zdfs("remote_pages_flushed", S_IRUGO, root, + &ramster_remote_pages_flushed); + zdfs("remote_object_flushes_failed", S_IRUGO, root, + &ramster_remote_object_flushes_failed); + zdfs("remote_page_flushes_failed", S_IRUGO, root, + &ramster_remote_page_flushes_failed); + zdfs("foreign_eph_pages", S_IRUGO, root, + &ramster_foreign_eph_pages); + zdfs("foreign_eph_pages_max", S_IRUGO, root, + &ramster_foreign_eph_pages_max); + zdfs("foreign_pers_pages", S_IRUGO, root, + &ramster_foreign_pers_pages); + zdfs("foreign_pers_pages_max", S_IRUGO, root, + &ramster_foreign_pers_pages_max); + return 0; +} +#undef zdebugfs +#undef zdfs64 +#endif + +static LIST_HEAD(ramster_rem_op_list); +static DEFINE_SPINLOCK(ramster_rem_op_list_lock); +static DEFINE_PER_CPU(struct ramster_preload, ramster_preloads); + +static DEFINE_PER_CPU(unsigned char *, ramster_remoteputmem1); +static DEFINE_PER_CPU(unsigned char *, ramster_remoteputmem2); + +static struct kmem_cache *ramster_flnode_cache __read_mostly; + +static struct flushlist_node *ramster_flnode_alloc(struct tmem_pool *pool) +{ + struct flushlist_node *flnode = NULL; + struct ramster_preload *kp; + + kp = &__get_cpu_var(ramster_preloads); + flnode = kp->flnode; + BUG_ON(flnode == NULL); + kp->flnode = NULL; + ramster_flnodes = atomic_inc_return(&ramster_flnodes_atomic); + if (ramster_flnodes > ramster_flnodes_max) + ramster_flnodes_max = ramster_flnodes; + return flnode; +} + +/* the "flush list" asynchronously collects pages to remotely flush */ +#define FLUSH_ENTIRE_OBJECT ((uint32_t)-1) +static void ramster_flnode_free(struct flushlist_node *flnode, + struct tmem_pool *pool) +{ + int flnodes; + + flnodes = atomic_dec_return(&ramster_flnodes_atomic); + BUG_ON(flnodes < 0); + kmem_cache_free(ramster_flnode_cache, flnode); +} + +int ramster_do_preload_flnode(struct tmem_pool *pool) +{ + struct ramster_preload *kp; + struct flushlist_node *flnode; + int ret = -ENOMEM; + + BUG_ON(!irqs_disabled()); + if (unlikely(ramster_flnode_cache == NULL)) + BUG(); + kp = &__get_cpu_var(ramster_preloads); + flnode = kmem_cache_alloc(ramster_flnode_cache, GFP_ATOMIC); + if (unlikely(flnode == NULL) && kp->flnode == NULL) + BUG(); /* FIXME handle more gracefully, but how??? */ + else if (kp->flnode == NULL) + kp->flnode = flnode; + else + kmem_cache_free(ramster_flnode_cache, flnode); + return ret; +} + +/* + * Called by the message handler after a (still compressed) page has been + * fetched from the remote machine in response to an "is_remote" tmem_get + * or persistent tmem_localify. For a tmem_get, "extra" is the address of + * the page that is to be filled to successfully resolve the tmem_get; for + * a (persistent) tmem_localify, "extra" is NULL (as the data is placed only + * in the local zcache). "data" points to "size" bytes of (compressed) data + * passed in the message. In the case of a persistent remote get, if + * pre-allocation was successful (see ramster_repatriate_preload), the page + * is placed into both local zcache and at "extra". + */ +int ramster_localify(int pool_id, struct tmem_oid *oidp, uint32_t index, + char *data, unsigned int size, void *extra) +{ + int ret = -ENOENT; + unsigned long flags; + struct tmem_pool *pool; + bool eph, delete = false; + void *pampd, *saved_hb; + struct tmem_obj *obj; + + pool = zcache_get_pool_by_id(LOCAL_CLIENT, pool_id); + if (unlikely(pool == NULL)) + /* pool doesn't exist anymore */ + goto out; + eph = is_ephemeral(pool); + local_irq_save(flags); /* FIXME: maybe only disable softirqs? */ + pampd = tmem_localify_get_pampd(pool, oidp, index, &obj, &saved_hb); + if (pampd == NULL) { + /* hmmm... must have been a flush while waiting */ +#ifdef RAMSTER_TESTING + pr_err("UNTESTED pampd==NULL in ramster_localify\n"); +#endif + if (eph) + ramster_remote_eph_pages_unsucc_get++; + else + ramster_remote_pers_pages_unsucc_get++; + obj = NULL; + goto finish; + } else if (unlikely(!pampd_is_remote(pampd))) { + /* hmmm... must have been a dup put while waiting */ +#ifdef RAMSTER_TESTING + pr_err("UNTESTED dup while waiting in ramster_localify\n"); +#endif + if (eph) + ramster_remote_eph_pages_unsucc_get++; + else + ramster_remote_pers_pages_unsucc_get++; + obj = NULL; + pampd = NULL; + ret = -EEXIST; + goto finish; + } else if (size == 0) { + /* no remote data, delete the local is_remote pampd */ + pampd = NULL; + if (eph) + ramster_remote_eph_pages_unsucc_get++; + else + BUG(); + delete = true; + goto finish; + } + if (pampd_is_intransit(pampd)) { + /* + * a pampd is marked intransit if it is remote and space has + * been allocated for it locally (note, only happens for + * persistent pages, in which case the remote copy is freed) + */ + BUG_ON(eph); + pampd = pampd_mask_intransit_and_remote(pampd); + zbud_copy_to_zbud(pampd, data, size); + } else { + /* + * setting pampd to NULL tells tmem_localify_finish to leave + * pampd alone... meaning it is left pointing to the + * remote copy + */ + pampd = NULL; + obj = NULL; + } + /* + * but in all cases, we decompress direct-to-memory to complete + * the remotify and return success + */ + BUG_ON(extra == NULL); + zcache_decompress_to_page(data, size, (struct page *)extra); + if (eph) + ramster_remote_eph_pages_succ_get++; + else + ramster_remote_pers_pages_succ_get++; + ret = 0; +finish: + tmem_localify_finish(obj, index, pampd, saved_hb, delete); + zcache_put_pool(pool); + local_irq_restore(flags); +out: + return ret; +} + +void ramster_pampd_new_obj(struct tmem_obj *obj) +{ + obj->extra = NULL; +} + +void ramster_pampd_free_obj(struct tmem_pool *pool, struct tmem_obj *obj, + bool pool_destroy) +{ + struct flushlist_node *flnode; + + BUG_ON(preemptible()); + if (obj->extra == NULL) + return; + if (pool_destroy && is_ephemeral(pool)) + /* FIXME don't bother with remote eph data for now */ + return; + BUG_ON(!pampd_is_remote(obj->extra)); + flnode = ramster_flnode_alloc(pool); + flnode->xh.client_id = pampd_remote_node(obj->extra); + flnode->xh.pool_id = pool->pool_id; + flnode->xh.oid = obj->oid; + flnode->xh.index = FLUSH_ENTIRE_OBJECT; + flnode->rem_op.op = RAMSTER_REMOTIFY_FLUSH_OBJ; + spin_lock(&ramster_rem_op_list_lock); + list_add(&flnode->rem_op.list, &ramster_rem_op_list); + spin_unlock(&ramster_rem_op_list_lock); +} + +/* + * Called on a remote persistent tmem_get to attempt to preallocate + * local storage for the data contained in the remote persistent page. + * If successfully preallocated, returns the pampd, marked as remote and + * in_transit. Else returns NULL. Note that the appropriate tmem data + * structure must be locked. + */ +void *ramster_pampd_repatriate_preload(void *pampd, struct tmem_pool *pool, + struct tmem_oid *oidp, uint32_t index, + bool *intransit) +{ + int clen = pampd_remote_size(pampd), c; + void *ret_pampd = NULL; + unsigned long flags; + struct tmem_handle th; + + BUG_ON(!pampd_is_remote(pampd)); + BUG_ON(is_ephemeral(pool)); + if (use_frontswap_exclusive_gets) + /* don't need local storage */ + goto out; + if (pampd_is_intransit(pampd)) { + /* + * to avoid multiple allocations (and maybe a memory leak) + * don't preallocate if already in the process of being + * repatriated + */ + *intransit = true; + goto out; + } + *intransit = false; + local_irq_save(flags); + th.client_id = pampd_remote_node(pampd); + th.pool_id = pool->pool_id; + th.oid = *oidp; + th.index = index; + ret_pampd = zcache_pampd_create(NULL, clen, true, false, &th); + if (ret_pampd != NULL) { + /* + * a pampd is marked intransit if it is remote and space has + * been allocated for it locally (note, only happens for + * persistent pages, in which case the remote copy is freed) + */ + ret_pampd = pampd_mark_intransit(ret_pampd); + c = atomic_dec_return(&ramster_remote_pers_pages); + WARN_ON_ONCE(c < 0); + } else { + ramster_pers_pages_remote_nomem++; + } + local_irq_restore(flags); +out: + return ret_pampd; +} + +/* + * Called on a remote tmem_get to invoke a message to fetch the page. + * Might sleep so no tmem locks can be held. "extra" is passed + * all the way through the round-trip messaging to ramster_localify. + */ +int ramster_pampd_repatriate(void *fake_pampd, void *real_pampd, + struct tmem_pool *pool, + struct tmem_oid *oid, uint32_t index, + bool free, void *extra) +{ + struct tmem_xhandle xh; + int ret; + + if (pampd_is_intransit(real_pampd)) + /* have local space pre-reserved, so free remote copy */ + free = true; + xh = tmem_xhandle_fill(LOCAL_CLIENT, pool, oid, index); + /* unreliable request/response for now */ + ret = r2net_remote_async_get(&xh, free, + pampd_remote_node(fake_pampd), + pampd_remote_size(fake_pampd), + pampd_remote_cksum(fake_pampd), + extra); + return ret; +} + +bool ramster_pampd_is_remote(void *pampd) +{ + return pampd_is_remote(pampd); +} + +int ramster_pampd_replace_in_obj(void *new_pampd, struct tmem_obj *obj) +{ + int ret = -1; + + if (new_pampd != NULL) { + if (obj->extra == NULL) + obj->extra = new_pampd; + /* enforce that all remote pages in an object reside + * in the same node! */ + else if (pampd_remote_node(new_pampd) != + pampd_remote_node((void *)(obj->extra))) + BUG(); + ret = 0; + } + return ret; +} + +void *ramster_pampd_free(void *pampd, struct tmem_pool *pool, + struct tmem_oid *oid, uint32_t index, bool acct) +{ + bool eph = is_ephemeral(pool); + void *local_pampd = NULL; + int c; + + BUG_ON(preemptible()); + BUG_ON(!pampd_is_remote(pampd)); + WARN_ON(acct == false); + if (oid == NULL) { + /* + * a NULL oid means to ignore this pampd free + * as the remote freeing will be handled elsewhere + */ + } else if (eph) { + /* FIXME remote flush optional but probably good idea */ + } else if (pampd_is_intransit(pampd)) { + /* did a pers remote get_and_free, so just free local */ + local_pampd = pampd_mask_intransit_and_remote(pampd); + } else { + struct flushlist_node *flnode = + ramster_flnode_alloc(pool); + + flnode->xh.client_id = pampd_remote_node(pampd); + flnode->xh.pool_id = pool->pool_id; + flnode->xh.oid = *oid; + flnode->xh.index = index; + flnode->rem_op.op = RAMSTER_REMOTIFY_FLUSH_PAGE; + spin_lock(&ramster_rem_op_list_lock); + list_add(&flnode->rem_op.list, &ramster_rem_op_list); + spin_unlock(&ramster_rem_op_list_lock); + c = atomic_dec_return(&ramster_remote_pers_pages); + WARN_ON_ONCE(c < 0); + } + return local_pampd; +} + +void ramster_count_foreign_pages(bool eph, int count) +{ + int c; + + BUG_ON(count != 1 && count != -1); + if (eph) { + if (count > 0) { + c = atomic_inc_return( + &ramster_foreign_eph_pages_atomic); + if (c > ramster_foreign_eph_pages_max) + ramster_foreign_eph_pages_max = c; + } else { + c = atomic_dec_return(&ramster_foreign_eph_pages_atomic); + WARN_ON_ONCE(c < 0); + } + ramster_foreign_eph_pages = c; + } else { + if (count > 0) { + c = atomic_inc_return( + &ramster_foreign_pers_pages_atomic); + if (c > ramster_foreign_pers_pages_max) + ramster_foreign_pers_pages_max = c; + } else { + c = atomic_dec_return( + &ramster_foreign_pers_pages_atomic); + WARN_ON_ONCE(c < 0); + } + ramster_foreign_pers_pages = c; + } +} + +/* + * For now, just push over a few pages every few seconds to + * ensure that it basically works + */ +static struct workqueue_struct *ramster_remotify_workqueue; +static void ramster_remotify_process(struct work_struct *work); +static DECLARE_DELAYED_WORK(ramster_remotify_worker, + ramster_remotify_process); + +static void ramster_remotify_queue_delayed_work(unsigned long delay) +{ + if (!queue_delayed_work(ramster_remotify_workqueue, + &ramster_remotify_worker, delay)) + pr_err("ramster_remotify: bad workqueue\n"); +} + +static void ramster_remote_flush_page(struct flushlist_node *flnode) +{ + struct tmem_xhandle *xh; + int remotenode, ret; + + preempt_disable(); + xh = &flnode->xh; + remotenode = flnode->xh.client_id; + ret = r2net_remote_flush(xh, remotenode); + if (ret >= 0) + ramster_remote_pages_flushed++; + else + ramster_remote_page_flushes_failed++; + preempt_enable_no_resched(); + ramster_flnode_free(flnode, NULL); +} + +static void ramster_remote_flush_object(struct flushlist_node *flnode) +{ + struct tmem_xhandle *xh; + int remotenode, ret; + + preempt_disable(); + xh = &flnode->xh; + remotenode = flnode->xh.client_id; + ret = r2net_remote_flush_object(xh, remotenode); + if (ret >= 0) + ramster_remote_objects_flushed++; + else + ramster_remote_object_flushes_failed++; + preempt_enable_no_resched(); + ramster_flnode_free(flnode, NULL); +} + +int ramster_remotify_pageframe(bool eph) +{ + struct tmem_xhandle xh; + unsigned int size; + int remotenode, ret, zbuds; + struct tmem_pool *pool; + unsigned long flags; + unsigned char cksum; + char *p; + int i, j; + unsigned char *tmpmem[2]; + struct tmem_handle th[2]; + unsigned int zsize[2]; + + tmpmem[0] = __get_cpu_var(ramster_remoteputmem1); + tmpmem[1] = __get_cpu_var(ramster_remoteputmem2); + local_bh_disable(); + zbuds = zbud_make_zombie_lru(&th[0], &tmpmem[0], &zsize[0], eph); + /* now OK to release lock set in caller */ + local_bh_enable(); + if (zbuds == 0) + goto out; + BUG_ON(zbuds > 2); + for (i = 0; i < zbuds; i++) { + xh.client_id = th[i].client_id; + xh.pool_id = th[i].pool_id; + xh.oid = th[i].oid; + xh.index = th[i].index; + size = zsize[i]; + BUG_ON(size == 0 || size > zbud_max_buddy_size()); + for (p = tmpmem[i], cksum = 0, j = 0; j < size; j++) + cksum += *p++; + ret = r2net_remote_put(&xh, tmpmem[i], size, eph, &remotenode); + if (ret != 0) { + /* + * This is some form of a memory leak... if the remote put + * fails, there will never be another attempt to remotify + * this page. But since we've dropped the zv pointer, + * the page may have been freed or the data replaced + * so we can't just "put it back" in the remote op list. + * Even if we could, not sure where to put it in the list + * because there may be flushes that must be strictly + * ordered vs the put. So leave this as a FIXME for now. + * But count them so we know if it becomes a problem. + */ + if (eph) + ramster_eph_pages_remote_failed++; + else + ramster_pers_pages_remote_failed++; + break; + } else { + if (!eph) + atomic_inc(&ramster_remote_pers_pages); + } + if (eph) + ramster_eph_pages_remoted++; + else + ramster_pers_pages_remoted++; + /* + * data was successfully remoted so change the local version to + * point to the remote node where it landed + */ + local_bh_disable(); + pool = zcache_get_pool_by_id(LOCAL_CLIENT, xh.pool_id); + local_irq_save(flags); + (void)tmem_replace(pool, &xh.oid, xh.index, + pampd_make_remote(remotenode, size, cksum)); + local_irq_restore(flags); + zcache_put_pool(pool); + local_bh_enable(); + } +out: + return zbuds; +} + +static void zcache_do_remotify_flushes(void) +{ + struct ramster_remotify_hdr *rem_op; + union remotify_list_node *u; + + while (1) { + spin_lock(&ramster_rem_op_list_lock); + if (list_empty(&ramster_rem_op_list)) { + spin_unlock(&ramster_rem_op_list_lock); + goto out; + } + rem_op = list_first_entry(&ramster_rem_op_list, + struct ramster_remotify_hdr, list); + list_del_init(&rem_op->list); + spin_unlock(&ramster_rem_op_list_lock); + u = (union remotify_list_node *)rem_op; + switch (rem_op->op) { + case RAMSTER_REMOTIFY_FLUSH_PAGE: + ramster_remote_flush_page((struct flushlist_node *)u); + break; + case RAMSTER_REMOTIFY_FLUSH_OBJ: + ramster_remote_flush_object((struct flushlist_node *)u); + break; + default: + BUG(); + } + } +out: + return; +} + +static void ramster_remotify_process(struct work_struct *work) +{ + static bool remotify_in_progress; + int i; + + BUG_ON(irqs_disabled()); + if (remotify_in_progress) + goto requeue; + if (ramster_remote_target_nodenum == -1) + goto requeue; + remotify_in_progress = true; + if (use_cleancache && ramster_eph_remotify_enable) { + for (i = 0; i < 100; i++) { + zcache_do_remotify_flushes(); + (void)ramster_remotify_pageframe(true); + } + } + if (use_frontswap && ramster_pers_remotify_enable) { + for (i = 0; i < 100; i++) { + zcache_do_remotify_flushes(); + (void)ramster_remotify_pageframe(false); + } + } + remotify_in_progress = false; +requeue: + ramster_remotify_queue_delayed_work(HZ); +} + +void __init ramster_remotify_init(void) +{ + unsigned long n = 60UL; + ramster_remotify_workqueue = + create_singlethread_workqueue("ramster_remotify"); + ramster_remotify_queue_delayed_work(n * HZ); +} + +static ssize_t ramster_manual_node_up_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + int i; + char *p = buf; + for (i = 0; i < MANUAL_NODES; i++) + if (ramster_nodes_manual_up[i]) + p += sprintf(p, "%d ", i); + p += sprintf(p, "\n"); + return p - buf; +} + +static ssize_t ramster_manual_node_up_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t count) +{ + int err; + unsigned long node_num; + + err = kstrtoul(buf, 10, &node_num); + if (err) { + pr_err("ramster: bad strtoul?\n"); + return -EINVAL; + } + if (node_num >= MANUAL_NODES) { + pr_err("ramster: bad node_num=%lu?\n", node_num); + return -EINVAL; + } + if (ramster_nodes_manual_up[node_num]) { + pr_err("ramster: node %d already up, ignoring\n", + (int)node_num); + } else { + ramster_nodes_manual_up[node_num] = true; + r2net_hb_node_up_manual((int)node_num); + } + return count; +} + +static struct kobj_attribute ramster_manual_node_up_attr = { + .attr = { .name = "manual_node_up", .mode = 0644 }, + .show = ramster_manual_node_up_show, + .store = ramster_manual_node_up_store, +}; + +static ssize_t ramster_remote_target_nodenum_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + if (ramster_remote_target_nodenum == -1UL) + return sprintf(buf, "unset\n"); + else + return sprintf(buf, "%d\n", ramster_remote_target_nodenum); +} + +static ssize_t ramster_remote_target_nodenum_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t count) +{ + int err; + unsigned long node_num; + + err = kstrtoul(buf, 10, &node_num); + if (err) { + pr_err("ramster: bad strtoul?\n"); + return -EINVAL; + } else if (node_num == -1UL) { + pr_err("ramster: disabling all remotification, " + "data may still reside on remote nodes however\n"); + return -EINVAL; + } else if (node_num >= MANUAL_NODES) { + pr_err("ramster: bad node_num=%lu?\n", node_num); + return -EINVAL; + } else if (!ramster_nodes_manual_up[node_num]) { + pr_err("ramster: node %d not up, ignoring setting " + "of remotification target\n", (int)node_num); + } else if (r2net_remote_target_node_set((int)node_num) >= 0) { + pr_info("ramster: node %d set as remotification target\n", + (int)node_num); + ramster_remote_target_nodenum = (int)node_num; + } else { + pr_err("ramster: bad num to node node_num=%d?\n", + (int)node_num); + return -EINVAL; + } + return count; +} + +static struct kobj_attribute ramster_remote_target_nodenum_attr = { + .attr = { .name = "remote_target_nodenum", .mode = 0644 }, + .show = ramster_remote_target_nodenum_show, + .store = ramster_remote_target_nodenum_store, +}; + +#define RAMSTER_SYSFS_RO(_name) \ + static ssize_t ramster_##_name##_show(struct kobject *kobj, \ + struct kobj_attribute *attr, char *buf) \ + { \ + return sprintf(buf, "%lu\n", ramster_##_name); \ + } \ + static struct kobj_attribute ramster_##_name##_attr = { \ + .attr = { .name = __stringify(_name), .mode = 0444 }, \ + .show = ramster_##_name##_show, \ + } + +#define RAMSTER_SYSFS_RW(_name) \ + static ssize_t ramster_##_name##_show(struct kobject *kobj, \ + struct kobj_attribute *attr, char *buf) \ + { \ + return sprintf(buf, "%lu\n", ramster_##_name); \ + } \ + static ssize_t ramster_##_name##_store(struct kobject *kobj, \ + struct kobj_attribute *attr, const char *buf, size_t count) \ + { \ + int err; \ + unsigned long enable; \ + err = kstrtoul(buf, 10, &enable); \ + if (err) \ + return -EINVAL; \ + ramster_##_name = enable; \ + return count; \ + } \ + static struct kobj_attribute ramster_##_name##_attr = { \ + .attr = { .name = __stringify(_name), .mode = 0644 }, \ + .show = ramster_##_name##_show, \ + .store = ramster_##_name##_store, \ + } + +#define RAMSTER_SYSFS_RO_ATOMIC(_name) \ + static ssize_t ramster_##_name##_show(struct kobject *kobj, \ + struct kobj_attribute *attr, char *buf) \ + { \ + return sprintf(buf, "%d\n", atomic_read(&ramster_##_name)); \ + } \ + static struct kobj_attribute ramster_##_name##_attr = { \ + .attr = { .name = __stringify(_name), .mode = 0444 }, \ + .show = ramster_##_name##_show, \ + } + +RAMSTER_SYSFS_RO(interface_revision); +RAMSTER_SYSFS_RO_ATOMIC(remote_pers_pages); +RAMSTER_SYSFS_RW(pers_remotify_enable); +RAMSTER_SYSFS_RW(eph_remotify_enable); + +static struct attribute *ramster_attrs[] = { + &ramster_interface_revision_attr.attr, + &ramster_remote_pers_pages_attr.attr, + &ramster_manual_node_up_attr.attr, + &ramster_remote_target_nodenum_attr.attr, + &ramster_pers_remotify_enable_attr.attr, + &ramster_eph_remotify_enable_attr.attr, + NULL, +}; + +static struct attribute_group ramster_attr_group = { + .attrs = ramster_attrs, + .name = "ramster", +}; + +/* + * frontswap selfshrinking + */ + +/* In HZ, controls frequency of worker invocation. */ +static unsigned int selfshrink_interval __read_mostly = 5; +/* Enable/disable with sysfs. */ +static bool frontswap_selfshrinking __read_mostly; + +static void selfshrink_process(struct work_struct *work); +static DECLARE_DELAYED_WORK(selfshrink_worker, selfshrink_process); + +/* Enable/disable with kernel boot option. */ +static bool use_frontswap_selfshrink __initdata = true; + +/* + * The default values for the following parameters were deemed reasonable + * by experimentation, may be workload-dependent, and can all be + * adjusted via sysfs. + */ + +/* Control rate for frontswap shrinking. Higher hysteresis is slower. */ +static unsigned int frontswap_hysteresis __read_mostly = 20; + +/* + * Number of selfshrink worker invocations to wait before observing that + * frontswap selfshrinking should commence. Note that selfshrinking does + * not use a separate worker thread. + */ +static unsigned int frontswap_inertia __read_mostly = 3; + +/* Countdown to next invocation of frontswap_shrink() */ +static unsigned long frontswap_inertia_counter; + +/* + * Invoked by the selfshrink worker thread, uses current number of pages + * in frontswap (frontswap_curr_pages()), previous status, and control + * values (hysteresis and inertia) to determine if frontswap should be + * shrunk and what the new frontswap size should be. Note that + * frontswap_shrink is essentially a partial swapoff that immediately + * transfers pages from the "swap device" (frontswap) back into kernel + * RAM; despite the name, frontswap "shrinking" is very different from + * the "shrinker" interface used by the kernel MM subsystem to reclaim + * memory. + */ +static void frontswap_selfshrink(void) +{ + static unsigned long cur_frontswap_pages; + static unsigned long last_frontswap_pages; + static unsigned long tgt_frontswap_pages; + + last_frontswap_pages = cur_frontswap_pages; + cur_frontswap_pages = frontswap_curr_pages(); + if (!cur_frontswap_pages || + (cur_frontswap_pages > last_frontswap_pages)) { + frontswap_inertia_counter = frontswap_inertia; + return; + } + if (frontswap_inertia_counter && --frontswap_inertia_counter) + return; + if (cur_frontswap_pages <= frontswap_hysteresis) + tgt_frontswap_pages = 0; + else + tgt_frontswap_pages = cur_frontswap_pages - + (cur_frontswap_pages / frontswap_hysteresis); + frontswap_shrink(tgt_frontswap_pages); +} + +static int __init ramster_nofrontswap_selfshrink_setup(char *s) +{ + use_frontswap_selfshrink = false; + return 1; +} + +__setup("noselfshrink", ramster_nofrontswap_selfshrink_setup); + +static void selfshrink_process(struct work_struct *work) +{ + if (frontswap_selfshrinking && frontswap_enabled) { + frontswap_selfshrink(); + schedule_delayed_work(&selfshrink_worker, + selfshrink_interval * HZ); + } +} + +void ramster_cpu_up(int cpu) +{ + unsigned char *p1 = kzalloc(PAGE_SIZE, GFP_KERNEL | __GFP_REPEAT); + unsigned char *p2 = kzalloc(PAGE_SIZE, GFP_KERNEL | __GFP_REPEAT); + BUG_ON(!p1 || !p2); + per_cpu(ramster_remoteputmem1, cpu) = p1; + per_cpu(ramster_remoteputmem2, cpu) = p2; +} + +void ramster_cpu_down(int cpu) +{ + struct ramster_preload *kp; + + kfree(per_cpu(ramster_remoteputmem1, cpu)); + per_cpu(ramster_remoteputmem1, cpu) = NULL; + kfree(per_cpu(ramster_remoteputmem2, cpu)); + per_cpu(ramster_remoteputmem2, cpu) = NULL; + kp = &per_cpu(ramster_preloads, cpu); + if (kp->flnode) { + kmem_cache_free(ramster_flnode_cache, kp->flnode); + kp->flnode = NULL; + } +} + +void ramster_register_pamops(struct tmem_pamops *pamops) +{ + pamops->free_obj = ramster_pampd_free_obj; + pamops->new_obj = ramster_pampd_new_obj; + pamops->replace_in_obj = ramster_pampd_replace_in_obj; + pamops->is_remote = ramster_pampd_is_remote; + pamops->repatriate = ramster_pampd_repatriate; + pamops->repatriate_preload = ramster_pampd_repatriate_preload; +} + +void __init ramster_init(bool cleancache, bool frontswap, + bool frontswap_exclusive_gets) +{ + int ret = 0; + + if (cleancache) + use_cleancache = true; + if (frontswap) + use_frontswap = true; + if (frontswap_exclusive_gets) + use_frontswap_exclusive_gets = true; + ramster_debugfs_init(); + ret = sysfs_create_group(mm_kobj, &ramster_attr_group); + if (ret) + pr_err("ramster: can't create sysfs for ramster\n"); + (void)r2net_register_handlers(); + INIT_LIST_HEAD(&ramster_rem_op_list); + ramster_flnode_cache = kmem_cache_create("ramster_flnode", + sizeof(struct flushlist_node), 0, 0, NULL); + frontswap_selfshrinking = use_frontswap_selfshrink; + if (frontswap_selfshrinking) { + pr_info("ramster: Initializing frontswap selfshrink driver.\n"); + schedule_delayed_work(&selfshrink_worker, + selfshrink_interval * HZ); + } + ramster_remotify_init(); +} diff --git a/drivers/staging/ramster/ramster/ramster.h b/drivers/staging/ramster/ramster/ramster.h new file mode 100644 index 0000000..12ae56f --- /dev/null +++ b/drivers/staging/ramster/ramster/ramster.h @@ -0,0 +1,161 @@ +/* + * ramster.h + * + * Peer-to-peer transcendent memory + * + * Copyright (c) 2009-2012, Dan Magenheimer, Oracle Corp. + */ + +#ifndef _RAMSTER_RAMSTER_H_ +#define _RAMSTER_RAMSTER_H_ + +#include "../tmem.h" + +enum ramster_remotify_op { + RAMSTER_REMOTIFY_FLUSH_PAGE, + RAMSTER_REMOTIFY_FLUSH_OBJ, +}; + +struct ramster_remotify_hdr { + enum ramster_remotify_op op; + struct list_head list; +}; + +struct flushlist_node { + struct ramster_remotify_hdr rem_op; + struct tmem_xhandle xh; +}; + +struct ramster_preload { + struct flushlist_node *flnode; +}; + +union remotify_list_node { + struct ramster_remotify_hdr rem_op; + struct { + struct ramster_remotify_hdr rem_op; + struct tmem_handle th; + } zbud_hdr; + struct flushlist_node flist; +}; + +/* + * format of remote pampd: + * bit 0 is reserved for zbud (in-page buddy selection) + * bit 1 == intransit + * bit 2 == is_remote... if this bit is set, then + * bit 3-10 == remotenode + * bit 11-23 == size + * bit 24-31 == cksum + */ +#define FAKE_PAMPD_INTRANSIT_BITS 1 +#define FAKE_PAMPD_ISREMOTE_BITS 1 +#define FAKE_PAMPD_REMOTENODE_BITS 8 +#define FAKE_PAMPD_REMOTESIZE_BITS 13 +#define FAKE_PAMPD_CHECKSUM_BITS 8 + +#define FAKE_PAMPD_INTRANSIT_SHIFT 1 +#define FAKE_PAMPD_ISREMOTE_SHIFT (FAKE_PAMPD_INTRANSIT_SHIFT + \ + FAKE_PAMPD_INTRANSIT_BITS) +#define FAKE_PAMPD_REMOTENODE_SHIFT (FAKE_PAMPD_ISREMOTE_SHIFT + \ + FAKE_PAMPD_ISREMOTE_BITS) +#define FAKE_PAMPD_REMOTESIZE_SHIFT (FAKE_PAMPD_REMOTENODE_SHIFT + \ + FAKE_PAMPD_REMOTENODE_BITS) +#define FAKE_PAMPD_CHECKSUM_SHIFT (FAKE_PAMPD_REMOTESIZE_SHIFT + \ + FAKE_PAMPD_REMOTESIZE_BITS) + +#define FAKE_PAMPD_MASK(x) ((1UL << (x)) - 1) + +static inline void *pampd_make_remote(int remotenode, size_t size, + unsigned char cksum) +{ + unsigned long fake_pampd = 0; + fake_pampd |= 1UL << FAKE_PAMPD_ISREMOTE_SHIFT; + fake_pampd |= ((unsigned long)remotenode & + FAKE_PAMPD_MASK(FAKE_PAMPD_REMOTENODE_BITS)) << + FAKE_PAMPD_REMOTENODE_SHIFT; + fake_pampd |= ((unsigned long)size & + FAKE_PAMPD_MASK(FAKE_PAMPD_REMOTESIZE_BITS)) << + FAKE_PAMPD_REMOTESIZE_SHIFT; + fake_pampd |= ((unsigned long)cksum & + FAKE_PAMPD_MASK(FAKE_PAMPD_CHECKSUM_BITS)) << + FAKE_PAMPD_CHECKSUM_SHIFT; + return (void *)fake_pampd; +} + +static inline unsigned int pampd_remote_node(void *pampd) +{ + unsigned long fake_pampd = (unsigned long)pampd; + return (fake_pampd >> FAKE_PAMPD_REMOTENODE_SHIFT) & + FAKE_PAMPD_MASK(FAKE_PAMPD_REMOTENODE_BITS); +} + +static inline unsigned int pampd_remote_size(void *pampd) +{ + unsigned long fake_pampd = (unsigned long)pampd; + return (fake_pampd >> FAKE_PAMPD_REMOTESIZE_SHIFT) & + FAKE_PAMPD_MASK(FAKE_PAMPD_REMOTESIZE_BITS); +} + +static inline unsigned char pampd_remote_cksum(void *pampd) +{ + unsigned long fake_pampd = (unsigned long)pampd; + return (fake_pampd >> FAKE_PAMPD_CHECKSUM_SHIFT) & + FAKE_PAMPD_MASK(FAKE_PAMPD_CHECKSUM_BITS); +} + +static inline bool pampd_is_remote(void *pampd) +{ + unsigned long fake_pampd = (unsigned long)pampd; + return (fake_pampd >> FAKE_PAMPD_ISREMOTE_SHIFT) & + FAKE_PAMPD_MASK(FAKE_PAMPD_ISREMOTE_BITS); +} + +static inline bool pampd_is_intransit(void *pampd) +{ + unsigned long fake_pampd = (unsigned long)pampd; + return (fake_pampd >> FAKE_PAMPD_INTRANSIT_SHIFT) & + FAKE_PAMPD_MASK(FAKE_PAMPD_INTRANSIT_BITS); +} + +/* note that it is a BUG for intransit to be set without isremote also set */ +static inline void *pampd_mark_intransit(void *pampd) +{ + unsigned long fake_pampd = (unsigned long)pampd; + + fake_pampd |= 1UL << FAKE_PAMPD_ISREMOTE_SHIFT; + fake_pampd |= 1UL << FAKE_PAMPD_INTRANSIT_SHIFT; + return (void *)fake_pampd; +} + +static inline void *pampd_mask_intransit_and_remote(void *marked_pampd) +{ + unsigned long pampd = (unsigned long)marked_pampd; + + pampd &= ~(1UL << FAKE_PAMPD_INTRANSIT_SHIFT); + pampd &= ~(1UL << FAKE_PAMPD_ISREMOTE_SHIFT); + return (void *)pampd; +} + +extern int r2net_remote_async_get(struct tmem_xhandle *, + bool, int, size_t, uint8_t, void *extra); +extern int r2net_remote_put(struct tmem_xhandle *, char *, size_t, + bool, int *); +extern int r2net_remote_flush(struct tmem_xhandle *, int); +extern int r2net_remote_flush_object(struct tmem_xhandle *, int); +extern int r2net_register_handlers(void); +extern int r2net_remote_target_node_set(int); + +extern int ramster_remotify_pageframe(bool); +extern void ramster_init(bool, bool, bool); +extern void ramster_register_pamops(struct tmem_pamops *); +extern int ramster_localify(int, struct tmem_oid *oidp, uint32_t, char *, + unsigned int, void *); +extern void *ramster_pampd_free(void *, struct tmem_pool *, struct tmem_oid *, + uint32_t, bool); +extern void ramster_count_foreign_pages(bool, int); +extern int ramster_do_preload_flnode(struct tmem_pool *); +extern void ramster_cpu_up(int); +extern void ramster_cpu_down(int); + +#endif /* _RAMSTER_RAMSTER_H */ diff --git a/drivers/staging/ramster/ramster/ramster_nodemanager.h b/drivers/staging/ramster/ramster/ramster_nodemanager.h new file mode 100644 index 0000000..49f879d --- /dev/null +++ b/drivers/staging/ramster/ramster/ramster_nodemanager.h @@ -0,0 +1,39 @@ +/* -*- mode: c; c-basic-offset: 8; -*- + * vim: noexpandtab sw=8 ts=8 sts=0: + * + * ramster_nodemanager.h + * + * Header describing the interface between userspace and the kernel + * for the ramster_nodemanager module. + * + * Copyright (C) 2002, 2004, 2012 Oracle. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + * + */ + +#ifndef _RAMSTER_NODEMANAGER_H +#define _RAMSTER_NODEMANAGER_H + +#define R2NM_API_VERSION 5 + +#define R2NM_MAX_NODES 255 +#define R2NM_INVALID_NODE_NUM 255 + +/* host name, group name, cluster name all 64 bytes */ +#define R2NM_MAX_NAME_LEN 64 /* __NEW_UTS_LEN */ + +#endif /* _RAMSTER_NODEMANAGER_H */ diff --git a/drivers/staging/ramster/ramster/tcp.c b/drivers/staging/ramster/ramster/tcp.c new file mode 100644 index 0000000..aa2a1a7 --- /dev/null +++ b/drivers/staging/ramster/ramster/tcp.c @@ -0,0 +1,2253 @@ +/* -*- mode: c; c-basic-offset: 8; -*- + * + * vim: noexpandtab sw=8 ts=8 sts=0: + * + * Copyright (C) 2004 Oracle. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + * + * ---- + * + * Callers for this were originally written against a very simple synchronus + * API. This implementation reflects those simple callers. Some day I'm sure + * we'll need to move to a more robust posting/callback mechanism. + * + * Transmit calls pass in kernel virtual addresses and block copying this into + * the socket's tx buffers via a usual blocking sendmsg. They'll block waiting + * for a failed socket to timeout. TX callers can also pass in a poniter to an + * 'int' which gets filled with an errno off the wire in response to the + * message they send. + * + * Handlers for unsolicited messages are registered. Each socket has a page + * that incoming data is copied into. First the header, then the data. + * Handlers are called from only one thread with a reference to this per-socket + * page. This page is destroyed after the handler call, so it can't be + * referenced beyond the call. Handlers may block but are discouraged from + * doing so. + * + * Any framing errors (bad magic, large payload lengths) close a connection. + * + * Our sock_container holds the state we associate with a socket. It's current + * framing state is held there as well as the refcounting we do around when it + * is safe to tear down the socket. The socket is only finally torn down from + * the container when the container loses all of its references -- so as long + * as you hold a ref on the container you can trust that the socket is valid + * for use with kernel socket APIs. + * + * Connections are initiated between a pair of nodes when the node with the + * higher node number gets a heartbeat callback which indicates that the lower + * numbered node has started heartbeating. The lower numbered node is passive + * and only accepts the connection if the higher numbered node is heartbeating. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "heartbeat.h" +#include "tcp.h" +#include "nodemanager.h" +#define MLOG_MASK_PREFIX ML_TCP +#include "masklog.h" + +#include "tcp_internal.h" + +#define SC_NODEF_FMT "node %s (num %u) at %pI4:%u" + +/* + * In the following two log macros, the whitespace after the ',' just + * before ##args is intentional. Otherwise, gcc 2.95 will eat the + * previous token if args expands to nothing. + */ +#define msglog(hdr, fmt, args...) do { \ + typeof(hdr) __hdr = (hdr); \ + mlog(ML_MSG, "[mag %u len %u typ %u stat %d sys_stat %d " \ + "key %08x num %u] " fmt, \ + be16_to_cpu(__hdr->magic), be16_to_cpu(__hdr->data_len), \ + be16_to_cpu(__hdr->msg_type), be32_to_cpu(__hdr->status), \ + be32_to_cpu(__hdr->sys_status), be32_to_cpu(__hdr->key), \ + be32_to_cpu(__hdr->msg_num) , ##args); \ +} while (0) + +#define sclog(sc, fmt, args...) do { \ + typeof(sc) __sc = (sc); \ + mlog(ML_SOCKET, "[sc %p refs %d sock %p node %u page %p " \ + "pg_off %zu] " fmt, __sc, \ + atomic_read(&__sc->sc_kref.refcount), __sc->sc_sock, \ + __sc->sc_node->nd_num, __sc->sc_page, __sc->sc_page_off , \ + ##args); \ +} while (0) + +static DEFINE_RWLOCK(r2net_handler_lock); +static struct rb_root r2net_handler_tree = RB_ROOT; + +static struct r2net_node r2net_nodes[R2NM_MAX_NODES]; + +/* XXX someday we'll need better accounting */ +static struct socket *r2net_listen_sock; + +/* + * listen work is only queued by the listening socket callbacks on the + * r2net_wq. teardown detaches the callbacks before destroying the workqueue. + * quorum work is queued as sock containers are shutdown.. stop_listening + * tears down all the node's sock containers, preventing future shutdowns + * and queued quorum work, before canceling delayed quorum work and + * destroying the work queue. + */ +static struct workqueue_struct *r2net_wq; +static struct work_struct r2net_listen_work; + +static struct r2hb_callback_func r2net_hb_up, r2net_hb_down; +#define R2NET_HB_PRI 0x1 + +static struct r2net_handshake *r2net_hand; +static struct r2net_msg *r2net_keep_req, *r2net_keep_resp; + +static int r2net_sys_err_translations[R2NET_ERR_MAX] = { + [R2NET_ERR_NONE] = 0, + [R2NET_ERR_NO_HNDLR] = -ENOPROTOOPT, + [R2NET_ERR_OVERFLOW] = -EOVERFLOW, + [R2NET_ERR_DIED] = -EHOSTDOWN,}; + +/* can't quite avoid *all* internal declarations :/ */ +static void r2net_sc_connect_completed(struct work_struct *work); +static void r2net_rx_until_empty(struct work_struct *work); +static void r2net_shutdown_sc(struct work_struct *work); +static void r2net_listen_data_ready(struct sock *sk, int bytes); +static void r2net_sc_send_keep_req(struct work_struct *work); +static void r2net_idle_timer(unsigned long data); +static void r2net_sc_postpone_idle(struct r2net_sock_container *sc); +static void r2net_sc_reset_idle_timer(struct r2net_sock_container *sc); + +#ifdef CONFIG_DEBUG_FS +static void r2net_init_nst(struct r2net_send_tracking *nst, u32 msgtype, + u32 msgkey, struct task_struct *task, u8 node) +{ + INIT_LIST_HEAD(&nst->st_net_debug_item); + nst->st_task = task; + nst->st_msg_type = msgtype; + nst->st_msg_key = msgkey; + nst->st_node = node; +} + +static inline void r2net_set_nst_sock_time(struct r2net_send_tracking *nst) +{ + nst->st_sock_time = ktime_get(); +} + +static inline void r2net_set_nst_send_time(struct r2net_send_tracking *nst) +{ + nst->st_send_time = ktime_get(); +} + +static inline void r2net_set_nst_status_time(struct r2net_send_tracking *nst) +{ + nst->st_status_time = ktime_get(); +} + +static inline void r2net_set_nst_sock_container(struct r2net_send_tracking *nst, + struct r2net_sock_container *sc) +{ + nst->st_sc = sc; +} + +static inline void r2net_set_nst_msg_id(struct r2net_send_tracking *nst, + u32 msg_id) +{ + nst->st_id = msg_id; +} + +static inline void r2net_set_sock_timer(struct r2net_sock_container *sc) +{ + sc->sc_tv_timer = ktime_get(); +} + +static inline void r2net_set_data_ready_time(struct r2net_sock_container *sc) +{ + sc->sc_tv_data_ready = ktime_get(); +} + +static inline void r2net_set_advance_start_time(struct r2net_sock_container *sc) +{ + sc->sc_tv_advance_start = ktime_get(); +} + +static inline void r2net_set_advance_stop_time(struct r2net_sock_container *sc) +{ + sc->sc_tv_advance_stop = ktime_get(); +} + +static inline void r2net_set_func_start_time(struct r2net_sock_container *sc) +{ + sc->sc_tv_func_start = ktime_get(); +} + +static inline void r2net_set_func_stop_time(struct r2net_sock_container *sc) +{ + sc->sc_tv_func_stop = ktime_get(); +} + +#else /* CONFIG_DEBUG_FS */ +# define r2net_init_nst(a, b, c, d, e) +# define r2net_set_nst_sock_time(a) +# define r2net_set_nst_send_time(a) +# define r2net_set_nst_status_time(a) +# define r2net_set_nst_sock_container(a, b) +# define r2net_set_nst_msg_id(a, b) +# define r2net_set_sock_timer(a) +# define r2net_set_data_ready_time(a) +# define r2net_set_advance_start_time(a) +# define r2net_set_advance_stop_time(a) +# define r2net_set_func_start_time(a) +# define r2net_set_func_stop_time(a) +#endif /* CONFIG_DEBUG_FS */ + +#ifdef CONFIG_RAMSTER_FS_STATS +static ktime_t r2net_get_func_run_time(struct r2net_sock_container *sc) +{ + return ktime_sub(sc->sc_tv_func_stop, sc->sc_tv_func_start); +} + +static void r2net_update_send_stats(struct r2net_send_tracking *nst, + struct r2net_sock_container *sc) +{ + sc->sc_tv_status_total = ktime_add(sc->sc_tv_status_total, + ktime_sub(ktime_get(), + nst->st_status_time)); + sc->sc_tv_send_total = ktime_add(sc->sc_tv_send_total, + ktime_sub(nst->st_status_time, + nst->st_send_time)); + sc->sc_tv_acquiry_total = ktime_add(sc->sc_tv_acquiry_total, + ktime_sub(nst->st_send_time, + nst->st_sock_time)); + sc->sc_send_count++; +} + +static void r2net_update_recv_stats(struct r2net_sock_container *sc) +{ + sc->sc_tv_process_total = ktime_add(sc->sc_tv_process_total, + r2net_get_func_run_time(sc)); + sc->sc_recv_count++; +} + +#else + +# define r2net_update_send_stats(a, b) + +# define r2net_update_recv_stats(sc) + +#endif /* CONFIG_RAMSTER_FS_STATS */ + +static inline int r2net_reconnect_delay(void) +{ + return r2nm_single_cluster->cl_reconnect_delay_ms; +} + +static inline int r2net_keepalive_delay(void) +{ + return r2nm_single_cluster->cl_keepalive_delay_ms; +} + +static inline int r2net_idle_timeout(void) +{ + return r2nm_single_cluster->cl_idle_timeout_ms; +} + +static inline int r2net_sys_err_to_errno(enum r2net_system_error err) +{ + int trans; + BUG_ON(err >= R2NET_ERR_MAX); + trans = r2net_sys_err_translations[err]; + + /* Just in case we mess up the translation table above */ + BUG_ON(err != R2NET_ERR_NONE && trans == 0); + return trans; +} + +struct r2net_node *r2net_nn_from_num(u8 node_num) +{ + BUG_ON(node_num >= ARRAY_SIZE(r2net_nodes)); + return &r2net_nodes[node_num]; +} + +static u8 r2net_num_from_nn(struct r2net_node *nn) +{ + BUG_ON(nn == NULL); + return nn - r2net_nodes; +} + +/* ------------------------------------------------------------ */ + +static int r2net_prep_nsw(struct r2net_node *nn, struct r2net_status_wait *nsw) +{ + int ret = 0; + + do { + if (!idr_pre_get(&nn->nn_status_idr, GFP_ATOMIC)) { + ret = -EAGAIN; + break; + } + spin_lock(&nn->nn_lock); + ret = idr_get_new(&nn->nn_status_idr, nsw, &nsw->ns_id); + if (ret == 0) + list_add_tail(&nsw->ns_node_item, + &nn->nn_status_list); + spin_unlock(&nn->nn_lock); + } while (ret == -EAGAIN); + + if (ret == 0) { + init_waitqueue_head(&nsw->ns_wq); + nsw->ns_sys_status = R2NET_ERR_NONE; + nsw->ns_status = 0; + } + + return ret; +} + +static void r2net_complete_nsw_locked(struct r2net_node *nn, + struct r2net_status_wait *nsw, + enum r2net_system_error sys_status, + s32 status) +{ + assert_spin_locked(&nn->nn_lock); + + if (!list_empty(&nsw->ns_node_item)) { + list_del_init(&nsw->ns_node_item); + nsw->ns_sys_status = sys_status; + nsw->ns_status = status; + idr_remove(&nn->nn_status_idr, nsw->ns_id); + wake_up(&nsw->ns_wq); + } +} + +static void r2net_complete_nsw(struct r2net_node *nn, + struct r2net_status_wait *nsw, + u64 id, enum r2net_system_error sys_status, + s32 status) +{ + spin_lock(&nn->nn_lock); + if (nsw == NULL) { + if (id > INT_MAX) + goto out; + + nsw = idr_find(&nn->nn_status_idr, id); + if (nsw == NULL) + goto out; + } + + r2net_complete_nsw_locked(nn, nsw, sys_status, status); + +out: + spin_unlock(&nn->nn_lock); + return; +} + +static void r2net_complete_nodes_nsw(struct r2net_node *nn) +{ + struct r2net_status_wait *nsw, *tmp; + unsigned int num_kills = 0; + + assert_spin_locked(&nn->nn_lock); + + list_for_each_entry_safe(nsw, tmp, &nn->nn_status_list, ns_node_item) { + r2net_complete_nsw_locked(nn, nsw, R2NET_ERR_DIED, 0); + num_kills++; + } + + mlog(0, "completed %d messages for node %u\n", num_kills, + r2net_num_from_nn(nn)); +} + +static int r2net_nsw_completed(struct r2net_node *nn, + struct r2net_status_wait *nsw) +{ + int completed; + spin_lock(&nn->nn_lock); + completed = list_empty(&nsw->ns_node_item); + spin_unlock(&nn->nn_lock); + return completed; +} + +/* ------------------------------------------------------------ */ + +static void sc_kref_release(struct kref *kref) +{ + struct r2net_sock_container *sc = container_of(kref, + struct r2net_sock_container, sc_kref); + BUG_ON(timer_pending(&sc->sc_idle_timeout)); + + sclog(sc, "releasing\n"); + + if (sc->sc_sock) { + sock_release(sc->sc_sock); + sc->sc_sock = NULL; + } + + r2nm_undepend_item(&sc->sc_node->nd_item); + r2nm_node_put(sc->sc_node); + sc->sc_node = NULL; + + r2net_debug_del_sc(sc); + kfree(sc); +} + +static void sc_put(struct r2net_sock_container *sc) +{ + sclog(sc, "put\n"); + kref_put(&sc->sc_kref, sc_kref_release); +} +static void sc_get(struct r2net_sock_container *sc) +{ + sclog(sc, "get\n"); + kref_get(&sc->sc_kref); +} +static struct r2net_sock_container *sc_alloc(struct r2nm_node *node) +{ + struct r2net_sock_container *sc, *ret = NULL; + struct page *page = NULL; + int status = 0; + + page = alloc_page(GFP_NOFS); + sc = kzalloc(sizeof(*sc), GFP_NOFS); + if (sc == NULL || page == NULL) + goto out; + + kref_init(&sc->sc_kref); + r2nm_node_get(node); + sc->sc_node = node; + + /* pin the node item of the remote node */ + status = r2nm_depend_item(&node->nd_item); + if (status) { + mlog_errno(status); + r2nm_node_put(node); + goto out; + } + INIT_WORK(&sc->sc_connect_work, r2net_sc_connect_completed); + INIT_WORK(&sc->sc_rx_work, r2net_rx_until_empty); + INIT_WORK(&sc->sc_shutdown_work, r2net_shutdown_sc); + INIT_DELAYED_WORK(&sc->sc_keepalive_work, r2net_sc_send_keep_req); + + init_timer(&sc->sc_idle_timeout); + sc->sc_idle_timeout.function = r2net_idle_timer; + sc->sc_idle_timeout.data = (unsigned long)sc; + + sclog(sc, "alloced\n"); + + ret = sc; + sc->sc_page = page; + r2net_debug_add_sc(sc); + sc = NULL; + page = NULL; + +out: + if (page) + __free_page(page); + kfree(sc); + + return ret; +} + +/* ------------------------------------------------------------ */ + +static void r2net_sc_queue_work(struct r2net_sock_container *sc, + struct work_struct *work) +{ + sc_get(sc); + if (!queue_work(r2net_wq, work)) + sc_put(sc); +} +static void r2net_sc_queue_delayed_work(struct r2net_sock_container *sc, + struct delayed_work *work, + int delay) +{ + sc_get(sc); + if (!queue_delayed_work(r2net_wq, work, delay)) + sc_put(sc); +} +static void r2net_sc_cancel_delayed_work(struct r2net_sock_container *sc, + struct delayed_work *work) +{ + if (cancel_delayed_work(work)) + sc_put(sc); +} + +static atomic_t r2net_connected_peers = ATOMIC_INIT(0); + +int r2net_num_connected_peers(void) +{ + return atomic_read(&r2net_connected_peers); +} + +static void r2net_set_nn_state(struct r2net_node *nn, + struct r2net_sock_container *sc, + unsigned valid, int err) +{ + int was_valid = nn->nn_sc_valid; + int was_err = nn->nn_persistent_error; + struct r2net_sock_container *old_sc = nn->nn_sc; + + assert_spin_locked(&nn->nn_lock); + + if (old_sc && !sc) + atomic_dec(&r2net_connected_peers); + else if (!old_sc && sc) + atomic_inc(&r2net_connected_peers); + + /* the node num comparison and single connect/accept path should stop + * an non-null sc from being overwritten with another */ + BUG_ON(sc && nn->nn_sc && nn->nn_sc != sc); + mlog_bug_on_msg(err && valid, "err %d valid %u\n", err, valid); + mlog_bug_on_msg(valid && !sc, "valid %u sc %p\n", valid, sc); + + if (was_valid && !valid && err == 0) + err = -ENOTCONN; + + mlog(ML_CONN, "node %u sc: %p -> %p, valid %u -> %u, err %d -> %d\n", + r2net_num_from_nn(nn), nn->nn_sc, sc, nn->nn_sc_valid, valid, + nn->nn_persistent_error, err); + + nn->nn_sc = sc; + nn->nn_sc_valid = valid ? 1 : 0; + nn->nn_persistent_error = err; + + /* mirrors r2net_tx_can_proceed() */ + if (nn->nn_persistent_error || nn->nn_sc_valid) + wake_up(&nn->nn_sc_wq); + + if (!was_err && nn->nn_persistent_error) { + queue_delayed_work(r2net_wq, &nn->nn_still_up, + msecs_to_jiffies(R2NET_QUORUM_DELAY_MS)); + } + + if (was_valid && !valid) { + pr_notice("ramster: No longer connected to " SC_NODEF_FMT "\n", + old_sc->sc_node->nd_name, old_sc->sc_node->nd_num, + &old_sc->sc_node->nd_ipv4_address, + ntohs(old_sc->sc_node->nd_ipv4_port)); + r2net_complete_nodes_nsw(nn); + } + + if (!was_valid && valid) { + cancel_delayed_work(&nn->nn_connect_expired); + pr_notice("ramster: %s " SC_NODEF_FMT "\n", + r2nm_this_node() > sc->sc_node->nd_num ? + "Connected to" : "Accepted connection from", + sc->sc_node->nd_name, sc->sc_node->nd_num, + &sc->sc_node->nd_ipv4_address, + ntohs(sc->sc_node->nd_ipv4_port)); + } + + /* trigger the connecting worker func as long as we're not valid, + * it will back off if it shouldn't connect. This can be called + * from node config teardown and so needs to be careful about + * the work queue actually being up. */ + if (!valid && r2net_wq) { + unsigned long delay; + /* delay if we're within a RECONNECT_DELAY of the + * last attempt */ + delay = (nn->nn_last_connect_attempt + + msecs_to_jiffies(r2net_reconnect_delay())) + - jiffies; + if (delay > msecs_to_jiffies(r2net_reconnect_delay())) + delay = 0; + mlog(ML_CONN, "queueing conn attempt in %lu jiffies\n", delay); + queue_delayed_work(r2net_wq, &nn->nn_connect_work, delay); + + /* + * Delay the expired work after idle timeout. + * + * We might have lots of failed connection attempts that run + * through here but we only cancel the connect_expired work when + * a connection attempt succeeds. So only the first enqueue of + * the connect_expired work will do anything. The rest will see + * that it's already queued and do nothing. + */ + delay += msecs_to_jiffies(r2net_idle_timeout()); + queue_delayed_work(r2net_wq, &nn->nn_connect_expired, delay); + } + + /* keep track of the nn's sc ref for the caller */ + if ((old_sc == NULL) && sc) + sc_get(sc); + if (old_sc && (old_sc != sc)) { + r2net_sc_queue_work(old_sc, &old_sc->sc_shutdown_work); + sc_put(old_sc); + } +} + +/* see r2net_register_callbacks() */ +static void r2net_data_ready(struct sock *sk, int bytes) +{ + void (*ready)(struct sock *sk, int bytes); + + read_lock(&sk->sk_callback_lock); + if (sk->sk_user_data) { + struct r2net_sock_container *sc = sk->sk_user_data; + sclog(sc, "data_ready hit\n"); + r2net_set_data_ready_time(sc); + r2net_sc_queue_work(sc, &sc->sc_rx_work); + ready = sc->sc_data_ready; + } else { + ready = sk->sk_data_ready; + } + read_unlock(&sk->sk_callback_lock); + + ready(sk, bytes); +} + +/* see r2net_register_callbacks() */ +static void r2net_state_change(struct sock *sk) +{ + void (*state_change)(struct sock *sk); + struct r2net_sock_container *sc; + + read_lock(&sk->sk_callback_lock); + sc = sk->sk_user_data; + if (sc == NULL) { + state_change = sk->sk_state_change; + goto out; + } + + sclog(sc, "state_change to %d\n", sk->sk_state); + + state_change = sc->sc_state_change; + + switch (sk->sk_state) { + + /* ignore connecting sockets as they make progress */ + case TCP_SYN_SENT: + case TCP_SYN_RECV: + break; + case TCP_ESTABLISHED: + r2net_sc_queue_work(sc, &sc->sc_connect_work); + break; + default: + pr_info("ramster: Connection to " + SC_NODEF_FMT " shutdown, state %d\n", + sc->sc_node->nd_name, sc->sc_node->nd_num, + &sc->sc_node->nd_ipv4_address, + ntohs(sc->sc_node->nd_ipv4_port), sk->sk_state); + r2net_sc_queue_work(sc, &sc->sc_shutdown_work); + break; + + } +out: + read_unlock(&sk->sk_callback_lock); + state_change(sk); +} + +/* + * we register callbacks so we can queue work on events before calling + * the original callbacks. our callbacks are careful to test user_data + * to discover when they've reaced with r2net_unregister_callbacks(). + */ +static void r2net_register_callbacks(struct sock *sk, + struct r2net_sock_container *sc) +{ + write_lock_bh(&sk->sk_callback_lock); + + /* accepted sockets inherit the old listen socket data ready */ + if (sk->sk_data_ready == r2net_listen_data_ready) { + sk->sk_data_ready = sk->sk_user_data; + sk->sk_user_data = NULL; + } + + BUG_ON(sk->sk_user_data != NULL); + sk->sk_user_data = sc; + sc_get(sc); + + sc->sc_data_ready = sk->sk_data_ready; + sc->sc_state_change = sk->sk_state_change; + sk->sk_data_ready = r2net_data_ready; + sk->sk_state_change = r2net_state_change; + + mutex_init(&sc->sc_send_lock); + + write_unlock_bh(&sk->sk_callback_lock); +} + +static int r2net_unregister_callbacks(struct sock *sk, + struct r2net_sock_container *sc) +{ + int ret = 0; + + write_lock_bh(&sk->sk_callback_lock); + if (sk->sk_user_data == sc) { + ret = 1; + sk->sk_user_data = NULL; + sk->sk_data_ready = sc->sc_data_ready; + sk->sk_state_change = sc->sc_state_change; + } + write_unlock_bh(&sk->sk_callback_lock); + + return ret; +} + +/* + * this is a little helper that is called by callers who have seen a problem + * with an sc and want to detach it from the nn if someone already hasn't beat + * them to it. if an error is given then the shutdown will be persistent + * and pending transmits will be canceled. + */ +static void r2net_ensure_shutdown(struct r2net_node *nn, + struct r2net_sock_container *sc, + int err) +{ + spin_lock(&nn->nn_lock); + if (nn->nn_sc == sc) + r2net_set_nn_state(nn, NULL, 0, err); + spin_unlock(&nn->nn_lock); +} + +/* + * This work queue function performs the blocking parts of socket shutdown. A + * few paths lead here. set_nn_state will trigger this callback if it sees an + * sc detached from the nn. state_change will also trigger this callback + * directly when it sees errors. In that case we need to call set_nn_state + * ourselves as state_change couldn't get the nn_lock and call set_nn_state + * itself. + */ +static void r2net_shutdown_sc(struct work_struct *work) +{ + struct r2net_sock_container *sc = + container_of(work, struct r2net_sock_container, + sc_shutdown_work); + struct r2net_node *nn = r2net_nn_from_num(sc->sc_node->nd_num); + + sclog(sc, "shutting down\n"); + + /* drop the callbacks ref and call shutdown only once */ + if (r2net_unregister_callbacks(sc->sc_sock->sk, sc)) { + /* we shouldn't flush as we're in the thread, the + * races with pending sc work structs are harmless */ + del_timer_sync(&sc->sc_idle_timeout); + r2net_sc_cancel_delayed_work(sc, &sc->sc_keepalive_work); + sc_put(sc); + kernel_sock_shutdown(sc->sc_sock, SHUT_RDWR); + } + + /* not fatal so failed connects before the other guy has our + * heartbeat can be retried */ + r2net_ensure_shutdown(nn, sc, 0); + sc_put(sc); +} + +/* ------------------------------------------------------------ */ + +static int r2net_handler_cmp(struct r2net_msg_handler *nmh, u32 msg_type, + u32 key) +{ + int ret = memcmp(&nmh->nh_key, &key, sizeof(key)); + + if (ret == 0) + ret = memcmp(&nmh->nh_msg_type, &msg_type, sizeof(msg_type)); + + return ret; +} + +static struct r2net_msg_handler * +r2net_handler_tree_lookup(u32 msg_type, u32 key, struct rb_node ***ret_p, + struct rb_node **ret_parent) +{ + struct rb_node **p = &r2net_handler_tree.rb_node; + struct rb_node *parent = NULL; + struct r2net_msg_handler *nmh, *ret = NULL; + int cmp; + + while (*p) { + parent = *p; + nmh = rb_entry(parent, struct r2net_msg_handler, nh_node); + cmp = r2net_handler_cmp(nmh, msg_type, key); + + if (cmp < 0) + p = &(*p)->rb_left; + else if (cmp > 0) + p = &(*p)->rb_right; + else { + ret = nmh; + break; + } + } + + if (ret_p != NULL) + *ret_p = p; + if (ret_parent != NULL) + *ret_parent = parent; + + return ret; +} + +static void r2net_handler_kref_release(struct kref *kref) +{ + struct r2net_msg_handler *nmh; + nmh = container_of(kref, struct r2net_msg_handler, nh_kref); + + kfree(nmh); +} + +static void r2net_handler_put(struct r2net_msg_handler *nmh) +{ + kref_put(&nmh->nh_kref, r2net_handler_kref_release); +} + +/* max_len is protection for the handler func. incoming messages won't + * be given to the handler if their payload is longer than the max. */ +int r2net_register_handler(u32 msg_type, u32 key, u32 max_len, + r2net_msg_handler_func *func, void *data, + r2net_post_msg_handler_func *post_func, + struct list_head *unreg_list) +{ + struct r2net_msg_handler *nmh = NULL; + struct rb_node **p, *parent; + int ret = 0; + + if (max_len > R2NET_MAX_PAYLOAD_BYTES) { + mlog(0, "max_len for message handler out of range: %u\n", + max_len); + ret = -EINVAL; + goto out; + } + + if (!msg_type) { + mlog(0, "no message type provided: %u, %p\n", msg_type, func); + ret = -EINVAL; + goto out; + + } + if (!func) { + mlog(0, "no message handler provided: %u, %p\n", + msg_type, func); + ret = -EINVAL; + goto out; + } + + nmh = kzalloc(sizeof(struct r2net_msg_handler), GFP_NOFS); + if (nmh == NULL) { + ret = -ENOMEM; + goto out; + } + + nmh->nh_func = func; + nmh->nh_func_data = data; + nmh->nh_post_func = post_func; + nmh->nh_msg_type = msg_type; + nmh->nh_max_len = max_len; + nmh->nh_key = key; + /* the tree and list get this ref.. they're both removed in + * unregister when this ref is dropped */ + kref_init(&nmh->nh_kref); + INIT_LIST_HEAD(&nmh->nh_unregister_item); + + write_lock(&r2net_handler_lock); + if (r2net_handler_tree_lookup(msg_type, key, &p, &parent)) + ret = -EEXIST; + else { + rb_link_node(&nmh->nh_node, parent, p); + rb_insert_color(&nmh->nh_node, &r2net_handler_tree); + list_add_tail(&nmh->nh_unregister_item, unreg_list); + + mlog(ML_TCP, "registered handler func %p type %u key %08x\n", + func, msg_type, key); + /* we've had some trouble with handlers seemingly vanishing. */ + mlog_bug_on_msg(r2net_handler_tree_lookup(msg_type, key, &p, + &parent) == NULL, + "couldn't find handler we *just* registered " + "for type %u key %08x\n", msg_type, key); + } + write_unlock(&r2net_handler_lock); + if (ret) + goto out; + +out: + if (ret) + kfree(nmh); + + return ret; +} +EXPORT_SYMBOL_GPL(r2net_register_handler); + +void r2net_unregister_handler_list(struct list_head *list) +{ + struct r2net_msg_handler *nmh, *n; + + write_lock(&r2net_handler_lock); + list_for_each_entry_safe(nmh, n, list, nh_unregister_item) { + mlog(ML_TCP, "unregistering handler func %p type %u key %08x\n", + nmh->nh_func, nmh->nh_msg_type, nmh->nh_key); + rb_erase(&nmh->nh_node, &r2net_handler_tree); + list_del_init(&nmh->nh_unregister_item); + kref_put(&nmh->nh_kref, r2net_handler_kref_release); + } + write_unlock(&r2net_handler_lock); +} +EXPORT_SYMBOL_GPL(r2net_unregister_handler_list); + +static struct r2net_msg_handler *r2net_handler_get(u32 msg_type, u32 key) +{ + struct r2net_msg_handler *nmh; + + read_lock(&r2net_handler_lock); + nmh = r2net_handler_tree_lookup(msg_type, key, NULL, NULL); + if (nmh) + kref_get(&nmh->nh_kref); + read_unlock(&r2net_handler_lock); + + return nmh; +} + +/* ------------------------------------------------------------ */ + +static int r2net_recv_tcp_msg(struct socket *sock, void *data, size_t len) +{ + int ret; + mm_segment_t oldfs; + struct kvec vec = { + .iov_len = len, + .iov_base = data, + }; + struct msghdr msg = { + .msg_iovlen = 1, + .msg_iov = (struct iovec *)&vec, + .msg_flags = MSG_DONTWAIT, + }; + + oldfs = get_fs(); + set_fs(get_ds()); + ret = sock_recvmsg(sock, &msg, len, msg.msg_flags); + set_fs(oldfs); + + return ret; +} + +static int r2net_send_tcp_msg(struct socket *sock, struct kvec *vec, + size_t veclen, size_t total) +{ + int ret; + mm_segment_t oldfs; + struct msghdr msg = { + .msg_iov = (struct iovec *)vec, + .msg_iovlen = veclen, + }; + + if (sock == NULL) { + ret = -EINVAL; + goto out; + } + + oldfs = get_fs(); + set_fs(get_ds()); + ret = sock_sendmsg(sock, &msg, total); + set_fs(oldfs); + if (ret != total) { + mlog(ML_ERROR, "sendmsg returned %d instead of %zu\n", ret, + total); + if (ret >= 0) + ret = -EPIPE; /* should be smarter, I bet */ + goto out; + } + + ret = 0; +out: + if (ret < 0) + mlog(0, "returning error: %d\n", ret); + return ret; +} + +static void r2net_sendpage(struct r2net_sock_container *sc, + void *kmalloced_virt, + size_t size) +{ + struct r2net_node *nn = r2net_nn_from_num(sc->sc_node->nd_num); + ssize_t ret; + + while (1) { + mutex_lock(&sc->sc_send_lock); + ret = sc->sc_sock->ops->sendpage(sc->sc_sock, + virt_to_page(kmalloced_virt), + (long)kmalloced_virt & ~PAGE_MASK, + size, MSG_DONTWAIT); + mutex_unlock(&sc->sc_send_lock); + if (ret == size) + break; + if (ret == (ssize_t)-EAGAIN) { + mlog(0, "sendpage of size %zu to " SC_NODEF_FMT + " returned EAGAIN\n", size, sc->sc_node->nd_name, + sc->sc_node->nd_num, + &sc->sc_node->nd_ipv4_address, + ntohs(sc->sc_node->nd_ipv4_port)); + cond_resched(); + continue; + } + mlog(ML_ERROR, "sendpage of size %zu to " SC_NODEF_FMT + " failed with %zd\n", size, sc->sc_node->nd_name, + sc->sc_node->nd_num, &sc->sc_node->nd_ipv4_address, + ntohs(sc->sc_node->nd_ipv4_port), ret); + r2net_ensure_shutdown(nn, sc, 0); + break; + } +} + +static void r2net_init_msg(struct r2net_msg *msg, u16 data_len, + u16 msg_type, u32 key) +{ + memset(msg, 0, sizeof(struct r2net_msg)); + msg->magic = cpu_to_be16(R2NET_MSG_MAGIC); + msg->data_len = cpu_to_be16(data_len); + msg->msg_type = cpu_to_be16(msg_type); + msg->sys_status = cpu_to_be32(R2NET_ERR_NONE); + msg->status = 0; + msg->key = cpu_to_be32(key); +} + +static int r2net_tx_can_proceed(struct r2net_node *nn, + struct r2net_sock_container **sc_ret, + int *error) +{ + int ret = 0; + + spin_lock(&nn->nn_lock); + if (nn->nn_persistent_error) { + ret = 1; + *sc_ret = NULL; + *error = nn->nn_persistent_error; + } else if (nn->nn_sc_valid) { + kref_get(&nn->nn_sc->sc_kref); + + ret = 1; + *sc_ret = nn->nn_sc; + *error = 0; + } + spin_unlock(&nn->nn_lock); + + return ret; +} + +/* Get a map of all nodes to which this node is currently connected to */ +void r2net_fill_node_map(unsigned long *map, unsigned bytes) +{ + struct r2net_sock_container *sc; + int node, ret; + + BUG_ON(bytes < (BITS_TO_LONGS(R2NM_MAX_NODES) * sizeof(unsigned long))); + + memset(map, 0, bytes); + for (node = 0; node < R2NM_MAX_NODES; ++node) { + r2net_tx_can_proceed(r2net_nn_from_num(node), &sc, &ret); + if (!ret) { + set_bit(node, map); + sc_put(sc); + } + } +} +EXPORT_SYMBOL_GPL(r2net_fill_node_map); + +int r2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec, + size_t caller_veclen, u8 target_node, int *status) +{ + int ret = 0; + struct r2net_msg *msg = NULL; + size_t veclen, caller_bytes = 0; + struct kvec *vec = NULL; + struct r2net_sock_container *sc = NULL; + struct r2net_node *nn = r2net_nn_from_num(target_node); + struct r2net_status_wait nsw = { + .ns_node_item = LIST_HEAD_INIT(nsw.ns_node_item), + }; + struct r2net_send_tracking nst; + + /* this may be a general bug fix */ + init_waitqueue_head(&nsw.ns_wq); + + r2net_init_nst(&nst, msg_type, key, current, target_node); + + if (r2net_wq == NULL) { + mlog(0, "attempt to tx without r2netd running\n"); + ret = -ESRCH; + goto out; + } + + if (caller_veclen == 0) { + mlog(0, "bad kvec array length\n"); + ret = -EINVAL; + goto out; + } + + caller_bytes = iov_length((struct iovec *)caller_vec, caller_veclen); + if (caller_bytes > R2NET_MAX_PAYLOAD_BYTES) { + mlog(0, "total payload len %zu too large\n", caller_bytes); + ret = -EINVAL; + goto out; + } + + if (target_node == r2nm_this_node()) { + ret = -ELOOP; + goto out; + } + + r2net_debug_add_nst(&nst); + + r2net_set_nst_sock_time(&nst); + + wait_event(nn->nn_sc_wq, r2net_tx_can_proceed(nn, &sc, &ret)); + if (ret) + goto out; + + r2net_set_nst_sock_container(&nst, sc); + + veclen = caller_veclen + 1; + vec = kmalloc(sizeof(struct kvec) * veclen, GFP_ATOMIC); + if (vec == NULL) { + mlog(0, "failed to %zu element kvec!\n", veclen); + ret = -ENOMEM; + goto out; + } + + msg = kmalloc(sizeof(struct r2net_msg), GFP_ATOMIC); + if (!msg) { + mlog(0, "failed to allocate a r2net_msg!\n"); + ret = -ENOMEM; + goto out; + } + + r2net_init_msg(msg, caller_bytes, msg_type, key); + + vec[0].iov_len = sizeof(struct r2net_msg); + vec[0].iov_base = msg; + memcpy(&vec[1], caller_vec, caller_veclen * sizeof(struct kvec)); + + ret = r2net_prep_nsw(nn, &nsw); + if (ret) + goto out; + + msg->msg_num = cpu_to_be32(nsw.ns_id); + r2net_set_nst_msg_id(&nst, nsw.ns_id); + + r2net_set_nst_send_time(&nst); + + /* finally, convert the message header to network byte-order + * and send */ + mutex_lock(&sc->sc_send_lock); + ret = r2net_send_tcp_msg(sc->sc_sock, vec, veclen, + sizeof(struct r2net_msg) + caller_bytes); + mutex_unlock(&sc->sc_send_lock); + msglog(msg, "sending returned %d\n", ret); + if (ret < 0) { + mlog(0, "error returned from r2net_send_tcp_msg=%d\n", ret); + goto out; + } + + /* wait on other node's handler */ + r2net_set_nst_status_time(&nst); + wait_event(nsw.ns_wq, r2net_nsw_completed(nn, &nsw) || + nn->nn_persistent_error || !nn->nn_sc_valid); + + r2net_update_send_stats(&nst, sc); + + /* Note that we avoid overwriting the callers status return + * variable if a system error was reported on the other + * side. Callers beware. */ + ret = r2net_sys_err_to_errno(nsw.ns_sys_status); + if (status && !ret) + *status = nsw.ns_status; + + mlog(0, "woken, returning system status %d, user status %d\n", + ret, nsw.ns_status); +out: + r2net_debug_del_nst(&nst); /* must be before dropping sc and node */ + if (sc) + sc_put(sc); + kfree(vec); + kfree(msg); + r2net_complete_nsw(nn, &nsw, 0, 0, 0); + return ret; +} +EXPORT_SYMBOL_GPL(r2net_send_message_vec); + +int r2net_send_message(u32 msg_type, u32 key, void *data, u32 len, + u8 target_node, int *status) +{ + struct kvec vec = { + .iov_base = data, + .iov_len = len, + }; + return r2net_send_message_vec(msg_type, key, &vec, 1, + target_node, status); +} +EXPORT_SYMBOL_GPL(r2net_send_message); + +static int r2net_send_status_magic(struct socket *sock, struct r2net_msg *hdr, + enum r2net_system_error syserr, int err) +{ + struct kvec vec = { + .iov_base = hdr, + .iov_len = sizeof(struct r2net_msg), + }; + + BUG_ON(syserr >= R2NET_ERR_MAX); + + /* leave other fields intact from the incoming message, msg_num + * in particular */ + hdr->sys_status = cpu_to_be32(syserr); + hdr->status = cpu_to_be32(err); + /* twiddle the magic */ + hdr->magic = cpu_to_be16(R2NET_MSG_STATUS_MAGIC); + hdr->data_len = 0; + + msglog(hdr, "about to send status magic %d\n", err); + /* hdr has been in host byteorder this whole time */ + return r2net_send_tcp_msg(sock, &vec, 1, sizeof(struct r2net_msg)); +} + +/* + * "data magic" is a long version of "status magic" where the message + * payload actually contains data to be passed in reply to certain messages + */ +static int r2net_send_data_magic(struct r2net_sock_container *sc, + struct r2net_msg *hdr, + void *data, size_t data_len, + enum r2net_system_error syserr, int err) +{ + struct kvec vec[2]; + int ret; + + vec[0].iov_base = hdr; + vec[0].iov_len = sizeof(struct r2net_msg); + vec[1].iov_base = data; + vec[1].iov_len = data_len; + + BUG_ON(syserr >= R2NET_ERR_MAX); + + /* leave other fields intact from the incoming message, msg_num + * in particular */ + hdr->sys_status = cpu_to_be32(syserr); + hdr->status = cpu_to_be32(err); + hdr->magic = cpu_to_be16(R2NET_MSG_DATA_MAGIC); /* twiddle magic */ + hdr->data_len = cpu_to_be16(data_len); + + msglog(hdr, "about to send data magic %d\n", err); + /* hdr has been in host byteorder this whole time */ + ret = r2net_send_tcp_msg(sc->sc_sock, vec, 2, + sizeof(struct r2net_msg) + data_len); + return ret; +} + +/* + * called by a message handler to convert an otherwise normal reply + * message into a "data magic" message + */ +void r2net_force_data_magic(struct r2net_msg *hdr, u16 msgtype, u32 msgkey) +{ + hdr->magic = cpu_to_be16(R2NET_MSG_DATA_MAGIC); + hdr->msg_type = cpu_to_be16(msgtype); + hdr->key = cpu_to_be32(msgkey); +} + +/* this returns -errno if the header was unknown or too large, etc. + * after this is called the buffer us reused for the next message */ +static int r2net_process_message(struct r2net_sock_container *sc, + struct r2net_msg *hdr) +{ + struct r2net_node *nn = r2net_nn_from_num(sc->sc_node->nd_num); + int ret = 0, handler_status; + enum r2net_system_error syserr; + struct r2net_msg_handler *nmh = NULL; + void *ret_data = NULL; + int data_magic = 0; + + msglog(hdr, "processing message\n"); + + r2net_sc_postpone_idle(sc); + + switch (be16_to_cpu(hdr->magic)) { + + case R2NET_MSG_STATUS_MAGIC: + /* special type for returning message status */ + r2net_complete_nsw(nn, NULL, be32_to_cpu(hdr->msg_num), + be32_to_cpu(hdr->sys_status), + be32_to_cpu(hdr->status)); + goto out; + case R2NET_MSG_KEEP_REQ_MAGIC: + r2net_sendpage(sc, r2net_keep_resp, sizeof(*r2net_keep_resp)); + goto out; + case R2NET_MSG_KEEP_RESP_MAGIC: + goto out; + case R2NET_MSG_MAGIC: + break; + case R2NET_MSG_DATA_MAGIC: + /* + * unlike a normal status magic, a data magic DOES + * (MUST) have a handler, so the control flow is + * a little funky here as a result + */ + data_magic = 1; + break; + default: + msglog(hdr, "bad magic\n"); + ret = -EINVAL; + goto out; + break; + } + + /* find a handler for it */ + handler_status = 0; + nmh = r2net_handler_get(be16_to_cpu(hdr->msg_type), + be32_to_cpu(hdr->key)); + if (!nmh) { + mlog(ML_TCP, "couldn't find handler for type %u key %08x\n", + be16_to_cpu(hdr->msg_type), be32_to_cpu(hdr->key)); + syserr = R2NET_ERR_NO_HNDLR; + goto out_respond; + } + + syserr = R2NET_ERR_NONE; + + if (be16_to_cpu(hdr->data_len) > nmh->nh_max_len) + syserr = R2NET_ERR_OVERFLOW; + + if (syserr != R2NET_ERR_NONE) { + pr_err("ramster_r2net, message length problem\n"); + goto out_respond; + } + + r2net_set_func_start_time(sc); + sc->sc_msg_key = be32_to_cpu(hdr->key); + sc->sc_msg_type = be16_to_cpu(hdr->msg_type); + handler_status = (nmh->nh_func)(hdr, sizeof(struct r2net_msg) + + be16_to_cpu(hdr->data_len), + nmh->nh_func_data, &ret_data); + if (data_magic) { + /* + * handler handled data sent in reply to request + * so complete the transaction + */ + r2net_complete_nsw(nn, NULL, be32_to_cpu(hdr->msg_num), + be32_to_cpu(hdr->sys_status), handler_status); + goto out; + } + /* + * handler changed magic to DATA_MAGIC to reply to request for data, + * implies ret_data points to data to return and handler_status + * is the number of bytes of data + */ + if (be16_to_cpu(hdr->magic) == R2NET_MSG_DATA_MAGIC) { + ret = r2net_send_data_magic(sc, hdr, + ret_data, handler_status, + syserr, 0); + hdr = NULL; + mlog(0, "sending data reply %d, syserr %d returned %d\n", + handler_status, syserr, ret); + r2net_set_func_stop_time(sc); + + r2net_update_recv_stats(sc); + goto out; + } + r2net_set_func_stop_time(sc); + + r2net_update_recv_stats(sc); + +out_respond: + /* this destroys the hdr, so don't use it after this */ + mutex_lock(&sc->sc_send_lock); + ret = r2net_send_status_magic(sc->sc_sock, hdr, syserr, + handler_status); + mutex_unlock(&sc->sc_send_lock); + hdr = NULL; + mlog(0, "sending handler status %d, syserr %d returned %d\n", + handler_status, syserr, ret); + + if (nmh) { + BUG_ON(ret_data != NULL && nmh->nh_post_func == NULL); + if (nmh->nh_post_func) + (nmh->nh_post_func)(handler_status, nmh->nh_func_data, + ret_data); + } + +out: + if (nmh) + r2net_handler_put(nmh); + return ret; +} + +static int r2net_check_handshake(struct r2net_sock_container *sc) +{ + struct r2net_handshake *hand = page_address(sc->sc_page); + struct r2net_node *nn = r2net_nn_from_num(sc->sc_node->nd_num); + + if (hand->protocol_version != cpu_to_be64(R2NET_PROTOCOL_VERSION)) { + pr_notice("ramster: " SC_NODEF_FMT " Advertised net " + "protocol version %llu but %llu is required. " + "Disconnecting.\n", sc->sc_node->nd_name, + sc->sc_node->nd_num, &sc->sc_node->nd_ipv4_address, + ntohs(sc->sc_node->nd_ipv4_port), + (unsigned long long)be64_to_cpu(hand->protocol_version), + R2NET_PROTOCOL_VERSION); + + /* don't bother reconnecting if its the wrong version. */ + r2net_ensure_shutdown(nn, sc, -ENOTCONN); + return -1; + } + + /* + * Ensure timeouts are consistent with other nodes, otherwise + * we can end up with one node thinking that the other must be down, + * but isn't. This can ultimately cause corruption. + */ + if (be32_to_cpu(hand->r2net_idle_timeout_ms) != + r2net_idle_timeout()) { + pr_notice("ramster: " SC_NODEF_FMT " uses a network " + "idle timeout of %u ms, but we use %u ms locally. " + "Disconnecting.\n", sc->sc_node->nd_name, + sc->sc_node->nd_num, &sc->sc_node->nd_ipv4_address, + ntohs(sc->sc_node->nd_ipv4_port), + be32_to_cpu(hand->r2net_idle_timeout_ms), + r2net_idle_timeout()); + r2net_ensure_shutdown(nn, sc, -ENOTCONN); + return -1; + } + + if (be32_to_cpu(hand->r2net_keepalive_delay_ms) != + r2net_keepalive_delay()) { + pr_notice("ramster: " SC_NODEF_FMT " uses a keepalive " + "delay of %u ms, but we use %u ms locally. " + "Disconnecting.\n", sc->sc_node->nd_name, + sc->sc_node->nd_num, &sc->sc_node->nd_ipv4_address, + ntohs(sc->sc_node->nd_ipv4_port), + be32_to_cpu(hand->r2net_keepalive_delay_ms), + r2net_keepalive_delay()); + r2net_ensure_shutdown(nn, sc, -ENOTCONN); + return -1; + } + + if (be32_to_cpu(hand->r2hb_heartbeat_timeout_ms) != + R2HB_MAX_WRITE_TIMEOUT_MS) { + pr_notice("ramster: " SC_NODEF_FMT " uses a heartbeat " + "timeout of %u ms, but we use %u ms locally. " + "Disconnecting.\n", sc->sc_node->nd_name, + sc->sc_node->nd_num, &sc->sc_node->nd_ipv4_address, + ntohs(sc->sc_node->nd_ipv4_port), + be32_to_cpu(hand->r2hb_heartbeat_timeout_ms), + R2HB_MAX_WRITE_TIMEOUT_MS); + r2net_ensure_shutdown(nn, sc, -ENOTCONN); + return -1; + } + + sc->sc_handshake_ok = 1; + + spin_lock(&nn->nn_lock); + /* set valid and queue the idle timers only if it hasn't been + * shut down already */ + if (nn->nn_sc == sc) { + r2net_sc_reset_idle_timer(sc); + atomic_set(&nn->nn_timeout, 0); + r2net_set_nn_state(nn, sc, 1, 0); + } + spin_unlock(&nn->nn_lock); + + /* shift everything up as though it wasn't there */ + sc->sc_page_off -= sizeof(struct r2net_handshake); + if (sc->sc_page_off) + memmove(hand, hand + 1, sc->sc_page_off); + + return 0; +} + +/* this demuxes the queued rx bytes into header or payload bits and calls + * handlers as each full message is read off the socket. it returns -error, + * == 0 eof, or > 0 for progress made.*/ +static int r2net_advance_rx(struct r2net_sock_container *sc) +{ + struct r2net_msg *hdr; + int ret = 0; + void *data; + size_t datalen; + + sclog(sc, "receiving\n"); + r2net_set_advance_start_time(sc); + + if (unlikely(sc->sc_handshake_ok == 0)) { + if (sc->sc_page_off < sizeof(struct r2net_handshake)) { + data = page_address(sc->sc_page) + sc->sc_page_off; + datalen = sizeof(struct r2net_handshake) - + sc->sc_page_off; + ret = r2net_recv_tcp_msg(sc->sc_sock, data, datalen); + if (ret > 0) + sc->sc_page_off += ret; + } + + if (sc->sc_page_off == sizeof(struct r2net_handshake)) { + r2net_check_handshake(sc); + if (unlikely(sc->sc_handshake_ok == 0)) + ret = -EPROTO; + } + goto out; + } + + /* do we need more header? */ + if (sc->sc_page_off < sizeof(struct r2net_msg)) { + data = page_address(sc->sc_page) + sc->sc_page_off; + datalen = sizeof(struct r2net_msg) - sc->sc_page_off; + ret = r2net_recv_tcp_msg(sc->sc_sock, data, datalen); + if (ret > 0) { + sc->sc_page_off += ret; + /* only swab incoming here.. we can + * only get here once as we cross from + * being under to over */ + if (sc->sc_page_off == sizeof(struct r2net_msg)) { + hdr = page_address(sc->sc_page); + if (be16_to_cpu(hdr->data_len) > + R2NET_MAX_PAYLOAD_BYTES) + ret = -EOVERFLOW; + WARN_ON_ONCE(ret == -EOVERFLOW); + } + } + if (ret <= 0) + goto out; + } + + if (sc->sc_page_off < sizeof(struct r2net_msg)) { + /* oof, still don't have a header */ + goto out; + } + + /* this was swabbed above when we first read it */ + hdr = page_address(sc->sc_page); + + msglog(hdr, "at page_off %zu\n", sc->sc_page_off); + + /* do we need more payload? */ + if (sc->sc_page_off - sizeof(struct r2net_msg) < + be16_to_cpu(hdr->data_len)) { + /* need more payload */ + data = page_address(sc->sc_page) + sc->sc_page_off; + datalen = (sizeof(struct r2net_msg) + + be16_to_cpu(hdr->data_len)) - + sc->sc_page_off; + ret = r2net_recv_tcp_msg(sc->sc_sock, data, datalen); + if (ret > 0) + sc->sc_page_off += ret; + if (ret <= 0) + goto out; + } + + if (sc->sc_page_off - sizeof(struct r2net_msg) == + be16_to_cpu(hdr->data_len)) { + /* we can only get here once, the first time we read + * the payload.. so set ret to progress if the handler + * works out. after calling this the message is toast */ + ret = r2net_process_message(sc, hdr); + if (ret == 0) + ret = 1; + sc->sc_page_off = 0; + } + +out: + sclog(sc, "ret = %d\n", ret); + r2net_set_advance_stop_time(sc); + return ret; +} + +/* this work func is triggerd by data ready. it reads until it can read no + * more. it interprets 0, eof, as fatal. if data_ready hits while we're doing + * our work the work struct will be marked and we'll be called again. */ +static void r2net_rx_until_empty(struct work_struct *work) +{ + struct r2net_sock_container *sc = + container_of(work, struct r2net_sock_container, sc_rx_work); + int ret; + + do { + ret = r2net_advance_rx(sc); + } while (ret > 0); + + if (ret <= 0 && ret != -EAGAIN) { + struct r2net_node *nn = r2net_nn_from_num(sc->sc_node->nd_num); + sclog(sc, "saw error %d, closing\n", ret); + /* not permanent so read failed handshake can retry */ + r2net_ensure_shutdown(nn, sc, 0); + } + sc_put(sc); +} + +static int r2net_set_nodelay(struct socket *sock) +{ + int ret, val = 1; + mm_segment_t oldfs; + + oldfs = get_fs(); + set_fs(KERNEL_DS); + + /* + * Dear unsuspecting programmer, + * + * Don't use sock_setsockopt() for SOL_TCP. It doesn't check its level + * argument and assumes SOL_SOCKET so, say, your TCP_NODELAY will + * silently turn into SO_DEBUG. + * + * Yours, + * Keeper of hilariously fragile interfaces. + */ + ret = sock->ops->setsockopt(sock, SOL_TCP, TCP_NODELAY, + (char __user *)&val, sizeof(val)); + + set_fs(oldfs); + return ret; +} + +static void r2net_initialize_handshake(void) +{ + r2net_hand->r2hb_heartbeat_timeout_ms = cpu_to_be32( + R2HB_MAX_WRITE_TIMEOUT_MS); + r2net_hand->r2net_idle_timeout_ms = cpu_to_be32(r2net_idle_timeout()); + r2net_hand->r2net_keepalive_delay_ms = cpu_to_be32( + r2net_keepalive_delay()); + r2net_hand->r2net_reconnect_delay_ms = cpu_to_be32( + r2net_reconnect_delay()); +} + +/* ------------------------------------------------------------ */ + +/* called when a connect completes and after a sock is accepted. the + * rx path will see the response and mark the sc valid */ +static void r2net_sc_connect_completed(struct work_struct *work) +{ + struct r2net_sock_container *sc = + container_of(work, struct r2net_sock_container, + sc_connect_work); + + mlog(ML_MSG, "sc sending handshake with ver %llu id %llx\n", + (unsigned long long)R2NET_PROTOCOL_VERSION, + (unsigned long long)be64_to_cpu(r2net_hand->connector_id)); + + r2net_initialize_handshake(); + r2net_sendpage(sc, r2net_hand, sizeof(*r2net_hand)); + sc_put(sc); +} + +/* this is called as a work_struct func. */ +static void r2net_sc_send_keep_req(struct work_struct *work) +{ + struct r2net_sock_container *sc = + container_of(work, struct r2net_sock_container, + sc_keepalive_work.work); + + r2net_sendpage(sc, r2net_keep_req, sizeof(*r2net_keep_req)); + sc_put(sc); +} + +/* socket shutdown does a del_timer_sync against this as it tears down. + * we can't start this timer until we've got to the point in sc buildup + * where shutdown is going to be involved */ +static void r2net_idle_timer(unsigned long data) +{ + struct r2net_sock_container *sc = (struct r2net_sock_container *)data; + struct r2net_node *nn = r2net_nn_from_num(sc->sc_node->nd_num); +#ifdef CONFIG_DEBUG_FS + unsigned long msecs = ktime_to_ms(ktime_get()) - + ktime_to_ms(sc->sc_tv_timer); +#else + unsigned long msecs = r2net_idle_timeout(); +#endif + + pr_notice("ramster: Connection to " SC_NODEF_FMT " has been " + "idle for %lu.%lu secs, shutting it down.\n", + sc->sc_node->nd_name, sc->sc_node->nd_num, + &sc->sc_node->nd_ipv4_address, ntohs(sc->sc_node->nd_ipv4_port), + msecs / 1000, msecs % 1000); + + /* + * Initialize the nn_timeout so that the next connection attempt + * will continue in r2net_start_connect. + */ + atomic_set(&nn->nn_timeout, 1); + r2net_sc_queue_work(sc, &sc->sc_shutdown_work); +} + +static void r2net_sc_reset_idle_timer(struct r2net_sock_container *sc) +{ + r2net_sc_cancel_delayed_work(sc, &sc->sc_keepalive_work); + r2net_sc_queue_delayed_work(sc, &sc->sc_keepalive_work, + msecs_to_jiffies(r2net_keepalive_delay())); + r2net_set_sock_timer(sc); + mod_timer(&sc->sc_idle_timeout, + jiffies + msecs_to_jiffies(r2net_idle_timeout())); +} + +static void r2net_sc_postpone_idle(struct r2net_sock_container *sc) +{ + /* Only push out an existing timer */ + if (timer_pending(&sc->sc_idle_timeout)) + r2net_sc_reset_idle_timer(sc); +} + +/* this work func is kicked whenever a path sets the nn state which doesn't + * have valid set. This includes seeing hb come up, losing a connection, + * having a connect attempt fail, etc. This centralizes the logic which decides + * if a connect attempt should be made or if we should give up and all future + * transmit attempts should fail */ +static void r2net_start_connect(struct work_struct *work) +{ + struct r2net_node *nn = + container_of(work, struct r2net_node, nn_connect_work.work); + struct r2net_sock_container *sc = NULL; + struct r2nm_node *node = NULL, *mynode = NULL; + struct socket *sock = NULL; + struct sockaddr_in myaddr = {0, }, remoteaddr = {0, }; + int ret = 0, stop; + unsigned int timeout; + + /* if we're greater we initiate tx, otherwise we accept */ + if (r2nm_this_node() <= r2net_num_from_nn(nn)) + goto out; + + /* watch for racing with tearing a node down */ + node = r2nm_get_node_by_num(r2net_num_from_nn(nn)); + if (node == NULL) { + ret = 0; + goto out; + } + + mynode = r2nm_get_node_by_num(r2nm_this_node()); + if (mynode == NULL) { + ret = 0; + goto out; + } + + spin_lock(&nn->nn_lock); + /* + * see if we already have one pending or have given up. + * For nn_timeout, it is set when we close the connection + * because of the idle time out. So it means that we have + * at least connected to that node successfully once, + * now try to connect to it again. + */ + timeout = atomic_read(&nn->nn_timeout); + stop = (nn->nn_sc || + (nn->nn_persistent_error && + (nn->nn_persistent_error != -ENOTCONN || timeout == 0))); + spin_unlock(&nn->nn_lock); + if (stop) + goto out; + + nn->nn_last_connect_attempt = jiffies; + + sc = sc_alloc(node); + if (sc == NULL) { + mlog(0, "couldn't allocate sc\n"); + ret = -ENOMEM; + goto out; + } + + ret = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock); + if (ret < 0) { + mlog(0, "can't create socket: %d\n", ret); + goto out; + } + sc->sc_sock = sock; /* freed by sc_kref_release */ + + sock->sk->sk_allocation = GFP_ATOMIC; + + myaddr.sin_family = AF_INET; + myaddr.sin_addr.s_addr = mynode->nd_ipv4_address; + myaddr.sin_port = htons(0); /* any port */ + + ret = sock->ops->bind(sock, (struct sockaddr *)&myaddr, + sizeof(myaddr)); + if (ret) { + mlog(ML_ERROR, "bind failed with %d at address %pI4\n", + ret, &mynode->nd_ipv4_address); + goto out; + } + + ret = r2net_set_nodelay(sc->sc_sock); + if (ret) { + mlog(ML_ERROR, "setting TCP_NODELAY failed with %d\n", ret); + goto out; + } + + r2net_register_callbacks(sc->sc_sock->sk, sc); + + spin_lock(&nn->nn_lock); + /* handshake completion will set nn->nn_sc_valid */ + r2net_set_nn_state(nn, sc, 0, 0); + spin_unlock(&nn->nn_lock); + + remoteaddr.sin_family = AF_INET; + remoteaddr.sin_addr.s_addr = node->nd_ipv4_address; + remoteaddr.sin_port = node->nd_ipv4_port; + + ret = sc->sc_sock->ops->connect(sc->sc_sock, + (struct sockaddr *)&remoteaddr, + sizeof(remoteaddr), + O_NONBLOCK); + if (ret == -EINPROGRESS) + ret = 0; + +out: + if (ret) { + pr_notice("ramster: Connect attempt to " SC_NODEF_FMT + " failed with errno %d\n", sc->sc_node->nd_name, + sc->sc_node->nd_num, &sc->sc_node->nd_ipv4_address, + ntohs(sc->sc_node->nd_ipv4_port), ret); + /* 0 err so that another will be queued and attempted + * from set_nn_state */ + if (sc) + r2net_ensure_shutdown(nn, sc, 0); + } + if (sc) + sc_put(sc); + if (node) + r2nm_node_put(node); + if (mynode) + r2nm_node_put(mynode); + + return; +} + +static void r2net_connect_expired(struct work_struct *work) +{ + struct r2net_node *nn = + container_of(work, struct r2net_node, nn_connect_expired.work); + + spin_lock(&nn->nn_lock); + if (!nn->nn_sc_valid) { + pr_notice("ramster: No connection established with " + "node %u after %u.%u seconds, giving up.\n", + r2net_num_from_nn(nn), + r2net_idle_timeout() / 1000, + r2net_idle_timeout() % 1000); + + r2net_set_nn_state(nn, NULL, 0, -ENOTCONN); + } + spin_unlock(&nn->nn_lock); +} + +static void r2net_still_up(struct work_struct *work) +{ +} + +/* ------------------------------------------------------------ */ + +void r2net_disconnect_node(struct r2nm_node *node) +{ + struct r2net_node *nn = r2net_nn_from_num(node->nd_num); + + /* don't reconnect until it's heartbeating again */ + spin_lock(&nn->nn_lock); + atomic_set(&nn->nn_timeout, 0); + r2net_set_nn_state(nn, NULL, 0, -ENOTCONN); + spin_unlock(&nn->nn_lock); + + if (r2net_wq) { + cancel_delayed_work(&nn->nn_connect_expired); + cancel_delayed_work(&nn->nn_connect_work); + cancel_delayed_work(&nn->nn_still_up); + flush_workqueue(r2net_wq); + } +} + +static void r2net_hb_node_down_cb(struct r2nm_node *node, int node_num, + void *data) +{ + if (!node) + return; + + if (node_num != r2nm_this_node()) + r2net_disconnect_node(node); + + BUG_ON(atomic_read(&r2net_connected_peers) < 0); +} + +static void r2net_hb_node_up_cb(struct r2nm_node *node, int node_num, + void *data) +{ + struct r2net_node *nn = r2net_nn_from_num(node_num); + + BUG_ON(!node); + + /* ensure an immediate connect attempt */ + nn->nn_last_connect_attempt = jiffies - + (msecs_to_jiffies(r2net_reconnect_delay()) + 1); + + if (node_num != r2nm_this_node()) { + /* believe it or not, accept and node hearbeating testing + * can succeed for this node before we got here.. so + * only use set_nn_state to clear the persistent error + * if that hasn't already happened */ + spin_lock(&nn->nn_lock); + atomic_set(&nn->nn_timeout, 0); + if (nn->nn_persistent_error) + r2net_set_nn_state(nn, NULL, 0, 0); + spin_unlock(&nn->nn_lock); + } +} + +void r2net_unregister_hb_callbacks(void) +{ + r2hb_unregister_callback(NULL, &r2net_hb_up); + r2hb_unregister_callback(NULL, &r2net_hb_down); +} + +int r2net_register_hb_callbacks(void) +{ + int ret; + + r2hb_setup_callback(&r2net_hb_down, R2HB_NODE_DOWN_CB, + r2net_hb_node_down_cb, NULL, R2NET_HB_PRI); + r2hb_setup_callback(&r2net_hb_up, R2HB_NODE_UP_CB, + r2net_hb_node_up_cb, NULL, R2NET_HB_PRI); + + ret = r2hb_register_callback(NULL, &r2net_hb_up); + if (ret == 0) + ret = r2hb_register_callback(NULL, &r2net_hb_down); + + if (ret) + r2net_unregister_hb_callbacks(); + + return ret; +} + +/* ------------------------------------------------------------ */ + +static int r2net_accept_one(struct socket *sock) +{ + int ret, slen; + struct sockaddr_in sin; + struct socket *new_sock = NULL; + struct r2nm_node *node = NULL; + struct r2nm_node *local_node = NULL; + struct r2net_sock_container *sc = NULL; + struct r2net_node *nn; + + BUG_ON(sock == NULL); + ret = sock_create_lite(sock->sk->sk_family, sock->sk->sk_type, + sock->sk->sk_protocol, &new_sock); + if (ret) + goto out; + + new_sock->type = sock->type; + new_sock->ops = sock->ops; + ret = sock->ops->accept(sock, new_sock, O_NONBLOCK); + if (ret < 0) + goto out; + + new_sock->sk->sk_allocation = GFP_ATOMIC; + + ret = r2net_set_nodelay(new_sock); + if (ret) { + mlog(ML_ERROR, "setting TCP_NODELAY failed with %d\n", ret); + goto out; + } + + slen = sizeof(sin); + ret = new_sock->ops->getname(new_sock, (struct sockaddr *) &sin, + &slen, 1); + if (ret < 0) + goto out; + + node = r2nm_get_node_by_ip(sin.sin_addr.s_addr); + if (node == NULL) { + pr_notice("ramster: Attempt to connect from unknown " + "node at %pI4:%d\n", &sin.sin_addr.s_addr, + ntohs(sin.sin_port)); + ret = -EINVAL; + goto out; + } + + if (r2nm_this_node() >= node->nd_num) { + local_node = r2nm_get_node_by_num(r2nm_this_node()); + pr_notice("ramster: Unexpected connect attempt seen " + "at node '%s' (%u, %pI4:%d) from node '%s' (%u, " + "%pI4:%d)\n", local_node->nd_name, local_node->nd_num, + &(local_node->nd_ipv4_address), + ntohs(local_node->nd_ipv4_port), node->nd_name, + node->nd_num, &sin.sin_addr.s_addr, ntohs(sin.sin_port)); + ret = -EINVAL; + goto out; + } + + /* this happens all the time when the other node sees our heartbeat + * and tries to connect before we see their heartbeat */ + if (!r2hb_check_node_heartbeating_from_callback(node->nd_num)) { + mlog(ML_CONN, "attempt to connect from node '%s' at " + "%pI4:%d but it isn't heartbeating\n", + node->nd_name, &sin.sin_addr.s_addr, + ntohs(sin.sin_port)); + ret = -EINVAL; + goto out; + } + + nn = r2net_nn_from_num(node->nd_num); + + spin_lock(&nn->nn_lock); + if (nn->nn_sc) + ret = -EBUSY; + else + ret = 0; + spin_unlock(&nn->nn_lock); + if (ret) { + pr_notice("ramster: Attempt to connect from node '%s' " + "at %pI4:%d but it already has an open connection\n", + node->nd_name, &sin.sin_addr.s_addr, + ntohs(sin.sin_port)); + goto out; + } + + sc = sc_alloc(node); + if (sc == NULL) { + ret = -ENOMEM; + goto out; + } + + sc->sc_sock = new_sock; + new_sock = NULL; + + spin_lock(&nn->nn_lock); + atomic_set(&nn->nn_timeout, 0); + r2net_set_nn_state(nn, sc, 0, 0); + spin_unlock(&nn->nn_lock); + + r2net_register_callbacks(sc->sc_sock->sk, sc); + r2net_sc_queue_work(sc, &sc->sc_rx_work); + + r2net_initialize_handshake(); + r2net_sendpage(sc, r2net_hand, sizeof(*r2net_hand)); + +out: + if (new_sock) + sock_release(new_sock); + if (node) + r2nm_node_put(node); + if (local_node) + r2nm_node_put(local_node); + if (sc) + sc_put(sc); + return ret; +} + +static void r2net_accept_many(struct work_struct *work) +{ + struct socket *sock = r2net_listen_sock; + while (r2net_accept_one(sock) == 0) + cond_resched(); +} + +static void r2net_listen_data_ready(struct sock *sk, int bytes) +{ + void (*ready)(struct sock *sk, int bytes); + + read_lock(&sk->sk_callback_lock); + ready = sk->sk_user_data; + if (ready == NULL) { /* check for teardown race */ + ready = sk->sk_data_ready; + goto out; + } + + /* ->sk_data_ready is also called for a newly established child socket + * before it has been accepted and the acceptor has set up their + * data_ready.. we only want to queue listen work for our listening + * socket */ + if (sk->sk_state == TCP_LISTEN) { + mlog(ML_TCP, "bytes: %d\n", bytes); + queue_work(r2net_wq, &r2net_listen_work); + } + +out: + read_unlock(&sk->sk_callback_lock); + ready(sk, bytes); +} + +static int r2net_open_listening_sock(__be32 addr, __be16 port) +{ + struct socket *sock = NULL; + int ret; + struct sockaddr_in sin = { + .sin_family = PF_INET, + .sin_addr = { .s_addr = addr }, + .sin_port = port, + }; + + ret = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock); + if (ret < 0) { + pr_err("ramster: Error %d while creating socket\n", ret); + goto out; + } + + sock->sk->sk_allocation = GFP_ATOMIC; + + write_lock_bh(&sock->sk->sk_callback_lock); + sock->sk->sk_user_data = sock->sk->sk_data_ready; + sock->sk->sk_data_ready = r2net_listen_data_ready; + write_unlock_bh(&sock->sk->sk_callback_lock); + + r2net_listen_sock = sock; + INIT_WORK(&r2net_listen_work, r2net_accept_many); + + sock->sk->sk_reuse = /* SK_CAN_REUSE FIXME FOR 3.4 */ 1; + ret = sock->ops->bind(sock, (struct sockaddr *)&sin, sizeof(sin)); + if (ret < 0) { + pr_err("ramster: Error %d while binding socket at %pI4:%u\n", + ret, &addr, ntohs(port)); + goto out; + } + + ret = sock->ops->listen(sock, 64); + if (ret < 0) + pr_err("ramster: Error %d while listening on %pI4:%u\n", + ret, &addr, ntohs(port)); + +out: + if (ret) { + r2net_listen_sock = NULL; + if (sock) + sock_release(sock); + } + return ret; +} + +/* + * called from node manager when we should bring up our network listening + * socket. node manager handles all the serialization to only call this + * once and to match it with r2net_stop_listening(). note, + * r2nm_this_node() doesn't work yet as we're being called while it + * is being set up. + */ +int r2net_start_listening(struct r2nm_node *node) +{ + int ret = 0; + + BUG_ON(r2net_wq != NULL); + BUG_ON(r2net_listen_sock != NULL); + + mlog(ML_KTHREAD, "starting r2net thread...\n"); + r2net_wq = create_singlethread_workqueue("r2net"); + if (r2net_wq == NULL) { + mlog(ML_ERROR, "unable to launch r2net thread\n"); + return -ENOMEM; /* ? */ + } + + ret = r2net_open_listening_sock(node->nd_ipv4_address, + node->nd_ipv4_port); + if (ret) { + destroy_workqueue(r2net_wq); + r2net_wq = NULL; + } + + return ret; +} + +/* again, r2nm_this_node() doesn't work here as we're involved in + * tearing it down */ +void r2net_stop_listening(struct r2nm_node *node) +{ + struct socket *sock = r2net_listen_sock; + size_t i; + + BUG_ON(r2net_wq == NULL); + BUG_ON(r2net_listen_sock == NULL); + + /* stop the listening socket from generating work */ + write_lock_bh(&sock->sk->sk_callback_lock); + sock->sk->sk_data_ready = sock->sk->sk_user_data; + sock->sk->sk_user_data = NULL; + write_unlock_bh(&sock->sk->sk_callback_lock); + + for (i = 0; i < ARRAY_SIZE(r2net_nodes); i++) { + struct r2nm_node *node = r2nm_get_node_by_num(i); + if (node) { + r2net_disconnect_node(node); + r2nm_node_put(node); + } + } + + /* finish all work and tear down the work queue */ + mlog(ML_KTHREAD, "waiting for r2net thread to exit....\n"); + destroy_workqueue(r2net_wq); + r2net_wq = NULL; + + sock_release(r2net_listen_sock); + r2net_listen_sock = NULL; +} + +void r2net_hb_node_up_manual(int node_num) +{ + struct r2nm_node dummy; + if (r2nm_single_cluster == NULL) + pr_err("ramster: cluster not alive, node_up_manual ignored\n"); + else { + r2hb_manual_set_node_heartbeating(node_num); + r2net_hb_node_up_cb(&dummy, node_num, NULL); + } +} + +/* ------------------------------------------------------------ */ + +int r2net_init(void) +{ + unsigned long i; + + if (r2net_debugfs_init()) + return -ENOMEM; + + r2net_hand = kzalloc(sizeof(struct r2net_handshake), GFP_KERNEL); + r2net_keep_req = kzalloc(sizeof(struct r2net_msg), GFP_KERNEL); + r2net_keep_resp = kzalloc(sizeof(struct r2net_msg), GFP_KERNEL); + if (!r2net_hand || !r2net_keep_req || !r2net_keep_resp) { + kfree(r2net_hand); + kfree(r2net_keep_req); + kfree(r2net_keep_resp); + return -ENOMEM; + } + + r2net_hand->protocol_version = cpu_to_be64(R2NET_PROTOCOL_VERSION); + r2net_hand->connector_id = cpu_to_be64(1); + + r2net_keep_req->magic = cpu_to_be16(R2NET_MSG_KEEP_REQ_MAGIC); + r2net_keep_resp->magic = cpu_to_be16(R2NET_MSG_KEEP_RESP_MAGIC); + + for (i = 0; i < ARRAY_SIZE(r2net_nodes); i++) { + struct r2net_node *nn = r2net_nn_from_num(i); + + atomic_set(&nn->nn_timeout, 0); + spin_lock_init(&nn->nn_lock); + INIT_DELAYED_WORK(&nn->nn_connect_work, r2net_start_connect); + INIT_DELAYED_WORK(&nn->nn_connect_expired, + r2net_connect_expired); + INIT_DELAYED_WORK(&nn->nn_still_up, r2net_still_up); + /* until we see hb from a node we'll return einval */ + nn->nn_persistent_error = -ENOTCONN; + init_waitqueue_head(&nn->nn_sc_wq); + idr_init(&nn->nn_status_idr); + INIT_LIST_HEAD(&nn->nn_status_list); + } + + return 0; +} + +void r2net_exit(void) +{ + kfree(r2net_hand); + kfree(r2net_keep_req); + kfree(r2net_keep_resp); + r2net_debugfs_exit(); +} diff --git a/drivers/staging/ramster/ramster/tcp.h b/drivers/staging/ramster/ramster/tcp.h new file mode 100644 index 0000000..9d05833 --- /dev/null +++ b/drivers/staging/ramster/ramster/tcp.h @@ -0,0 +1,159 @@ +/* -*- mode: c; c-basic-offset: 8; -*- + * vim: noexpandtab sw=8 ts=8 sts=0: + * + * tcp.h + * + * Function prototypes + * + * Copyright (C) 2004 Oracle. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + * + */ + +#ifndef R2CLUSTER_TCP_H +#define R2CLUSTER_TCP_H + +#include +#ifdef __KERNEL__ +#include +#include +#else +#include +#endif +#include +#include + +struct r2net_msg { + __be16 magic; + __be16 data_len; + __be16 msg_type; + __be16 pad1; + __be32 sys_status; + __be32 status; + __be32 key; + __be32 msg_num; + __u8 buf[0]; +}; + +typedef int (r2net_msg_handler_func)(struct r2net_msg *msg, u32 len, void *data, + void **ret_data); +typedef void (r2net_post_msg_handler_func)(int status, void *data, + void *ret_data); + +#define R2NET_MAX_PAYLOAD_BYTES (4096 - sizeof(struct r2net_msg)) + +/* same as hb delay, we're waiting for another node to recognize our hb */ +#define R2NET_RECONNECT_DELAY_MS_DEFAULT 2000 + +#define R2NET_KEEPALIVE_DELAY_MS_DEFAULT 2000 +#define R2NET_IDLE_TIMEOUT_MS_DEFAULT 30000 + + +/* TODO: figure this out.... */ +static inline int r2net_link_down(int err, struct socket *sock) +{ + if (sock) { + if (sock->sk->sk_state != TCP_ESTABLISHED && + sock->sk->sk_state != TCP_CLOSE_WAIT) + return 1; + } + + if (err >= 0) + return 0; + switch (err) { + + /* ????????????????????????? */ + case -ERESTARTSYS: + case -EBADF: + /* When the server has died, an ICMP port unreachable + * message prompts ECONNREFUSED. */ + case -ECONNREFUSED: + case -ENOTCONN: + case -ECONNRESET: + case -EPIPE: + return 1; + + } + return 0; +} + +enum { + R2NET_DRIVER_UNINITED, + R2NET_DRIVER_READY, +}; + +int r2net_send_message(u32 msg_type, u32 key, void *data, u32 len, + u8 target_node, int *status); +int r2net_send_message_vec(u32 msg_type, u32 key, struct kvec *vec, + size_t veclen, u8 target_node, int *status); + +int r2net_register_handler(u32 msg_type, u32 key, u32 max_len, + r2net_msg_handler_func *func, void *data, + r2net_post_msg_handler_func *post_func, + struct list_head *unreg_list); +void r2net_unregister_handler_list(struct list_head *list); + +void r2net_fill_node_map(unsigned long *map, unsigned bytes); + +void r2net_force_data_magic(struct r2net_msg *, u16, u32); +void r2net_hb_node_up_manual(int); +struct r2net_node *r2net_nn_from_num(u8); + +struct r2nm_node; +int r2net_register_hb_callbacks(void); +void r2net_unregister_hb_callbacks(void); +int r2net_start_listening(struct r2nm_node *node); +void r2net_stop_listening(struct r2nm_node *node); +void r2net_disconnect_node(struct r2nm_node *node); +int r2net_num_connected_peers(void); + +int r2net_init(void); +void r2net_exit(void); + +struct r2net_send_tracking; +struct r2net_sock_container; + +#if 0 +int r2net_debugfs_init(void); +void r2net_debugfs_exit(void); +void r2net_debug_add_nst(struct r2net_send_tracking *nst); +void r2net_debug_del_nst(struct r2net_send_tracking *nst); +void r2net_debug_add_sc(struct r2net_sock_container *sc); +void r2net_debug_del_sc(struct r2net_sock_container *sc); +#else +static inline int r2net_debugfs_init(void) +{ + return 0; +} +static inline void r2net_debugfs_exit(void) +{ +} +static inline void r2net_debug_add_nst(struct r2net_send_tracking *nst) +{ +} +static inline void r2net_debug_del_nst(struct r2net_send_tracking *nst) +{ +} +static inline void r2net_debug_add_sc(struct r2net_sock_container *sc) +{ +} +static inline void r2net_debug_del_sc(struct r2net_sock_container *sc) +{ +} +#endif /* CONFIG_DEBUG_FS */ + +#endif /* R2CLUSTER_TCP_H */ diff --git a/drivers/staging/ramster/ramster/tcp_internal.h b/drivers/staging/ramster/ramster/tcp_internal.h new file mode 100644 index 0000000..4d8cc9f --- /dev/null +++ b/drivers/staging/ramster/ramster/tcp_internal.h @@ -0,0 +1,248 @@ +/* -*- mode: c; c-basic-offset: 8; -*- + * vim: noexpandtab sw=8 ts=8 sts=0: + * + * Copyright (C) 2005 Oracle. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + */ + +#ifndef R2CLUSTER_TCP_INTERNAL_H +#define R2CLUSTER_TCP_INTERNAL_H + +#define R2NET_MSG_MAGIC ((u16)0xfa55) +#define R2NET_MSG_STATUS_MAGIC ((u16)0xfa56) +#define R2NET_MSG_KEEP_REQ_MAGIC ((u16)0xfa57) +#define R2NET_MSG_KEEP_RESP_MAGIC ((u16)0xfa58) +/* + * "data magic" is a long version of "status magic" where the message + * payload actually contains data to be passed in reply to certain messages + */ +#define R2NET_MSG_DATA_MAGIC ((u16)0xfa59) + +/* we're delaying our quorum decision so that heartbeat will have timed + * out truly dead nodes by the time we come around to making decisions + * on their number */ +#define R2NET_QUORUM_DELAY_MS \ + ((r2hb_dead_threshold + 2) * R2HB_REGION_TIMEOUT_MS) + +/* + * This version number represents quite a lot, unfortunately. It not + * only represents the raw network message protocol on the wire but also + * locking semantics of the file system using the protocol. It should + * be somewhere else, I'm sure, but right now it isn't. + * + * With version 11, we separate out the filesystem locking portion. The + * filesystem now has a major.minor version it negotiates. Version 11 + * introduces this negotiation to the r2dlm protocol, and as such the + * version here in tcp_internal.h should not need to be bumped for + * filesystem locking changes. + * + * New in version 11 + * - Negotiation of filesystem locking in the dlm join. + * + * New in version 10: + * - Meta/data locks combined + * + * New in version 9: + * - All votes removed + * + * New in version 8: + * - Replace delete inode votes with a cluster lock + * + * New in version 7: + * - DLM join domain includes the live nodemap + * + * New in version 6: + * - DLM lockres remote refcount fixes. + * + * New in version 5: + * - Network timeout checking protocol + * + * New in version 4: + * - Remove i_generation from lock names for better stat performance. + * + * New in version 3: + * - Replace dentry votes with a cluster lock + * + * New in version 2: + * - full 64 bit i_size in the metadata lock lvbs + * - introduction of "rw" lock and pushing meta/data locking down + */ +#define R2NET_PROTOCOL_VERSION 11ULL +struct r2net_handshake { + __be64 protocol_version; + __be64 connector_id; + __be32 r2hb_heartbeat_timeout_ms; + __be32 r2net_idle_timeout_ms; + __be32 r2net_keepalive_delay_ms; + __be32 r2net_reconnect_delay_ms; +}; + +struct r2net_node { + /* this is never called from int/bh */ + spinlock_t nn_lock; + + /* set the moment an sc is allocated and a connect is started */ + struct r2net_sock_container *nn_sc; + /* _valid is only set after the handshake passes and tx can happen */ + unsigned nn_sc_valid:1; + /* if this is set tx just returns it */ + int nn_persistent_error; + /* It is only set to 1 after the idle time out. */ + atomic_t nn_timeout; + + /* threads waiting for an sc to arrive wait on the wq for generation + * to increase. it is increased when a connecting socket succeeds + * or fails or when an accepted socket is attached. */ + wait_queue_head_t nn_sc_wq; + + struct idr nn_status_idr; + struct list_head nn_status_list; + + /* connects are attempted from when heartbeat comes up until either hb + * goes down, the node is unconfigured, no connect attempts succeed + * before R2NET_CONN_IDLE_DELAY, or a connect succeeds. connect_work + * is queued from set_nn_state both from hb up and from itself if a + * connect attempt fails and so can be self-arming. shutdown is + * careful to first mark the nn such that no connects will be attempted + * before canceling delayed connect work and flushing the queue. */ + struct delayed_work nn_connect_work; + unsigned long nn_last_connect_attempt; + + /* this is queued as nodes come up and is canceled when a connection is + * established. this expiring gives up on the node and errors out + * transmits */ + struct delayed_work nn_connect_expired; + + /* after we give up on a socket we wait a while before deciding + * that it is still heartbeating and that we should do some + * quorum work */ + struct delayed_work nn_still_up; +}; + +struct r2net_sock_container { + struct kref sc_kref; + /* the next two are valid for the life time of the sc */ + struct socket *sc_sock; + struct r2nm_node *sc_node; + + /* all of these sc work structs hold refs on the sc while they are + * queued. they should not be able to ref a freed sc. the teardown + * race is with r2net_wq destruction in r2net_stop_listening() */ + + /* rx and connect work are generated from socket callbacks. sc + * shutdown removes the callbacks and then flushes the work queue */ + struct work_struct sc_rx_work; + struct work_struct sc_connect_work; + /* shutdown work is triggered in two ways. the simple way is + * for a code path calls ensure_shutdown which gets a lock, removes + * the sc from the nn, and queues the work. in this case the + * work is single-shot. the work is also queued from a sock + * callback, though, and in this case the work will find the sc + * still on the nn and will call ensure_shutdown itself.. this + * ends up triggering the shutdown work again, though nothing + * will be done in that second iteration. so work queue teardown + * has to be careful to remove the sc from the nn before waiting + * on the work queue so that the shutdown work doesn't remove the + * sc and rearm itself. + */ + struct work_struct sc_shutdown_work; + + struct timer_list sc_idle_timeout; + struct delayed_work sc_keepalive_work; + + unsigned sc_handshake_ok:1; + + struct page *sc_page; + size_t sc_page_off; + + /* original handlers for the sockets */ + void (*sc_state_change)(struct sock *sk); + void (*sc_data_ready)(struct sock *sk, int bytes); + + u32 sc_msg_key; + u16 sc_msg_type; + +#ifdef CONFIG_DEBUG_FS + struct list_head sc_net_debug_item; + ktime_t sc_tv_timer; + ktime_t sc_tv_data_ready; + ktime_t sc_tv_advance_start; + ktime_t sc_tv_advance_stop; + ktime_t sc_tv_func_start; + ktime_t sc_tv_func_stop; +#endif +#ifdef CONFIG_RAMSTER_FS_STATS + ktime_t sc_tv_acquiry_total; + ktime_t sc_tv_send_total; + ktime_t sc_tv_status_total; + u32 sc_send_count; + u32 sc_recv_count; + ktime_t sc_tv_process_total; +#endif + struct mutex sc_send_lock; +}; + +struct r2net_msg_handler { + struct rb_node nh_node; + u32 nh_max_len; + u32 nh_msg_type; + u32 nh_key; + r2net_msg_handler_func *nh_func; + r2net_msg_handler_func *nh_func_data; + r2net_post_msg_handler_func + *nh_post_func; + struct kref nh_kref; + struct list_head nh_unregister_item; +}; + +enum r2net_system_error { + R2NET_ERR_NONE = 0, + R2NET_ERR_NO_HNDLR, + R2NET_ERR_OVERFLOW, + R2NET_ERR_DIED, + R2NET_ERR_MAX +}; + +struct r2net_status_wait { + enum r2net_system_error ns_sys_status; + s32 ns_status; + int ns_id; + wait_queue_head_t ns_wq; + struct list_head ns_node_item; +}; + +#ifdef CONFIG_DEBUG_FS +/* just for state dumps */ +struct r2net_send_tracking { + struct list_head st_net_debug_item; + struct task_struct *st_task; + struct r2net_sock_container *st_sc; + u32 st_id; + u32 st_msg_type; + u32 st_msg_key; + u8 st_node; + ktime_t st_sock_time; + ktime_t st_send_time; + ktime_t st_status_time; +}; +#else +struct r2net_send_tracking { + u32 dummy; +}; +#endif /* CONFIG_DEBUG_FS */ + +#endif /* R2CLUSTER_TCP_INTERNAL_H */ -- cgit v0.10.2 From b077f2cd9b63798c676d62e03c85ace094e2d970 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:20:58 -0700 Subject: staging: comedi: comedi_fops: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 7a76f9c..fb2ed2f 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -426,7 +426,7 @@ static int do_bufconfig_ioctl(struct comedi_device *dev, if (bc.subdevice >= dev->n_subdevices || bc.subdevice < 0) return -EINVAL; - s = dev->subdevices + bc.subdevice; + s = &dev->subdevices[bc.subdevice]; async = s->async; if (!async) { @@ -539,7 +539,7 @@ static int do_subdinfo_ioctl(struct comedi_device *dev, /* fill subdinfo structs */ for (i = 0; i < dev->n_subdevices; i++) { - s = dev->subdevices + i; + s = &dev->subdevices[i]; us = tmp + i; us->type = s->type; @@ -617,7 +617,7 @@ static int do_chaninfo_ioctl(struct comedi_device *dev, if (it.subdev >= dev->n_subdevices) return -EINVAL; - s = dev->subdevices + it.subdev; + s = &dev->subdevices[it.subdev]; if (it.maxdata_list) { if (s->maxdata || !s->maxdata_list) @@ -685,7 +685,7 @@ static int do_bufinfo_ioctl(struct comedi_device *dev, if (bi.subdevice >= dev->n_subdevices || bi.subdevice < 0) return -EINVAL; - s = dev->subdevices + bi.subdevice; + s = &dev->subdevices[bi.subdevice]; if (s->lock && s->lock != file) return -EACCES; @@ -938,7 +938,7 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, ret = -EINVAL; break; } - s = dev->subdevices + insn->subdev; + s = &dev->subdevices[insn->subdev]; if (!s->async) { DPRINTK("no async\n"); ret = -EINVAL; @@ -967,7 +967,7 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, ret = -EINVAL; goto out; } - s = dev->subdevices + insn->subdev; + s = &dev->subdevices[insn->subdev]; if (s->type == COMEDI_SUBD_UNUSED) { DPRINTK("%d not usable subdevice\n", insn->subdev); @@ -1151,7 +1151,7 @@ static int do_cmd_ioctl(struct comedi_device *dev, return -ENODEV; } - s = dev->subdevices + user_cmd.subdev; + s = &dev->subdevices[user_cmd.subdev]; async = s->async; if (s->type == COMEDI_SUBD_UNUSED) { @@ -1301,7 +1301,7 @@ static int do_cmdtest_ioctl(struct comedi_device *dev, return -ENODEV; } - s = dev->subdevices + user_cmd.subdev; + s = &dev->subdevices[user_cmd.subdev]; if (s->type == COMEDI_SUBD_UNUSED) { DPRINTK("%d not valid subdevice\n", user_cmd.subdev); return -EIO; @@ -1388,7 +1388,7 @@ static int do_lock_ioctl(struct comedi_device *dev, unsigned int arg, if (arg >= dev->n_subdevices) return -EINVAL; - s = dev->subdevices + arg; + s = &dev->subdevices[arg]; spin_lock_irqsave(&s->spin_lock, flags); if (s->busy || s->lock) @@ -1431,7 +1431,7 @@ static int do_unlock_ioctl(struct comedi_device *dev, unsigned int arg, if (arg >= dev->n_subdevices) return -EINVAL; - s = dev->subdevices + arg; + s = &dev->subdevices[arg]; if (s->busy) return -EBUSY; @@ -1472,7 +1472,7 @@ static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg, if (arg >= dev->n_subdevices) return -EINVAL; - s = dev->subdevices + arg; + s = &dev->subdevices[arg]; if (s->async == NULL) return -EINVAL; @@ -1509,7 +1509,7 @@ static int do_poll_ioctl(struct comedi_device *dev, unsigned int arg, if (arg >= dev->n_subdevices) return -EINVAL; - s = dev->subdevices + arg; + s = &dev->subdevices[arg]; if (s->lock && s->lock != file) return -EACCES; @@ -2138,7 +2138,7 @@ static int comedi_close(struct inode *inode, struct file *file) if (dev->subdevices) { for (i = 0; i < dev->n_subdevices; i++) { - s = dev->subdevices + i; + s = &dev->subdevices[i]; if (s->busy == file) do_cancel(dev, s); @@ -2359,7 +2359,7 @@ static int is_device_busy(struct comedi_device *dev) return 0; for (i = 0; i < dev->n_subdevices; i++) { - s = dev->subdevices + i; + s = &dev->subdevices[i]; if (s->busy) return 1; if (s->async && s->async->mmap_count) -- cgit v0.10.2 From 5e4c58ce65103a820c4ca4b4b0bd8609e638cf75 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:21:25 -0700 Subject: staging: comedi: drivers: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 3153388..5e91444 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -71,7 +71,7 @@ int comedi_alloc_subdevices(struct comedi_device *dev, int num_subdevices) dev->n_subdevices = num_subdevices; for (i = 0; i < num_subdevices; ++i) { - s = dev->subdevices + i; + s = &dev->subdevices[i]; s->device = dev; s->async_dma_dir = DMA_NONE; spin_lock_init(&s->spin_lock); @@ -88,7 +88,7 @@ static void cleanup_device(struct comedi_device *dev) if (dev->subdevices) { for (i = 0; i < dev->n_subdevices; i++) { - s = dev->subdevices + i; + s = &dev->subdevices[i]; comedi_free_subdevice_minor(s); if (s->async) { comedi_buf_alloc(dev, s, 0); @@ -260,7 +260,7 @@ static int postconfig(struct comedi_device *dev) int ret; for (i = 0; i < dev->n_subdevices; i++) { - s = dev->subdevices + i; + s = &dev->subdevices[i]; if (s->type == COMEDI_SUBD_UNUSED) continue; -- cgit v0.10.2 From 5101b4d1877396d9b1ce5a6a6e91bb302289bf89 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:21:53 -0700 Subject: staging: comedi: 8255: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index 4c9977b..e2506dd 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -403,7 +403,7 @@ static int dev_8255_attach(struct comedi_device *dev, return ret; for (i = 0; i < dev->n_subdevices; i++) { - s = dev->subdevices + i; + s = &dev->subdevices[i]; iobase = it->options[i]; if (!request_region(iobase, _8255_SIZE, "8255")) { @@ -429,7 +429,7 @@ static void dev_8255_detach(struct comedi_device *dev) int i; for (i = 0; i < dev->n_subdevices; i++) { - s = dev->subdevices + i; + s = &dev->subdevices[i]; if (s->type != COMEDI_SUBD_UNUSED) { spriv = s->private; release_region(spriv->iobase, _8255_SIZE); -- cgit v0.10.2 From 6e269d7cac312ebb1efc1adaf20e4a92abe24978 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:22:25 -0700 Subject: staging: comedi: acl7225b: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/acl7225b.c b/drivers/staging/comedi/drivers/acl7225b.c index ddba5db..28c7fd3 100644 --- a/drivers/staging/comedi/drivers/acl7225b.c +++ b/drivers/staging/comedi/drivers/acl7225b.c @@ -81,7 +81,7 @@ static int acl7225b_attach(struct comedi_device *dev, if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; /* Relays outputs */ s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE; @@ -91,7 +91,7 @@ static int acl7225b_attach(struct comedi_device *dev, s->range_table = &range_digital; s->private = (void *)ACL7225_RIO_LO; - s = dev->subdevices + 1; + s = &dev->subdevices[1]; /* Relays status */ s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; @@ -101,7 +101,7 @@ static int acl7225b_attach(struct comedi_device *dev, s->range_table = &range_digital; s->private = (void *)ACL7225_RIO_LO; - s = dev->subdevices + 2; + s = &dev->subdevices[2]; /* Isolated digital inputs */ s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; -- cgit v0.10.2 From 3237c964138cc777c007caa897526d84f4d7f928 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:22:47 -0700 Subject: staging: comedi: addi_common: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index a3d4ed2..99a96bd 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -1669,7 +1669,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) return ret; /* Allocate and Initialise AI Subdevice Structures */ - s = dev->subdevices + 0; + s = &dev->subdevices[0]; if ((devpriv->s_EeParameters.i_NbrAiChannel) || (this_board->i_NbrAiChannelDiff)) { dev->read_subdev = s; @@ -1705,7 +1705,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) } /* Allocate and Initialise AO Subdevice Structures */ - s = dev->subdevices + 1; + s = &dev->subdevices[1]; if (devpriv->s_EeParameters.i_NbrAoChannel) { s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; @@ -1720,7 +1720,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) s->type = COMEDI_SUBD_UNUSED; } /* Allocate and Initialise DI Subdevice Structures */ - s = dev->subdevices + 2; + s = &dev->subdevices[2]; if (devpriv->s_EeParameters.i_NbrDiChannel) { s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; @@ -1738,7 +1738,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) s->type = COMEDI_SUBD_UNUSED; } /* Allocate and Initialise DO Subdevice Structures */ - s = dev->subdevices + 3; + s = &dev->subdevices[3]; if (devpriv->s_EeParameters.i_NbrDoChannel) { s->type = COMEDI_SUBD_DO; s->subdev_flags = @@ -1760,7 +1760,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) } /* Allocate and Initialise Timer Subdevice Structures */ - s = dev->subdevices + 4; + s = &dev->subdevices[4]; if (devpriv->s_EeParameters.i_Timer) { s->type = COMEDI_SUBD_TIMER; s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; @@ -1778,7 +1778,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) } /* Allocate and Initialise TTL */ - s = dev->subdevices + 5; + s = &dev->subdevices[5]; if (this_board->i_NbrTTLChannel) { s->type = COMEDI_SUBD_TTLIO; s->subdev_flags = @@ -1797,7 +1797,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) } /* EEPROM */ - s = dev->subdevices + 6; + s = &dev->subdevices[6]; if (this_board->i_PCIEeprom) { s->type = COMEDI_SUBD_MEMORY; s->subdev_flags = SDF_READABLE | SDF_INTERNAL; -- cgit v0.10.2 From 49433746020e88d15407131bc81a545671622504 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:23:09 -0700 Subject: staging: comedi: hwdrv_APCI1710: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c index 595238f..f9a8937 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c @@ -67,7 +67,7 @@ void i_ADDI_AttachPCI1710(struct comedi_device *dev) return; /* Allocate and Initialise Timer Subdevice Structures */ - s = dev->subdevices + 0; + s = &dev->subdevices[0]; s->type = COMEDI_SUBD_TIMER; s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; @@ -81,7 +81,7 @@ void i_ADDI_AttachPCI1710(struct comedi_device *dev) s->insn_bits = i_APCI1710_InsnBitsTimer; /* Allocate and Initialise DIO Subdevice Structures */ - s = dev->subdevices + 1; + s = &dev->subdevices[1]; s->type = COMEDI_SUBD_DIO; s->subdev_flags = @@ -96,7 +96,7 @@ void i_ADDI_AttachPCI1710(struct comedi_device *dev) s->insn_write = i_APCI1710_InsnWriteDigitalIOChlOnOff; /* Allocate and Initialise Chrono Subdevice Structures */ - s = dev->subdevices + 2; + s = &dev->subdevices[2]; s->type = COMEDI_SUBD_CHRONO; s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; @@ -110,7 +110,7 @@ void i_ADDI_AttachPCI1710(struct comedi_device *dev) s->insn_bits = i_APCI1710_InsnBitsChronoDigitalIO; /* Allocate and Initialise PWM Subdevice Structures */ - s = dev->subdevices + 3; + s = &dev->subdevices[3]; s->type = COMEDI_SUBD_PWM; s->subdev_flags = SDF_WRITEABLE | SDF_READABLE | SDF_GROUND | SDF_COMMON; @@ -125,7 +125,7 @@ void i_ADDI_AttachPCI1710(struct comedi_device *dev) s->insn_bits = i_APCI1710_InsnBitsReadPWMInterrupt; /* Allocate and Initialise TTLIO Subdevice Structures */ - s = dev->subdevices + 4; + s = &dev->subdevices[4]; s->type = COMEDI_SUBD_TTLIO; s->subdev_flags = SDF_WRITEABLE | SDF_READABLE | SDF_GROUND | SDF_COMMON; @@ -139,7 +139,7 @@ void i_ADDI_AttachPCI1710(struct comedi_device *dev) s->insn_read = i_APCI1710_InsnReadTTLIOAllPortValue; /* Allocate and Initialise TOR Subdevice Structures */ - s = dev->subdevices + 5; + s = &dev->subdevices[5]; s->type = COMEDI_SUBD_TOR; s->subdev_flags = SDF_WRITEABLE | SDF_READABLE | SDF_GROUND | SDF_COMMON; @@ -154,7 +154,7 @@ void i_ADDI_AttachPCI1710(struct comedi_device *dev) s->insn_bits = i_APCI1710_InsnBitsGetTorCounterProgressStatusAndValue; /* Allocate and Initialise SSI Subdevice Structures */ - s = dev->subdevices + 6; + s = &dev->subdevices[6]; s->type = COMEDI_SUBD_SSI; s->subdev_flags = SDF_WRITEABLE | SDF_READABLE | SDF_GROUND | SDF_COMMON; @@ -167,7 +167,7 @@ void i_ADDI_AttachPCI1710(struct comedi_device *dev) s->insn_bits = i_APCI1710_InsnBitsSSIDigitalIO; /* Allocate and Initialise PULSEENCODER Subdevice Structures */ - s = dev->subdevices + 7; + s = &dev->subdevices[7]; s->type = COMEDI_SUBD_PULSEENCODER; s->subdev_flags = SDF_WRITEABLE | SDF_READABLE | SDF_GROUND | SDF_COMMON; @@ -181,7 +181,7 @@ void i_ADDI_AttachPCI1710(struct comedi_device *dev) s->insn_read = i_APCI1710_InsnReadInterruptPulseEncoder; /* Allocate and Initialise INCREMENTALCOUNTER Subdevice Structures */ - s = dev->subdevices + 8; + s = &dev->subdevices[8]; s->type = COMEDI_SUBD_INCREMENTALCOUNTER; s->subdev_flags = SDF_WRITEABLE | SDF_READABLE | SDF_GROUND | SDF_COMMON; -- cgit v0.10.2 From ca0fceee36f6a52ecfe1feede1889b3719b62a16 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:23:32 -0700 Subject: staging: comedi: hwdrv_apci3120: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index ffe390c..d61fce0 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -1451,7 +1451,7 @@ void v_APCI3120_Interrupt(int irq, void *d) unsigned short us_TmpValue; unsigned char b_DummyRead; - struct comedi_subdevice *s = dev->subdevices + 0; + struct comedi_subdevice *s = &dev->subdevices[0]; ui_Check = 1; int_daq = inw(dev->iobase + APCI3120_RD_STATUS) & 0xf000; /* get IRQ reasons */ @@ -1656,7 +1656,7 @@ void v_APCI3120_Interrupt(int irq, void *d) int i_APCI3120_InterruptHandleEos(struct comedi_device *dev) { int n_chan, i; - struct comedi_subdevice *s = dev->subdevices + 0; + struct comedi_subdevice *s = &dev->subdevices[0]; int err = 1; n_chan = devpriv->ui_AiNbrofChannels; @@ -1698,7 +1698,7 @@ int i_APCI3120_InterruptHandleEos(struct comedi_device *dev) void v_APCI3120_InterruptDma(int irq, void *d) { struct comedi_device *dev = d; - struct comedi_subdevice *s = dev->subdevices + 0; + struct comedi_subdevice *s = &dev->subdevices[0]; unsigned int next_dma_buf, samplesinbuf; unsigned long low_word, high_word, var; -- cgit v0.10.2 From b272f8cb328c05c093eaa4cb007db9f04ba304c7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:23:53 -0700 Subject: staging: comedi: hwdrv_apci3200: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c index 5aed4a1..f6f5092 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c @@ -3497,7 +3497,7 @@ void v_APCI3200_Interrupt(int irq, void *d) int i_APCI3200_InterruptHandleEos(struct comedi_device *dev) { unsigned int ui_StatusRegister = 0; - struct comedi_subdevice *s = dev->subdevices + 0; + struct comedi_subdevice *s = &dev->subdevices[0]; /* BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ /* comedi_async *async = s->async; */ -- cgit v0.10.2 From 1f6115a4875f3192658e8b7f63e4197cc36aec78 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:24:13 -0700 Subject: staging: comedi: adl_pci6208: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c index 99fbd94..3492ce1 100644 --- a/drivers/staging/comedi/drivers/adl_pci6208.c +++ b/drivers/staging/comedi/drivers/adl_pci6208.c @@ -205,7 +205,7 @@ static int pci6208_attach_pci(struct comedi_device *dev, if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; /* analog output subdevice */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; @@ -215,7 +215,7 @@ static int pci6208_attach_pci(struct comedi_device *dev, s->insn_write = pci6208_ao_winsn; s->insn_read = pci6208_ao_rinsn; - s = dev->subdevices + 1; + s = &dev->subdevices[1]; /* digital input subdevice */ s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; @@ -224,7 +224,7 @@ static int pci6208_attach_pci(struct comedi_device *dev, s->range_table = &range_digital; s->insn_bits = pci6208_di_insn_bits; - s = dev->subdevices + 2; + s = &dev->subdevices[2]; /* digital output subdevice */ s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE; -- cgit v0.10.2 From 630b713b2730dfede5f7ebe3273fae82d8c51bc6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:24:34 -0700 Subject: staging: comedi: adl_pci7296: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci7296.c b/drivers/staging/comedi/drivers/adl_pci7296.c index 67233be..96cfc9c 100644 --- a/drivers/staging/comedi/drivers/adl_pci7296.c +++ b/drivers/staging/comedi/drivers/adl_pci7296.c @@ -121,7 +121,7 @@ static int adl_pci7296_attach_pci(struct comedi_device *dev, return ret; for (i = 0; i < board->nsubdevs; i++) { - s = dev->subdevices + i; + s = &dev->subdevices[i]; ret = subdev_8255_init(dev, s, NULL, dev->iobase + (i * 4)); if (ret) return ret; @@ -142,7 +142,7 @@ static void adl_pci7296_detach(struct comedi_device *dev) if (dev->subdevices) { for (i = 0; i < board->nsubdevs; i++) { - s = dev->subdevices + i; + s = &dev->subdevices[i]; subdev_8255_cleanup(dev, s); } } -- cgit v0.10.2 From 2bac8ab3c348856d701ce7fbbd87622ed400bc65 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:24:52 -0700 Subject: staging: comedi: adl_pci7x3x: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci7x3x.c b/drivers/staging/comedi/drivers/adl_pci7x3x.c index 48b3baa..599714e 100644 --- a/drivers/staging/comedi/drivers/adl_pci7x3x.c +++ b/drivers/staging/comedi/drivers/adl_pci7x3x.c @@ -211,7 +211,7 @@ static int adl_pci7x3x_attach_pci(struct comedi_device *dev, if (board->di_nchan) { nchan = min(board->di_nchan, 32); - s = dev->subdevices + subdev; + s = &dev->subdevices[subdev]; /* Isolated digital inputs 0 to 15/31 */ s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; @@ -226,7 +226,7 @@ static int adl_pci7x3x_attach_pci(struct comedi_device *dev, nchan = board->di_nchan - nchan; if (nchan) { - s = dev->subdevices + subdev; + s = &dev->subdevices[subdev]; /* Isolated digital inputs 32 to 63 */ s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; @@ -244,7 +244,7 @@ static int adl_pci7x3x_attach_pci(struct comedi_device *dev, if (board->do_nchan) { nchan = min(board->do_nchan, 32); - s = dev->subdevices + subdev; + s = &dev->subdevices[subdev]; /* Isolated digital outputs 0 to 15/31 */ s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE; @@ -259,7 +259,7 @@ static int adl_pci7x3x_attach_pci(struct comedi_device *dev, nchan = board->do_nchan - nchan; if (nchan) { - s = dev->subdevices + subdev; + s = &dev->subdevices[subdev]; /* Isolated digital outputs 32 to 63 */ s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE; -- cgit v0.10.2 From b23faec807c2f540b574f713e4a020b1cd8d54bd Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:25:11 -0700 Subject: staging: comedi: adl_pci8164: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c index ac406cf..05e06e7 100644 --- a/drivers/staging/comedi/drivers/adl_pci8164.c +++ b/drivers/staging/comedi/drivers/adl_pci8164.c @@ -231,7 +231,7 @@ static int adl_pci8164_attach_pci(struct comedi_device *dev, if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; s->type = COMEDI_SUBD_PROC; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = 4; @@ -241,7 +241,7 @@ static int adl_pci8164_attach_pci(struct comedi_device *dev, s->insn_read = adl_pci8164_insn_read_msts; s->insn_write = adl_pci8164_insn_write_cmd; - s = dev->subdevices + 1; + s = &dev->subdevices[1]; s->type = COMEDI_SUBD_PROC; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = 4; @@ -251,7 +251,7 @@ static int adl_pci8164_attach_pci(struct comedi_device *dev, s->insn_read = adl_pci8164_insn_read_ssts; s->insn_write = adl_pci8164_insn_write_otp; - s = dev->subdevices + 2; + s = &dev->subdevices[2]; s->type = COMEDI_SUBD_PROC; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = 4; @@ -261,7 +261,7 @@ static int adl_pci8164_attach_pci(struct comedi_device *dev, s->insn_read = adl_pci8164_insn_read_buf0; s->insn_write = adl_pci8164_insn_write_buf0; - s = dev->subdevices + 3; + s = &dev->subdevices[3]; s->type = COMEDI_SUBD_PROC; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = 4; -- cgit v0.10.2 From d1d7b20def05f0278033c9b12d319b6fd735f7b8 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:25:33 -0700 Subject: staging: comedi: adl_pci9111: rename 'subdevice' variable to 's' Rename the variable used for the comedi_subdevice pointer from 'subdevice' to 's'. This is more typical in other comedi drivers and helps when searching with grep. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index a31dae6..92eaf16 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -754,9 +754,9 @@ pci9111_ai_do_cmd_test(struct comedi_device *dev, /* Analog input command */ static int pci9111_ai_do_cmd(struct comedi_device *dev, - struct comedi_subdevice *subdevice) + struct comedi_subdevice *s) { - struct comedi_cmd *async_cmd = &subdevice->async->cmd; + struct comedi_cmd *async_cmd = &s->async->cmd; if (!dev->irq) { comedi_error(dev, @@ -907,7 +907,7 @@ static void pci9111_ai_munge(struct comedi_device *dev, static irqreturn_t pci9111_interrupt(int irq, void *p_device) { struct comedi_device *dev = p_device; - struct comedi_subdevice *subdevice = dev->read_subdev; + struct comedi_subdevice *s = dev->read_subdev; struct comedi_async *async; unsigned long irq_flags; unsigned char intcsr; @@ -918,7 +918,7 @@ static irqreturn_t pci9111_interrupt(int irq, void *p_device) return IRQ_NONE; } - async = subdevice->async; + async = s->async; spin_lock_irqsave(&dev->spinlock, irq_flags); @@ -944,9 +944,9 @@ static irqreturn_t pci9111_interrupt(int irq, void *p_device) spin_unlock_irqrestore(&dev->spinlock, irq_flags); comedi_error(dev, PCI9111_DRIVER_NAME " fifo overflow"); pci9111_interrupt_clear(); - pci9111_ai_cancel(dev, subdevice); + pci9111_ai_cancel(dev, s); async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; - comedi_event(dev, subdevice); + comedi_event(dev, s); return IRQ_HANDLED; } @@ -970,7 +970,7 @@ static irqreturn_t pci9111_interrupt(int irq, void *p_device) if (dev_private->scan_delay < 1) { bytes_written = - cfc_write_array_to_buffer(subdevice, + cfc_write_array_to_buffer(s, dev_private-> ai_bounce_buffer, num_samples * @@ -994,7 +994,7 @@ static irqreturn_t pci9111_interrupt(int irq, void *p_device) bytes_written += cfc_write_array_to_buffer - (subdevice, + (s, dev_private->ai_bounce_buffer + position, to_read * sizeof(short)); @@ -1029,7 +1029,7 @@ static irqreturn_t pci9111_interrupt(int irq, void *p_device) if ((dev_private->stop_counter == 0) && (!dev_private->stop_is_none)) { async->events |= COMEDI_CB_EOA; - pci9111_ai_cancel(dev, subdevice); + pci9111_ai_cancel(dev, s); } /* Very important, otherwise another interrupt request will be inserted @@ -1039,7 +1039,7 @@ static irqreturn_t pci9111_interrupt(int irq, void *p_device) spin_unlock_irqrestore(&dev->spinlock, irq_flags); - comedi_event(dev, subdevice); + comedi_event(dev, s); return IRQ_HANDLED; } @@ -1053,7 +1053,7 @@ static irqreturn_t pci9111_interrupt(int irq, void *p_device) #undef AI_INSN_DEBUG static int pci9111_ai_insn_read(struct comedi_device *dev, - struct comedi_subdevice *subdevice, + struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { int resolution = @@ -1144,7 +1144,7 @@ static int pci9111_ao_insn_read(struct comedi_device *dev, /* Digital inputs */ static int pci9111_di_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *subdevice, + struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { unsigned int bits; @@ -1158,7 +1158,7 @@ static int pci9111_di_insn_bits(struct comedi_device *dev, /* Digital outputs */ static int pci9111_do_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *subdevice, + struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { unsigned int bits; @@ -1169,10 +1169,10 @@ static int pci9111_do_insn_bits(struct comedi_device *dev, data[0] &= PCI9111_DO_MASK; - bits = subdevice->state; + bits = s->state; bits &= ~data[0]; bits |= data[0] & data[1]; - subdevice->state = bits; + s->state = bits; pci9111_do_set_bits(bits); @@ -1247,7 +1247,7 @@ static int pci9111_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct pci_dev *pcidev; - struct comedi_subdevice *subdevice; + struct comedi_subdevice *s; unsigned long io_base, io_range, lcr_io_base, lcr_io_range; int error; const struct pci9111_board *board; @@ -1322,51 +1322,51 @@ static int pci9111_attach(struct comedi_device *dev, if (error) return error; - subdevice = dev->subdevices + 0; - dev->read_subdev = subdevice; + s = dev->subdevices + 0; + dev->read_subdev = s; - subdevice->type = COMEDI_SUBD_AI; - subdevice->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_CMD_READ; + s->type = COMEDI_SUBD_AI; + s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_CMD_READ; /* TODO: Add external multiplexer data */ - /* if (devpriv->usemux) { subdevice->n_chan = devpriv->usemux; } */ - /* else { subdevice->n_chan = this_board->n_aichan; } */ - - subdevice->n_chan = board->ai_channel_nbr; - subdevice->maxdata = board->ai_resolution_mask; - subdevice->len_chanlist = board->ai_channel_nbr; - subdevice->range_table = board->ai_range_list; - subdevice->cancel = pci9111_ai_cancel; - subdevice->insn_read = pci9111_ai_insn_read; - subdevice->do_cmdtest = pci9111_ai_do_cmd_test; - subdevice->do_cmd = pci9111_ai_do_cmd; - subdevice->munge = pci9111_ai_munge; - - subdevice = dev->subdevices + 1; - subdevice->type = COMEDI_SUBD_AO; - subdevice->subdev_flags = SDF_WRITABLE | SDF_COMMON; - subdevice->n_chan = board->ao_channel_nbr; - subdevice->maxdata = board->ao_resolution_mask; - subdevice->len_chanlist = board->ao_channel_nbr; - subdevice->range_table = board->ao_range_list; - subdevice->insn_write = pci9111_ao_insn_write; - subdevice->insn_read = pci9111_ao_insn_read; - - subdevice = dev->subdevices + 2; - subdevice->type = COMEDI_SUBD_DI; - subdevice->subdev_flags = SDF_READABLE; - subdevice->n_chan = PCI9111_DI_CHANNEL_NBR; - subdevice->maxdata = 1; - subdevice->range_table = &range_digital; - subdevice->insn_bits = pci9111_di_insn_bits; - - subdevice = dev->subdevices + 3; - subdevice->type = COMEDI_SUBD_DO; - subdevice->subdev_flags = SDF_READABLE | SDF_WRITABLE; - subdevice->n_chan = PCI9111_DO_CHANNEL_NBR; - subdevice->maxdata = 1; - subdevice->range_table = &range_digital; - subdevice->insn_bits = pci9111_do_insn_bits; + /* if (devpriv->usemux) { s->n_chan = devpriv->usemux; } */ + /* else { s->n_chan = this_board->n_aichan; } */ + + s->n_chan = board->ai_channel_nbr; + s->maxdata = board->ai_resolution_mask; + s->len_chanlist = board->ai_channel_nbr; + s->range_table = board->ai_range_list; + s->cancel = pci9111_ai_cancel; + s->insn_read = pci9111_ai_insn_read; + s->do_cmdtest = pci9111_ai_do_cmd_test; + s->do_cmd = pci9111_ai_do_cmd; + s->munge = pci9111_ai_munge; + + s = dev->subdevices + 1; + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITABLE | SDF_COMMON; + s->n_chan = board->ao_channel_nbr; + s->maxdata = board->ao_resolution_mask; + s->len_chanlist = board->ao_channel_nbr; + s->range_table = board->ao_range_list; + s->insn_write = pci9111_ao_insn_write; + s->insn_read = pci9111_ao_insn_read; + + s = dev->subdevices + 2; + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE; + s->n_chan = PCI9111_DI_CHANNEL_NBR; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = pci9111_di_insn_bits; + + s = dev->subdevices + 3; + s->type = COMEDI_SUBD_DO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = PCI9111_DO_CHANNEL_NBR; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = pci9111_do_insn_bits; dev_private->is_valid = 1; -- cgit v0.10.2 From 573e31af7cb709dad96bb8d9dd7140d3b2f57071 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:25:55 -0700 Subject: staging: comedi: adl_pci9111: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 92eaf16..63d55b0 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -1322,7 +1322,7 @@ static int pci9111_attach(struct comedi_device *dev, if (error) return error; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; dev->read_subdev = s; s->type = COMEDI_SUBD_AI; @@ -1342,7 +1342,7 @@ static int pci9111_attach(struct comedi_device *dev, s->do_cmd = pci9111_ai_do_cmd; s->munge = pci9111_ai_munge; - s = dev->subdevices + 1; + s = &dev->subdevices[1]; s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE | SDF_COMMON; s->n_chan = board->ao_channel_nbr; @@ -1352,7 +1352,7 @@ static int pci9111_attach(struct comedi_device *dev, s->insn_write = pci9111_ao_insn_write; s->insn_read = pci9111_ao_insn_read; - s = dev->subdevices + 2; + s = &dev->subdevices[2]; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; s->n_chan = PCI9111_DI_CHANNEL_NBR; @@ -1360,7 +1360,7 @@ static int pci9111_attach(struct comedi_device *dev, s->range_table = &range_digital; s->insn_bits = pci9111_di_insn_bits; - s = dev->subdevices + 3; + s = &dev->subdevices[3]; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = PCI9111_DO_CHANNEL_NBR; -- cgit v0.10.2 From 17c7ac9144f0733ef91b64599481dfecb7d940fc Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:26:16 -0700 Subject: staging: comedi: adl_pci9118: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index a1f74c2..fdb0f5d 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -837,7 +837,7 @@ static irqreturn_t interrupt_pci9118(int irq, void *d) } } - (devpriv->int_ai_func) (dev, dev->subdevices + 0, int_adstat, + (devpriv->int_ai_func) (dev, &dev->subdevices[0], int_adstat, int_amcc, int_daq); } @@ -2273,7 +2273,7 @@ static int pci9118_attach(struct comedi_device *dev, if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; dev->read_subdev = s; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF; @@ -2294,7 +2294,7 @@ static int pci9118_attach(struct comedi_device *dev, s->munge = pci9118_ai_munge; } - s = dev->subdevices + 1; + s = &dev->subdevices[1]; s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; s->n_chan = this_board->n_aochan; @@ -2304,7 +2304,7 @@ static int pci9118_attach(struct comedi_device *dev, s->insn_write = pci9118_insn_write_ao; s->insn_read = pci9118_insn_read_ao; - s = dev->subdevices + 2; + s = &dev->subdevices[2]; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; s->n_chan = 4; @@ -2314,7 +2314,7 @@ static int pci9118_attach(struct comedi_device *dev, s->io_bits = 0; /* all bits input */ s->insn_bits = pci9118_insn_bits_di; - s = dev->subdevices + 3; + s = &dev->subdevices[3]; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; s->n_chan = 4; -- cgit v0.10.2 From 4fe92e16060e24dcf84730307e925e3b1a4302cd Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:26:36 -0700 Subject: staging: comedi: adq12b: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adq12b.c b/drivers/staging/comedi/drivers/adq12b.c index 6df51c8..0340c9c 100644 --- a/drivers/staging/comedi/drivers/adq12b.c +++ b/drivers/staging/comedi/drivers/adq12b.c @@ -272,7 +272,7 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; /* analog input subdevice */ s->type = COMEDI_SUBD_AI; if (differential) { @@ -294,7 +294,7 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it) the board can handle */ s->insn_read = adq12b_ai_rinsn; - s = dev->subdevices + 1; + s = &dev->subdevices[1]; /* digital input subdevice */ s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; @@ -303,7 +303,7 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->range_table = &range_digital; s->insn_bits = adq12b_di_insn_bits; - s = dev->subdevices + 2; + s = &dev->subdevices[2]; /* digital output subdevice */ s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE; -- cgit v0.10.2 From 5c60f867b1381f53e5d84a1c02a13b6f546cde0b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:26:55 -0700 Subject: staging: comedi: adv_pci1710: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 66bd385..699f267 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -744,7 +744,7 @@ static void interrupt_pci1710_every_sample(void *d) { struct comedi_device *dev = d; struct pci1710_private *devpriv = dev->private; - struct comedi_subdevice *s = dev->subdevices + 0; + struct comedi_subdevice *s = &dev->subdevices[0]; int m; #ifdef PCI171x_PARANOIDCHECK const struct boardtype *this_board = comedi_board(dev); @@ -873,7 +873,7 @@ static void interrupt_pci1710_half_fifo(void *d) struct comedi_device *dev = d; const struct boardtype *this_board = comedi_board(dev); struct pci1710_private *devpriv = dev->private; - struct comedi_subdevice *s = dev->subdevices + 0; + struct comedi_subdevice *s = &dev->subdevices[0]; int m, samplesinbuf; m = inw(dev->iobase + PCI171x_STATUS); @@ -1395,7 +1395,7 @@ static int pci1710_attach(struct comedi_device *dev, subdev = 0; if (this_board->n_aichan) { - s = dev->subdevices + subdev; + s = &dev->subdevices[subdev]; dev->read_subdev = s; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND; @@ -1417,7 +1417,7 @@ static int pci1710_attach(struct comedi_device *dev, } if (this_board->n_aochan) { - s = dev->subdevices + subdev; + s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; s->n_chan = this_board->n_aochan; @@ -1437,7 +1437,7 @@ static int pci1710_attach(struct comedi_device *dev, } if (this_board->n_dichan) { - s = dev->subdevices + subdev; + s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; s->n_chan = this_board->n_dichan; @@ -1450,7 +1450,7 @@ static int pci1710_attach(struct comedi_device *dev, } if (this_board->n_dochan) { - s = dev->subdevices + subdev; + s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; s->n_chan = this_board->n_dochan; @@ -1465,7 +1465,7 @@ static int pci1710_attach(struct comedi_device *dev, } if (this_board->n_counter) { - s = dev->subdevices + subdev; + s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_COUNTER; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = this_board->n_counter; -- cgit v0.10.2 From dd25ab4546631fd806ca1ef2f595d54f6c49a8dc Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:27:15 -0700 Subject: staging: comedi: adv_pci1723: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index cbce06a..df4efc0 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -258,7 +258,7 @@ static int pci1723_attach_pci(struct comedi_device *dev, if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; dev->write_subdev = s; s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; @@ -269,7 +269,7 @@ static int pci1723_attach_pci(struct comedi_device *dev, s->insn_write = pci1723_ao_write_winsn; s->insn_read = pci1723_insn_read_ao; - s = dev->subdevices + 1; + s = &dev->subdevices[1]; s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = 16; -- cgit v0.10.2 From 2b36ab6c6f6931509b0445e8e229162ef004c61e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:27:36 -0700 Subject: staging: comedi: adv_pci_dio: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index a4c1b13..fa5a6a1 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -957,7 +957,7 @@ static int pci1760_attach(struct comedi_device *dev) struct comedi_subdevice *s; int subdev = 0; - s = dev->subdevices + subdev; + s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; s->n_chan = 8; @@ -967,7 +967,7 @@ static int pci1760_attach(struct comedi_device *dev) s->insn_bits = pci1760_insn_bits_di; subdev++; - s = dev->subdevices + subdev; + s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; s->n_chan = 8; @@ -978,7 +978,7 @@ static int pci1760_attach(struct comedi_device *dev) s->insn_bits = pci1760_insn_bits_do; subdev++; - s = dev->subdevices + subdev; + s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_TIMER; s->subdev_flags = SDF_WRITABLE | SDF_LSAMPL; s->n_chan = 2; @@ -987,7 +987,7 @@ static int pci1760_attach(struct comedi_device *dev) /* s->insn_config=pci1760_insn_pwm_cfg; */ subdev++; - s = dev->subdevices + subdev; + s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_COUNTER; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = 8; @@ -1128,21 +1128,21 @@ static int pci_dio_attach_pci(struct comedi_device *dev, subdev = 0; for (i = 0; i < MAX_DI_SUBDEVS; i++) if (this_board->sdi[i].chans) { - s = dev->subdevices + subdev; + s = &dev->subdevices[subdev]; pci_dio_add_di(dev, s, &this_board->sdi[i], subdev); subdev++; } for (i = 0; i < MAX_DO_SUBDEVS; i++) if (this_board->sdo[i].chans) { - s = dev->subdevices + subdev; + s = &dev->subdevices[subdev]; pci_dio_add_do(dev, s, &this_board->sdo[i], subdev); subdev++; } for (i = 0; i < MAX_DIO_SUBDEVG; i++) for (j = 0; j < this_board->sdio[i].regs; j++) { - s = dev->subdevices + subdev; + s = &dev->subdevices[subdev]; subdev_8255_init(dev, s, NULL, dev->iobase + this_board->sdio[i].addr + @@ -1151,7 +1151,7 @@ static int pci_dio_attach_pci(struct comedi_device *dev, } if (this_board->boardid.chans) { - s = dev->subdevices + subdev; + s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_DI; pci_dio_add_di(dev, s, &this_board->boardid, subdev); subdev++; @@ -1159,7 +1159,7 @@ static int pci_dio_attach_pci(struct comedi_device *dev, for (i = 0; i < MAX_8254_SUBDEVS; i++) if (this_board->s8254[i].chans) { - s = dev->subdevices + subdev; + s = &dev->subdevices[subdev]; pci_dio_add_8254(dev, s, &this_board->s8254[i], subdev); subdev++; } @@ -1187,7 +1187,7 @@ static void pci_dio_detach(struct comedi_device *dev) } if (dev->subdevices) { for (i = 0; i < dev->n_subdevices; i++) { - s = dev->subdevices + i; + s = &dev->subdevices[i]; if (s->type == COMEDI_SUBD_DIO) subdev_8255_cleanup(dev, s); s->private = NULL; -- cgit v0.10.2 From a2b7bcac20ca917b481c2ac5941c339d06b6d211 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:28:00 -0700 Subject: staging: comedi: adv_pci_dio: clarify subdevice index in pci1760_attach() The subdevice index numbers are fixed when attaching to a pci1710 card. Remove the subdev variable and just open code the array index numbers. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index fa5a6a1..9c9896d 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -955,9 +955,8 @@ static int pci_dio_reset(struct comedi_device *dev) static int pci1760_attach(struct comedi_device *dev) { struct comedi_subdevice *s; - int subdev = 0; - s = &dev->subdevices[subdev]; + s = &dev->subdevices[0]; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; s->n_chan = 8; @@ -965,9 +964,8 @@ static int pci1760_attach(struct comedi_device *dev) s->len_chanlist = 8; s->range_table = &range_digital; s->insn_bits = pci1760_insn_bits_di; - subdev++; - s = &dev->subdevices[subdev]; + s = &dev->subdevices[1]; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; s->n_chan = 8; @@ -976,18 +974,16 @@ static int pci1760_attach(struct comedi_device *dev) s->range_table = &range_digital; s->state = 0; s->insn_bits = pci1760_insn_bits_do; - subdev++; - s = &dev->subdevices[subdev]; + s = &dev->subdevices[2]; s->type = COMEDI_SUBD_TIMER; s->subdev_flags = SDF_WRITABLE | SDF_LSAMPL; s->n_chan = 2; s->maxdata = 0xffffffff; s->len_chanlist = 2; /* s->insn_config=pci1760_insn_pwm_cfg; */ - subdev++; - s = &dev->subdevices[subdev]; + s = &dev->subdevices[3]; s->type = COMEDI_SUBD_COUNTER; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = 8; @@ -996,7 +992,6 @@ static int pci1760_attach(struct comedi_device *dev) s->insn_read = pci1760_insn_cnt_read; s->insn_write = pci1760_insn_cnt_write; /* s->insn_config=pci1760_insn_cnt_cfg; */ - subdev++; return 0; } -- cgit v0.10.2 From 9e006a70e92a582f61a346e09d2eaa0a55bfc831 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:28:21 -0700 Subject: staging: comedi: adv_pci_dio: remove 'subdev' param from pci_dio_add_*() The subdevice index number is not used in the pci_dio_add_*() functions. Just remove them. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 9c9896d..a3c2241 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -999,8 +999,9 @@ static int pci1760_attach(struct comedi_device *dev) /* ============================================================================== */ -static int pci_dio_add_di(struct comedi_device *dev, struct comedi_subdevice *s, - const struct diosubd_data *d, int subdev) +static int pci_dio_add_di(struct comedi_device *dev, + struct comedi_subdevice *s, + const struct diosubd_data *d) { const struct dio_boardtype *this_board = comedi_board(dev); @@ -1028,8 +1029,9 @@ static int pci_dio_add_di(struct comedi_device *dev, struct comedi_subdevice *s, /* ============================================================================== */ -static int pci_dio_add_do(struct comedi_device *dev, struct comedi_subdevice *s, - const struct diosubd_data *d, int subdev) +static int pci_dio_add_do(struct comedi_device *dev, + struct comedi_subdevice *s, + const struct diosubd_data *d) { const struct dio_boardtype *this_board = comedi_board(dev); @@ -1060,7 +1062,7 @@ static int pci_dio_add_do(struct comedi_device *dev, struct comedi_subdevice *s, */ static int pci_dio_add_8254(struct comedi_device *dev, struct comedi_subdevice *s, - const struct diosubd_data *d, int subdev) + const struct diosubd_data *d) { s->type = COMEDI_SUBD_COUNTER; s->subdev_flags = SDF_WRITABLE | SDF_READABLE; @@ -1124,14 +1126,14 @@ static int pci_dio_attach_pci(struct comedi_device *dev, for (i = 0; i < MAX_DI_SUBDEVS; i++) if (this_board->sdi[i].chans) { s = &dev->subdevices[subdev]; - pci_dio_add_di(dev, s, &this_board->sdi[i], subdev); + pci_dio_add_di(dev, s, &this_board->sdi[i]); subdev++; } for (i = 0; i < MAX_DO_SUBDEVS; i++) if (this_board->sdo[i].chans) { s = &dev->subdevices[subdev]; - pci_dio_add_do(dev, s, &this_board->sdo[i], subdev); + pci_dio_add_do(dev, s, &this_board->sdo[i]); subdev++; } @@ -1148,14 +1150,14 @@ static int pci_dio_attach_pci(struct comedi_device *dev, if (this_board->boardid.chans) { s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_DI; - pci_dio_add_di(dev, s, &this_board->boardid, subdev); + pci_dio_add_di(dev, s, &this_board->boardid); subdev++; } for (i = 0; i < MAX_8254_SUBDEVS; i++) if (this_board->s8254[i].chans) { s = &dev->subdevices[subdev]; - pci_dio_add_8254(dev, s, &this_board->s8254[i], subdev); + pci_dio_add_8254(dev, s, &this_board->s8254[i]); subdev++; } -- cgit v0.10.2 From ef83beae680dc7eae41997c14af6ad7cdaac3175 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:28:42 -0700 Subject: staging: comedi: aio_aio12_8: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/aio_aio12_8.c b/drivers/staging/comedi/drivers/aio_aio12_8.c index c07de3e..8acf60d 100644 --- a/drivers/staging/comedi/drivers/aio_aio12_8.c +++ b/drivers/staging/comedi/drivers/aio_aio12_8.c @@ -221,7 +221,7 @@ static int aio_aio12_8_attach(struct comedi_device *dev, if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; if (board->ai_nchan) { /* Analog input subdevice */ s->type = COMEDI_SUBD_AI; @@ -234,7 +234,7 @@ static int aio_aio12_8_attach(struct comedi_device *dev, s->type = COMEDI_SUBD_UNUSED; } - s = dev->subdevices + 1; + s = &dev->subdevices[1]; if (board->ao_nchan) { /* Analog output subdevice */ s->type = COMEDI_SUBD_AO; @@ -248,14 +248,14 @@ static int aio_aio12_8_attach(struct comedi_device *dev, s->type = COMEDI_SUBD_UNUSED; } - s = dev->subdevices + 2; + s = &dev->subdevices[2]; /* 8255 Digital i/o subdevice */ iobase = dev->iobase + AIO12_8_8255_BASE_REG; ret = subdev_8255_init(dev, s, NULL, iobase); if (ret) return ret; - s = dev->subdevices + 3; + s = &dev->subdevices[3]; /* 8254 counter/timer subdevice */ s->type = COMEDI_SUBD_UNUSED; @@ -268,7 +268,7 @@ static int aio_aio12_8_attach(struct comedi_device *dev, static void aio_aio12_8_detach(struct comedi_device *dev) { if (dev->subdevices) - subdev_8255_cleanup(dev, dev->subdevices + 2); + subdev_8255_cleanup(dev, &dev->subdevices[2]); if (dev->iobase) release_region(dev->iobase, 24); } -- cgit v0.10.2 From 40c4db8b6de1636e2bc9868c092fa0c3af398508 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:29:02 -0700 Subject: staging: comedi: aio_iiro_16: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/aio_iiro_16.c b/drivers/staging/comedi/drivers/aio_iiro_16.c index ba1e3bb..b2cb8b0 100644 --- a/drivers/staging/comedi/drivers/aio_iiro_16.c +++ b/drivers/staging/comedi/drivers/aio_iiro_16.c @@ -112,7 +112,7 @@ static int aio_iiro_16_attach(struct comedi_device *dev, if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_WRITABLE; s->n_chan = 16; @@ -120,7 +120,7 @@ static int aio_iiro_16_attach(struct comedi_device *dev, s->range_table = &range_digital; s->insn_bits = aio_iiro_16_dio_insn_bits_write; - s = dev->subdevices + 1; + s = &dev->subdevices[1]; s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE; s->n_chan = 16; -- cgit v0.10.2 From 6b680f90c3300505a62e456b3c0e56de358f5d9a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:29:25 -0700 Subject: staging: comedi: amplc_dio200: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Use a local variable for the subdevice pointer to keep the line < 80 chars. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 5858892..b7cfc13 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -978,15 +978,15 @@ static irqreturn_t dio200_interrupt(int irq, void *d) { struct comedi_device *dev = d; struct dio200_private *devpriv = dev->private; + struct comedi_subdevice *s; int handled; if (!dev->attached) return IRQ_NONE; if (devpriv->intr_sd >= 0) { - handled = dio200_handle_read_intr(dev, - dev->subdevices + - devpriv->intr_sd); + s = &dev->subdevices[devpriv->intr_sd]; + handled = dio200_handle_read_intr(dev, s); } else { handled = 0; } -- cgit v0.10.2 From 39d37be4113f8c423ab2a3a7af37cd50c802d779 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:29:45 -0700 Subject: staging: comedi: amplc_pc236: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index 52f7575..a957cd8 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -412,7 +412,7 @@ static int pc236_intr_cancel(struct comedi_device *dev, static irqreturn_t pc236_interrupt(int irq, void *d) { struct comedi_device *dev = d; - struct comedi_subdevice *s = dev->subdevices + 1; + struct comedi_subdevice *s = &dev->subdevices[1]; int handled; handled = pc236_intr_check(dev); @@ -464,14 +464,14 @@ static int pc236_common_attach(struct comedi_device *dev, unsigned long iobase, if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; /* digital i/o subdevice (8255) */ ret = subdev_8255_init(dev, s, NULL, iobase); if (ret < 0) { dev_err(dev->class_dev, "error! out of memory!\n"); return ret; } - s = dev->subdevices + 1; + s = &dev->subdevices[1]; dev->read_subdev = s; s->type = COMEDI_SUBD_UNUSED; pc236_intr_disable(dev); @@ -598,7 +598,7 @@ static void pc236_detach(struct comedi_device *dev) if (dev->irq) free_irq(dev->irq, dev); if (dev->subdevices) - subdev_8255_cleanup(dev, dev->subdevices + 0); + subdev_8255_cleanup(dev, &dev->subdevices[0]); if (is_isa_board(thisboard)) { if (dev->iobase) release_region(dev->iobase, PC236_IO_SIZE); -- cgit v0.10.2 From d8029dcf1be06797d75ff53100bf45949d4a2767 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:30:08 -0700 Subject: staging: comedi: amplc_pc263: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index 017e33e..60830cc 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -225,7 +225,7 @@ static int pc263_common_attach(struct comedi_device *dev, unsigned long iobase) if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; /* digital output subdevice */ s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; -- cgit v0.10.2 From e11c07fe386c4aff703ac87c9ec990acdfe12e39 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:30:28 -0700 Subject: staging: comedi: amplc_pci224: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 8bf109e..365f911 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -1375,7 +1375,7 @@ static int pci224_attach_common(struct comedi_device *dev, if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; /* Analog output subdevice. */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE; @@ -1523,7 +1523,7 @@ static void pci224_detach(struct comedi_device *dev) if (dev->subdevices) { struct comedi_subdevice *s; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; /* AO subdevice */ kfree(s->range_table_list); } -- cgit v0.10.2 From 5bf4a7a7081204eca004e04b0da726513f49142c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:30:47 -0700 Subject: staging: comedi: amplc_pci230: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index 66e74bd..4c9f131 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -2838,7 +2838,7 @@ static int pci230_attach_common(struct comedi_device *dev, if (rc) return rc; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; /* analog input subdevice */ s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND; @@ -2855,7 +2855,7 @@ static int pci230_attach_common(struct comedi_device *dev, s->do_cmdtest = &pci230_ai_cmdtest; s->cancel = pci230_ai_cancel; } - s = dev->subdevices + 1; + s = &dev->subdevices[1]; /* analog output subdevice */ if (thisboard->ao_chans > 0) { s->type = COMEDI_SUBD_AO; @@ -2878,7 +2878,7 @@ static int pci230_attach_common(struct comedi_device *dev, } else { s->type = COMEDI_SUBD_UNUSED; } - s = dev->subdevices + 2; + s = &dev->subdevices[2]; /* digital i/o subdevice */ if (thisboard->have_dio) { rc = subdev_8255_init(dev, s, NULL, @@ -2941,7 +2941,7 @@ static void pci230_detach(struct comedi_device *dev) struct pci_dev *pcidev = comedi_to_pci_dev(dev); if (dev->subdevices && thisboard->have_dio) - subdev_8255_cleanup(dev, dev->subdevices + 2); + subdev_8255_cleanup(dev, &dev->subdevices[2]); if (dev->irq) free_irq(dev->irq, dev); if (pcidev) { -- cgit v0.10.2 From 0c2d3aacfe04425a3b95d92d1a0c2fbfec6c14ba Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:31:08 -0700 Subject: staging: comedi: c6xdigio: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/c6xdigio.c b/drivers/staging/comedi/drivers/c6xdigio.c index 41ed857..070037c 100644 --- a/drivers/staging/comedi/drivers/c6xdigio.c +++ b/drivers/staging/comedi/drivers/c6xdigio.c @@ -447,7 +447,7 @@ static int c6xdigio_attach(struct comedi_device *dev, else if (irq == 0) printk(KERN_DEBUG "comedi%d: no irq\n", dev->minor); - s = dev->subdevices + 0; + s = &dev->subdevices[0]; /* pwm output subdevice */ s->type = COMEDI_SUBD_AO; /* Not sure what to put here */ s->subdev_flags = SDF_WRITEABLE; @@ -458,7 +458,7 @@ static int c6xdigio_attach(struct comedi_device *dev, s->maxdata = 500; s->range_table = &range_bipolar10; /* A suitable lie */ - s = dev->subdevices + 1; + s = &dev->subdevices[1]; /* encoder (counter) subdevice */ s->type = COMEDI_SUBD_COUNTER; s->subdev_flags = SDF_READABLE | SDF_LSAMPL; @@ -468,7 +468,7 @@ static int c6xdigio_attach(struct comedi_device *dev, s->maxdata = 0xffffff; s->range_table = &range_unknown; - /* s = dev->subdevices + 2; */ + /* s = &dev->subdevices[2]; */ /* pwm output subdevice */ /* s->type = COMEDI_SUBD_COUNTER; // Not sure what to put here */ /* s->subdev_flags = SDF_WRITEABLE; */ -- cgit v0.10.2 From 3d69288a5f2e25d5205b896038938b7d2bafece4 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:31:27 -0700 Subject: staging: comedi: cb_das16_cs: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 58d4529..a3d53ba 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -478,7 +478,7 @@ static int das16cs_attach(struct comedi_device *dev, if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; dev->read_subdev = s; /* analog input subdevice */ s->type = COMEDI_SUBD_AI; @@ -491,7 +491,7 @@ static int das16cs_attach(struct comedi_device *dev, s->do_cmd = das16cs_ai_cmd; s->do_cmdtest = das16cs_ai_cmdtest; - s = dev->subdevices + 1; + s = &dev->subdevices[1]; /* analog output subdevice */ if (thisboard->n_ao_chans) { s->type = COMEDI_SUBD_AO; @@ -505,7 +505,7 @@ static int das16cs_attach(struct comedi_device *dev, s->type = COMEDI_SUBD_UNUSED; } - s = dev->subdevices + 2; + s = &dev->subdevices[2]; /* digital i/o subdevice */ s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; -- cgit v0.10.2 From e89c61b989229c194d532d4bc4fbe1a8bb55112e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:31:45 -0700 Subject: staging: comedi: cb_pcidas: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index 4b6fb88..4dd87c2 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -1560,7 +1560,7 @@ static int cb_pcidas_attach_pci(struct comedi_device *dev, if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; /* analog input subdevice */ dev->read_subdev = s; s->type = COMEDI_SUBD_AI; @@ -1577,7 +1577,7 @@ static int cb_pcidas_attach_pci(struct comedi_device *dev, s->cancel = cb_pcidas_cancel; /* analog output subdevice */ - s = dev->subdevices + 1; + s = &dev->subdevices[1]; if (thisboard->ao_nchan) { s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND; @@ -1604,14 +1604,14 @@ static int cb_pcidas_attach_pci(struct comedi_device *dev, } /* 8255 */ - s = dev->subdevices + 2; + s = &dev->subdevices[2]; ret = subdev_8255_init(dev, s, NULL, devpriv->pacer_counter_dio + DIO_8255); if (ret) return ret; /* serial EEPROM, */ - s = dev->subdevices + 3; + s = &dev->subdevices[3]; s->type = COMEDI_SUBD_MEMORY; s->subdev_flags = SDF_READABLE | SDF_INTERNAL; s->n_chan = 256; @@ -1619,7 +1619,7 @@ static int cb_pcidas_attach_pci(struct comedi_device *dev, s->insn_read = eeprom_read_insn; /* 8800 caldac */ - s = dev->subdevices + 4; + s = &dev->subdevices[4]; s->type = COMEDI_SUBD_CALIB; s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; s->n_chan = NUM_CHANNELS_8800; @@ -1630,7 +1630,7 @@ static int cb_pcidas_attach_pci(struct comedi_device *dev, caldac_8800_write(dev, i, s->maxdata / 2); /* trim potentiometer */ - s = dev->subdevices + 5; + s = &dev->subdevices[5]; s->type = COMEDI_SUBD_CALIB; s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; if (thisboard->trimpot == AD7376) { @@ -1646,7 +1646,7 @@ static int cb_pcidas_attach_pci(struct comedi_device *dev, cb_pcidas_trimpot_write(dev, i, s->maxdata / 2); /* dac08 caldac */ - s = dev->subdevices + 6; + s = &dev->subdevices[6]; if (thisboard->has_dac08) { s->type = COMEDI_SUBD_CALIB; s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; @@ -1688,7 +1688,7 @@ static void cb_pcidas_detach(struct comedi_device *dev) if (dev->irq) free_irq(dev->irq, dev); if (dev->subdevices) - subdev_8255_cleanup(dev, dev->subdevices + 2); + subdev_8255_cleanup(dev, &dev->subdevices[2]); if (pcidev) { if (devpriv->s5933_config) comedi_pci_disable(pcidev); -- cgit v0.10.2 From e4eb9523efb89dc22f7db02df7495e89fac61416 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:32:04 -0700 Subject: staging: comedi: cb_pcidas64: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 65cbaab..7168883 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -1348,7 +1348,7 @@ static int setup_subdevices(struct comedi_device *dev) if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; /* analog input subdevice */ dev->read_subdev = s; s->type = COMEDI_SUBD_AI; @@ -1379,7 +1379,7 @@ static int setup_subdevices(struct comedi_device *dev) } /* analog output subdevice */ - s = dev->subdevices + 1; + s = &dev->subdevices[1]; if (board(dev)->ao_nchan) { s->type = COMEDI_SUBD_AO; s->subdev_flags = @@ -1401,7 +1401,7 @@ static int setup_subdevices(struct comedi_device *dev) } /* digital input */ - s = dev->subdevices + 2; + s = &dev->subdevices[2]; if (board(dev)->layout == LAYOUT_64XX) { s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; @@ -1414,7 +1414,7 @@ static int setup_subdevices(struct comedi_device *dev) /* digital output */ if (board(dev)->layout == LAYOUT_64XX) { - s = dev->subdevices + 3; + s = &dev->subdevices[3]; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE | SDF_READABLE; s->n_chan = 4; @@ -1425,7 +1425,7 @@ static int setup_subdevices(struct comedi_device *dev) s->type = COMEDI_SUBD_UNUSED; /* 8255 */ - s = dev->subdevices + 4; + s = &dev->subdevices[4]; if (board(dev)->has_8255) { if (board(dev)->layout == LAYOUT_4020) { dio_8255_iobase = @@ -1442,7 +1442,7 @@ static int setup_subdevices(struct comedi_device *dev) s->type = COMEDI_SUBD_UNUSED; /* 8 channel dio for 60xx */ - s = dev->subdevices + 5; + s = &dev->subdevices[5]; if (board(dev)->layout == LAYOUT_60XX) { s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_WRITABLE | SDF_READABLE; @@ -1455,7 +1455,7 @@ static int setup_subdevices(struct comedi_device *dev) s->type = COMEDI_SUBD_UNUSED; /* caldac */ - s = dev->subdevices + 6; + s = &dev->subdevices[6]; s->type = COMEDI_SUBD_CALIB; s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; s->n_chan = 8; @@ -1469,7 +1469,7 @@ static int setup_subdevices(struct comedi_device *dev) caldac_write(dev, i, s->maxdata / 2); /* 2 channel ad8402 potentiometer */ - s = dev->subdevices + 7; + s = &dev->subdevices[7]; if (board(dev)->layout == LAYOUT_64XX) { s->type = COMEDI_SUBD_CALIB; s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; @@ -1483,7 +1483,7 @@ static int setup_subdevices(struct comedi_device *dev) s->type = COMEDI_SUBD_UNUSED; /* serial EEPROM, if present */ - s = dev->subdevices + 8; + s = &dev->subdevices[8]; if (readl(priv(dev)->plx9080_iobase + PLX_CONTROL_REG) & CTL_EECHK) { s->type = COMEDI_SUBD_MEMORY; s->subdev_flags = SDF_READABLE | SDF_INTERNAL; @@ -1494,7 +1494,7 @@ static int setup_subdevices(struct comedi_device *dev) s->type = COMEDI_SUBD_UNUSED; /* user counter subd XXX */ - s = dev->subdevices + 9; + s = &dev->subdevices[9]; s->type = COMEDI_SUBD_UNUSED; return 0; @@ -1847,7 +1847,7 @@ static void detach(struct comedi_device *dev) } } if (dev->subdevices) - subdev_8255_cleanup(dev, dev->subdevices + 4); + subdev_8255_cleanup(dev, &dev->subdevices[4]); if (pcidev) { if (dev->iobase) comedi_pci_disable(pcidev); -- cgit v0.10.2 From 82ec595aa045e2efea7b0f2f50fe62cb82a88176 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:32:23 -0700 Subject: staging: comedi: cb_pcidda: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index c5944e3..ad9f3a3 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -716,7 +716,7 @@ static int cb_pcidda_attach_pci(struct comedi_device *dev, if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; /* analog output subdevice */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; @@ -730,9 +730,9 @@ static int cb_pcidda_attach_pci(struct comedi_device *dev, /* s->do_cmdtest = cb_pcidda_ai_cmdtest; */ /* two 8255 digital io subdevices */ - s = dev->subdevices + 1; + s = &dev->subdevices[1]; subdev_8255_init(dev, s, NULL, devpriv->digitalio); - s = dev->subdevices + 2; + s = &dev->subdevices[2]; subdev_8255_init(dev, s, NULL, devpriv->digitalio + PORT2A); dev_dbg(dev->class_dev, "eeprom:\n"); @@ -756,8 +756,8 @@ static void cb_pcidda_detach(struct comedi_device *dev) struct pci_dev *pcidev = comedi_to_pci_dev(dev); if (dev->subdevices) { - subdev_8255_cleanup(dev, dev->subdevices + 1); - subdev_8255_cleanup(dev, dev->subdevices + 2); + subdev_8255_cleanup(dev, &dev->subdevices[1]); + subdev_8255_cleanup(dev, &dev->subdevices[2]); } if (pcidev) { if (dev->iobase) -- cgit v0.10.2 From fbe09e33f549d803320fc75a8295fa4b803d2024 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:32:42 -0700 Subject: staging: comedi: cb_pcidio: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcidio.c b/drivers/staging/comedi/drivers/cb_pcidio.c index 52c6379..9f406ef 100644 --- a/drivers/staging/comedi/drivers/cb_pcidio.c +++ b/drivers/staging/comedi/drivers/cb_pcidio.c @@ -119,7 +119,7 @@ static int pcidio_attach_pci(struct comedi_device *dev, return ret; for (i = 0; i < board->n_8255; i++) { - s = dev->subdevices + i; + s = &dev->subdevices[i]; ret = subdev_8255_init(dev, s, NULL, dev->iobase + i * 4); if (ret) return ret; @@ -140,7 +140,7 @@ static void pcidio_detach(struct comedi_device *dev) if (dev->subdevices) { for (i = 0; i < board->n_8255; i++) { - s = dev->subdevices + i; + s = &dev->subdevices[i]; subdev_8255_cleanup(dev, s); } } -- cgit v0.10.2 From 13201d88114f485ee6f9e66b81eeb436323089d0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:33:00 -0700 Subject: staging: comedi: cb_pcimdas: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index fa3fd88..9515b69 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -318,7 +318,7 @@ static int cb_pcimdas_attach_pci(struct comedi_device *dev, if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; /* dev->read_subdev=s; */ /* analog input subdevice */ s->type = COMEDI_SUBD_AI; @@ -330,7 +330,7 @@ static int cb_pcimdas_attach_pci(struct comedi_device *dev, /* the board can handle */ s->insn_read = cb_pcimdas_ai_rinsn; - s = dev->subdevices + 1; + s = &dev->subdevices[1]; /* analog output subdevice */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; @@ -341,7 +341,7 @@ static int cb_pcimdas_attach_pci(struct comedi_device *dev, s->insn_write = &cb_pcimdas_ao_winsn; s->insn_read = &cb_pcimdas_ao_rinsn; - s = dev->subdevices + 2; + s = &dev->subdevices[2]; /* digital i/o subdevice */ if (thisboard->has_dio) subdev_8255_init(dev, s, NULL, iobase_8255); -- cgit v0.10.2 From 6807d64d21e0721e9ff8b57c62824f9bcce31a63 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:33:19 -0700 Subject: staging: comedi: cb_pcimdda: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index ea96514..ba9f059 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -176,7 +176,7 @@ static int cb_pcimdda_attach_pci(struct comedi_device *dev, if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; /* analog output subdevice */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE | SDF_READABLE; @@ -186,7 +186,7 @@ static int cb_pcimdda_attach_pci(struct comedi_device *dev, s->insn_write = cb_pcimdda_ao_winsn; s->insn_read = cb_pcimdda_ao_rinsn; - s = dev->subdevices + 1; + s = &dev->subdevices[1]; /* digital i/o subdevice */ ret = subdev_8255_init(dev, s, NULL, dev->iobase + PCIMDDA_8255_BASE_REG); @@ -203,7 +203,7 @@ static void cb_pcimdda_detach(struct comedi_device *dev) struct pci_dev *pcidev = comedi_to_pci_dev(dev); if (dev->subdevices) - subdev_8255_cleanup(dev, dev->subdevices + 1); + subdev_8255_cleanup(dev, &dev->subdevices[1]); if (pcidev) { if (dev->iobase) comedi_pci_disable(pcidev); -- cgit v0.10.2 From 379585ab5cedda27bb919457acc2441a384353d0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:33:38 -0700 Subject: staging: comedi: comedi_bond: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/comedi_bond.c b/drivers/staging/comedi/drivers/comedi_bond.c index 6b516ed..5c768bc 100644 --- a/drivers/staging/comedi/drivers/comedi_bond.c +++ b/drivers/staging/comedi/drivers/comedi_bond.c @@ -321,7 +321,7 @@ static int bonding_attach(struct comedi_device *dev, if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = devpriv->nchans; -- cgit v0.10.2 From 9da5ae29cd92beb8dda6da2ee149ebb593fba7ab Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:33:57 -0700 Subject: staging: comedi: comedi_parport: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/comedi_parport.c b/drivers/staging/comedi/drivers/comedi_parport.c index 2dce9df..c9e40a9 100644 --- a/drivers/staging/comedi/drivers/comedi_parport.c +++ b/drivers/staging/comedi/drivers/comedi_parport.c @@ -277,7 +277,7 @@ static irqreturn_t parport_interrupt(int irq, void *d) { struct comedi_device *dev = d; struct parport_private *devpriv = dev->private; - struct comedi_subdevice *s = dev->subdevices + 3; + struct comedi_subdevice *s = &dev->subdevices[3]; if (!devpriv->enable_irq) return IRQ_NONE; @@ -327,7 +327,7 @@ static int parport_attach(struct comedi_device *dev, return ret; devpriv = dev->private; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = 8; @@ -336,7 +336,7 @@ static int parport_attach(struct comedi_device *dev, s->insn_bits = parport_insn_a; s->insn_config = parport_insn_config_a; - s = dev->subdevices + 1; + s = &dev->subdevices[1]; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; s->n_chan = 5; @@ -344,7 +344,7 @@ static int parport_attach(struct comedi_device *dev, s->range_table = &range_digital; s->insn_bits = parport_insn_b; - s = dev->subdevices + 2; + s = &dev->subdevices[2]; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE; s->n_chan = 4; @@ -352,7 +352,7 @@ static int parport_attach(struct comedi_device *dev, s->range_table = &range_digital; s->insn_bits = parport_insn_c; - s = dev->subdevices + 3; + s = &dev->subdevices[3]; if (irq) { dev->read_subdev = s; s->type = COMEDI_SUBD_DI; -- cgit v0.10.2 From 713e5c35e10215874ae60ef57912f21b31bc3ccc Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:34:16 -0700 Subject: staging: comedi: comedi_test: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c index 8ea9202..b0f0ec5 100644 --- a/drivers/staging/comedi/drivers/comedi_test.c +++ b/drivers/staging/comedi/drivers/comedi_test.c @@ -453,7 +453,7 @@ static int waveform_attach(struct comedi_device *dev, if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; dev->read_subdev = s; /* analog input subdevice */ s->type = COMEDI_SUBD_AI; @@ -467,7 +467,7 @@ static int waveform_attach(struct comedi_device *dev, s->do_cmdtest = waveform_ai_cmdtest; s->cancel = waveform_ai_cancel; - s = dev->subdevices + 1; + s = &dev->subdevices[1]; dev->write_subdev = s; /* analog output subdevice (loopback) */ s->type = COMEDI_SUBD_AO; -- cgit v0.10.2 From b31654fe4b79ee650d12e194016c47e3640f440d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:34:37 -0700 Subject: staging: comedi: contec_pci_dio: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c index def3e7d..178a6a4 100644 --- a/drivers/staging/comedi/drivers/contec_pci_dio.c +++ b/drivers/staging/comedi/drivers/contec_pci_dio.c @@ -87,7 +87,7 @@ static int contec_attach_pci(struct comedi_device *dev, if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; s->n_chan = 16; @@ -95,7 +95,7 @@ static int contec_attach_pci(struct comedi_device *dev, s->range_table = &range_digital; s->insn_bits = contec_di_insn_bits; - s = dev->subdevices + 1; + s = &dev->subdevices[1]; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE; s->n_chan = 16; -- cgit v0.10.2 From b81535777699f6970b10cc16d51fb6f1b96c259e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:34:59 -0700 Subject: staging: comedi: daqboard2000: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index cad559a..39a2b1e 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -804,7 +804,7 @@ static int daqboard2000_attach(struct comedi_device *dev, dev->board_name = this_board->name; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; /* ai subdevice */ s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_GROUND; @@ -813,7 +813,7 @@ static int daqboard2000_attach(struct comedi_device *dev, s->insn_read = daqboard2000_ai_insn_read; s->range_table = &range_daqboard2000_ai; - s = dev->subdevices + 1; + s = &dev->subdevices[1]; /* ao subdevice */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; @@ -823,7 +823,7 @@ static int daqboard2000_attach(struct comedi_device *dev, s->insn_write = daqboard2000_ao_insn_write; s->range_table = &range_daqboard2000_ao; - s = dev->subdevices + 2; + s = &dev->subdevices[2]; result = subdev_8255_init(dev, s, daqboard2000_8255_cb, (unsigned long)(devpriv->daq + 0x40)); @@ -836,7 +836,7 @@ static void daqboard2000_detach(struct comedi_device *dev) struct pci_dev *pcidev = comedi_to_pci_dev(dev); if (dev->subdevices) - subdev_8255_cleanup(dev, dev->subdevices + 2); + subdev_8255_cleanup(dev, &dev->subdevices[2]); if (dev->irq) free_irq(dev->irq, dev); if (devpriv) { -- cgit v0.10.2 From 2add117c2fcbfe9821dd9c97bf76610ed186e767 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:35:24 -0700 Subject: staging: comedi: das08: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 0c69b05..5fd21fa 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -670,7 +670,7 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase) if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; /* ai */ if (thisboard->ai_nbits) { s->type = COMEDI_SUBD_AI; @@ -689,7 +689,7 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase) s->type = COMEDI_SUBD_UNUSED; } - s = dev->subdevices + 1; + s = &dev->subdevices[1]; /* ao */ if (thisboard->ao_nbits) { s->type = COMEDI_SUBD_AO; @@ -704,7 +704,7 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase) s->type = COMEDI_SUBD_UNUSED; } - s = dev->subdevices + 2; + s = &dev->subdevices[2]; /* di */ if (thisboard->di_nchan) { s->type = COMEDI_SUBD_DI; @@ -718,7 +718,7 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase) s->type = COMEDI_SUBD_UNUSED; } - s = dev->subdevices + 3; + s = &dev->subdevices[3]; /* do */ if (thisboard->do_nchan) { s->type = COMEDI_SUBD_DO; @@ -732,7 +732,7 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase) s->type = COMEDI_SUBD_UNUSED; } - s = dev->subdevices + 4; + s = &dev->subdevices[4]; /* 8255 */ if (thisboard->i8255_offset != 0) { subdev_8255_init(dev, s, NULL, (unsigned long)(dev->iobase + @@ -742,7 +742,7 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase) s->type = COMEDI_SUBD_UNUSED; } - s = dev->subdevices + 5; + s = &dev->subdevices[5]; /* 8254 */ if (thisboard->i8254_offset != 0) { s->type = COMEDI_SUBD_COUNTER; @@ -838,7 +838,7 @@ das08_attach(struct comedi_device *dev, struct comedi_devconfig *it) void das08_common_detach(struct comedi_device *dev) { if (dev->subdevices) - subdev_8255_cleanup(dev, dev->subdevices + 4); + subdev_8255_cleanup(dev, &dev->subdevices[4]); } EXPORT_SYMBOL_GPL(das08_common_detach); -- cgit v0.10.2 From 35d10629f19570cd0d9e7b4485f027f300a12d33 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:35:45 -0700 Subject: staging: comedi: das16: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c index 895cc77..2a38915 100644 --- a/drivers/staging/comedi/drivers/das16.c +++ b/drivers/staging/comedi/drivers/das16.c @@ -1268,7 +1268,7 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; dev->read_subdev = s; /* ai */ if (board->ai) { @@ -1300,7 +1300,7 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->type = COMEDI_SUBD_UNUSED; } - s = dev->subdevices + 1; + s = &dev->subdevices[1]; /* ao */ if (board->ao) { s->type = COMEDI_SUBD_AO; @@ -1318,7 +1318,7 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->type = COMEDI_SUBD_UNUSED; } - s = dev->subdevices + 2; + s = &dev->subdevices[2]; /* di */ if (board->di) { s->type = COMEDI_SUBD_DI; @@ -1331,7 +1331,7 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->type = COMEDI_SUBD_UNUSED; } - s = dev->subdevices + 3; + s = &dev->subdevices[3]; /* do */ if (board->do_) { s->type = COMEDI_SUBD_DO; @@ -1346,7 +1346,7 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->type = COMEDI_SUBD_UNUSED; } - s = dev->subdevices + 4; + s = &dev->subdevices[4]; /* 8255 */ if (board->i8255_offset != 0) { subdev_8255_init(dev, s, NULL, (dev->iobase + @@ -1376,7 +1376,7 @@ static void das16_detach(struct comedi_device *dev) das16_reset(dev); if (dev->subdevices) - subdev_8255_cleanup(dev, dev->subdevices + 4); + subdev_8255_cleanup(dev, &dev->subdevices[4]); if (devpriv) { int i; for (i = 0; i < 2; i++) { -- cgit v0.10.2 From 9b7beb661377e4bc8e6fdd02342d94caf51491cd Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:36:03 -0700 Subject: staging: comedi: das16m1: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c index 2009263..7f0668f 100644 --- a/drivers/staging/comedi/drivers/das16m1.c +++ b/drivers/staging/comedi/drivers/das16m1.c @@ -650,7 +650,7 @@ static int das16m1_attach(struct comedi_device *dev, if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; dev->read_subdev = s; /* ai */ s->type = COMEDI_SUBD_AI; @@ -666,7 +666,7 @@ static int das16m1_attach(struct comedi_device *dev, s->cancel = das16m1_cancel; s->poll = das16m1_poll; - s = dev->subdevices + 1; + s = &dev->subdevices[1]; /* di */ s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; @@ -675,7 +675,7 @@ static int das16m1_attach(struct comedi_device *dev, s->range_table = &range_digital; s->insn_bits = das16m1_di_rbits; - s = dev->subdevices + 2; + s = &dev->subdevices[2]; /* do */ s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE | SDF_READABLE; @@ -684,7 +684,7 @@ static int das16m1_attach(struct comedi_device *dev, s->range_table = &range_digital; s->insn_bits = das16m1_do_wbits; - s = dev->subdevices + 3; + s = &dev->subdevices[3]; /* 8255 */ subdev_8255_init(dev, s, NULL, dev->iobase + DAS16M1_82C55); @@ -707,7 +707,7 @@ static int das16m1_attach(struct comedi_device *dev, static void das16m1_detach(struct comedi_device *dev) { if (dev->subdevices) - subdev_8255_cleanup(dev, dev->subdevices + 3); + subdev_8255_cleanup(dev, &dev->subdevices[3]); if (dev->irq) free_irq(dev->irq, dev); if (dev->iobase) { -- cgit v0.10.2 From 2e3d3cf5c7d6c69d6940054645bc2d3d575ab916 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:36:21 -0700 Subject: staging: comedi: das1800: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index 25e7e56..5aca8fb 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -656,7 +656,7 @@ static int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s) /* the guts of the interrupt handler, that is shared with das1800_ai_poll */ static void das1800_ai_handler(struct comedi_device *dev) { - struct comedi_subdevice *s = dev->subdevices + 0; /* analog input subdevice */ + struct comedi_subdevice *s = &dev->subdevices[0]; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; unsigned int status = inb(dev->iobase + DAS1800_STATUS); @@ -1653,7 +1653,7 @@ static int das1800_attach(struct comedi_device *dev, return retval; /* analog input subdevice */ - s = dev->subdevices + 0; + s = &dev->subdevices[0]; dev->read_subdev = s; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND | SDF_CMD_READ; @@ -1670,7 +1670,7 @@ static int das1800_attach(struct comedi_device *dev, s->cancel = das1800_cancel; /* analog out */ - s = dev->subdevices + 1; + s = &dev->subdevices[1]; if (thisboard->ao_ability == 1) { s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; @@ -1683,7 +1683,7 @@ static int das1800_attach(struct comedi_device *dev, } /* di */ - s = dev->subdevices + 2; + s = &dev->subdevices[2]; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; s->n_chan = 4; @@ -1692,7 +1692,7 @@ static int das1800_attach(struct comedi_device *dev, s->insn_bits = das1800_di_rbits; /* do */ - s = dev->subdevices + 3; + s = &dev->subdevices[3]; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE | SDF_READABLE; s->n_chan = thisboard->do_n_chan; -- cgit v0.10.2 From 92cfef5d90148f1a91fba528971ed6ae39b1c14b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:36:41 -0700 Subject: staging: comedi: das6402: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/das6402.c b/drivers/staging/comedi/drivers/das6402.c index e3afcfa..e134c46 100644 --- a/drivers/staging/comedi/drivers/das6402.c +++ b/drivers/staging/comedi/drivers/das6402.c @@ -152,7 +152,7 @@ static void das6402_setcounter(struct comedi_device *dev) static irqreturn_t intr_handler(int irq, void *d) { struct comedi_device *dev = d; - struct comedi_subdevice *s = dev->subdevices; + struct comedi_subdevice *s = &dev->subdevices[0]; if (!dev->attached || devpriv->das6402_ignoreirq) { dev_warn(dev->class_dev, "BUG: spurious interrupt\n"); @@ -312,7 +312,7 @@ static int das6402_attach(struct comedi_device *dev, return ret; /* ai subdevice */ - s = dev->subdevices + 0; + s = &dev->subdevices[0]; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_GROUND; s->n_chan = 8; -- cgit v0.10.2 From 77d2f7c24725e3caa82492dd3d1cbd466b8a0abf Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:38:11 -0700 Subject: staging: comedi: das800: 'dev->subdevices + 0' is already known There is no need to calculate the subdevice for the call to das800_cancel. The variable 's' in this function is set to the 'dev->read_subdev' which is the same as 'dev->subdevices + 0'. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c index a0959a5..834054d 100644 --- a/drivers/staging/comedi/drivers/das800.c +++ b/drivers/staging/comedi/drivers/das800.c @@ -435,7 +435,7 @@ static irqreturn_t das800_interrupt(int irq, void *d) if (fifo_overflow) { spin_unlock_irqrestore(&dev->spinlock, irq_flags); comedi_error(dev, "DAS800 FIFO overflow"); - das800_cancel(dev, dev->subdevices + 0); + das800_cancel(dev, s); async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; comedi_event(dev, s); async->events = 0; -- cgit v0.10.2 From f20dce3848c8335dc80600093ce5c22ddadc2b93 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:38:30 -0700 Subject: staging: comedi: das800: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c index 834054d..8e89101 100644 --- a/drivers/staging/comedi/drivers/das800.c +++ b/drivers/staging/comedi/drivers/das800.c @@ -517,7 +517,7 @@ static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it) return ret; /* analog input subdevice */ - s = dev->subdevices + 0; + s = &dev->subdevices[0]; dev->read_subdev = s; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ; @@ -531,7 +531,7 @@ static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->cancel = das800_cancel; /* di */ - s = dev->subdevices + 1; + s = &dev->subdevices[1]; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; s->n_chan = 3; @@ -540,7 +540,7 @@ static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->insn_bits = das800_di_rbits; /* do */ - s = dev->subdevices + 2; + s = &dev->subdevices[2]; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE | SDF_READABLE; s->n_chan = 4; -- cgit v0.10.2 From 2930d0ba656d035d01a2cac37b6fe1250df16c28 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:38:49 -0700 Subject: staging: comedi: dmm32at: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c index 7107f59..0703ca5 100644 --- a/drivers/staging/comedi/drivers/dmm32at.c +++ b/drivers/staging/comedi/drivers/dmm32at.c @@ -825,7 +825,7 @@ static int dmm32at_attach(struct comedi_device *dev, if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; dev->read_subdev = s; /* analog input subdevice */ s->type = COMEDI_SUBD_AI; @@ -841,7 +841,7 @@ static int dmm32at_attach(struct comedi_device *dev, s->do_cmdtest = dmm32at_ai_cmdtest; s->cancel = dmm32at_ai_cancel; - s = dev->subdevices + 1; + s = &dev->subdevices[1]; /* analog output subdevice */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; @@ -851,7 +851,7 @@ static int dmm32at_attach(struct comedi_device *dev, s->insn_write = dmm32at_ao_winsn; s->insn_read = dmm32at_ao_rinsn; - s = dev->subdevices + 2; + s = &dev->subdevices[2]; /* digital i/o subdevice */ /* get access to the DIO regs */ -- cgit v0.10.2 From 52a07cde495ccca9212b3f725b606c75e8d89a2e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:39:13 -0700 Subject: staging: comedi: dt2801: fix access to 2nd dio subdevice Only 4 subdevices are allocated by this driver. The 2nd dio subdevice is 'dev->subdevice + 3' not '... + 4'. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/dt2801.c b/drivers/staging/comedi/drivers/dt2801.c index d332269..b6481bc 100644 --- a/drivers/staging/comedi/drivers/dt2801.c +++ b/drivers/staging/comedi/drivers/dt2801.c @@ -532,7 +532,7 @@ static int dt2801_dio_insn_bits(struct comedi_device *dev, { int which = 0; - if (s == dev->subdevices + 4) + if (s == dev->subdevices + 3) which = 1; if (data[0]) { @@ -555,7 +555,7 @@ static int dt2801_dio_insn_config(struct comedi_device *dev, { int which = 0; - if (s == dev->subdevices + 4) + if (s == dev->subdevices + 3) which = 1; /* configure */ -- cgit v0.10.2 From 4b812ac50811e8afbe2d0fd0404de02f5a2532ad Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:39:32 -0700 Subject: staging: comedi: dt2801: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/dt2801.c b/drivers/staging/comedi/drivers/dt2801.c index b6481bc..c59a652 100644 --- a/drivers/staging/comedi/drivers/dt2801.c +++ b/drivers/staging/comedi/drivers/dt2801.c @@ -532,7 +532,7 @@ static int dt2801_dio_insn_bits(struct comedi_device *dev, { int which = 0; - if (s == dev->subdevices + 3) + if (s == &dev->subdevices[3]) which = 1; if (data[0]) { @@ -555,7 +555,7 @@ static int dt2801_dio_insn_config(struct comedi_device *dev, { int which = 0; - if (s == dev->subdevices + 3) + if (s == &dev->subdevices[3]) which = 1; /* configure */ @@ -636,7 +636,7 @@ havetype: dev->board_name = boardtype.name; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; /* ai subdevice */ s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_GROUND; @@ -652,7 +652,7 @@ havetype: s->range_table = ai_range_lkup(boardtype.adrangetype, it->options[3]); s->insn_read = dt2801_ai_insn_read; - s++; + s = &dev->subdevices[1]; /* ao subdevice */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; @@ -664,7 +664,7 @@ havetype: s->insn_read = dt2801_ao_insn_read; s->insn_write = dt2801_ao_insn_write; - s++; + s = &dev->subdevices[2]; /* 1st digital subdevice */ s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; @@ -674,7 +674,7 @@ havetype: s->insn_bits = dt2801_dio_insn_bits; s->insn_config = dt2801_dio_insn_config; - s++; + s = &dev->subdevices[3]; /* 2nd digital subdevice */ s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; -- cgit v0.10.2 From 4ea498964a9168a17bc61183c400308f11eaee8a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:39:51 -0700 Subject: staging: comedi: dt2811: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/dt2811.c b/drivers/staging/comedi/drivers/dt2811.c index 290b933..d3a8c1a 100644 --- a/drivers/staging/comedi/drivers/dt2811.c +++ b/drivers/staging/comedi/drivers/dt2811.c @@ -510,7 +510,7 @@ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it) break; } - s = dev->subdevices + 0; + s = &dev->subdevices[0]; /* initialize the ADC subdevice */ s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_GROUND; @@ -530,7 +530,7 @@ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it) break; } - s = dev->subdevices + 1; + s = &dev->subdevices[1]; /* ao subdevice */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; @@ -542,7 +542,7 @@ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->range_type_list[0] = dac_range_types[devpriv->dac_range[0]]; devpriv->range_type_list[1] = dac_range_types[devpriv->dac_range[1]]; - s = dev->subdevices + 2; + s = &dev->subdevices[2]; /* di subdevice */ s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; @@ -551,7 +551,7 @@ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->maxdata = 1; s->range_table = &range_digital; - s = dev->subdevices + 3; + s = &dev->subdevices[3]; /* do subdevice */ s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE; -- cgit v0.10.2 From 92af10e1e210f1b9772d98715bb76950137423e2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:40:09 -0700 Subject: staging: comedi: dt2814: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/dt2814.c b/drivers/staging/comedi/drivers/dt2814.c index 2e39ebe..ce5d837 100644 --- a/drivers/staging/comedi/drivers/dt2814.c +++ b/drivers/staging/comedi/drivers/dt2814.c @@ -247,7 +247,7 @@ static irqreturn_t dt2814_interrupt(int irq, void *d) return IRQ_HANDLED; } - s = dev->subdevices + 0; + s = &dev->subdevices[0]; hi = inb(dev->iobase + DT2814_DATA); lo = inb(dev->iobase + DT2814_DATA); @@ -346,7 +346,7 @@ static int dt2814_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret < 0) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; dev->read_subdev = s; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ; -- cgit v0.10.2 From 76c40c470dd0cd6560e3362f087a52830581a767 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:40:29 -0700 Subject: staging: comedi: dt2815: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/dt2815.c b/drivers/staging/comedi/drivers/dt2815.c index 45b20be..b9692ef 100644 --- a/drivers/staging/comedi/drivers/dt2815.c +++ b/drivers/staging/comedi/drivers/dt2815.c @@ -185,7 +185,7 @@ static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (alloc_private(dev, sizeof(struct dt2815_private)) < 0) return -ENOMEM; - s = dev->subdevices; + s = &dev->subdevices[0]; /* ao subdevice */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; -- cgit v0.10.2 From d784e4c33f93ceacf609b796aa53e33fc17ce8fe Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:40:49 -0700 Subject: staging: comedi: dt2817: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/dt2817.c b/drivers/staging/comedi/drivers/dt2817.c index beba044..502e42e 100644 --- a/drivers/staging/comedi/drivers/dt2817.c +++ b/drivers/staging/comedi/drivers/dt2817.c @@ -141,7 +141,7 @@ static int dt2817_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; s->n_chan = 32; s->type = COMEDI_SUBD_DIO; -- cgit v0.10.2 From e1d7cf9c9dd7e08390d836e9f9c8b4851c0b1df0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:41:08 -0700 Subject: staging: comedi: dt282x: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c index 1f0b40e..b7c43c8 100644 --- a/drivers/staging/comedi/drivers/dt282x.c +++ b/drivers/staging/comedi/drivers/dt282x.c @@ -312,7 +312,7 @@ static void dt282x_ao_dma_interrupt(struct comedi_device *dev) void *ptr; int size; int i; - struct comedi_subdevice *s = dev->subdevices + 1; + struct comedi_subdevice *s = &dev->subdevices[1]; outw(devpriv->supcsr | DT2821_CLRDMADNE, dev->iobase + DT2821_SUPCSR); @@ -345,7 +345,7 @@ static void dt282x_ai_dma_interrupt(struct comedi_device *dev) int size; int i; int ret; - struct comedi_subdevice *s = dev->subdevices; + struct comedi_subdevice *s = &dev->subdevices[0]; outw(devpriv->supcsr | DT2821_CLRDMADNE, dev->iobase + DT2821_SUPCSR); @@ -457,8 +457,8 @@ static irqreturn_t dt282x_interrupt(int irq, void *d) return IRQ_HANDLED; } - s = dev->subdevices + 0; - s_ao = dev->subdevices + 1; + s = &dev->subdevices[0]; + s_ao = &dev->subdevices[1]; adcsr = inw(dev->iobase + DT2821_ADCSR); dacsr = inw(dev->iobase + DT2821_DACSR); supcsr = inw(dev->iobase + DT2821_SUPCSR); @@ -1275,7 +1275,7 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; dev->read_subdev = s; /* ai subdevice */ @@ -1294,7 +1294,7 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it) opt_ai_range_lkup(boardtype.ispgl, it->options[opt_ai_range]); devpriv->ad_2scomp = it->options[opt_ai_twos]; - s++; + s = &dev->subdevices[1]; s->n_chan = boardtype.dachan; if (s->n_chan) { @@ -1320,7 +1320,7 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->type = COMEDI_SUBD_UNUSED; } - s++; + s = &dev->subdevices[2]; /* dio subsystem */ s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; -- cgit v0.10.2 From 9263cd67b95e289e8fb48731eabee15e2b559103 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:41:29 -0700 Subject: staging: comedi: dt3000: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index 3476cda..3a940a2 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -330,7 +330,7 @@ static irqreturn_t dt3k_interrupt(int irq, void *d) if (!dev->attached) return IRQ_NONE; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; status = readw(devpriv->io_addr + DPR_Intr_Flag); #ifdef DEBUG debug_intr_flags(status); @@ -842,7 +842,7 @@ static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - s = dev->subdevices; + s = &dev->subdevices[0]; dev->read_subdev = s; /* ai subdevice */ @@ -857,7 +857,7 @@ static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->do_cmdtest = dt3k_ai_cmdtest; s->cancel = dt3k_ai_cancel; - s++; + s = &dev->subdevices[1]; /* ao subsystem */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; @@ -868,7 +868,7 @@ static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->len_chanlist = 1; s->range_table = &range_bipolar10; - s++; + s = &dev->subdevices[2]; /* dio subsystem */ s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; @@ -879,7 +879,7 @@ static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->len_chanlist = 8; s->range_table = &range_digital; - s++; + s = &dev->subdevices[3]; /* mem subsystem */ s->type = COMEDI_SUBD_MEMORY; s->subdev_flags = SDF_READABLE; @@ -890,7 +890,7 @@ static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->range_table = &range_unknown; #if 0 - s++; + s = &dev->subdevices[4]; /* proc subsystem */ s->type = COMEDI_SUBD_PROC; #endif -- cgit v0.10.2 From 3a2078914e00dff94ab132176ad9857fb6eeefb3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:42:02 -0700 Subject: staging: comedi: dt9812: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c index 40821c7..bc6f409 100644 --- a/drivers/staging/comedi/drivers/dt9812.c +++ b/drivers/staging/comedi/drivers/dt9812.c @@ -1041,7 +1041,7 @@ static int dt9812_attach(struct comedi_device *dev, struct comedi_devconfig *it) return ret; /* digital input subdevice */ - s = dev->subdevices + 0; + s = &dev->subdevices[0]; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; s->n_chan = 0; @@ -1050,7 +1050,7 @@ static int dt9812_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->insn_read = &dt9812_di_rinsn; /* digital output subdevice */ - s = dev->subdevices + 1; + s = &dev->subdevices[1]; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITEABLE; s->n_chan = 0; @@ -1059,7 +1059,7 @@ static int dt9812_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->insn_write = &dt9812_do_winsn; /* analog input subdevice */ - s = dev->subdevices + 2; + s = &dev->subdevices[2]; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_GROUND; s->n_chan = 0; @@ -1068,7 +1068,7 @@ static int dt9812_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->insn_read = &dt9812_ai_rinsn; /* analog output subdevice */ - s = dev->subdevices + 3; + s = &dev->subdevices[3]; s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITEABLE; s->n_chan = 0; -- cgit v0.10.2 From 1b39406b3ec9fb58e5577e7266562dd9a7816949 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:42:24 -0700 Subject: staging: comedi: dyna_pci10xx: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index 9d55aa9..6f612be 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -208,7 +208,7 @@ static int dyna_pci10xx_attach_pci(struct comedi_device *dev, return ret; /* analog input */ - s = dev->subdevices + 0; + s = &dev->subdevices[0]; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; s->n_chan = 16; @@ -218,7 +218,7 @@ static int dyna_pci10xx_attach_pci(struct comedi_device *dev, s->insn_read = dyna_pci10xx_insn_read_ai; /* analog output */ - s = dev->subdevices + 1; + s = &dev->subdevices[1]; s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; s->n_chan = 16; @@ -228,7 +228,7 @@ static int dyna_pci10xx_attach_pci(struct comedi_device *dev, s->insn_write = dyna_pci10xx_insn_write_ao; /* digital input */ - s = dev->subdevices + 2; + s = &dev->subdevices[2]; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE | SDF_GROUND; s->n_chan = 16; @@ -238,7 +238,7 @@ static int dyna_pci10xx_attach_pci(struct comedi_device *dev, s->insn_bits = dyna_pci10xx_di_insn_bits; /* digital output */ - s = dev->subdevices + 3; + s = &dev->subdevices[3]; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE | SDF_GROUND; s->n_chan = 16; -- cgit v0.10.2 From 6fc01d32a2b9e0ac2879e69b2d15caf4ad50c5f7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:42:42 -0700 Subject: staging: comedi: fl512: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/fl512.c b/drivers/staging/comedi/drivers/fl512.c index d1da809..ae8e8f4 100644 --- a/drivers/staging/comedi/drivers/fl512.c +++ b/drivers/staging/comedi/drivers/fl512.c @@ -140,7 +140,7 @@ static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it) * this if the definitions of the supdevices, 2 have been defined */ /* Analog indput */ - s = dev->subdevices + 0; + s = &dev->subdevices[0]; /* define subdevice as Analog In */ s->type = COMEDI_SUBD_AI; /* you can read it from userspace */ @@ -156,7 +156,7 @@ static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it) printk(KERN_INFO "comedi: fl512: subdevice 0 initialized\n"); /* Analog output */ - s = dev->subdevices + 1; + s = &dev->subdevices[1]; /* define subdevice as Analog OUT */ s->type = COMEDI_SUBD_AO; /* you can write it from userspace */ -- cgit v0.10.2 From 2de13f1bac495eb354a442963dfc1eb5e7d5b134 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:43:20 -0700 Subject: staging: comedi: gsc_hpdi: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index 79f5808..5d3fa71 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -436,7 +436,7 @@ static int setup_subdevices(struct comedi_device *dev) if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; /* analog input subdevice */ dev->read_subdev = s; /* dev->write_subdev = s; */ -- cgit v0.10.2 From 27f7f1002faae4034f86dd9d28ff8ecb4b8926ed Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:43:46 -0700 Subject: staging: comedi: icp_multi: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index b10ebdb..73fe8a3 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -931,7 +931,7 @@ static int icp_multi_attach(struct comedi_device *dev, subdev = 0; if (this_board->n_aichan) { - s = dev->subdevices + subdev; + s = &dev->subdevices[subdev]; dev->read_subdev = s; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND; @@ -946,7 +946,7 @@ static int icp_multi_attach(struct comedi_device *dev, } if (this_board->n_aochan) { - s = dev->subdevices + subdev; + s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; s->n_chan = this_board->n_aochan; @@ -959,7 +959,7 @@ static int icp_multi_attach(struct comedi_device *dev, } if (this_board->n_dichan) { - s = dev->subdevices + subdev; + s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; s->n_chan = this_board->n_dichan; @@ -972,7 +972,7 @@ static int icp_multi_attach(struct comedi_device *dev, } if (this_board->n_dochan) { - s = dev->subdevices + subdev; + s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE | SDF_READABLE; s->n_chan = this_board->n_dochan; @@ -986,7 +986,7 @@ static int icp_multi_attach(struct comedi_device *dev, } if (this_board->n_ctrs) { - s = dev->subdevices + subdev; + s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_COUNTER; s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; s->n_chan = this_board->n_ctrs; -- cgit v0.10.2 From 35fcaeb87d14c2385dac6ef1520e136f288d1bd6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:44:06 -0700 Subject: staging: comedi: ii_pci20kc: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ii_pci20kc.c b/drivers/staging/comedi/drivers/ii_pci20kc.c index 0f9cfe6..65ff1c9 100644 --- a/drivers/staging/comedi/drivers/ii_pci20kc.c +++ b/drivers/staging/comedi/drivers/ii_pci20kc.c @@ -224,7 +224,7 @@ static int pci20xxx_attach(struct comedi_device *dev, dev->minor, devpriv->ioaddr); for (i = 0; i < PCI20000_MODULES; i++) { - s = dev->subdevices + i; + s = &dev->subdevices[i]; id = readb(devpriv->ioaddr + (i + 1) * PCI20000_OFFSET); s->private = devpriv->subdev_private + i; sdp = s->private; @@ -259,7 +259,7 @@ static int pci20xxx_attach(struct comedi_device *dev, } /* initialize struct pci20xxx_private */ - pci20xxx_dio_init(dev, dev->subdevices + PCI20000_MODULES); + pci20xxx_dio_init(dev, &dev->subdevices[PCI20000_MODULES]); return 1; } -- cgit v0.10.2 From 30c4d3b862aa97c52a180c458f471e21a2e4db23 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:44:26 -0700 Subject: staging: comedi: ke_counter: rename 'subdevice' variable to 's' Rename the variable used for the comedi_subdevice pointer from 'subdevice' to 's'. This is more typical in other comedi drivers and helps when searching with grep. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c index a24e932..a2d0bb4 100644 --- a/drivers/staging/comedi/drivers/ke_counter.c +++ b/drivers/staging/comedi/drivers/ke_counter.c @@ -125,7 +125,7 @@ static int cnt_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) { const struct cnt_board_struct *board; - struct comedi_subdevice *subdevice; + struct comedi_subdevice *s; int ret; comedi_set_hw_dev(dev, &pcidev->dev); @@ -145,15 +145,15 @@ static int cnt_attach_pci(struct comedi_device *dev, if (ret) return ret; - subdevice = dev->subdevices + 0; - dev->read_subdev = subdevice; + s = dev->subdevices + 0; + dev->read_subdev = s; - subdevice->type = COMEDI_SUBD_COUNTER; - subdevice->subdev_flags = SDF_READABLE /* | SDF_COMMON */ ; - subdevice->n_chan = board->cnt_channel_nbr; - subdevice->maxdata = (1 << board->cnt_bits) - 1; - subdevice->insn_read = cnt_rinsn; - subdevice->insn_write = cnt_winsn; + s->type = COMEDI_SUBD_COUNTER; + s->subdev_flags = SDF_READABLE /* | SDF_COMMON */ ; + s->n_chan = board->cnt_channel_nbr; + s->maxdata = (1 << board->cnt_bits) - 1; + s->insn_read = cnt_rinsn; + s->insn_write = cnt_winsn; /* select 20MHz clock */ outb(3, dev->iobase + 248); -- cgit v0.10.2 From bce27067e50e799fdada532d440d087eec6a571c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:44:44 -0700 Subject: staging: comedi: ke_counter: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c index a2d0bb4..e867b72 100644 --- a/drivers/staging/comedi/drivers/ke_counter.c +++ b/drivers/staging/comedi/drivers/ke_counter.c @@ -145,7 +145,7 @@ static int cnt_attach_pci(struct comedi_device *dev, if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; dev->read_subdev = s; s->type = COMEDI_SUBD_COUNTER; -- cgit v0.10.2 From 8aaf2717d9e8328b1ee04c9bdb68091a0a7c5fdc Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:45:05 -0700 Subject: staging: comedi: me4000: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 9a8258e..050f0e4 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -1410,7 +1410,7 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) { unsigned int tmp; struct comedi_device *dev = dev_id; - struct comedi_subdevice *s = dev->subdevices; + struct comedi_subdevice *s = &dev->subdevices[0]; struct me4000_ai_context *ai_context = &info->ai_context; int i; int c = 0; @@ -2017,7 +2017,7 @@ static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it) Analog input subdevice ========================================================================*/ - s = dev->subdevices + 0; + s = &dev->subdevices[0]; if (thisboard->ai.count) { s->type = COMEDI_SUBD_AI; @@ -2055,7 +2055,7 @@ static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it) Analog output subdevice ========================================================================*/ - s = dev->subdevices + 1; + s = &dev->subdevices[1]; if (thisboard->ao.count) { s->type = COMEDI_SUBD_AO; @@ -2073,7 +2073,7 @@ static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it) Digital I/O subdevice ========================================================================*/ - s = dev->subdevices + 2; + s = &dev->subdevices[2]; if (thisboard->dio.count) { s->type = COMEDI_SUBD_DIO; @@ -2100,7 +2100,7 @@ static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it) Counter subdevice ========================================================================*/ - s = dev->subdevices + 3; + s = &dev->subdevices[3]; if (thisboard->cnt.count) { s->type = COMEDI_SUBD_COUNTER; -- cgit v0.10.2 From bc1acb209e77e698182bb167f49b5763211f4010 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:45:26 -0700 Subject: staging: comedi: me_daq: rename 'subdevice' variable to 's' Rename the variable used for the comedi_subdevice pointer from 'subdevice' to 's'. This is more typical in other comedi drivers and helps when searching with grep. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 8c6f8b9..b028eb8 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -341,7 +341,7 @@ static int me_dio_insn_bits(struct comedi_device *dev, /* Analog instant input */ static int me_ai_insn_read(struct comedi_device *dev, - struct comedi_subdevice *subdevice, + struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { unsigned short value; @@ -435,7 +435,7 @@ static int me_ai_do_cmd_test(struct comedi_device *dev, /* Analog input command */ static int me_ai_do_cmd(struct comedi_device *dev, - struct comedi_subdevice *subdevice) + struct comedi_subdevice *s) { return 0; } @@ -643,7 +643,7 @@ static struct pci_dev *me_find_pci_dev(struct comedi_device *dev, static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct pci_dev *pci_device; - struct comedi_subdevice *subdevice; + struct comedi_subdevice *s; struct me_board *board; resource_size_t plx_regbase_tmp; unsigned long plx_regbase_size_tmp; @@ -758,38 +758,38 @@ static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (error) return error; - subdevice = dev->subdevices + 0; - subdevice->type = COMEDI_SUBD_AI; - subdevice->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_CMD_READ; - subdevice->n_chan = board->ai_channel_nbr; - subdevice->maxdata = board->ai_resolution_mask; - subdevice->len_chanlist = board->ai_channel_nbr; - subdevice->range_table = board->ai_range_list; - subdevice->cancel = me_ai_cancel; - subdevice->insn_read = me_ai_insn_read; - subdevice->do_cmdtest = me_ai_do_cmd_test; - subdevice->do_cmd = me_ai_do_cmd; - - subdevice = dev->subdevices + 1; - subdevice->type = COMEDI_SUBD_AO; - subdevice->subdev_flags = SDF_WRITEABLE | SDF_COMMON; - subdevice->n_chan = board->ao_channel_nbr; - subdevice->maxdata = board->ao_resolution_mask; - subdevice->len_chanlist = board->ao_channel_nbr; - subdevice->range_table = board->ao_range_list; - subdevice->insn_read = me_ao_insn_read; - subdevice->insn_write = me_ao_insn_write; - - subdevice = dev->subdevices + 2; - subdevice->type = COMEDI_SUBD_DIO; - subdevice->subdev_flags = SDF_READABLE | SDF_WRITEABLE; - subdevice->n_chan = board->dio_channel_nbr; - subdevice->maxdata = 1; - subdevice->len_chanlist = board->dio_channel_nbr; - subdevice->range_table = &range_digital; - subdevice->insn_bits = me_dio_insn_bits; - subdevice->insn_config = me_dio_insn_config; - subdevice->io_bits = 0; + s = dev->subdevices + 0; + s->type = COMEDI_SUBD_AI; + s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_CMD_READ; + s->n_chan = board->ai_channel_nbr; + s->maxdata = board->ai_resolution_mask; + s->len_chanlist = board->ai_channel_nbr; + s->range_table = board->ai_range_list; + s->cancel = me_ai_cancel; + s->insn_read = me_ai_insn_read; + s->do_cmdtest = me_ai_do_cmd_test; + s->do_cmd = me_ai_do_cmd; + + s = dev->subdevices + 1; + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITEABLE | SDF_COMMON; + s->n_chan = board->ao_channel_nbr; + s->maxdata = board->ao_resolution_mask; + s->len_chanlist = board->ao_channel_nbr; + s->range_table = board->ao_range_list; + s->insn_read = me_ao_insn_read; + s->insn_write = me_ao_insn_write; + + s = dev->subdevices + 2; + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITEABLE; + s->n_chan = board->dio_channel_nbr; + s->maxdata = 1; + s->len_chanlist = board->dio_channel_nbr; + s->range_table = &range_digital; + s->insn_bits = me_dio_insn_bits; + s->insn_config = me_dio_insn_config; + s->io_bits = 0; printk(KERN_INFO "comedi%d: " ME_DRIVER_NAME " attached.\n", dev->minor); -- cgit v0.10.2 From f6e5602710ca71fd7084dc923c6ed22892df20c7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:45:45 -0700 Subject: staging: comedi: me_daq: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index b028eb8..c68c407 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -758,7 +758,7 @@ static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (error) return error; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_CMD_READ; s->n_chan = board->ai_channel_nbr; @@ -770,7 +770,7 @@ static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->do_cmdtest = me_ai_do_cmd_test; s->do_cmd = me_ai_do_cmd; - s = dev->subdevices + 1; + s = &dev->subdevices[1]; s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITEABLE | SDF_COMMON; s->n_chan = board->ao_channel_nbr; @@ -780,7 +780,7 @@ static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->insn_read = me_ao_insn_read; s->insn_write = me_ao_insn_write; - s = dev->subdevices + 2; + s = &dev->subdevices[2]; s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITEABLE; s->n_chan = board->dio_channel_nbr; -- cgit v0.10.2 From 283fd0b2ac1de771255bdeb8749440d7488219a0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:46:07 -0700 Subject: staging: comedi: mpc624: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/mpc624.c b/drivers/staging/comedi/drivers/mpc624.c index b928b67..f8b7fae 100644 --- a/drivers/staging/comedi/drivers/mpc624.c +++ b/drivers/staging/comedi/drivers/mpc624.c @@ -353,7 +353,7 @@ static int mpc624_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_DIFF; s->n_chan = 8; -- cgit v0.10.2 From e49b26e779cce2a5e73b7433d9edcbd157f5a470 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:46:26 -0700 Subject: staging: comedi: mpc8260cpm: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/mpc8260cpm.c b/drivers/staging/comedi/drivers/mpc8260cpm.c index a7fda8f..c0c3329 100644 --- a/drivers/staging/comedi/drivers/mpc8260cpm.c +++ b/drivers/staging/comedi/drivers/mpc8260cpm.c @@ -137,7 +137,7 @@ static int mpc8260cpm_attach(struct comedi_device *dev, return ret; for (i = 0; i < 4; i++) { - s = dev->subdevices + i; + s = &dev->subdevices[i]; s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = 32; -- cgit v0.10.2 From 1b348f0594ec31b974cd8082dd5f1e4b5f3aa2db Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:46:47 -0700 Subject: staging: comedi: multiq3: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/multiq3.c b/drivers/staging/comedi/drivers/multiq3.c index eccbe1f..4625cb4 100644 --- a/drivers/staging/comedi/drivers/multiq3.c +++ b/drivers/staging/comedi/drivers/multiq3.c @@ -204,8 +204,10 @@ static int multiq3_encoder_insn_read(struct comedi_device *dev, static void encoder_reset(struct comedi_device *dev) { + struct comedi_subdevice *s = &dev->subdevices[4]; int chan; - for (chan = 0; chan < dev->subdevices[4].n_chan; chan++) { + + for (chan = 0; chan < s->n_chan; chan++) { int control = MULTIQ3_CONTROL_MUST | MULTIQ3_AD_MUX_EN | (chan << 3); outw(control, dev->iobase + MULTIQ3_CONTROL); @@ -258,7 +260,7 @@ static int multiq3_attach(struct comedi_device *dev, if (result < 0) return result; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; /* ai subdevice */ s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_GROUND; @@ -267,7 +269,7 @@ static int multiq3_attach(struct comedi_device *dev, s->maxdata = 0x1fff; s->range_table = &range_bipolar5; - s = dev->subdevices + 1; + s = &dev->subdevices[1]; /* ao subdevice */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; @@ -277,7 +279,7 @@ static int multiq3_attach(struct comedi_device *dev, s->maxdata = 0xfff; s->range_table = &range_bipolar5; - s = dev->subdevices + 2; + s = &dev->subdevices[2]; /* di subdevice */ s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; @@ -286,7 +288,7 @@ static int multiq3_attach(struct comedi_device *dev, s->maxdata = 1; s->range_table = &range_digital; - s = dev->subdevices + 3; + s = &dev->subdevices[3]; /* do subdevice */ s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE; @@ -296,7 +298,7 @@ static int multiq3_attach(struct comedi_device *dev, s->range_table = &range_digital; s->state = 0; - s = dev->subdevices + 4; + s = &dev->subdevices[4]; /* encoder (counter) subdevice */ s->type = COMEDI_SUBD_COUNTER; s->subdev_flags = SDF_READABLE | SDF_LSAMPL; -- cgit v0.10.2 From 3d30dca5738c87bc4c61d9530893b122e6c6a89f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:47:06 -0700 Subject: staging: comedi: ni_6527: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index a80c52f..cfebd0b 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -212,7 +212,7 @@ static int ni6527_do_insn_bits(struct comedi_device *dev, static irqreturn_t ni6527_interrupt(int irq, void *d) { struct comedi_device *dev = d; - struct comedi_subdevice *s = dev->subdevices + 2; + struct comedi_subdevice *s = &dev->subdevices[2]; unsigned int status; status = readb(devpriv->mite->daq_io_addr + Change_Status); @@ -393,7 +393,7 @@ static int ni6527_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; s->n_chan = 24; @@ -402,7 +402,7 @@ static int ni6527_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->insn_config = ni6527_di_insn_config; s->insn_bits = ni6527_di_insn_bits; - s = dev->subdevices + 1; + s = &dev->subdevices[1]; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = 24; @@ -410,7 +410,7 @@ static int ni6527_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->maxdata = 1; s->insn_bits = ni6527_do_insn_bits; - s = dev->subdevices + 2; + s = &dev->subdevices[2]; dev->read_subdev = s; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE | SDF_CMD_READ; -- cgit v0.10.2 From a9c6f0bb2c06c5bdbb16c7f063811e977ce04892 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:47:24 -0700 Subject: staging: comedi: ni_65xx: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index bce39f1..f4c4233 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -478,7 +478,7 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev, static irqreturn_t ni_65xx_interrupt(int irq, void *d) { struct comedi_device *dev = d; - struct comedi_subdevice *s = dev->subdevices + 2; + struct comedi_subdevice *s = &dev->subdevices[2]; unsigned int status; status = readb(private(dev)->mite->daq_io_addr + Change_Status); @@ -678,7 +678,7 @@ static int ni_65xx_attach(struct comedi_device *dev, if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; if (board(dev)->num_di_ports) { s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; @@ -696,7 +696,7 @@ static int ni_65xx_attach(struct comedi_device *dev, s->type = COMEDI_SUBD_UNUSED; } - s = dev->subdevices + 1; + s = &dev->subdevices[1]; if (board(dev)->num_do_ports) { s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; @@ -713,7 +713,7 @@ static int ni_65xx_attach(struct comedi_device *dev, s->type = COMEDI_SUBD_UNUSED; } - s = dev->subdevices + 2; + s = &dev->subdevices[2]; if (board(dev)->num_dio_ports) { s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; @@ -737,7 +737,7 @@ static int ni_65xx_attach(struct comedi_device *dev, s->type = COMEDI_SUBD_UNUSED; } - s = dev->subdevices + 3; + s = &dev->subdevices[3]; dev->read_subdev = s; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE | SDF_CMD_READ; @@ -791,10 +791,13 @@ static void ni_65xx_detach(struct comedi_device *dev) if (dev->irq) free_irq(dev->irq, dev); if (private(dev)) { + struct comedi_subdevice *s; unsigned i; + for (i = 0; i < dev->n_subdevices; ++i) { - kfree(dev->subdevices[i].private); - dev->subdevices[i].private = NULL; + s = &dev->subdevices[i]; + kfree(s->private); + s->private = NULL; } if (private(dev)->mite) mite_unsetup(private(dev)->mite); -- cgit v0.10.2 From 41e862f3ab234349023e90bf2461977f31073a32 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:47:44 -0700 Subject: staging: comedi: ni_660x: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 5e863ff..6bd5b55 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -985,7 +985,7 @@ static irqreturn_t ni_660x_interrupt(int irq, void *d) spin_lock_irqsave(&private(dev)->interrupt_lock, flags); smp_mb(); for (i = 0; i < ni_660x_num_counters(dev); ++i) { - s = dev->subdevices + NI_660X_GPCT_SUBDEV(i); + s = &dev->subdevices[NI_660X_GPCT_SUBDEV(i)]; ni_660x_handle_gpct_interrupt(dev, s); } spin_unlock_irqrestore(&private(dev)->interrupt_lock, flags); @@ -1097,11 +1097,11 @@ static int ni_660x_attach(struct comedi_device *dev, if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; /* Old GENERAL-PURPOSE COUNTER/TIME (GPCT) subdevice, no longer used */ s->type = COMEDI_SUBD_UNUSED; - s = dev->subdevices + NI_660X_DIO_SUBDEV; + s = &dev->subdevices[NI_660X_DIO_SUBDEV]; /* DIGITAL I/O SUBDEVICE */ s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; @@ -1124,7 +1124,7 @@ static int ni_660x_attach(struct comedi_device *dev, if (private(dev)->counter_dev == NULL) return -ENOMEM; for (i = 0; i < NI_660X_MAX_NUM_COUNTERS; ++i) { - s = dev->subdevices + NI_660X_GPCT_SUBDEV(i); + s = &dev->subdevices[NI_660X_GPCT_SUBDEV(i)]; if (i < ni_660x_num_counters(dev)) { s->type = COMEDI_SUBD_COUNTER; s->subdev_flags = -- cgit v0.10.2 From fc041c20105ad3c4e58905e912eb191dfbc5664d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:48:03 -0700 Subject: staging: comedi: ni_670x: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c index 9c57618..cdb36b8 100644 --- a/drivers/staging/comedi/drivers/ni_670x.c +++ b/drivers/staging/comedi/drivers/ni_670x.c @@ -247,7 +247,7 @@ static int ni_670x_attach(struct comedi_device *dev, if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; /* analog output subdevice */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; @@ -271,7 +271,7 @@ static int ni_670x_attach(struct comedi_device *dev, s->insn_write = &ni_670x_ao_winsn; s->insn_read = &ni_670x_ao_rinsn; - s = dev->subdevices + 1; + s = &dev->subdevices[1]; /* digital i/o subdevice */ s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; @@ -298,7 +298,7 @@ static void ni_670x_detach(struct comedi_device *dev) struct comedi_subdevice *s; if (dev->n_subdevices) { - s = dev->subdevices + 0; + s = &dev->subdevices[0]; if (s) kfree(s->range_table_list); } -- cgit v0.10.2 From ca3caabbb192fa8b1faef17830dff12cb1d0fb72 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:48:20 -0700 Subject: staging: comedi: ni_at_a2150: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c index b53a428..5895d4d 100644 --- a/drivers/staging/comedi/drivers/ni_at_a2150.c +++ b/drivers/staging/comedi/drivers/ni_at_a2150.c @@ -832,7 +832,7 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it) return ret; /* analog input subdevice */ - s = dev->subdevices + 0; + s = &dev->subdevices[0]; dev->read_subdev = s; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_OTHER | SDF_CMD_READ; -- cgit v0.10.2 From 66c5beee8f8de1a952192c8afe4d7708edbaa328 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:48:38 -0700 Subject: staging: comedi: ni_at_ao: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_at_ao.c b/drivers/staging/comedi/drivers/ni_at_ao.c index 62c8c44..93938ce 100644 --- a/drivers/staging/comedi/drivers/ni_at_ao.c +++ b/drivers/staging/comedi/drivers/ni_at_ao.c @@ -358,7 +358,7 @@ static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; /* analog output subdevice */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; @@ -371,7 +371,7 @@ static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->insn_write = &atao_ao_winsn; s->insn_read = &atao_ao_rinsn; - s = dev->subdevices + 1; + s = &dev->subdevices[1]; /* digital i/o subdevice */ s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; @@ -381,7 +381,7 @@ static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->insn_bits = atao_dio_insn_bits; s->insn_config = atao_dio_insn_config; - s = dev->subdevices + 2; + s = &dev->subdevices[2]; /* caldac subdevice */ s->type = COMEDI_SUBD_CALIB; s->subdev_flags = SDF_WRITABLE | SDF_INTERNAL; @@ -390,7 +390,7 @@ static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->insn_read = atao_calib_insn_read; s->insn_write = atao_calib_insn_write; - s = dev->subdevices + 3; + s = &dev->subdevices[3]; /* eeprom subdevice */ /* s->type=COMEDI_SUBD_EEPROM; */ s->type = COMEDI_SUBD_UNUSED; -- cgit v0.10.2 From 3f507ce1ac0f7a6f5f205162d5c1db1524dfb162 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:48:58 -0700 Subject: staging: comedi: ni_atmio16d: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_atmio16d.c b/drivers/staging/comedi/drivers/ni_atmio16d.c index 2c78d3d..4108cbf 100644 --- a/drivers/staging/comedi/drivers/ni_atmio16d.c +++ b/drivers/staging/comedi/drivers/ni_atmio16d.c @@ -234,7 +234,7 @@ static void reset_atmio16d(struct comedi_device *dev) static irqreturn_t atmio16d_interrupt(int irq, void *d) { struct comedi_device *dev = d; - struct comedi_subdevice *s = dev->subdevices + 0; + struct comedi_subdevice *s = &dev->subdevices[0]; comedi_buf_put(s->async, inw(dev->iobase + AD_FIFO_REG)); @@ -724,7 +724,7 @@ static int atmio16d_attach(struct comedi_device *dev, devpriv->dac1_coding = it->options[12]; /* setup sub-devices */ - s = dev->subdevices + 0; + s = &dev->subdevices[0]; dev->read_subdev = s; /* ai subdevice */ s->type = COMEDI_SUBD_AI; @@ -749,7 +749,7 @@ static int atmio16d_attach(struct comedi_device *dev, } /* ao subdevice */ - s++; + s = &dev->subdevices[1]; s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; s->n_chan = 2; @@ -775,7 +775,7 @@ static int atmio16d_attach(struct comedi_device *dev, } /* Digital I/O */ - s++; + s = &dev->subdevices[2]; s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_WRITABLE | SDF_READABLE; s->n_chan = 8; @@ -785,7 +785,7 @@ static int atmio16d_attach(struct comedi_device *dev, s->range_table = &range_digital; /* 8255 subdevice */ - s++; + s = &dev->subdevices[3]; if (board->has_8255) subdev_8255_init(dev, s, NULL, dev->iobase); else @@ -793,7 +793,7 @@ static int atmio16d_attach(struct comedi_device *dev, /* don't yet know how to deal with counter/timers */ #if 0 - s++; + s = &dev->subdevices[4]; /* do */ s->type = COMEDI_SUBD_TIMER; s->n_chan = 0; @@ -807,9 +807,12 @@ static int atmio16d_attach(struct comedi_device *dev, static void atmio16d_detach(struct comedi_device *dev) { const struct atmio16_board_t *board = comedi_board(dev); + struct comedi_subdevice *s; - if (dev->subdevices && board->has_8255) - subdev_8255_cleanup(dev, dev->subdevices + 3); + if (dev->subdevices && board->has_8255) { + s = &dev->subdevices[3]; + subdev_8255_cleanup(dev, s); + } if (dev->irq) free_irq(dev->irq, dev); reset_atmio16d(dev); -- cgit v0.10.2 From fe2e334a334d032b3c60c47a5a98429ee6d84a53 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:49:16 -0700 Subject: staging: comedi: ni_daq_700: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 83016b4..7355860 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -121,7 +121,7 @@ static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it) return ret; /* DAQCard-700 dio */ - s = dev->subdevices + 0; + s = &dev->subdevices[0]; s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = 16; -- cgit v0.10.2 From 06e915e2ac55afb4989da4fb212150aa67a369ca Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:49:34 -0700 Subject: staging: comedi: ni_daq_dio24: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_daq_dio24.c b/drivers/staging/comedi/drivers/ni_daq_dio24.c index e27cae0..5f713c9 100644 --- a/drivers/staging/comedi/drivers/ni_daq_dio24.c +++ b/drivers/staging/comedi/drivers/ni_daq_dio24.c @@ -164,7 +164,7 @@ static int dio24_attach(struct comedi_device *dev, struct comedi_devconfig *it) return ret; /* 8255 dio */ - s = dev->subdevices + 0; + s = &dev->subdevices[0]; subdev_8255_init(dev, s, NULL, dev->iobase); return 0; @@ -172,8 +172,12 @@ static int dio24_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void dio24_detach(struct comedi_device *dev) { - if (dev->subdevices) - subdev_8255_cleanup(dev, dev->subdevices + 0); + struct comedi_subdevice *s; + + if (dev->subdevices) { + s = &dev->subdevices[0]; + subdev_8255_cleanup(dev, s); + } if (thisboard->bustype != pcmcia_bustype && dev->iobase) release_region(dev->iobase, DIO24_SIZE); if (dev->irq) -- cgit v0.10.2 From c65e3be19a9c256ce88f057241f5a168aa3bff70 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:49:58 -0700 Subject: staging: comedi: ni_labpc: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index ab8b787..65d5dfc 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -628,7 +628,7 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, return ret; /* analog input subdevice */ - s = dev->subdevices + 0; + s = &dev->subdevices[0]; dev->read_subdev = s; s->type = COMEDI_SUBD_AI; s->subdev_flags = @@ -643,7 +643,7 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, s->cancel = labpc_cancel; /* analog output */ - s = dev->subdevices + 1; + s = &dev->subdevices[1]; if (thisboard->has_ao) { /* * Could provide command support, except it only has a @@ -670,7 +670,7 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, } /* 8255 dio */ - s = dev->subdevices + 2; + s = &dev->subdevices[2]; /* if board uses io memory we have to give a custom callback * function to the 8255 driver */ if (thisboard->memory_mapped_io) @@ -680,7 +680,7 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, subdev_8255_init(dev, s, NULL, dev->iobase + DIO_BASE_REG); /* calibration subdevices for boards that have one */ - s = dev->subdevices + 3; + s = &dev->subdevices[3]; if (thisboard->register_layout == labpc_1200_layout) { s->type = COMEDI_SUBD_CALIB; s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; @@ -695,7 +695,7 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, s->type = COMEDI_SUBD_UNUSED; /* EEPROM */ - s = dev->subdevices + 4; + s = &dev->subdevices[4]; if (thisboard->register_layout == labpc_1200_layout) { s->type = COMEDI_SUBD_MEMORY; s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; @@ -809,8 +809,12 @@ static int labpc_find_device(struct comedi_device *dev, int bus, int slot) void labpc_common_detach(struct comedi_device *dev) { - if (dev->subdevices) - subdev_8255_cleanup(dev, dev->subdevices + 2); + struct comedi_subdevice *s; + + if (dev->subdevices) { + s = &dev->subdevices[2]; + subdev_8255_cleanup(dev, s); + } #ifdef CONFIG_ISA_DMA_API /* only free stuff if it has been allocated by _attach */ kfree(devpriv->dma_buffer); -- cgit v0.10.2 From f9cd92eb81ea5edea0fb3d0f778a5aef35532a31 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:50:19 -0700 Subject: staging: comedi: ni_mio_common: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index cf0e0d14..68f3bdd 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -872,7 +872,7 @@ static irqreturn_t ni_E_interrupt(int irq, void *d) #ifdef PCIDMA static void ni_sync_ai_dma(struct comedi_device *dev) { - struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV; + struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV]; unsigned long flags; spin_lock_irqsave(&devpriv->mite_channel_lock, flags); @@ -884,7 +884,7 @@ static void ni_sync_ai_dma(struct comedi_device *dev) static void mite_handle_b_linkc(struct mite_struct *mite, struct comedi_device *dev) { - struct comedi_subdevice *s = dev->subdevices + NI_AO_SUBDEV; + struct comedi_subdevice *s = &dev->subdevices[NI_AO_SUBDEV]; unsigned long flags; spin_lock_irqsave(&devpriv->mite_channel_lock, flags); @@ -942,7 +942,7 @@ static void ni_handle_eos(struct comedi_device *dev, struct comedi_subdevice *s) static void shutdown_ai_command(struct comedi_device *dev) { - struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV; + struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV]; #ifdef PCIDMA ni_ai_drain_dma(dev); @@ -984,8 +984,9 @@ static void handle_gpct_interrupt(struct comedi_device *dev, unsigned short counter_index) { #ifdef PCIDMA - struct comedi_subdevice *s = - dev->subdevices + NI_GPCT_SUBDEV(counter_index); + struct comedi_subdevice *s; + + s = &dev->subdevices[NI_GPCT_SUBDEV(counter_index)]; ni_tio_handle_interrupt(&devpriv->counter_dev->counters[counter_index], s); @@ -1018,7 +1019,7 @@ static void ack_a_interrupt(struct comedi_device *dev, unsigned short a_status) static void handle_a_interrupt(struct comedi_device *dev, unsigned short status, unsigned ai_mite_status) { - struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV; + struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV]; /* 67xx boards don't have ai subdevice, but their gpct0 might generate an a interrupt */ if (s->type == COMEDI_SUBD_UNUSED) @@ -1150,7 +1151,7 @@ static void ack_b_interrupt(struct comedi_device *dev, unsigned short b_status) static void handle_b_interrupt(struct comedi_device *dev, unsigned short b_status, unsigned ao_mite_status) { - struct comedi_subdevice *s = dev->subdevices + NI_AO_SUBDEV; + struct comedi_subdevice *s = &dev->subdevices[NI_AO_SUBDEV]; /* unsigned short ack=0; */ #ifdef DEBUG_INTERRUPT printk("ni_mio_common: interrupt: b_status=%04x m1_status=%08x\n", @@ -1422,7 +1423,7 @@ static void ni_ai_fifo_read(struct comedi_device *dev, static void ni_handle_fifo_half_full(struct comedi_device *dev) { int n; - struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV; + struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV]; n = boardtype.ai_fifo_depth / 2; @@ -1470,7 +1471,7 @@ static int ni_ai_drain_dma(struct comedi_device *dev) */ static void ni_handle_fifo_dregs(struct comedi_device *dev) { - struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV; + struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV]; short data[2]; u32 dl; short fifo_empty; @@ -1534,7 +1535,7 @@ static void ni_handle_fifo_dregs(struct comedi_device *dev) static void get_last_sample_611x(struct comedi_device *dev) { - struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV; + struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV]; short data; u32 dl; @@ -1551,7 +1552,7 @@ static void get_last_sample_611x(struct comedi_device *dev) static void get_last_sample_6143(struct comedi_device *dev) { - struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV; + struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV]; short data; u32 dl; @@ -1598,7 +1599,7 @@ static void ni_ai_munge(struct comedi_device *dev, struct comedi_subdevice *s, static int ni_ai_setup_MITE_dma(struct comedi_device *dev) { - struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV; + struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV]; int retval; unsigned long flags; @@ -1637,7 +1638,7 @@ static int ni_ai_setup_MITE_dma(struct comedi_device *dev) static int ni_ao_setup_MITE_dma(struct comedi_device *dev) { - struct comedi_subdevice *s = dev->subdevices + NI_AO_SUBDEV; + struct comedi_subdevice *s = &dev->subdevices[NI_AO_SUBDEV]; int retval; unsigned long flags; @@ -3852,7 +3853,7 @@ static int ni_cdio_cancel(struct comedi_device *dev, struct comedi_subdevice *s) static void handle_cdio_interrupt(struct comedi_device *dev) { unsigned cdio_status; - struct comedi_subdevice *s = dev->subdevices + NI_DIO_SUBDEV; + struct comedi_subdevice *s = &dev->subdevices[NI_DIO_SUBDEV]; #ifdef PCIDMA unsigned long flags; #endif @@ -4101,13 +4102,17 @@ static int ni_serial_sw_readwrite8(struct comedi_device *dev, static void mio_common_detach(struct comedi_device *dev) { + struct comedi_subdevice *s; + if (dev->private) { if (devpriv->counter_dev) { ni_gpct_device_destroy(devpriv->counter_dev); } } - if (dev->subdevices && boardtype.has_8255) - subdev_8255_cleanup(dev, dev->subdevices + NI_8255_DIO_SUBDEV); + if (dev->subdevices && boardtype.has_8255) { + s = &dev->subdevices[NI_8255_DIO_SUBDEV]; + subdev_8255_cleanup(dev, s); + } } static void init_ao_67xx(struct comedi_device *dev, struct comedi_subdevice *s) @@ -4417,7 +4422,7 @@ static int ni_E_init(struct comedi_device *dev, struct comedi_devconfig *it) /* analog input subdevice */ - s = dev->subdevices + NI_AI_SUBDEV; + s = &dev->subdevices[NI_AI_SUBDEV]; dev->read_subdev = s; if (boardtype.n_adchan) { s->type = COMEDI_SUBD_AI; @@ -4449,7 +4454,7 @@ static int ni_E_init(struct comedi_device *dev, struct comedi_devconfig *it) /* analog output subdevice */ - s = dev->subdevices + NI_AO_SUBDEV; + s = &dev->subdevices[NI_AO_SUBDEV]; if (boardtype.n_aochan) { s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE | SDF_DEGLITCH | SDF_GROUND; @@ -4488,7 +4493,7 @@ static int ni_E_init(struct comedi_device *dev, struct comedi_devconfig *it) /* digital i/o subdevice */ - s = dev->subdevices + NI_DIO_SUBDEV; + s = &dev->subdevices[NI_DIO_SUBDEV]; s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_WRITABLE | SDF_READABLE; s->maxdata = 1; @@ -4516,7 +4521,7 @@ static int ni_E_init(struct comedi_device *dev, struct comedi_devconfig *it) } /* 8255 device */ - s = dev->subdevices + NI_8255_DIO_SUBDEV; + s = &dev->subdevices[NI_8255_DIO_SUBDEV]; if (boardtype.has_8255) { subdev_8255_init(dev, s, ni_8255_callback, (unsigned long)dev); } else { @@ -4524,11 +4529,11 @@ static int ni_E_init(struct comedi_device *dev, struct comedi_devconfig *it) } /* formerly general purpose counter/timer device, but no longer used */ - s = dev->subdevices + NI_UNUSED_SUBDEV; + s = &dev->subdevices[NI_UNUSED_SUBDEV]; s->type = COMEDI_SUBD_UNUSED; /* calibration subdevice -- ai and ao */ - s = dev->subdevices + NI_CALIBRATION_SUBDEV; + s = &dev->subdevices[NI_CALIBRATION_SUBDEV]; s->type = COMEDI_SUBD_CALIB; if (boardtype.reg_type & ni_reg_m_series_mask) { /* internal PWM analog output used for AI nonlinearity calibration */ @@ -4551,7 +4556,7 @@ static int ni_E_init(struct comedi_device *dev, struct comedi_devconfig *it) } /* EEPROM */ - s = dev->subdevices + NI_EEPROM_SUBDEV; + s = &dev->subdevices[NI_EEPROM_SUBDEV]; s->type = COMEDI_SUBD_MEMORY; s->subdev_flags = SDF_READABLE | SDF_INTERNAL; s->maxdata = 0xff; @@ -4564,7 +4569,7 @@ static int ni_E_init(struct comedi_device *dev, struct comedi_devconfig *it) } /* PFI */ - s = dev->subdevices + NI_PFI_DIO_SUBDEV; + s = &dev->subdevices[NI_PFI_DIO_SUBDEV]; s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; if (boardtype.reg_type & ni_reg_m_series_mask) { @@ -4586,7 +4591,7 @@ static int ni_E_init(struct comedi_device *dev, struct comedi_devconfig *it) ni_set_bits(dev, IO_Bidirection_Pin_Register, ~0, 0); /* cs5529 calibration adc */ - s = dev->subdevices + NI_CS5529_CALIBRATION_SUBDEV; + s = &dev->subdevices[NI_CS5529_CALIBRATION_SUBDEV]; if (boardtype.reg_type & ni_reg_67xx_mask) { s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_INTERNAL; @@ -4602,7 +4607,7 @@ static int ni_E_init(struct comedi_device *dev, struct comedi_devconfig *it) } /* Serial */ - s = dev->subdevices + NI_SERIAL_SUBDEV; + s = &dev->subdevices[NI_SERIAL_SUBDEV]; s->type = COMEDI_SUBD_SERIAL; s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; s->n_chan = 1; @@ -4612,7 +4617,7 @@ static int ni_E_init(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->serial_hw_mode = 0; /* RTSI */ - s = dev->subdevices + NI_RTSI_SUBDEV; + s = &dev->subdevices[NI_RTSI_SUBDEV]; s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; s->n_chan = 8; @@ -4633,7 +4638,7 @@ static int ni_E_init(struct comedi_device *dev, struct comedi_devconfig *it) NUM_GPCT); /* General purpose counters */ for (j = 0; j < NUM_GPCT; ++j) { - s = dev->subdevices + NI_GPCT_SUBDEV(j); + s = &dev->subdevices[NI_GPCT_SUBDEV(j)]; s->type = COMEDI_SUBD_COUNTER; s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | SDF_CMD_READ @@ -4659,7 +4664,7 @@ static int ni_E_init(struct comedi_device *dev, struct comedi_devconfig *it) } /* Frequency output */ - s = dev->subdevices + NI_FREQ_OUT_SUBDEV; + s = &dev->subdevices[NI_FREQ_OUT_SUBDEV]; s->type = COMEDI_SUBD_COUNTER; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = 1; @@ -4669,7 +4674,8 @@ static int ni_E_init(struct comedi_device *dev, struct comedi_devconfig *it) s->insn_config = &ni_freq_out_insn_config; /* ai configuration */ - ni_ai_reset(dev, dev->subdevices + NI_AI_SUBDEV); + s = &dev->subdevices[NI_AI_SUBDEV]; + ni_ai_reset(dev, s); if ((boardtype.reg_type & ni_reg_6xxx_mask) == 0) { /* BEAM is this needed for PCI-6143 ?? */ devpriv->clock_and_fout = @@ -4688,7 +4694,8 @@ static int ni_E_init(struct comedi_device *dev, struct comedi_devconfig *it) Clock_and_FOUT_Register); /* analog output configuration */ - ni_ao_reset(dev, dev->subdevices + NI_AO_SUBDEV); + s = &dev->subdevices[NI_AO_SUBDEV]; + ni_ao_reset(dev, s); if (dev->irq) { devpriv->stc_writew(dev, -- cgit v0.10.2 From 88892ca3cebe278b4eaa8ab692d45adb1c1439fc Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:50:39 -0700 Subject: staging: comedi: ni_pcidio: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index 0a55de9..a83f525 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -480,7 +480,7 @@ static int ni_pcidio_poll(struct comedi_device *dev, struct comedi_subdevice *s) static irqreturn_t nidio_interrupt(int irq, void *d) { struct comedi_device *dev = d; - struct comedi_subdevice *s = dev->subdevices; + struct comedi_subdevice *s = &dev->subdevices[0]; struct comedi_async *async = s->async; struct mite_struct *mite = devpriv->mite; @@ -1252,8 +1252,8 @@ static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (!this_board->is_diodaq) { for (i = 0; i < this_board->n_8255; i++) { - subdev_8255_init(dev, dev->subdevices + i, - nidio96_8255_cb, + s = &dev->subdevices[i]; + subdev_8255_init(dev, s, nidio96_8255_cb, (unsigned long)(devpriv->mite-> daq_io_addr + NIDIO_8255_BASE(i))); @@ -1263,7 +1263,7 @@ static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it) printk(KERN_INFO " rev=%d", readb(devpriv->mite->daq_io_addr + Chip_Version)); - s = dev->subdevices + 0; + s = &dev->subdevices[0]; dev->read_subdev = s; s->type = COMEDI_SUBD_DIO; @@ -1307,11 +1307,14 @@ static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void nidio_detach(struct comedi_device *dev) { + struct comedi_subdevice *s; int i; if (this_board && !this_board->is_diodaq) { - for (i = 0; i < this_board->n_8255; i++) - subdev_8255_cleanup(dev, dev->subdevices + i); + for (i = 0; i < this_board->n_8255; i++) { + s = &dev->subdevices[i]; + subdev_8255_cleanup(dev, s); + } } if (dev->irq) free_irq(dev->irq, dev); -- cgit v0.10.2 From af77727a2b14b0c475709cfa200e7a25045a2a82 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:51:01 -0700 Subject: staging: comedi: pcl711: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c index bb72d0b..ef77b15 100644 --- a/drivers/staging/comedi/drivers/pcl711.c +++ b/drivers/staging/comedi/drivers/pcl711.c @@ -168,7 +168,7 @@ static irqreturn_t pcl711_interrupt(int irq, void *d) int data; struct comedi_device *dev = d; const struct pcl711_board *board = comedi_board(dev); - struct comedi_subdevice *s = dev->subdevices + 0; + struct comedi_subdevice *s = &dev->subdevices[0]; if (!dev->attached) { comedi_error(dev, "spurious interrupt"); @@ -520,7 +520,7 @@ static int pcl711_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret < 0) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; /* AI subdevice */ s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_GROUND; @@ -536,7 +536,7 @@ static int pcl711_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->do_cmd = pcl711_ai_cmd; } - s++; + s = &dev->subdevices[1]; /* AO subdevice */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; @@ -547,7 +547,7 @@ static int pcl711_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->insn_write = pcl711_ao_insn; s->insn_read = pcl711_ao_insn_read; - s++; + s = &dev->subdevices[2]; /* 16-bit digital input */ s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; @@ -557,7 +557,7 @@ static int pcl711_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->range_table = &range_digital; s->insn_bits = pcl711_di_insn_bits; - s++; + s = &dev->subdevices[3]; /* 16-bit digital out */ s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE; -- cgit v0.10.2 From d533ef070d0af7816616499fc4bf0eb36dfd63a6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:51:20 -0700 Subject: staging: comedi: pcl724: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/pcl724.c b/drivers/staging/comedi/drivers/pcl724.c index c8fe23c..7b3c429 100644 --- a/drivers/staging/comedi/drivers/pcl724.c +++ b/drivers/staging/comedi/drivers/pcl724.c @@ -99,6 +99,7 @@ static int subdev_8255mapped_cb(int dir, int port, int data, static int pcl724_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct pcl724_board *board = comedi_board(dev); + struct comedi_subdevice *s; unsigned long iobase; unsigned int iorange; int ret, i, n_subdevices; @@ -161,14 +162,13 @@ static int pcl724_attach(struct comedi_device *dev, struct comedi_devconfig *it) return ret; for (i = 0; i < dev->n_subdevices; i++) { + s = &dev->subdevices[i]; if (board->is_pet48) { - subdev_8255_init(dev, dev->subdevices + i, - subdev_8255mapped_cb, + subdev_8255_init(dev, s, subdev_8255mapped_cb, (unsigned long)(dev->iobase + i * 0x1000)); } else - subdev_8255_init(dev, dev->subdevices + i, - subdev_8255_cb, + subdev_8255_init(dev, s, subdev_8255_cb, (unsigned long)(dev->iobase + SIZE_8255 * i)); } @@ -179,10 +179,13 @@ static int pcl724_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void pcl724_detach(struct comedi_device *dev) { const struct pcl724_board *board = comedi_board(dev); + struct comedi_subdevice *s; int i; - for (i = 0; i < dev->n_subdevices; i++) - subdev_8255_cleanup(dev, dev->subdevices + i); + for (i = 0; i < dev->n_subdevices; i++) { + s = &dev->subdevices[i]; + subdev_8255_cleanup(dev, s); + } #ifdef PCL724_IRQ if (dev->irq) free_irq(dev->irq, dev); -- cgit v0.10.2 From 7d780555c03e052756b97ff6625dceb03e8575d8 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:51:38 -0700 Subject: staging: comedi: pcl725: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/pcl725.c b/drivers/staging/comedi/drivers/pcl725.c index d5b60cf..21fbc1a 100644 --- a/drivers/staging/comedi/drivers/pcl725.c +++ b/drivers/staging/comedi/drivers/pcl725.c @@ -62,7 +62,7 @@ static int pcl725_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; /* do */ s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE; @@ -71,7 +71,7 @@ static int pcl725_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->insn_bits = pcl725_do_insn; s->range_table = &range_digital; - s = dev->subdevices + 1; + s = &dev->subdevices[1]; /* di */ s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; -- cgit v0.10.2 From 95ce832a8157d356f4894bfbc9fd1704c40ba734 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:51:55 -0700 Subject: staging: comedi: pcl726: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/pcl726.c b/drivers/staging/comedi/drivers/pcl726.c index 2b10f1d..07e72de 100644 --- a/drivers/staging/comedi/drivers/pcl726.c +++ b/drivers/staging/comedi/drivers/pcl726.c @@ -290,7 +290,7 @@ static int pcl726_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; /* ao */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE | SDF_GROUND; @@ -316,7 +316,7 @@ static int pcl726_attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->bipolar[i] = 1; /* bipolar range */ } - s = dev->subdevices + 1; + s = &dev->subdevices[1]; /* di */ if (!board->have_dio) { s->type = COMEDI_SUBD_UNUSED; @@ -330,7 +330,7 @@ static int pcl726_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->range_table = &range_digital; } - s = dev->subdevices + 2; + s = &dev->subdevices[2]; /* do */ if (!board->have_dio) { s->type = COMEDI_SUBD_UNUSED; -- cgit v0.10.2 From dda841ff2ffe12f39309d970fbd1a550a7eda570 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:52:13 -0700 Subject: staging: comedi: pcl730: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/pcl730.c b/drivers/staging/comedi/drivers/pcl730.c index 4675ec5..e3de499 100644 --- a/drivers/staging/comedi/drivers/pcl730.c +++ b/drivers/staging/comedi/drivers/pcl730.c @@ -84,7 +84,7 @@ static int pcl730_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; /* Isolated do */ s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE; @@ -94,7 +94,7 @@ static int pcl730_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->range_table = &range_digital; s->private = (void *)PCL730_IDIO_LO; - s = dev->subdevices + 1; + s = &dev->subdevices[1]; /* Isolated di */ s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; @@ -104,7 +104,7 @@ static int pcl730_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->range_table = &range_digital; s->private = (void *)PCL730_IDIO_LO; - s = dev->subdevices + 2; + s = &dev->subdevices[2]; /* TTL do */ s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE; @@ -114,7 +114,7 @@ static int pcl730_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->range_table = &range_digital; s->private = (void *)PCL730_DIO_LO; - s = dev->subdevices + 3; + s = &dev->subdevices[3]; /* TTL di */ s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; -- cgit v0.10.2 From 93a37955bcc0ce1b261d4e9dc280a90e416ca9e1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:52:32 -0700 Subject: staging: comedi: pcl812: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index 578fd89..d196343 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -806,7 +806,7 @@ static irqreturn_t interrupt_pcl812_ai_int(int irq, void *d) char err = 1; unsigned int mask, timeout; struct comedi_device *dev = d; - struct comedi_subdevice *s = dev->subdevices + 0; + struct comedi_subdevice *s = &dev->subdevices[0]; unsigned int next_chan; s->async->events = 0; @@ -909,7 +909,7 @@ static void transfer_from_dma_buf(struct comedi_device *dev, static irqreturn_t interrupt_pcl812_ai_dma(int irq, void *d) { struct comedi_device *dev = d; - struct comedi_subdevice *s = dev->subdevices + 0; + struct comedi_subdevice *s = &dev->subdevices[0]; unsigned long dma_flags; int len, bufptr; short *ptr; @@ -1267,7 +1267,7 @@ no_dma: /* analog input */ if (board->n_aichan > 0) { - s = dev->subdevices + subdev; + s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE; switch (board->board_type) { @@ -1409,7 +1409,7 @@ no_dma: /* analog output */ if (board->n_aochan > 0) { - s = dev->subdevices + subdev; + s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE | SDF_GROUND; s->n_chan = board->n_aochan; @@ -1438,7 +1438,7 @@ no_dma: /* digital input */ if (board->n_dichan > 0) { - s = dev->subdevices + subdev; + s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; s->n_chan = board->n_dichan; @@ -1451,7 +1451,7 @@ no_dma: /* digital output */ if (board->n_dochan > 0) { - s = dev->subdevices + subdev; + s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE; s->n_chan = board->n_dochan; -- cgit v0.10.2 From 9417de06e02b8d968d52e7d59e7f751d592e322e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:52:49 -0700 Subject: staging: comedi: pcl816: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index ba6911f..f65fd66 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -258,7 +258,7 @@ static int pcl816_ai_insn_read(struct comedi_device *dev, static irqreturn_t interrupt_pcl816_ai_mode13_int(int irq, void *d) { struct comedi_device *dev = d; - struct comedi_subdevice *s = dev->subdevices + 0; + struct comedi_subdevice *s = &dev->subdevices[0]; int low, hi; int timeout = 50; /* wait max 50us */ @@ -349,7 +349,7 @@ static void transfer_from_dma_buf(struct comedi_device *dev, static irqreturn_t interrupt_pcl816_ai_mode13_dma(int irq, void *d) { struct comedi_device *dev = d; - struct comedi_subdevice *s = dev->subdevices + 0; + struct comedi_subdevice *s = &dev->subdevices[0]; int len, bufptr, this_dma_buf; unsigned long dma_flags; short *ptr; @@ -1183,7 +1183,7 @@ no_dma: if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; if (board->n_aichan > 0) { s->type = COMEDI_SUBD_AI; devpriv->sub_ai = s; -- cgit v0.10.2 From 9fab612335c0822e0e0a404fdd6d9222b3bfc800 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:53:07 -0700 Subject: staging: comedi: pcl818: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c index 34169c1..023a27d 100644 --- a/drivers/staging/comedi/drivers/pcl818.c +++ b/drivers/staging/comedi/drivers/pcl818.c @@ -477,7 +477,7 @@ static int pcl818_do_insn_bits(struct comedi_device *dev, static irqreturn_t interrupt_pcl818_ai_mode13_int(int irq, void *d) { struct comedi_device *dev = d; - struct comedi_subdevice *s = dev->subdevices + 0; + struct comedi_subdevice *s = &dev->subdevices[0]; int low; int timeout = 50; /* wait max 50us */ @@ -536,7 +536,7 @@ conv_finish: static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d) { struct comedi_device *dev = d; - struct comedi_subdevice *s = dev->subdevices + 0; + struct comedi_subdevice *s = &dev->subdevices[0]; int i, len, bufptr; unsigned long flags; short *ptr; @@ -615,7 +615,7 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d) static irqreturn_t interrupt_pcl818_ai_mode13_dma_rtc(int irq, void *d) { struct comedi_device *dev = d; - struct comedi_subdevice *s = dev->subdevices + 0; + struct comedi_subdevice *s = &dev->subdevices[0]; unsigned long tmp; unsigned int top1, top2, i, bufptr; long ofs_dats; @@ -720,7 +720,7 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma_rtc(int irq, void *d) static irqreturn_t interrupt_pcl818_ai_mode13_fifo(int irq, void *d) { struct comedi_device *dev = d; - struct comedi_subdevice *s = dev->subdevices + 0; + struct comedi_subdevice *s = &dev->subdevices[0]; int i, len, lo; outb(0, dev->iobase + PCL818_FI_INTCLR); /* clear fifo int request */ @@ -811,7 +811,7 @@ static irqreturn_t interrupt_pcl818(int irq, void *d) being reprogrammed while a DMA transfer is in progress. */ - struct comedi_subdevice *s = dev->subdevices + 0; + struct comedi_subdevice *s = &dev->subdevices[0]; devpriv->ai_act_scan = 0; devpriv->neverending_ai = 0; pcl818_ai_cancel(dev, s); @@ -1763,7 +1763,7 @@ no_dma: if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; if (!board->n_aichan_se) { s->type = COMEDI_SUBD_UNUSED; } else { @@ -1829,7 +1829,7 @@ no_dma: } } - s = dev->subdevices + 1; + s = &dev->subdevices[1]; if (!board->n_aochan) { s->type = COMEDI_SUBD_UNUSED; } else { @@ -1862,7 +1862,7 @@ no_dma: } } - s = dev->subdevices + 2; + s = &dev->subdevices[2]; if (!board->n_dichan) { s->type = COMEDI_SUBD_UNUSED; } else { @@ -1875,7 +1875,7 @@ no_dma: s->insn_bits = pcl818_di_insn_bits; } - s = dev->subdevices + 3; + s = &dev->subdevices[3]; if (!board->n_dochan) { s->type = COMEDI_SUBD_UNUSED; } else { -- cgit v0.10.2 From 0a96639fe702a06ca428323a0cfcf7cabc26f6c7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:53:24 -0700 Subject: staging: comedi: pcm3724: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/pcm3724.c b/drivers/staging/comedi/drivers/pcm3724.c index 62c22cc..4102547 100644 --- a/drivers/staging/comedi/drivers/pcm3724.c +++ b/drivers/staging/comedi/drivers/pcm3724.c @@ -119,6 +119,8 @@ static int compute_buffer(int config, int devno, struct comedi_subdevice *s) static void do_3724_config(struct comedi_device *dev, struct comedi_subdevice *s, int chanspec) { + struct comedi_subdevice *s_dio1 = &dev->subdevices[0]; + struct comedi_subdevice *s_dio2 = &dev->subdevices[1]; int config; int buffer_config; unsigned long port_8255_cfg; @@ -136,10 +138,10 @@ static void do_3724_config(struct comedi_device *dev, if (!(s->io_bits & 0xff0000)) config |= CR_C_IO; - buffer_config = compute_buffer(0, 0, dev->subdevices); - buffer_config = compute_buffer(buffer_config, 1, (dev->subdevices) + 1); + buffer_config = compute_buffer(0, 0, s_dio1); + buffer_config = compute_buffer(buffer_config, 1, s_dio2); - if (s == dev->subdevices) + if (s == s_dio1) port_8255_cfg = dev->iobase + _8255_CR; else port_8255_cfg = dev->iobase + SIZE_8255 + _8255_CR; @@ -154,6 +156,7 @@ static void do_3724_config(struct comedi_device *dev, static void enable_chan(struct comedi_device *dev, struct comedi_subdevice *s, int chanspec) { + struct comedi_subdevice *s_dio1 = &dev->subdevices[0]; unsigned int mask; int gatecfg; struct priv_pcm3724 *priv; @@ -162,9 +165,9 @@ static void enable_chan(struct comedi_device *dev, struct comedi_subdevice *s, priv = dev->private; mask = 1 << CR_CHAN(chanspec); - if (s == dev->subdevices) /* subdev 0 */ + if (s == s_dio1) priv->dio_1 |= mask; - else /* subdev 1 */ + else priv->dio_2 |= mask; if (priv->dio_1 & 0xff0000) @@ -231,6 +234,7 @@ static int pcm3724_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct pcm3724_board *board = comedi_board(dev); + struct comedi_subdevice *s; unsigned long iobase; unsigned int iorange; int ret, i, n_subdevices; @@ -263,9 +267,10 @@ static int pcm3724_attach(struct comedi_device *dev, return ret; for (i = 0; i < dev->n_subdevices; i++) { - subdev_8255_init(dev, dev->subdevices + i, subdev_8255_cb, + s = &dev->subdevices[i]; + subdev_8255_init(dev, s, subdev_8255_cb, (unsigned long)(dev->iobase + SIZE_8255 * i)); - ((dev->subdevices) + i)->insn_config = subdev_3724_insn_config; + s->insn_config = subdev_3724_insn_config; } return 0; } @@ -273,11 +278,14 @@ static int pcm3724_attach(struct comedi_device *dev, static void pcm3724_detach(struct comedi_device *dev) { const struct pcm3724_board *board = comedi_board(dev); + struct comedi_subdevice *s; int i; if (dev->subdevices) { - for (i = 0; i < dev->n_subdevices; i++) - subdev_8255_cleanup(dev, dev->subdevices + i); + for (i = 0; i < dev->n_subdevices; i++) { + s = &dev->subdevices[i]; + subdev_8255_cleanup(dev, s); + } } if (dev->iobase) release_region(dev->iobase, board->io_range); -- cgit v0.10.2 From edb9dac794678286c171583aacc673cf60a9dbc0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:53:42 -0700 Subject: staging: comedi: pcm3730: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/pcm3730.c b/drivers/staging/comedi/drivers/pcm3730.c index d65e0bd..067f14d 100644 --- a/drivers/staging/comedi/drivers/pcm3730.c +++ b/drivers/staging/comedi/drivers/pcm3730.c @@ -72,7 +72,7 @@ static int pcm3730_attach(struct comedi_device *dev, if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE; s->maxdata = 1; @@ -81,7 +81,7 @@ static int pcm3730_attach(struct comedi_device *dev, s->range_table = &range_digital; s->private = (void *)PCM3730_DOA; - s = dev->subdevices + 1; + s = &dev->subdevices[1]; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE; s->maxdata = 1; @@ -90,7 +90,7 @@ static int pcm3730_attach(struct comedi_device *dev, s->range_table = &range_digital; s->private = (void *)PCM3730_DOB; - s = dev->subdevices + 2; + s = &dev->subdevices[2]; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE; s->maxdata = 1; @@ -99,7 +99,7 @@ static int pcm3730_attach(struct comedi_device *dev, s->range_table = &range_digital; s->private = (void *)PCM3730_DOC; - s = dev->subdevices + 3; + s = &dev->subdevices[3]; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; s->maxdata = 1; @@ -108,7 +108,7 @@ static int pcm3730_attach(struct comedi_device *dev, s->range_table = &range_digital; s->private = (void *)PCM3730_DIA; - s = dev->subdevices + 4; + s = &dev->subdevices[4]; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; s->maxdata = 1; @@ -117,7 +117,7 @@ static int pcm3730_attach(struct comedi_device *dev, s->range_table = &range_digital; s->private = (void *)PCM3730_DIB; - s = dev->subdevices + 5; + s = &dev->subdevices[5]; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; s->maxdata = 1; -- cgit v0.10.2 From 86bb856a0264de6e1cab46539193444fe2ed2344 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:54:00 -0700 Subject: staging: comedi: pcmad: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/pcmad.c b/drivers/staging/comedi/drivers/pcmad.c index 54d19c9..5efeb92 100644 --- a/drivers/staging/comedi/drivers/pcmad.c +++ b/drivers/staging/comedi/drivers/pcmad.c @@ -127,7 +127,7 @@ static int pcmad_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = board->name; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | AREF_GROUND; s->n_chan = 16; /* XXX */ -- cgit v0.10.2 From 623733ffc0432a8f76667a1ddcdc2ba4c57aa2e3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:54:19 -0700 Subject: staging: comedi: pcmda12: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/pcmda12.c b/drivers/staging/comedi/drivers/pcmda12.c index 291ce7c..28af8f6 100644 --- a/drivers/staging/comedi/drivers/pcmda12.c +++ b/drivers/staging/comedi/drivers/pcmda12.c @@ -195,7 +195,7 @@ static int pcmda12_attach(struct comedi_device *dev, if (ret) return ret; - s = dev->subdevices; + s = &dev->subdevices[0]; s->private = NULL; s->maxdata = (0x1 << BITS) - 1; s->range_table = &pcmda12_ranges; -- cgit v0.10.2 From 33e101ad9d6f8d23fb67d92081e8c2a5b695d83c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:54:46 -0700 Subject: staging: comedi: pcmmio: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c index 3d2e6f0..9a9af0b 100644 --- a/drivers/staging/comedi/drivers/pcmmio.c +++ b/drivers/staging/comedi/drivers/pcmmio.c @@ -526,6 +526,7 @@ static irqreturn_t interrupt_pcmmio(int irq, void *d) { int asic, got1 = 0; struct comedi_device *dev = (struct comedi_device *)d; + int i; for (asic = 0; asic < MAX_ASICS; ++asic) { if (irq == devpriv->asics[asic].irq) { @@ -583,9 +584,8 @@ static irqreturn_t interrupt_pcmmio(int irq, void *d) printk (KERN_DEBUG "got edge detect interrupt %d asic %d which_chans: %06x\n", irq, asic, triggered); - for (s = dev->subdevices + 2; - s < dev->subdevices + dev->n_subdevices; - ++s) { + for (i = 2; i < dev->n_subdevices; i++) { + s = &dev->subdevices[i]; /* * this is an interrupt subdev, * and it matches this asic! @@ -1076,9 +1076,8 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) return ret; /* First, AI */ - sdev_no = 0; - s = dev->subdevices + sdev_no; - s->private = devpriv->sprivs + sdev_no; + s = &dev->subdevices[0]; + s->private = &devpriv->sprivs[0]; s->maxdata = (1 << board->ai_bits) - 1; s->range_table = board->ai_range_table; s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; @@ -1092,9 +1091,8 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) outb(0, subpriv->iobase + 4 + 3); /* Next, AO */ - ++sdev_no; - s = dev->subdevices + sdev_no; - s->private = devpriv->sprivs + sdev_no; + s = &dev->subdevices[1]; + s->private = &devpriv->sprivs[1]; s->maxdata = (1 << board->ao_bits) - 1; s->range_table = board->ao_range_table; s->subdev_flags = SDF_READABLE; @@ -1108,14 +1106,13 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) outb(0, subpriv->iobase + 3); outb(0, subpriv->iobase + 4 + 3); - ++sdev_no; port = 0; asic = 0; - for (; sdev_no < (int)dev->n_subdevices; ++sdev_no) { + for (sdev_no = 2; sdev_no < dev->n_subdevices; ++sdev_no) { int byte_no; - s = dev->subdevices + sdev_no; - s->private = devpriv->sprivs + sdev_no; + s = &dev->subdevices[sdev_no]; + s->private = &devpriv->sprivs[sdev_no]; s->maxdata = 1; s->range_table = &range_digital; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; -- cgit v0.10.2 From 68720ae68a94444387d56bc5a166396e33e420a5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:55:08 -0700 Subject: staging: comedi: pcmuio: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c index feef3d0..aba6b45 100644 --- a/drivers/staging/comedi/drivers/pcmuio.c +++ b/drivers/staging/comedi/drivers/pcmuio.c @@ -456,6 +456,7 @@ static irqreturn_t interrupt_pcmuio(int irq, void *d) { int asic, got1 = 0; struct comedi_device *dev = (struct comedi_device *)d; + int i; for (asic = 0; asic < MAX_ASICS; ++asic) { if (irq == devpriv->asics[asic].irq) { @@ -507,9 +508,8 @@ static irqreturn_t interrupt_pcmuio(int irq, void *d) printk ("PCMUIO DEBUG: got edge detect interrupt %d asic %d which_chans: %06x\n", irq, asic, triggered); - for (s = dev->subdevices; - s < dev->subdevices + dev->n_subdevices; - ++s) { + for (i = 0; i < dev->n_subdevices; i++) { + s = &dev->subdevices[i]; if (subpriv->intr.asic == asic) { /* this is an interrupt subdev, and it matches this asic! */ unsigned long flags; unsigned oldevents; @@ -811,8 +811,8 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) for (sdev_no = 0; sdev_no < (int)dev->n_subdevices; ++sdev_no) { int byte_no; - s = dev->subdevices + sdev_no; - s->private = devpriv->sprivs + sdev_no; + s = &dev->subdevices[sdev_no]; + s->private = &devpriv->sprivs[sdev_no]; s->maxdata = 1; s->range_table = &range_digital; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; -- cgit v0.10.2 From eb31b63a76b0cd4e0aafa3dcc338dbb16698d4de Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:55:27 -0700 Subject: staging: comedi: poc: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/poc.c b/drivers/staging/comedi/drivers/poc.c index c253bb9..78dfe16 100644 --- a/drivers/staging/comedi/drivers/poc.c +++ b/drivers/staging/comedi/drivers/poc.c @@ -164,7 +164,7 @@ static int poc_attach(struct comedi_device *dev, struct comedi_devconfig *it) return -ENOMEM; /* analog output subdevice */ - s = dev->subdevices + 0; + s = &dev->subdevices[0]; s->type = board->type; s->n_chan = board->n_chan; s->maxdata = (1 << board->n_bits) - 1; -- cgit v0.10.2 From 123c0e03a49986fbe63509f7511484f929eb1a42 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:55:46 -0700 Subject: staging: comedi: quatech_daqp_cs: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c index a029147..e95a4eb 100644 --- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c +++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c @@ -878,7 +878,7 @@ static int daqp_attach(struct comedi_device *dev, struct comedi_devconfig *it) printk(KERN_INFO "comedi%d: attaching daqp%d (io 0x%04lx)\n", dev->minor, it->options[0], dev->iobase); - s = dev->subdevices + 0; + s = &dev->subdevices[0]; dev->read_subdev = s; s->private = local; s->type = COMEDI_SUBD_AI; @@ -892,7 +892,7 @@ static int daqp_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->do_cmd = daqp_ai_cmd; s->cancel = daqp_ai_cancel; - s = dev->subdevices + 1; + s = &dev->subdevices[1]; dev->write_subdev = s; s->private = local; s->type = COMEDI_SUBD_AO; @@ -903,7 +903,7 @@ static int daqp_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->range_table = &range_daqp_ao; s->insn_write = daqp_ao_insn_write; - s = dev->subdevices + 2; + s = &dev->subdevices[2]; s->private = local; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; @@ -911,7 +911,7 @@ static int daqp_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->len_chanlist = 1; s->insn_read = daqp_di_insn_read; - s = dev->subdevices + 3; + s = &dev->subdevices[3]; s->private = local; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITEABLE; -- cgit v0.10.2 From 58f2045935b452ad1e98dc37da92c092c4ba0865 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:56:05 -0700 Subject: staging: comedi: rtd520: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 5aa8be1..58f5922 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -783,7 +783,7 @@ static irqreturn_t rtd_interrupt(int irq, /* interrupt number (ignored) */ void *d) { /* our data *//* cpu context (ignored) */ struct comedi_device *dev = d; - struct comedi_subdevice *s = dev->subdevices + 0; /* analog in subdevice */ + struct comedi_subdevice *s = &dev->subdevices[0]; struct rtdPrivate *devpriv = dev->private; u32 overrun; u16 status; @@ -1706,7 +1706,7 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; dev->read_subdev = s; /* analog input subdevice */ s->type = COMEDI_SUBD_AI; @@ -1726,7 +1726,7 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->cancel = rtd_ai_cancel; /* s->poll = rtd_ai_poll; *//* not ready yet */ - s = dev->subdevices + 1; + s = &dev->subdevices[1]; /* analog output subdevice */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; @@ -1736,7 +1736,7 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->insn_write = rtd_ao_winsn; s->insn_read = rtd_ao_rinsn; - s = dev->subdevices + 2; + s = &dev->subdevices[2]; /* digital i/o subdevice */ s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; @@ -1748,7 +1748,7 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->insn_config = rtd_dio_insn_config; /* timer/counter subdevices (not currently supported) */ - s = dev->subdevices + 3; + s = &dev->subdevices[3]; s->type = COMEDI_SUBD_COUNTER; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = 3; -- cgit v0.10.2 From 13bee03ef928df908b3c4d58a4e100460d25bdbb Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:56:23 -0700 Subject: staging: comedi: rti800: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/rti800.c b/drivers/staging/comedi/drivers/rti800.c index f7fa940..137885b 100644 --- a/drivers/staging/comedi/drivers/rti800.c +++ b/drivers/staging/comedi/drivers/rti800.c @@ -360,7 +360,7 @@ static int rti800_attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->dac1_coding = it->options[8]; devpriv->muxgain_bits = -1; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; /* ai subdevice */ s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_GROUND; @@ -379,7 +379,7 @@ static int rti800_attach(struct comedi_device *dev, struct comedi_devconfig *it) break; } - s++; + s = &dev->subdevices[1]; if (board->has_ao) { /* ao subdevice (only on rti815) */ s->type = COMEDI_SUBD_AO; @@ -409,7 +409,7 @@ static int rti800_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->type = COMEDI_SUBD_UNUSED; } - s++; + s = &dev->subdevices[2]; /* di */ s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; @@ -418,7 +418,7 @@ static int rti800_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->maxdata = 1; s->range_table = &range_digital; - s++; + s = &dev->subdevices[3]; /* do */ s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE; @@ -429,7 +429,7 @@ static int rti800_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* don't yet know how to deal with counter/timers */ #if 0 - s++; + s = &dev->subdevices[4]; /* do */ s->type = COMEDI_SUBD_TIMER; #endif -- cgit v0.10.2 From 7badc90d218dc7900147ec080ec72a5cbc99c381 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:56:41 -0700 Subject: staging: comedi: rti802: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/rti802.c b/drivers/staging/comedi/drivers/rti802.c index fc16508..3f9d027 100644 --- a/drivers/staging/comedi/drivers/rti802.c +++ b/drivers/staging/comedi/drivers/rti802.c @@ -111,7 +111,7 @@ static int rti802_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - s = dev->subdevices; + s = &dev->subdevices[0]; /* ao subdevice */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; -- cgit v0.10.2 From 97073c05d4b3ec5ba8c4c4b64a6f1005a4e1eb10 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:57:01 -0700 Subject: staging: comedi: s526: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c index 737a194..c89bd6c 100644 --- a/drivers/staging/comedi/drivers/s526.c +++ b/drivers/staging/comedi/drivers/s526.c @@ -768,7 +768,7 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; /* GENERAL-PURPOSE COUNTER/TIME (GPCT) */ s->type = COMEDI_SUBD_COUNTER; s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL; @@ -786,7 +786,7 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* s->do_cmdtest = s526_gpct_cmdtest; */ /* s->cancel = s526_gpct_cancel; */ - s = dev->subdevices + 1; + s = &dev->subdevices[1]; /* dev->read_subdev=s; */ /* analog input subdevice */ s->type = COMEDI_SUBD_AI; @@ -802,7 +802,7 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->insn_read = s526_ai_rinsn; s->insn_config = s526_ai_insn_config; - s = dev->subdevices + 2; + s = &dev->subdevices[2]; /* analog output subdevice */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; @@ -812,7 +812,7 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->insn_write = s526_ao_winsn; s->insn_read = s526_ao_rinsn; - s = dev->subdevices + 3; + s = &dev->subdevices[3]; /* digital i/o subdevice */ if (board->have_dio) { s->type = COMEDI_SUBD_DIO; -- cgit v0.10.2 From 8e27a730df3a78d7f27320036164fa4a576b8107 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:57:21 -0700 Subject: staging: comedi: serial2002: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c index 0b58eec..5bf84cf 100644 --- a/drivers/staging/comedi/drivers/serial2002.c +++ b/drivers/staging/comedi/drivers/serial2002.c @@ -800,7 +800,7 @@ static int serial2002_attach(struct comedi_device *dev, return ret; /* digital input subdevice */ - s = dev->subdevices + 0; + s = &dev->subdevices[0]; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; s->n_chan = 0; @@ -809,7 +809,7 @@ static int serial2002_attach(struct comedi_device *dev, s->insn_read = &serial2002_di_rinsn; /* digital output subdevice */ - s = dev->subdevices + 1; + s = &dev->subdevices[1]; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITEABLE; s->n_chan = 0; @@ -818,7 +818,7 @@ static int serial2002_attach(struct comedi_device *dev, s->insn_write = &serial2002_do_winsn; /* analog input subdevice */ - s = dev->subdevices + 2; + s = &dev->subdevices[2]; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_GROUND; s->n_chan = 0; @@ -827,7 +827,7 @@ static int serial2002_attach(struct comedi_device *dev, s->insn_read = &serial2002_ai_rinsn; /* analog output subdevice */ - s = dev->subdevices + 3; + s = &dev->subdevices[3]; s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITEABLE; s->n_chan = 0; @@ -837,7 +837,7 @@ static int serial2002_attach(struct comedi_device *dev, s->insn_read = &serial2002_ao_rinsn; /* encoder input subdevice */ - s = dev->subdevices + 4; + s = &dev->subdevices[4]; s->type = COMEDI_SUBD_COUNTER; s->subdev_flags = SDF_READABLE | SDF_LSAMPL; s->n_chan = 0; -- cgit v0.10.2 From 0f72ca312b63621424c863f12a150e9bd4ebf894 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:57:38 -0700 Subject: staging: comedi: skel: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c index 9a68eeb..eb70bac 100644 --- a/drivers/staging/comedi/drivers/skel.c +++ b/drivers/staging/comedi/drivers/skel.c @@ -238,7 +238,7 @@ static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; /* dev->read_subdev=s; */ /* analog input subdevice */ s->type = COMEDI_SUBD_AI; @@ -256,7 +256,7 @@ static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it) */ s->do_cmdtest = skel_ai_cmdtest; - s = dev->subdevices + 1; + s = &dev->subdevices[1]; /* analog output subdevice */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; @@ -266,7 +266,7 @@ static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->insn_write = skel_ao_winsn; s->insn_read = skel_ao_rinsn; - s = dev->subdevices + 2; + s = &dev->subdevices[2]; /* digital i/o subdevice */ if (thisboard->have_dio) { s->type = COMEDI_SUBD_DIO; -- cgit v0.10.2 From 015ebbe86d223f55c45ea2bdaca0af69a0ddd0c4 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:57:57 -0700 Subject: staging: comedi: ssv_dnp: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ssv_dnp.c b/drivers/staging/comedi/drivers/ssv_dnp.c index d1f5118..ae3aa1c 100644 --- a/drivers/staging/comedi/drivers/ssv_dnp.c +++ b/drivers/staging/comedi/drivers/ssv_dnp.c @@ -183,7 +183,7 @@ static int dnp_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; /* digital i/o subdevice */ s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; -- cgit v0.10.2 From 4760904fb4a2841c9ac651e36610724929122385 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:58:15 -0700 Subject: staging: comedi: usbdux: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 11ee836..7aac213 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -404,7 +404,7 @@ static void usbduxsub_ai_IsocIrq(struct urb *urb) /* the private structure of the subdevice is struct usbduxsub */ this_usbduxsub = this_comedidev->private; /* subdevice which is the AD converter */ - s = this_comedidev->subdevices + SUBDEV_AD; + s = &this_comedidev->subdevices[SUBDEV_AD]; /* first we test if something unusual has just happened */ switch (urb->status) { @@ -604,7 +604,7 @@ static void usbduxsub_ao_IsocIrq(struct urb *urb) /* the private structure of the subdevice is struct usbduxsub */ this_usbduxsub = this_comedidev->private; - s = this_comedidev->subdevices + SUBDEV_DA; + s = &this_comedidev->subdevices[SUBDEV_DA]; switch (urb->status) { case 0: @@ -1947,7 +1947,7 @@ static void usbduxsub_pwm_irq(struct urb *urb) /* the private structure of the subdevice is struct usbduxsub */ this_usbduxsub = this_comedidev->private; - s = this_comedidev->subdevices + SUBDEV_DA; + s = &this_comedidev->subdevices[SUBDEV_DA]; switch (urb->status) { case 0: @@ -2331,7 +2331,7 @@ static int usbdux_attach_common(struct comedi_device *dev, dev->private = udev; /* the first subdevice is the A/D converter */ - s = dev->subdevices + SUBDEV_AD; + s = &dev->subdevices[SUBDEV_AD]; /* the URBs get the comedi subdevice */ /* which is responsible for reading */ /* this is the subdevice which reads data */ @@ -2358,7 +2358,7 @@ static int usbdux_attach_common(struct comedi_device *dev, s->range_table = (&range_usbdux_ai_range); /* analog out */ - s = dev->subdevices + SUBDEV_DA; + s = &dev->subdevices[SUBDEV_DA]; /* analog out */ s->type = COMEDI_SUBD_AO; /* backward pointer */ @@ -2384,7 +2384,7 @@ static int usbdux_attach_common(struct comedi_device *dev, s->insn_write = usbdux_ao_insn_write; /* digital I/O */ - s = dev->subdevices + SUBDEV_DIO; + s = &dev->subdevices[SUBDEV_DIO]; s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = 8; @@ -2396,7 +2396,7 @@ static int usbdux_attach_common(struct comedi_device *dev, s->private = NULL; /* counter */ - s = dev->subdevices + SUBDEV_COUNTER; + s = &dev->subdevices[SUBDEV_COUNTER]; s->type = COMEDI_SUBD_COUNTER; s->subdev_flags = SDF_WRITABLE | SDF_READABLE; s->n_chan = 4; @@ -2407,7 +2407,7 @@ static int usbdux_attach_common(struct comedi_device *dev, if (udev->high_speed) { /* timer / pwm */ - s = dev->subdevices + SUBDEV_PWM; + s = &dev->subdevices[SUBDEV_PWM]; s->type = COMEDI_SUBD_PWM; s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE; s->n_chan = 8; -- cgit v0.10.2 From bbea99d9c7221f69cadb4fd764f2a65e6292c756 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:58:32 -0700 Subject: staging: comedi: usbduxfast: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index 8eb41257..3f68fc3 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -346,7 +346,7 @@ static void usbduxfastsub_ai_Irq(struct urb *urb) return; } /* subdevice which is the AD converter */ - s = this_comedidev->subdevices + SUBDEV_AD; + s = &this_comedidev->subdevices[SUBDEV_AD]; /* first we test if something unusual has just happened */ switch (urb->status) { @@ -1453,7 +1453,7 @@ static int usbduxfast_attach_common(struct comedi_device *dev, /* private structure is also simply the usb-structure */ dev->private = udfs; /* the first subdevice is the A/D converter */ - s = dev->subdevices + SUBDEV_AD; + s = &dev->subdevices[SUBDEV_AD]; /* * the URBs get the comedi subdevice which is responsible for reading * this is the subdevice which reads data -- cgit v0.10.2 From ae4498216be8ed2ecd1508a72458a01e6976185a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:58:51 -0700 Subject: staging: comedi: usbduxsigma: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index f54ab8c..034f5df 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -356,7 +356,7 @@ static void usbduxsub_ai_IsocIrq(struct urb *urb) /* the private structure of the subdevice is struct usbduxsub */ this_usbduxsub = this_comedidev->private; /* subdevice which is the AD converter */ - s = this_comedidev->subdevices + SUBDEV_AD; + s = &this_comedidev->subdevices[SUBDEV_AD]; /* first we test if something unusual has just happened */ switch (urb->status) { @@ -558,7 +558,7 @@ static void usbduxsub_ao_IsocIrq(struct urb *urb) /* the private structure of the subdevice is struct usbduxsub */ this_usbduxsub = this_comedidev->private; - s = this_comedidev->subdevices + SUBDEV_DA; + s = &this_comedidev->subdevices[SUBDEV_DA]; switch (urb->status) { case 0: @@ -1950,7 +1950,7 @@ static void usbduxsub_pwm_irq(struct urb *urb) /* the private structure of the subdevice is struct usbduxsub */ this_usbduxsub = this_comedidev->private; - s = this_comedidev->subdevices + SUBDEV_DA; + s = &this_comedidev->subdevices[SUBDEV_DA]; switch (urb->status) { case 0: @@ -2331,7 +2331,7 @@ static int usbduxsigma_attach_common(struct comedi_device *dev, /* private structure is also simply the usb-structure */ dev->private = uds; /* the first subdevice is the A/D converter */ - s = dev->subdevices + SUBDEV_AD; + s = &dev->subdevices[SUBDEV_AD]; /* the URBs get the comedi subdevice */ /* which is responsible for reading */ /* this is the subdevice which reads data */ @@ -2358,7 +2358,7 @@ static int usbduxsigma_attach_common(struct comedi_device *dev, /* range table to convert to physical units */ s->range_table = (&range_usbdux_ai_range); /* analog output subdevice */ - s = dev->subdevices + SUBDEV_DA; + s = &dev->subdevices[SUBDEV_DA]; /* analog out */ s->type = COMEDI_SUBD_AO; /* backward pointer */ @@ -2383,7 +2383,7 @@ static int usbduxsigma_attach_common(struct comedi_device *dev, s->insn_read = usbdux_ao_insn_read; s->insn_write = usbdux_ao_insn_write; /* digital I/O subdevice */ - s = dev->subdevices + SUBDEV_DIO; + s = &dev->subdevices[SUBDEV_DIO]; s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; /* 8 external and 16 internal channels */ @@ -2396,7 +2396,7 @@ static int usbduxsigma_attach_common(struct comedi_device *dev, s->private = NULL; if (uds->high_speed) { /* timer / pwm subdevice */ - s = dev->subdevices + SUBDEV_PWM; + s = &dev->subdevices[SUBDEV_PWM]; s->type = COMEDI_SUBD_PWM; s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE; s->n_chan = 8; -- cgit v0.10.2 From d3d1e2532f33b49515bf9ea9e2b4cc1dbb1d47c9 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:59:09 -0700 Subject: staging: comedi: vmk80xx: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c index 94010fc..f9fef26 100644 --- a/drivers/staging/comedi/drivers/vmk80xx.c +++ b/drivers/staging/comedi/drivers/vmk80xx.c @@ -1119,7 +1119,7 @@ static int vmk80xx_attach_common(struct comedi_device *cdev, return ret; } /* Analog input subdevice */ - s = cdev->subdevices + VMK80XX_SUBD_AI; + s = &cdev->subdevices[VMK80XX_SUBD_AI]; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_GROUND; s->n_chan = dev->board.ai_chans; @@ -1127,7 +1127,7 @@ static int vmk80xx_attach_common(struct comedi_device *cdev, s->range_table = dev->board.range; s->insn_read = vmk80xx_ai_rinsn; /* Analog output subdevice */ - s = cdev->subdevices + VMK80XX_SUBD_AO; + s = &cdev->subdevices[VMK80XX_SUBD_AO]; s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITEABLE | SDF_GROUND; s->n_chan = dev->board.ao_chans; @@ -1139,7 +1139,7 @@ static int vmk80xx_attach_common(struct comedi_device *cdev, s->insn_read = vmk80xx_ao_rinsn; } /* Digital input subdevice */ - s = cdev->subdevices + VMK80XX_SUBD_DI; + s = &cdev->subdevices[VMK80XX_SUBD_DI]; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE | SDF_GROUND; s->n_chan = dev->board.di_chans; @@ -1147,7 +1147,7 @@ static int vmk80xx_attach_common(struct comedi_device *cdev, s->insn_read = vmk80xx_di_rinsn; s->insn_bits = vmk80xx_di_bits; /* Digital output subdevice */ - s = cdev->subdevices + VMK80XX_SUBD_DO; + s = &cdev->subdevices[VMK80XX_SUBD_DO]; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITEABLE | SDF_GROUND; s->n_chan = dev->board.do_chans; @@ -1159,7 +1159,7 @@ static int vmk80xx_attach_common(struct comedi_device *cdev, s->insn_read = vmk80xx_do_rinsn; } /* Counter subdevice */ - s = cdev->subdevices + VMK80XX_SUBD_CNT; + s = &cdev->subdevices[VMK80XX_SUBD_CNT]; s->type = COMEDI_SUBD_COUNTER; s->subdev_flags = SDF_READABLE; s->n_chan = dev->board.cnt_chans; @@ -1172,7 +1172,7 @@ static int vmk80xx_attach_common(struct comedi_device *cdev, } /* PWM subdevice */ if (dev->board.model == VMK8061_MODEL) { - s = cdev->subdevices + VMK80XX_SUBD_PWM; + s = &cdev->subdevices[VMK80XX_SUBD_PWM]; s->type = COMEDI_SUBD_PWM; s->subdev_flags = SDF_READABLE | SDF_WRITEABLE; s->n_chan = dev->board.pwm_chans; -- cgit v0.10.2 From 5818e7090bb6eacb886bd2f7fc3df06e23047b29 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:59:26 -0700 Subject: staging: comedi: kcomedilib: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c index 0252b44..f96416d 100644 --- a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c +++ b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c @@ -90,7 +90,7 @@ static int comedi_do_insn(struct comedi_device *dev, struct comedi_insn *insn) ret = -EINVAL; goto error; } - s = dev->subdevices + insn->subdev; + s = &dev->subdevices[insn->subdev]; if (s->type == COMEDI_SUBD_UNUSED) { printk(KERN_ERR "%d not useable subdevice\n", insn->subdev); @@ -175,11 +175,14 @@ EXPORT_SYMBOL(comedi_dio_bitfield); int comedi_find_subdevice_by_type(struct comedi_device *dev, int type, unsigned int subd) { + struct comedi_subdevice *s; + if (subd > dev->n_subdevices) return -ENODEV; for (; subd < dev->n_subdevices; subd++) { - if (dev->subdevices[subd].type == type) + s = &dev->subdevices[subd]; + if (s->type == type) return subd; } return -1; @@ -188,7 +191,7 @@ EXPORT_SYMBOL(comedi_find_subdevice_by_type); int comedi_get_n_channels(struct comedi_device *dev, unsigned int subdevice) { - struct comedi_subdevice *s = dev->subdevices + subdevice; + struct comedi_subdevice *s = &dev->subdevices[subdevice]; return s->n_chan; } -- cgit v0.10.2 From d08d6cfe3b594b797e1204891613d1cdf70fb0c7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Sep 2012 18:59:44 -0700 Subject: staging: comedi: range: remove subdevice pointer math Convert the comedi_subdevice access from pointer math to array access. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/range.c b/drivers/staging/comedi/range.c index 5a6b6df..59ff0cf 100644 --- a/drivers/staging/comedi/range.c +++ b/drivers/staging/comedi/range.c @@ -68,7 +68,7 @@ int do_rangeinfo_ioctl(struct comedi_device *dev, return -EINVAL; if (subd >= dev->n_subdevices) return -EINVAL; - s = dev->subdevices + subd; + s = &dev->subdevices[subd]; if (s->range_table) { lr = s->range_table; } else if (s->range_table_list) { -- cgit v0.10.2 From f0290de23de19b592b2934cdf21c0c0c2eb16500 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 6 Sep 2012 15:40:20 +0300 Subject: staging: ramster: fix range checks in zcache_autocreate_pool() If "pool_id" is negative then it leads to a read before the start of the array. If "cli_id" is out of bounds then it leads to a NULL dereference of "cli". GCC would have warned about that bug except that we initialized the warning message away. Also it's better to put the parameter names into the function declaration in the .h file. It serves as a kind of documentation. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ramster/zcache-main.c b/drivers/staging/ramster/zcache-main.c index 24b3d4a..86e19d6 100644 --- a/drivers/staging/ramster/zcache-main.c +++ b/drivers/staging/ramster/zcache-main.c @@ -1338,10 +1338,10 @@ static int zcache_local_new_pool(uint32_t flags) return zcache_new_pool(LOCAL_CLIENT, flags); } -int zcache_autocreate_pool(int cli_id, int pool_id, bool eph) +int zcache_autocreate_pool(unsigned int cli_id, unsigned int pool_id, bool eph) { struct tmem_pool *pool; - struct zcache_client *cli = NULL; + struct zcache_client *cli; uint32_t flags = eph ? 0 : TMEM_POOL_PERSIST; int ret = -1; @@ -1350,8 +1350,10 @@ int zcache_autocreate_pool(int cli_id, int pool_id, bool eph) goto out; if (pool_id >= MAX_POOLS_PER_CLIENT) goto out; - else if ((unsigned int)cli_id < MAX_CLIENTS) - cli = &zcache_clients[cli_id]; + if (cli_id >= MAX_CLIENTS) + goto out; + + cli = &zcache_clients[cli_id]; if ((eph && disable_cleancache) || (!eph && disable_frontswap)) { pr_err("zcache_autocreate_pool: pool type disabled\n"); goto out; diff --git a/drivers/staging/ramster/zcache.h b/drivers/staging/ramster/zcache.h index c59666e..81722b3 100644 --- a/drivers/staging/ramster/zcache.h +++ b/drivers/staging/ramster/zcache.h @@ -42,7 +42,7 @@ extern void zcache_decompress_to_page(char *, unsigned int, struct page *); #ifdef CONFIG_RAMSTER extern void *zcache_pampd_create(char *, unsigned int, bool, int, struct tmem_handle *); -extern int zcache_autocreate_pool(int, int, bool); +int zcache_autocreate_pool(unsigned int cli_id, unsigned int pool_id, bool eph); #endif #define MAX_POOLS_PER_CLIENT 16 -- cgit v0.10.2 From 84bda909312a5df79cddad875ea6b468cf18da03 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Thu, 6 Sep 2012 12:38:59 +0800 Subject: staging: wlags49_h2: use list_move instead of list_del/list_add Using list_move() instead of list_del() + list_add(). spatch with a semantic match is used to found this problem. (http://coccinelle.lip6.fr/) Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlags49_h2/wl_netdev.c b/drivers/staging/wlags49_h2/wl_netdev.c index dde6327..cc56141 100644 --- a/drivers/staging/wlags49_h2/wl_netdev.c +++ b/drivers/staging/wlags49_h2/wl_netdev.c @@ -835,8 +835,7 @@ int wl_tx( struct sk_buff *skb, struct net_device *dev, int port ) txF->frame.port = port; /* Move the frame to the txQ */ /* NOTE: Here's where we would do priority queueing */ - list_del( &( txF->node )); - list_add( &( txF->node ), &( lp->txQ[0] )); + list_move(&(txF->node), &(lp->txQ[0])); lp->txQ_count++; if( lp->txQ_count >= DEFAULT_NUM_TX_FRAMES ) { -- cgit v0.10.2 From 73295fe185e58b8c0b288fee61a8a994015ab4b2 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Thu, 6 Sep 2012 12:36:49 +0800 Subject: staging: gdm72xx: use list_move instead of list_del/list_add Using list_move() instead of list_del() + list_add(). spatch with a semantic match is used to found this problem. (http://coccinelle.lip6.fr/) Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/gdm72xx/gdm_usb.c b/drivers/staging/gdm72xx/gdm_usb.c index 932a797..41e08a7 100644 --- a/drivers/staging/gdm72xx/gdm_usb.c +++ b/drivers/staging/gdm72xx/gdm_usb.c @@ -186,8 +186,7 @@ static struct usb_rx *get_rx_struct(struct rx_cxt *rx) /* Before this function is called, spin lock should be locked. */ static void put_rx_struct(struct rx_cxt *rx, struct usb_rx *r) { - list_del(&r->list); - list_add(&r->list, &rx->free_list); + list_move(&r->list, &rx->free_list); } static int init_usb(struct usbwm_dev *udev) -- cgit v0.10.2 From 236742de5bfd2af772004ec829518856ff12b469 Mon Sep 17 00:00:00 2001 From: Bernard Blackham Date: Thu, 6 Sep 2012 20:25:04 +1000 Subject: staging: usbip: avoid deadlock in vhci_device_unlink_cleanup() Almost all of usbip assumes that the_controller->lock is acquired before vdev->priv_lock. The exception is in vhci_device_unlink_cleanup(), where locks are acquired in the reverse order. This leads to occasional deadlocks. Fixing this is a bit fiddly, as the_controller->lock can't be held when calling usb_hcd_unlink_urb_from_ep() in the middle of the list traversal. As I can't rule out concurrent callers to this function (perhaps it is safe?), the code here becomes slightly uglier - when locks are dropped in the middle so the list may have emptied itself (not even list_for_each_entry_safe is safe here). Signed-off-by: Bernard Blackham Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c index a5b028d..fd2b21a 100644 --- a/drivers/staging/usbip/vhci_hcd.c +++ b/drivers/staging/usbip/vhci_hcd.c @@ -749,6 +749,7 @@ static void vhci_device_unlink_cleanup(struct vhci_device *vdev) { struct vhci_unlink *unlink, *tmp; + spin_lock(&the_controller->lock); spin_lock(&vdev->priv_lock); list_for_each_entry_safe(unlink, tmp, &vdev->unlink_tx, list) { @@ -757,9 +758,12 @@ static void vhci_device_unlink_cleanup(struct vhci_device *vdev) kfree(unlink); } - list_for_each_entry_safe(unlink, tmp, &vdev->unlink_rx, list) { + while (!list_empty(&vdev->unlink_rx)) { struct urb *urb; + unlink = list_first_entry(&vdev->unlink_rx, struct vhci_unlink, + list); + /* give back URB of unanswered unlink request */ pr_info("unlink cleanup rx %lu\n", unlink->unlink_seqnum); @@ -774,18 +778,24 @@ static void vhci_device_unlink_cleanup(struct vhci_device *vdev) urb->status = -ENODEV; - spin_lock(&the_controller->lock); usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb); + + list_del(&unlink->list); + + spin_unlock(&vdev->priv_lock); spin_unlock(&the_controller->lock); usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, urb->status); - list_del(&unlink->list); + spin_lock(&the_controller->lock); + spin_lock(&vdev->priv_lock); + kfree(unlink); } spin_unlock(&vdev->priv_lock); + spin_unlock(&the_controller->lock); } /* -- cgit v0.10.2 From 107f04bbce331bf622b901ccec34a124e6b78584 Mon Sep 17 00:00:00 2001 From: navin patidar Date: Thu, 6 Sep 2012 16:49:50 +0530 Subject: staging: usbip: vhci_hcd: fixed suspend-resume loop USB autosuspend suspends vhci_hcd. In this process hcd_bus_suspend gets executed which puts vhci_hcd in suspend state and calls vhci_hub_status. vhci_hub_status function checks hub state and if it is in suspend state, usb_hcd_resume_root_hub gets executed which resumes hub and if hub is idle, again autosuspend puts it in suspend state and this goes on. vhci_hub_status should resume hub only when hub port is in suspend state and hub port status has changed. Signed-off-by: navin patidar Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c index fd2b21a..bd79d18 100644 --- a/drivers/staging/usbip/vhci_hcd.c +++ b/drivers/staging/usbip/vhci_hcd.c @@ -220,7 +220,7 @@ static int vhci_hub_status(struct usb_hcd *hcd, char *buf) pr_info("changed %d\n", changed); - if (hcd->state == HC_STATE_SUSPENDED) + if ((hcd->state == HC_STATE_SUSPENDED) && (changed == 1)) usb_hcd_resume_root_hub(hcd); done: -- cgit v0.10.2 From 7c9ab035acb4088dbbf1fec2f478a3a9e47ba15b Mon Sep 17 00:00:00 2001 From: srinivas pandruvada Date: Wed, 5 Sep 2012 13:56:00 +0100 Subject: iio: core: Add hysteresis in channel spec Added hysteresis to the list of channel info enumeration, shared /separate bit defines and to postfix channel info strings. Signed-off-by: srinivas pandruvada Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index fa3b9f5..0499330 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -99,6 +99,7 @@ static const char * const iio_chan_info_postfix[] = { [IIO_CHAN_INFO_FREQUENCY] = "frequency", [IIO_CHAN_INFO_PHASE] = "phase", [IIO_CHAN_INFO_HARDWAREGAIN] = "hardwaregain", + [IIO_CHAN_INFO_HYSTERESIS] = "hysteresis", }; const struct iio_chan_spec diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 057d603..30affa5 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -35,6 +35,7 @@ enum iio_chan_info_enum { IIO_CHAN_INFO_FREQUENCY, IIO_CHAN_INFO_PHASE, IIO_CHAN_INFO_HARDWAREGAIN, + IIO_CHAN_INFO_HYSTERESIS, }; #define IIO_CHAN_INFO_SHARED_BIT(type) BIT(type*2) @@ -100,6 +101,10 @@ enum iio_chan_info_enum { IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_HARDWAREGAIN) #define IIO_CHAN_INFO_HARDWAREGAIN_SHARED_BIT \ IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_HARDWAREGAIN) +#define IIO_CHAN_INFO_HYSTERESIS_SEPARATE_BIT \ + IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_HYSTERESIS) +#define IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT \ + IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_HYSTERESIS) enum iio_endian { IIO_CPU, -- cgit v0.10.2 From 620c789263cdcbb507f332b89beda6a40b82daaf Mon Sep 17 00:00:00 2001 From: srinivas pandruvada Date: Wed, 5 Sep 2012 13:56:00 +0100 Subject: HID: sensors: add documentation Added a summary of HID sensor framework. Signed-off-by: srinivas pandruvada Signed-off-by: Jiri Kosina Signed-off-by: Jonathan Cameron diff --git a/Documentation/hid/hid-sensor.txt b/Documentation/hid/hid-sensor.txt new file mode 100755 index 0000000..948b098 --- /dev/null +++ b/Documentation/hid/hid-sensor.txt @@ -0,0 +1,140 @@ + +HID Sensors Framework +====================== +HID sensor framework provides necessary interfaces to implement sensor drivers, +which are connected to a sensor hub. The sensor hub is a HID device and it provides +a report descriptor conforming to HID 1.12 sensor usage tables. + +Description from the HID 1.12 "HID Sensor Usages" specification: +"Standardization of HID usages for sensors would allow (but not require) sensor +hardware vendors to provide a consistent Plug And Play interface at the USB boundary, +thereby enabling some operating systems to incorporate common device drivers that +could be reused between vendors, alleviating any need for the vendors to provide +the drivers themselves." + +This specification describes many usage IDs, which describe the type of sensor +and also the individual data fields. Each sensor can have variable number of +data fields. The length and order is specified in the report descriptor. For +example a part of report descriptor can look like: + + INPUT(1)[INPUT] + .. + Field(2) + Physical(0020.0073) + Usage(1) + 0020.045f + Logical Minimum(-32767) + Logical Maximum(32767) + Report Size(8) + Report Count(1) + Report Offset(16) + Flags(Variable Absolute) +.. +.. + +The report is indicating "sensor page (0x20)" contains an accelerometer-3D (0x73). +This accelerometer-3D has some fields. Here for example field 2 is motion intensity +(0x045f) with a logical minimum value of -32767 and logical maximum of 32767. The +order of fields and length of each field is important as the input event raw +data will use this format. + + +Implementation +================= + +This specification defines many different types of sensors with different sets of +data fields. It is difficult to have a common input event to user space applications, +for different sensors. For example an accelerometer can send X,Y and Z data, whereas +an ambient light sensor can send illumination data. +So the implementation has two parts: +- Core hid driver +- Individual sensor processing part (sensor drivers) + +Core driver +----------- +The core driver registers (hid-sensor-hub) registers as a HID driver. It parses +report descriptors and identifies all the sensors present. It adds an MFD device +with name HID-SENSOR-xxxx (where xxxx is usage id from the specification). +For example +HID-SENSOR-200073 is registered for an Accelerometer 3D driver. +So if any driver with this name is inserted, then the probe routine for that +function will be called. So an accelerometer processing driver can register +with this name and will be probed if there is an accelerometer-3D detected. + +The core driver provides a set of APIs which can be used by the processing +drivers to register and get events for that usage id. Also it provides parsing +functions, which get and set each input/feature/output report. + +Individual sensor processing part (sensor drivers) +----------- +The processing driver will use an interface provided by the core driver to parse +the report and get the indexes of the fields and also can get events. This driver +can use IIO interface to use the standard ABI defined for a type of sensor. + + +Core driver Interface +===================== + +Callback structure: +Each processing driver can use this structure to set some callbacks. + int (*suspend)(..): Callback when HID suspend is received + int (*resume)(..): Callback when HID resume is received + int (*capture_sample)(..): Capture a sample for one of its data fields + int (*send_event)(..): One complete event is received which can have + multiple data fields. + +Registration functions: +int sensor_hub_register_callback(struct hid_sensor_hub_device *hsdev, + u32 usage_id, + struct hid_sensor_hub_callbacks *usage_callback): + +Registers callbacks for an usage id. The callback functions are not allowed +to sleep. + + +int sensor_hub_remove_callback(struct hid_sensor_hub_device *hsdev, + u32 usage_id): + +Removes callbacks for an usage id. + + +Parsing function: +int sensor_hub_input_get_attribute_info(struct hid_sensor_hub_device *hsdev, + u8 type, + u32 usage_id, u32 attr_usage_id, + struct hid_sensor_hub_attribute_info *info); + +A processing driver can look for some field of interest and check if it exists +in a report descriptor. If it exists it will store necessary information +so that fields can be set or get individually. +These indexes avoid searching every time and getting field index to get or set. + + +Set Feature report +int sensor_hub_set_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, + u32 field_index, s32 value); + +This interface is used to set a value for a field in feature report. For example +if there is a field report_interval, which is parsed by a call to +sensor_hub_input_get_attribute_info before, then it can directly set that individual +field. + + +int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, + u32 field_index, s32 *value); + +This interface is used to get a value for a field in input report. For example +if there is a field report_interval, which is parsed by a call to +sensor_hub_input_get_attribute_info before, then it can directly get that individual +field value. + + +int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev, + u32 usage_id, + u32 attr_usage_id, u32 report_id); + +This is used to get a particular field value through input reports. For example +accelerometer wants to poll X axis value, then it can call this function with +the usage id of X axis. HID sensors can provide events, so this is not necessary +to poll for any field. If there is some new sample, the core driver will call +registered callback function to process the sample. -- cgit v0.10.2 From c8147d9ea19bfe7d8e569351bc7239e118dd6997 Mon Sep 17 00:00:00 2001 From: srinivas pandruvada Date: Wed, 5 Sep 2012 13:56:00 +0100 Subject: HID: sensors: add to special driver list Adding Intel and STM sensor hub in the list of drivers with specialized driver. Signed-off-by: srinivas pandruvada Signed-off-by: Jiri Kosina Signed-off-by: Jonathan Cameron diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 60ea284..15ffc0a 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1550,6 +1550,10 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) }, { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK, USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP) }, { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD) }, + { HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8086, USB_DEVICE_ID_SENSOR_HUB_1020) }, + { HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8086, USB_DEVICE_ID_SENSOR_HUB_09FA) }, + { HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8087, USB_DEVICE_ID_SENSOR_HUB_1020) }, + { HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8087, USB_DEVICE_ID_SENSOR_HUB_09FA) }, { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) }, { HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) }, { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) }, @@ -1642,6 +1646,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) }, { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, + { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM, USB_DEVICE_ID_SENSOR_HUB_7014) }, { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) }, { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) }, { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 1dcb76f..8a270a3 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -419,6 +419,11 @@ #define USB_VENDOR_ID_IMATION 0x0718 #define USB_DEVICE_ID_DISC_STAKKA 0xd000 +#define USB_VENDOR_ID_INTEL_8086 0x8086 +#define USB_VENDOR_ID_INTEL_8087 0x8087 +#define USB_DEVICE_ID_SENSOR_HUB_1020 0x1020 +#define USB_DEVICE_ID_SENSOR_HUB_09FA 0x09FA + #define USB_VENDOR_ID_IRTOUCHSYSTEMS 0x6615 #define USB_DEVICE_ID_IRTOUCH_INFRARED_USB 0x0070 @@ -695,6 +700,7 @@ #define USB_VENDOR_ID_STANTUM_STM 0x0483 #define USB_DEVICE_ID_MTP_STM 0x3261 +#define USB_DEVICE_ID_SENSOR_HUB_7014 0x7014 #define USB_VENDOR_ID_STANTUM_SITRONIX 0x1403 #define USB_DEVICE_ID_MTP_SITRONIX 0x5001 -- cgit v0.10.2 From 401ca24fb34aee0cedf9c4fef361e533224f15a1 Mon Sep 17 00:00:00 2001 From: srinivas pandruvada Date: Wed, 5 Sep 2012 13:56:00 +0100 Subject: HID: sensors: introduce sensor framework Adding processing for HID Sensor usage table as defined by HID 1.12, Request #: HUTRR39, dated 05 May, 2011. This driver uses HID driver framework to register, send and receive events. This uses MFD framework, so that actual processing for a specific usage id can be done in a different driver. For example an accelerometer driver can be a separate driver and use the interface provided by this driver to register for events. Signed-off-by: srinivas pandruvada Signed-off-by: Jiri Kosina Signed-off-by: Jonathan Cameron diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index fbf4950..f8d3140 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -690,6 +690,20 @@ config HID_ZYDACRON ---help--- Support for Zydacron remote control. +config HID_SENSOR_HUB + tristate "HID Sensors framework support" + depends on USB_HID + select MFD_CORE + default n + -- help--- + Support for HID Sensor framework. This creates a MFD instance + for a sensor hub and identifies all the sensors connected to it. + Each sensor is registered as a MFD cell, so that sensor specific + processing can be done in a separate driver. Each sensor + drivers can use the service provided by this driver to register + for events and handle data streams. Each sensor driver can format + data and present to user mode using input or IIO interface. + endmenu endif # HID diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index f975485..1173d7a 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -91,6 +91,7 @@ obj-$(CONFIG_HID_ZYDACRON) += hid-zydacron.o obj-$(CONFIG_HID_WACOM) += hid-wacom.o obj-$(CONFIG_HID_WALTOP) += hid-waltop.o obj-$(CONFIG_HID_WIIMOTE) += hid-wiimote.o +obj-$(CONFIG_HID_SENSOR_HUB) += hid-sensor-hub.o obj-$(CONFIG_USB_HID) += usbhid/ obj-$(CONFIG_USB_MOUSE) += usbhid/ diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c new file mode 100644 index 0000000..34a35ba --- /dev/null +++ b/drivers/hid/hid-sensor-hub.c @@ -0,0 +1,695 @@ +/* + * HID Sensors Driver + * Copyright (c) 2012, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ +#include +#include +#include +#include "usbhid/usbhid.h" +#include +#include +#include +#include +#include +#include +#include "hid-ids.h" + +/** + * struct sensor_hub_pending - Synchronous read pending information + * @status: Pending status true/false. + * @ready: Completion synchronization data. + * @usage_id: Usage id for physical device, E.g. Gyro usage id. + * @attr_usage_id: Usage Id of a field, E.g. X-AXIS for a gyro. + * @raw_size: Response size for a read request. + * @raw_data: Place holder for received response. + */ +struct sensor_hub_pending { + bool status; + struct completion ready; + u32 usage_id; + u32 attr_usage_id; + int raw_size; + u8 *raw_data; +}; + +/** + * struct sensor_hub_data - Hold a instance data for a HID hub device + * @hsdev: Stored hid instance for current hub device. + * @mutex: Mutex to serialize synchronous request. + * @lock: Spin lock to protect pending request structure. + * @pending: Holds information of pending sync read request. + * @dyn_callback_list: Holds callback function + * @dyn_callback_lock: spin lock to protect callback list + * @hid_sensor_hub_client_devs: Stores all MFD cells for a hub instance. + * @hid_sensor_client_cnt: Number of MFD cells, (no of sensors attached). + */ +struct sensor_hub_data { + struct hid_sensor_hub_device *hsdev; + struct mutex mutex; + spinlock_t lock; + struct sensor_hub_pending pending; + struct list_head dyn_callback_list; + spinlock_t dyn_callback_lock; + struct mfd_cell *hid_sensor_hub_client_devs; + int hid_sensor_client_cnt; +}; + +/** + * struct hid_sensor_hub_callbacks_list - Stores callback list + * @list: list head. + * @usage_id: usage id for a physical device. + * @usage_callback: Stores registered callback functions. + * @priv: Private data for a physical device. + */ +struct hid_sensor_hub_callbacks_list { + struct list_head list; + u32 usage_id; + struct hid_sensor_hub_callbacks *usage_callback; + void *priv; +}; + +static int sensor_hub_check_for_sensor_page(struct hid_device *hdev) +{ + int i; + int ret = -EINVAL; + + for (i = 0; i < hdev->maxcollection; i++) { + struct hid_collection *col = &hdev->collection[i]; + if (col->type == HID_COLLECTION_PHYSICAL && + (col->usage & HID_USAGE_PAGE) == HID_UP_SENSOR) { + ret = 0; + break; + } + } + + return ret; +} + +static struct hid_report *sensor_hub_report(int id, struct hid_device *hdev, + int dir) +{ + struct hid_report *report; + + list_for_each_entry(report, &hdev->report_enum[dir].report_list, list) { + if (report->id == id) + return report; + } + hid_warn(hdev, "No report with id 0x%x found\n", id); + + return NULL; +} + +static int sensor_hub_get_physical_device_count( + struct hid_report_enum *report_enum) +{ + struct hid_report *report; + struct hid_field *field; + int cnt = 0; + + list_for_each_entry(report, &report_enum->report_list, list) { + field = report->field[0]; + if (report->maxfield && field && + field->physical) + cnt++; + } + + return cnt; +} + +static void sensor_hub_fill_attr_info( + struct hid_sensor_hub_attribute_info *info, + s32 index, s32 report_id, s32 units, s32 unit_expo, s32 size) +{ + info->index = index; + info->report_id = report_id; + info->units = units; + info->unit_expo = unit_expo; + info->size = size/8; +} + +static struct hid_sensor_hub_callbacks *sensor_hub_get_callback( + struct hid_device *hdev, + u32 usage_id, void **priv) +{ + struct hid_sensor_hub_callbacks_list *callback; + struct sensor_hub_data *pdata = hid_get_drvdata(hdev); + + spin_lock(&pdata->dyn_callback_lock); + list_for_each_entry(callback, &pdata->dyn_callback_list, list) + if (callback->usage_id == usage_id) { + *priv = callback->priv; + spin_unlock(&pdata->dyn_callback_lock); + return callback->usage_callback; + } + spin_unlock(&pdata->dyn_callback_lock); + + return NULL; +} + +int sensor_hub_register_callback(struct hid_sensor_hub_device *hsdev, + u32 usage_id, + struct hid_sensor_hub_callbacks *usage_callback) +{ + struct hid_sensor_hub_callbacks_list *callback; + struct sensor_hub_data *pdata = hid_get_drvdata(hsdev->hdev); + + spin_lock(&pdata->dyn_callback_lock); + list_for_each_entry(callback, &pdata->dyn_callback_list, list) + if (callback->usage_id == usage_id) { + spin_unlock(&pdata->dyn_callback_lock); + return -EINVAL; + } + callback = kzalloc(sizeof(*callback), GFP_KERNEL); + if (!callback) { + spin_unlock(&pdata->dyn_callback_lock); + return -ENOMEM; + } + callback->usage_callback = usage_callback; + callback->usage_id = usage_id; + callback->priv = NULL; + list_add_tail(&callback->list, &pdata->dyn_callback_list); + spin_unlock(&pdata->dyn_callback_lock); + + return 0; +} +EXPORT_SYMBOL_GPL(sensor_hub_register_callback); + +int sensor_hub_remove_callback(struct hid_sensor_hub_device *hsdev, + u32 usage_id) +{ + struct hid_sensor_hub_callbacks_list *callback; + struct sensor_hub_data *pdata = hid_get_drvdata(hsdev->hdev); + + spin_lock(&pdata->dyn_callback_lock); + list_for_each_entry(callback, &pdata->dyn_callback_list, list) + if (callback->usage_id == usage_id) { + list_del(&callback->list); + kfree(callback); + break; + } + spin_unlock(&pdata->dyn_callback_lock); + + return 0; +} +EXPORT_SYMBOL_GPL(sensor_hub_remove_callback); + +int sensor_hub_set_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, + u32 field_index, s32 value) +{ + struct hid_report *report; + struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev); + int ret = 0; + + if (report_id < 0) + return -EINVAL; + + mutex_lock(&data->mutex); + report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT); + if (!report || (field_index >= report->maxfield)) { + ret = -EINVAL; + goto done_proc; + } + hid_set_field(report->field[field_index], 0, value); + usbhid_submit_report(hsdev->hdev, report, USB_DIR_OUT); + usbhid_wait_io(hsdev->hdev); + +done_proc: + mutex_unlock(&data->mutex); + + return ret; +} +EXPORT_SYMBOL_GPL(sensor_hub_set_feature); + +int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, + u32 field_index, s32 *value) +{ + struct hid_report *report; + struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev); + int ret = 0; + + if (report_id < 0) + return -EINVAL; + + mutex_lock(&data->mutex); + report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT); + if (!report || (field_index >= report->maxfield)) { + ret = -EINVAL; + goto done_proc; + } + usbhid_submit_report(hsdev->hdev, report, USB_DIR_IN); + usbhid_wait_io(hsdev->hdev); + *value = report->field[field_index]->value[0]; + +done_proc: + mutex_unlock(&data->mutex); + + return ret; +} +EXPORT_SYMBOL_GPL(sensor_hub_get_feature); + + +int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev, + u32 usage_id, + u32 attr_usage_id, u32 report_id) +{ + struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev); + unsigned long flags; + struct hid_report *report; + int ret_val = 0; + + if (report_id < 0) + return -EINVAL; + + mutex_lock(&data->mutex); + memset(&data->pending, 0, sizeof(data->pending)); + init_completion(&data->pending.ready); + data->pending.usage_id = usage_id; + data->pending.attr_usage_id = attr_usage_id; + data->pending.raw_size = 0; + + spin_lock_irqsave(&data->lock, flags); + data->pending.status = true; + report = sensor_hub_report(report_id, hsdev->hdev, HID_INPUT_REPORT); + if (!report) { + spin_unlock_irqrestore(&data->lock, flags); + goto err_free; + } + usbhid_submit_report(hsdev->hdev, report, USB_DIR_IN); + spin_unlock_irqrestore(&data->lock, flags); + wait_for_completion_interruptible_timeout(&data->pending.ready, HZ*5); + switch (data->pending.raw_size) { + case 1: + ret_val = *(u8 *)data->pending.raw_data; + break; + case 2: + ret_val = *(u16 *)data->pending.raw_data; + break; + case 4: + ret_val = *(u32 *)data->pending.raw_data; + break; + default: + ret_val = 0; + } + kfree(data->pending.raw_data); + +err_free: + data->pending.status = false; + mutex_unlock(&data->mutex); + + return ret_val; +} +EXPORT_SYMBOL_GPL(sensor_hub_input_attr_get_raw_value); + +int sensor_hub_input_get_attribute_info(struct hid_sensor_hub_device *hsdev, + u8 type, + u32 usage_id, + u32 attr_usage_id, + struct hid_sensor_hub_attribute_info *info) +{ + int ret = -1; + int i, j; + int collection_index = -1; + struct hid_report *report; + struct hid_field *field; + struct hid_report_enum *report_enum; + struct hid_device *hdev = hsdev->hdev; + + /* Initialize with defaults */ + info->usage_id = usage_id; + info->attrib_id = attr_usage_id; + info->report_id = -1; + info->index = -1; + info->units = -1; + info->unit_expo = -1; + + for (i = 0; i < hdev->maxcollection; ++i) { + struct hid_collection *collection = &hdev->collection[i]; + if (usage_id == collection->usage) { + collection_index = i; + break; + } + } + if (collection_index == -1) + goto err_ret; + + report_enum = &hdev->report_enum[type]; + list_for_each_entry(report, &report_enum->report_list, list) { + for (i = 0; i < report->maxfield; ++i) { + field = report->field[i]; + if (field->physical == usage_id && + field->logical == attr_usage_id) { + sensor_hub_fill_attr_info(info, i, report->id, + field->unit, field->unit_exponent, + field->report_size); + ret = 0; + } else { + for (j = 0; j < field->maxusage; ++j) { + if (field->usage[j].hid == + attr_usage_id && + field->usage[j].collection_index == + collection_index) { + sensor_hub_fill_attr_info(info, + i, report->id, + field->unit, + field->unit_exponent, + field->report_size); + ret = 0; + break; + } + } + } + if (ret == 0) + break; + } + } + +err_ret: + return ret; +} +EXPORT_SYMBOL_GPL(sensor_hub_input_get_attribute_info); + +#ifdef CONFIG_PM +static int sensor_hub_suspend(struct hid_device *hdev, pm_message_t message) +{ + struct sensor_hub_data *pdata = hid_get_drvdata(hdev); + struct hid_sensor_hub_callbacks_list *callback; + + hid_dbg(hdev, " sensor_hub_suspend\n"); + spin_lock(&pdata->dyn_callback_lock); + list_for_each_entry(callback, &pdata->dyn_callback_list, list) { + if (callback->usage_callback->suspend) + callback->usage_callback->suspend( + pdata->hsdev, callback->priv); + } + spin_unlock(&pdata->dyn_callback_lock); + + return 0; +} + +static int sensor_hub_resume(struct hid_device *hdev) +{ + struct sensor_hub_data *pdata = hid_get_drvdata(hdev); + struct hid_sensor_hub_callbacks_list *callback; + + hid_dbg(hdev, " sensor_hub_resume\n"); + spin_lock(&pdata->dyn_callback_lock); + list_for_each_entry(callback, &pdata->dyn_callback_list, list) { + if (callback->usage_callback->resume) + callback->usage_callback->resume( + pdata->hsdev, callback->priv); + } + spin_unlock(&pdata->dyn_callback_lock); + + return 0; +} + +static int sensor_hub_reset_resume(struct hid_device *hdev) +{ + return 0; +} +#endif +/* + * Handle raw report as sent by device + */ +static int sensor_hub_raw_event(struct hid_device *hdev, + struct hid_report *report, u8 *raw_data, int size) +{ + int i; + u8 *ptr; + int sz; + struct sensor_hub_data *pdata = hid_get_drvdata(hdev); + unsigned long flags; + struct hid_sensor_hub_callbacks *callback = NULL; + struct hid_collection *collection = NULL; + void *priv = NULL; + + hid_dbg(hdev, "sensor_hub_raw_event report id:0x%x size:%d type:%d\n", + report->id, size, report->type); + hid_dbg(hdev, "maxfield:%d\n", report->maxfield); + if (report->type != HID_INPUT_REPORT) + return 1; + + ptr = raw_data; + ptr++; /*Skip report id*/ + + if (!report) + goto err_report; + + spin_lock_irqsave(&pdata->lock, flags); + + for (i = 0; i < report->maxfield; ++i) { + + hid_dbg(hdev, "%d collection_index:%x hid:%x sz:%x\n", + i, report->field[i]->usage->collection_index, + report->field[i]->usage->hid, + report->field[i]->report_size/8); + + sz = report->field[i]->report_size/8; + if (pdata->pending.status && pdata->pending.attr_usage_id == + report->field[i]->usage->hid) { + hid_dbg(hdev, "data was pending ...\n"); + pdata->pending.raw_data = kmalloc(sz, GFP_KERNEL); + if (pdata->pending.raw_data) { + memcpy(pdata->pending.raw_data, ptr, sz); + pdata->pending.raw_size = sz; + } else + pdata->pending.raw_size = 0; + complete(&pdata->pending.ready); + } + collection = &hdev->collection[ + report->field[i]->usage->collection_index]; + hid_dbg(hdev, "collection->usage %x\n", + collection->usage); + callback = sensor_hub_get_callback(pdata->hsdev->hdev, + report->field[i]->physical, + &priv); + if (callback && callback->capture_sample) { + if (report->field[i]->logical) + callback->capture_sample(pdata->hsdev, + report->field[i]->logical, sz, ptr, + callback->pdev); + else + callback->capture_sample(pdata->hsdev, + report->field[i]->usage->hid, sz, ptr, + callback->pdev); + } + ptr += sz; + } + if (callback && collection && callback->send_event) + callback->send_event(pdata->hsdev, collection->usage, + callback->pdev); + spin_unlock_irqrestore(&pdata->lock, flags); + +err_report: + return 1; +} + +static int sensor_hub_probe(struct hid_device *hdev, + const struct hid_device_id *id) +{ + int ret; + struct sensor_hub_data *sd; + int i; + char *name; + struct hid_report *report; + struct hid_report_enum *report_enum; + struct hid_field *field; + int dev_cnt; + + sd = kzalloc(sizeof(struct sensor_hub_data), GFP_KERNEL); + if (!sd) { + hid_err(hdev, "cannot allocate Sensor data\n"); + return -ENOMEM; + } + sd->hsdev = kzalloc(sizeof(struct hid_sensor_hub_device), GFP_KERNEL); + if (!sd->hsdev) { + hid_err(hdev, "cannot allocate hid_sensor_hub_device\n"); + ret = -ENOMEM; + goto err_free_hub; + } + hid_set_drvdata(hdev, sd); + sd->hsdev->hdev = hdev; + sd->hsdev->vendor_id = hdev->vendor; + sd->hsdev->product_id = hdev->product; + spin_lock_init(&sd->lock); + spin_lock_init(&sd->dyn_callback_lock); + mutex_init(&sd->mutex); + ret = hid_parse(hdev); + if (ret) { + hid_err(hdev, "parse failed\n"); + goto err_free; + } + if (sensor_hub_check_for_sensor_page(hdev) < 0) { + hid_err(hdev, "sensor page not found\n"); + goto err_free; + } + INIT_LIST_HEAD(&hdev->inputs); + + hdev->claimed = HID_CLAIMED_INPUT; + ret = hid_hw_start(hdev, 0); + if (ret) { + hid_err(hdev, "hw start failed\n"); + goto err_free; + } + ret = hid_hw_open(hdev); + if (ret) { + hid_err(hdev, "failed to open input interrupt pipe\n"); + goto err_stop_hw; + } + + INIT_LIST_HEAD(&sd->dyn_callback_list); + sd->hid_sensor_client_cnt = 0; + report_enum = &hdev->report_enum[HID_INPUT_REPORT]; + + dev_cnt = sensor_hub_get_physical_device_count(report_enum); + if (dev_cnt > HID_MAX_PHY_DEVICES) { + hid_err(hdev, "Invalid Physical device count\n"); + ret = -EINVAL; + goto err_close; + } + sd->hid_sensor_hub_client_devs = kzalloc(dev_cnt * + sizeof(struct mfd_cell), + GFP_KERNEL); + if (sd->hid_sensor_hub_client_devs == NULL) { + hid_err(hdev, + "Failed to allocate memory for mfd cells\n"); + ret = -ENOMEM; + goto err_close; + } + list_for_each_entry(report, &report_enum->report_list, list) { + hid_dbg(hdev, "Report id:%x\n", report->id); + field = report->field[0]; + if (report->maxfield && field && + field->physical) { + name = kasprintf(GFP_KERNEL, "HID-SENSOR-%x", + field->physical); + if (name == NULL) { + hid_err(hdev, + "Failed MFD device name\n"); + ret = -ENOMEM; + goto err_free_cells; + } + sd->hid_sensor_hub_client_devs[ + sd->hid_sensor_client_cnt].name = name; + sd->hid_sensor_hub_client_devs[ + sd->hid_sensor_client_cnt].platform_data = + sd->hsdev; + sd->hid_sensor_hub_client_devs[ + sd->hid_sensor_client_cnt].pdata_size = + sizeof(*sd->hsdev); + hid_dbg(hdev, "Adding %s:%p\n", name, sd); + sd->hid_sensor_client_cnt++; + } + } + ret = mfd_add_devices(&hdev->dev, 0, sd->hid_sensor_hub_client_devs, + sd->hid_sensor_client_cnt, NULL, 0); + if (ret < 0) + goto err_free_names; + + return ret; + +err_free_names: + for (i = 0; i < sd->hid_sensor_client_cnt ; ++i) + kfree(sd->hid_sensor_hub_client_devs[i].name); +err_free_cells: + kfree(sd->hid_sensor_hub_client_devs); +err_close: + hid_hw_stop(hdev); + hid_hw_close(hdev); +err_stop_hw: + hid_hw_stop(hdev); +err_free: + kfree(sd->hsdev); +err_free_hub: + kfree(sd); + + return ret; +} + +static void sensor_hub_remove(struct hid_device *hdev) +{ + struct sensor_hub_data *data = hid_get_drvdata(hdev); + unsigned long flags; + int i; + + hid_dbg(hdev, " hardware removed\n"); + hdev->claimed &= ~HID_CLAIMED_INPUT; + hid_hw_stop(hdev); + hid_hw_close(hdev); + spin_lock_irqsave(&data->lock, flags); + if (data->pending.status) + complete(&data->pending.ready); + spin_unlock_irqrestore(&data->lock, flags); + mfd_remove_devices(&hdev->dev); + for (i = 0; i < data->hid_sensor_client_cnt ; ++i) + kfree(data->hid_sensor_hub_client_devs[i].name); + kfree(data->hid_sensor_hub_client_devs); + hid_set_drvdata(hdev, NULL); + mutex_destroy(&data->mutex); + kfree(data->hsdev); + kfree(data); +} + +static const struct hid_device_id sensor_hub_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8086, + USB_DEVICE_ID_SENSOR_HUB_1020) }, + { HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8087, + USB_DEVICE_ID_SENSOR_HUB_1020) }, + { HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8086, + USB_DEVICE_ID_SENSOR_HUB_09FA) }, + { HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8087, + USB_DEVICE_ID_SENSOR_HUB_09FA) }, + { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM, + USB_DEVICE_ID_SENSOR_HUB_7014) }, + { } +}; +MODULE_DEVICE_TABLE(hid, sensor_hub_devices); + +static const struct hid_usage_id sensor_hub_grabbed_usages[] = { + { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID }, + { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1 } +}; + +static struct hid_driver sensor_hub_driver = { + .name = "hid-sensor-hub", + .id_table = sensor_hub_devices, + .probe = sensor_hub_probe, + .remove = sensor_hub_remove, + .raw_event = sensor_hub_raw_event, +#ifdef CONFIG_PM + .suspend = sensor_hub_suspend, + .resume = sensor_hub_resume, + .reset_resume = sensor_hub_reset_resume, +#endif +}; + +static int __init sensor_hub_init(void) +{ + return hid_register_driver(&sensor_hub_driver); +} + +static void __exit sensor_hub_exit(void) +{ + hid_unregister_driver(&sensor_hub_driver); +} + +module_init(sensor_hub_init); +module_exit(sensor_hub_exit); + +MODULE_DESCRIPTION("HID Sensor Hub driver"); +MODULE_AUTHOR("Srinivas Pandruvada "); +MODULE_LICENSE("GPL"); diff --git a/include/linux/hid-sensor-hub.h b/include/linux/hid-sensor-hub.h new file mode 100644 index 0000000..0aa5f4c --- /dev/null +++ b/include/linux/hid-sensor-hub.h @@ -0,0 +1,160 @@ +/* + * HID Sensors Driver + * Copyright (c) 2012, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ +#ifndef _HID_SENSORS_HUB_H +#define _HID_SENSORS_HUB_H + +#include +#include + +/** + * struct hid_sensor_hub_attribute_info - Attribute info + * @usage_id: Parent usage id of a physical device. + * @attrib_id: Attribute id for this attribute. + * @report_id: Report id in which this information resides. + * @index: Field index in the report. + * @units: Measurment unit for this attribute. + * @unit_expo: Exponent used in the data. + * @size: Size in bytes for data size. + */ +struct hid_sensor_hub_attribute_info { + u32 usage_id; + u32 attrib_id; + s32 report_id; + s32 index; + s32 units; + s32 unit_expo; + s32 size; +}; + +/** + * struct hid_sensor_hub_device - Stores the hub instance data + * @hdev: Stores the hid instance. + * @vendor_id: Vendor id of hub device. + * @product_id: Product id of hub device. + */ +struct hid_sensor_hub_device { + struct hid_device *hdev; + u32 vendor_id; + u32 product_id; +}; + +/** + * struct hid_sensor_hub_callbacks - Client callback functions + * @pdev: Platform device instance of the client driver. + * @suspend: Suspend callback. + * @resume: Resume callback. + * @capture_sample: Callback to get a sample. + * @send_event: Send notification to indicate all samples are + * captured, process and send event + */ +struct hid_sensor_hub_callbacks { + struct platform_device *pdev; + int (*suspend)(struct hid_sensor_hub_device *hsdev, void *priv); + int (*resume)(struct hid_sensor_hub_device *hsdev, void *priv); + int (*capture_sample)(struct hid_sensor_hub_device *hsdev, + u32 usage_id, size_t raw_len, char *raw_data, + void *priv); + int (*send_event)(struct hid_sensor_hub_device *hsdev, u32 usage_id, + void *priv); +}; + +/* Registration functions */ + +/** +* sensor_hub_register_callback() - Register client callbacks +* @hsdev: Hub device instance. +* @usage_id: Usage id of the client (E.g. 0x200076 for Gyro). +* @usage_callback: Callback function storage +* +* Used to register callbacks by client processing drivers. Sensor +* hub core driver will call these callbacks to offload processing +* of data streams and notifications. +*/ +int sensor_hub_register_callback(struct hid_sensor_hub_device *hsdev, + u32 usage_id, + struct hid_sensor_hub_callbacks *usage_callback); + +/** +* sensor_hub_remove_callback() - Remove client callbacks +* @hsdev: Hub device instance. +* @usage_id: Usage id of the client (E.g. 0x200076 for Gyro). +* +* If there is a callback registred, this call will remove that +* callbacks, so that it will stop data and event notifications. +*/ +int sensor_hub_remove_callback(struct hid_sensor_hub_device *hsdev, + u32 usage_id); + + +/* Hid sensor hub core interfaces */ + +/** +* sensor_hub_input_get_attribute_info() - Get an attribute information +* @hsdev: Hub device instance. +* @type: Type of this attribute, input/output/feature +* @usage_id: Attribute usage id of parent physical device as per spec +* @attr_usage_id: Attribute usage id as per spec +* @info: return information about attribute after parsing report +* +* Parses report and returns the attribute information such as report id, +* field index, units and exponet etc. +*/ +int sensor_hub_input_get_attribute_info(struct hid_sensor_hub_device *hsdev, + u8 type, + u32 usage_id, u32 attr_usage_id, + struct hid_sensor_hub_attribute_info *info); + +/** +* sensor_hub_input_attr_get_raw_value() - Synchronous read request +* @usage_id: Attribute usage id of parent physical device as per spec +* @attr_usage_id: Attribute usage id as per spec +* @report_id: Report id to look for +* +* Issues a synchronous read request for an input attribute. Returns +* data upto 32 bits. Since client can get events, so this call should +* not be used for data paths, this will impact performance. +*/ + +int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev, + u32 usage_id, + u32 attr_usage_id, u32 report_id); +/** +* sensor_hub_set_feature() - Feature set request +* @report_id: Report id to look for +* @field_index: Field index inside a report +* @value: Value to set +* +* Used to set a field in feature report. For example this can set polling +* interval, sensitivity, activate/deactivate state. +*/ +int sensor_hub_set_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, + u32 field_index, s32 value); + +/** +* sensor_hub_get_feature() - Feature get request +* @report_id: Report id to look for +* @field_index: Field index inside a report +* @value: Place holder for return value +* +* Used to get a field in feature report. For example this can get polling +* interval, sensitivity, activate/deactivate state. +*/ +int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, + u32 field_index, s32 *value); +#endif diff --git a/include/linux/hid-sensor-ids.h b/include/linux/hid-sensor-ids.h new file mode 100644 index 0000000..ca8d7e9 --- /dev/null +++ b/include/linux/hid-sensor-ids.h @@ -0,0 +1,112 @@ +/* + * HID Sensors Driver + * Copyright (c) 2012, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ +#ifndef _HID_SENSORS_IDS_H +#define _HID_SENSORS_IDS_H + +#define HID_UP_SENSOR 0x00200000 +#define HID_MAX_PHY_DEVICES 0xFF + +/* Accel 3D (200073) */ +#define HID_USAGE_SENSOR_ACCEL_3D 0x200073 +#define HID_USAGE_SENSOR_ACCEL_X_AXIS 0x200453 +#define HID_USAGE_SENSOR_ACCEL_Y_AXIS 0x200454 +#define HID_USAGE_SENSOR_ACCEL_Z_AXIS 0x200455 + +/* ALS (200041) */ +#define HID_USAGE_SENSOR_ALS 0x200041 +#define HID_USAGE_SENSOR_LIGHT_ILLUM 0x2004d1 + +/* Gyro 3D: (200076) */ +#define HID_USAGE_SENSOR_GYRO_3D 0x200076 +#define HID_USAGE_SENSOR_ANGL_VELOCITY_X_AXIS 0x200457 +#define HID_USAGE_SENSOR_ANGL_VELOCITY_Y_AXIS 0x200458 +#define HID_USAGE_SENSOR_ANGL_VELOCITY_Z_AXIS 0x200459 + +/*ORIENTATION: Compass 3D: (200083) */ +#define HID_USAGE_SENSOR_COMPASS_3D 0x200083 +#define HID_USAGE_SENSOR_ORIENT_MAGN_HEADING 0x200471 +#define HID_USAGE_SENSOR_ORIENT_MAGN_HEADING_X 0x200472 +#define HID_USAGE_SENSOR_ORIENT_MAGN_HEADING_Y 0x200473 +#define HID_USAGE_SENSOR_ORIENT_MAGN_HEADING_Z 0x200474 + +#define HID_USAGE_SENSOR_ORIENT_COMP_MAGN_NORTH 0x200475 +#define HID_USAGE_SENSOR_ORIENT_COMP_TRUE_NORTH 0x200476 +#define HID_USAGE_SENSOR_ORIENT_MAGN_NORTH 0x200477 +#define HID_USAGE_SENSOR_ORIENT_TRUE_NORTH 0x200478 + +#define HID_USAGE_SENSOR_ORIENT_DISTANCE 0x200479 +#define HID_USAGE_SENSOR_ORIENT_DISTANCE_X 0x20047A +#define HID_USAGE_SENSOR_ORIENT_DISTANCE_Y 0x20047B +#define HID_USAGE_SENSOR_ORIENT_DISTANCE_Z 0x20047C +#define HID_USAGE_SENSOR_ORIENT_DISTANCE_OUT_OF_RANGE 0x20047D +#define HID_USAGE_SENSOR_ORIENT_TILT 0x20047E +#define HID_USAGE_SENSOR_ORIENT_TILT_X 0x20047F +#define HID_USAGE_SENSOR_ORIENT_TILT_Y 0x200480 +#define HID_USAGE_SENSOR_ORIENT_TILT_Z 0x200481 +#define HID_USAGE_SENSOR_ORIENT_ROTATION_MATRIX 0x200482 +#define HID_USAGE_SENSOR_ORIENT_QUATERNION 0x200483 +#define HID_USAGE_SENSOR_ORIENT_MAGN_FLUX 0x200484 + +#define HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS 0x200485 +#define HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Y_AXIS 0x200486 +#define HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS 0x200487 + +/* Units */ +#define HID_USAGE_SENSOR_UNITS_NOT_SPECIFIED 0x00 +#define HID_USAGE_SENSOR_UNITS_LUX 0x01 +#define HID_USAGE_SENSOR_UNITS_KELVIN 0x01000100 +#define HID_USAGE_SENSOR_UNITS_FAHRENHEIT 0x03000100 +#define HID_USAGE_SENSOR_UNITS_PASCAL 0xF1E1 +#define HID_USAGE_SENSOR_UNITS_NEWTON 0x11E1 +#define HID_USAGE_SENSOR_UNITS_METERS_PER_SECOND 0x11F0 +#define HID_USAGE_SENSOR_UNITS_METERS_PER_SEC_SQRD 0x11E0 +#define HID_USAGE_SENSOR_UNITS_FARAD 0xE14F2000 +#define HID_USAGE_SENSOR_UNITS_AMPERE 0x01001000 +#define HID_USAGE_SENSOR_UNITS_WATT 0x21d1 +#define HID_USAGE_SENSOR_UNITS_HENRY 0x21E1E000 +#define HID_USAGE_SENSOR_UNITS_OHM 0x21D1E000 +#define HID_USAGE_SENSOR_UNITS_VOLT 0x21D1F000 +#define HID_USAGE_SENSOR_UNITS_HERTZ 0x01F0 +#define HID_USAGE_SENSOR_UNITS_DEGREES_PER_SEC_SQRD 0x14E0 +#define HID_USAGE_SENSOR_UNITS_RADIANS 0x12 +#define HID_USAGE_SENSOR_UNITS_RADIANS_PER_SECOND 0x12F0 +#define HID_USAGE_SENSOR_UNITS_RADIANS_PER_SEC_SQRD 0x12E0 +#define HID_USAGE_SENSOR_UNITS_SECOND 0x0110 +#define HID_USAGE_SENSOR_UNITS_GAUSS 0x01E1F000 +#define HID_USAGE_SENSOR_UNITS_GRAM 0x0101 +#define HID_USAGE_SENSOR_UNITS_CENTIMETER 0x11 +#define HID_USAGE_SENSOR_UNITS_G 0x1A +#define HID_USAGE_SENSOR_UNITS_MILLISECOND 0x19 +#define HID_USAGE_SENSOR_UNITS_PERCENT 0x17 +#define HID_USAGE_SENSOR_UNITS_DEGREES 0x14 +#define HID_USAGE_SENSOR_UNITS_DEGREES_PER_SECOND 0x15 + +/* Common selectors */ +#define HID_USAGE_SENSOR_PROP_REPORT_INTERVAL 0x20030E +#define HID_USAGE_SENSOR_PROP_SENSITIVITY_ABS 0x20030F +#define HID_USAGE_SENSOR_PROP_SENSITIVITY_RANGE_PCT 0x200310 +#define HID_USAGE_SENSOR_PROP_SENSITIVITY_REL_PCT 0x200311 +#define HID_USAGE_SENSOR_PROP_ACCURACY 0x200312 +#define HID_USAGE_SENSOR_PROP_RESOLUTION 0x200313 +#define HID_USAGE_SENSOR_PROP_RANGE_MAXIMUM 0x200314 +#define HID_USAGE_SENSOR_PROP_RANGE_MINIMUM 0x200315 +#define HID_USAGE_SENSOR_PROP_REPORT_STATE 0x200316 +#define HID_USAGE_SENSOR_PROY_POWER_STATE 0x200319 + +#endif -- cgit v0.10.2 From 73c6768b710a1621903f2bc179ae9c7789d41e9f Mon Sep 17 00:00:00 2001 From: srinivas pandruvada Date: Wed, 5 Sep 2012 13:56:00 +0100 Subject: iio: hid-sensors: Common attribute and trigger This patch contains the common code, which is used by all HID sensors. There are some common set of attributes, which every hid sensor needs it. This patch contains all such attributes processing. Also the trigger interface is common among all HID sensors. This patch contains common trigger functions utilized by all HID sensors. Signed-off-by: srinivas pandruvada Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig index 56825e6..c402610 100644 --- a/drivers/iio/Kconfig +++ b/drivers/iio/Kconfig @@ -59,5 +59,6 @@ source "drivers/iio/amplifiers/Kconfig" source "drivers/iio/light/Kconfig" source "drivers/iio/frequency/Kconfig" source "drivers/iio/dac/Kconfig" +source "drivers/iio/common/Kconfig" endif # IIO diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile index 34309ab..cfafb0d 100644 --- a/drivers/iio/Makefile +++ b/drivers/iio/Makefile @@ -15,3 +15,4 @@ obj-y += amplifiers/ obj-y += light/ obj-y += frequency/ obj-y += dac/ +obj-y += common/ diff --git a/drivers/iio/common/Kconfig b/drivers/iio/common/Kconfig new file mode 100644 index 0000000..ed45ee5 --- /dev/null +++ b/drivers/iio/common/Kconfig @@ -0,0 +1,5 @@ +# +# IIO common modules +# + +source "drivers/iio/common/hid-sensors/Kconfig" diff --git a/drivers/iio/common/Makefile b/drivers/iio/common/Makefile new file mode 100644 index 0000000..8158400 --- /dev/null +++ b/drivers/iio/common/Makefile @@ -0,0 +1,9 @@ +# +# Makefile for the IIO common modules. +# Common modules contains modules, which can be shared among multiple +# IIO modules. For example if the trigger processing is common for +# multiple IIO modules then this can be moved to a common module +# instead of duplicating in each module. +# + +obj-y += hid-sensors/ diff --git a/drivers/iio/common/hid-sensors/Kconfig b/drivers/iio/common/hid-sensors/Kconfig new file mode 100644 index 0000000..8e63d81 --- /dev/null +++ b/drivers/iio/common/hid-sensors/Kconfig @@ -0,0 +1,26 @@ +# +# Hid Sensor common modules +# +menu "Hid Sensor IIO Common" + +config HID_SENSOR_IIO_COMMON + tristate "Common modules for all HID Sensor IIO drivers" + depends on HID_SENSOR_HUB + select IIO_TRIGGER if IIO_BUFFER + help + Say yes here to build support for HID sensor to use + HID sensor common processing for attributes and IIO triggers. + There are many attributes which can be shared among multiple + HID sensor drivers, this module contains processing for those + attributes. + +config HID_SENSOR_ENUM_BASE_QUIRKS + tristate "ENUM base quirks for HID Sensor IIO drivers" + depends on HID_SENSOR_IIO_COMMON + help + Say yes here to build support for sensor hub FW using + enumeration, which is using 1 as base instead of 0. + Since logical minimum is still set 0 instead of 1, + there is no easy way to differentiate. + +endmenu diff --git a/drivers/iio/common/hid-sensors/Makefile b/drivers/iio/common/hid-sensors/Makefile new file mode 100644 index 0000000..1f463e0 --- /dev/null +++ b/drivers/iio/common/hid-sensors/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for the Hid sensor common modules. +# + +obj-$(CONFIG_HID_SENSOR_IIO_COMMON) += hid-sensor-iio-common.o +hid-sensor-iio-common-y := hid-sensor-attributes.o hid-sensor-trigger.o diff --git a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c new file mode 100644 index 0000000..7537495 --- /dev/null +++ b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c @@ -0,0 +1,250 @@ +/* + * HID Sensors Driver + * Copyright (c) 2012, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hid-sensor-attributes.h" + +static int pow_10(unsigned power) +{ + int i; + int ret = 1; + for (i = 0; i < power; ++i) + ret = ret * 10; + + return ret; +} + +static void simple_div(int dividend, int divisor, int *whole, + int *micro_frac) +{ + int rem; + int exp = 0; + + *micro_frac = 0; + if (divisor == 0) { + *whole = 0; + return; + } + *whole = dividend/divisor; + rem = dividend % divisor; + if (rem) { + while (rem <= divisor) { + rem *= 10; + exp++; + } + *micro_frac = (rem / divisor) * pow_10(6-exp); + } +} + +static void split_micro_fraction(unsigned int no, int exp, int *val1, int *val2) +{ + *val1 = no/pow_10(exp); + *val2 = no%pow_10(exp) * pow_10(6-exp); +} + +/* +VTF format uses exponent and variable size format. +For example if the size is 2 bytes +0x0067 with VTF16E14 format -> +1.03 +To convert just change to 0x67 to decimal and use two decimal as E14 stands +for 10^-2. +Negative numbers are 2's complement +*/ +static void convert_from_vtf_format(u32 value, int size, int exp, + int *val1, int *val2) +{ + int sign = 1; + + if (value & BIT(size*8 - 1)) { + value = ((1LL << (size * 8)) - value); + sign = -1; + } + exp = hid_sensor_convert_exponent(exp); + if (exp >= 0) { + *val1 = sign * value * pow_10(exp); + *val2 = 0; + } else { + split_micro_fraction(value, -exp, val1, val2); + if (*val1) + *val1 = sign * (*val1); + else + *val2 = sign * (*val2); + } +} + +static u32 convert_to_vtf_format(int size, int exp, int val1, int val2) +{ + u32 value; + int sign = 1; + + if (val1 < 0 || val2 < 0) + sign = -1; + exp = hid_sensor_convert_exponent(exp); + if (exp < 0) { + value = abs(val1) * pow_10(-exp); + value += abs(val2) / pow_10(6+exp); + } else + value = abs(val1) / pow_10(exp); + if (sign < 0) + value = ((1LL << (size * 8)) - value); + + return value; +} + +int hid_sensor_read_samp_freq_value(struct hid_sensor_iio_common *st, + int *val1, int *val2) +{ + s32 value; + int ret; + + ret = sensor_hub_get_feature(st->hsdev, + st->poll.report_id, + st->poll.index, &value); + if (ret < 0 || value < 0) { + *val1 = *val2 = 0; + return -EINVAL; + } else { + if (st->poll.units == HID_USAGE_SENSOR_UNITS_MILLISECOND) + simple_div(1000, value, val1, val2); + else if (st->poll.units == HID_USAGE_SENSOR_UNITS_SECOND) + simple_div(1, value, val1, val2); + else { + *val1 = *val2 = 0; + return -EINVAL; + } + } + + return IIO_VAL_INT_PLUS_MICRO; +} +EXPORT_SYMBOL(hid_sensor_read_samp_freq_value); + +int hid_sensor_write_samp_freq_value(struct hid_sensor_iio_common *st, + int val1, int val2) +{ + s32 value; + int ret; + + if (val1 < 0 || val2 < 0) + ret = -EINVAL; + + value = val1 * pow_10(6) + val2; + if (value) { + if (st->poll.units == HID_USAGE_SENSOR_UNITS_MILLISECOND) + value = pow_10(9)/value; + else if (st->poll.units == HID_USAGE_SENSOR_UNITS_SECOND) + value = pow_10(6)/value; + else + value = 0; + } + ret = sensor_hub_set_feature(st->hsdev, + st->poll.report_id, + st->poll.index, value); + if (ret < 0 || value < 0) + ret = -EINVAL; + + return ret; +} +EXPORT_SYMBOL(hid_sensor_write_samp_freq_value); + +int hid_sensor_read_raw_hyst_value(struct hid_sensor_iio_common *st, + int *val1, int *val2) +{ + s32 value; + int ret; + + ret = sensor_hub_get_feature(st->hsdev, + st->sensitivity.report_id, + st->sensitivity.index, &value); + if (ret < 0 || value < 0) { + *val1 = *val2 = 0; + return -EINVAL; + } else { + convert_from_vtf_format(value, st->sensitivity.size, + st->sensitivity.unit_expo, + val1, val2); + } + + return IIO_VAL_INT_PLUS_MICRO; +} +EXPORT_SYMBOL(hid_sensor_read_raw_hyst_value); + +int hid_sensor_write_raw_hyst_value(struct hid_sensor_iio_common *st, + int val1, int val2) +{ + s32 value; + int ret; + + value = convert_to_vtf_format(st->sensitivity.size, + st->sensitivity.unit_expo, + val1, val2); + ret = sensor_hub_set_feature(st->hsdev, + st->sensitivity.report_id, + st->sensitivity.index, value); + if (ret < 0 || value < 0) + ret = -EINVAL; + + return ret; +} +EXPORT_SYMBOL(hid_sensor_write_raw_hyst_value); + +int hid_sensor_parse_common_attributes(struct hid_sensor_hub_device *hsdev, + u32 usage_id, + struct hid_sensor_iio_common *st) +{ + + sensor_hub_input_get_attribute_info(hsdev, + HID_FEATURE_REPORT, usage_id, + HID_USAGE_SENSOR_PROP_REPORT_INTERVAL, + &st->poll); + + sensor_hub_input_get_attribute_info(hsdev, + HID_FEATURE_REPORT, usage_id, + HID_USAGE_SENSOR_PROP_REPORT_STATE, + &st->report_state); + + sensor_hub_input_get_attribute_info(hsdev, + HID_FEATURE_REPORT, usage_id, + HID_USAGE_SENSOR_PROY_POWER_STATE, + &st->power_state); + + sensor_hub_input_get_attribute_info(hsdev, + HID_FEATURE_REPORT, usage_id, + HID_USAGE_SENSOR_PROP_SENSITIVITY_ABS, + &st->sensitivity); + + hid_dbg(hsdev->hdev, "common attributes: %x:%x, %x:%x, %x:%x %x:%x\n", + st->poll.index, st->poll.report_id, + st->report_state.index, st->report_state.report_id, + st->power_state.index, st->power_state.report_id, + st->sensitivity.index, st->sensitivity.report_id); + + return 0; +} +EXPORT_SYMBOL(hid_sensor_parse_common_attributes); + +MODULE_AUTHOR("Srinivas Pandruvada "); +MODULE_DESCRIPTION("HID Sensor common attribute processing"); +MODULE_LICENSE("GPL"); diff --git a/drivers/iio/common/hid-sensors/hid-sensor-attributes.h b/drivers/iio/common/hid-sensors/hid-sensor-attributes.h new file mode 100644 index 0000000..a4676a0 --- /dev/null +++ b/drivers/iio/common/hid-sensors/hid-sensor-attributes.h @@ -0,0 +1,57 @@ +/* + * HID Sensors Driver + * Copyright (c) 2012, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ +#ifndef _HID_SENSORS_ATTRIBUTES_H +#define _HID_SENSORS_ATTRIBUTES_H + +/* Common hid sensor iio structure */ +struct hid_sensor_iio_common { + struct hid_sensor_hub_device *hsdev; + struct platform_device *pdev; + unsigned usage_id; + bool data_ready; + struct hid_sensor_hub_attribute_info poll; + struct hid_sensor_hub_attribute_info report_state; + struct hid_sensor_hub_attribute_info power_state; + struct hid_sensor_hub_attribute_info sensitivity; +}; + +/*Convert from hid unit expo to regular exponent*/ +static inline int hid_sensor_convert_exponent(int unit_expo) +{ + if (unit_expo < 0x08) + return unit_expo; + else if (unit_expo <= 0x0f) + return -(0x0f-unit_expo+1); + else + return 0; +} + +int hid_sensor_parse_common_attributes(struct hid_sensor_hub_device *hsdev, + u32 usage_id, + struct hid_sensor_iio_common *st); +int hid_sensor_write_raw_hyst_value(struct hid_sensor_iio_common *st, + int val1, int val2); +int hid_sensor_read_raw_hyst_value(struct hid_sensor_iio_common *st, + int *val1, int *val2); +int hid_sensor_write_samp_freq_value(struct hid_sensor_iio_common *st, + int val1, int val2); +int hid_sensor_read_samp_freq_value(struct hid_sensor_iio_common *st, + int *val1, int *val2); + +#endif diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c new file mode 100644 index 0000000..12277e8 --- /dev/null +++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c @@ -0,0 +1,102 @@ +/* + * HID Sensors Driver + * Copyright (c) 2012, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hid-sensor-attributes.h" +#include "hid-sensor-trigger.h" + +static int hid_sensor_data_rdy_trigger_set_state(struct iio_trigger *trig, + bool state) +{ + struct hid_sensor_iio_common *st = trig->private_data; + int state_val; + + state_val = state ? 1 : 0; +#if (defined CONFIG_HID_SENSOR_ENUM_BASE_QUIRKS) || \ + (defined CONFIG_HID_SENSOR_ENUM_BASE_QUIRKS_MODULE) + ++state_val; +#endif + st->data_ready = state; + sensor_hub_set_feature(st->hsdev, st->power_state.report_id, + st->power_state.index, + (s32)state_val); + + sensor_hub_set_feature(st->hsdev, st->report_state.report_id, + st->report_state.index, + (s32)state_val); + + return 0; +} + +void hid_sensor_remove_trigger(struct iio_dev *indio_dev) +{ + iio_trigger_unregister(indio_dev->trig); + iio_trigger_free(indio_dev->trig); +} +EXPORT_SYMBOL(hid_sensor_remove_trigger); + +static const struct iio_trigger_ops hid_sensor_trigger_ops = { + .owner = THIS_MODULE, + .set_trigger_state = &hid_sensor_data_rdy_trigger_set_state, +}; + +int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name, + struct hid_sensor_iio_common *attrb) +{ + int ret; + struct iio_trigger *trig; + + trig = iio_trigger_alloc("%s-dev%d", name, indio_dev->id); + if (trig == NULL) { + dev_err(&indio_dev->dev, "Trigger Allocate Failed\n"); + ret = -ENOMEM; + goto error_ret; + } + + trig->dev.parent = indio_dev->dev.parent; + trig->private_data = attrb; + trig->ops = &hid_sensor_trigger_ops; + ret = iio_trigger_register(trig); + + if (ret) { + dev_err(&indio_dev->dev, "Trigger Register Failed\n"); + goto error_free_trig; + } + indio_dev->trig = trig; + + return ret; + +error_free_trig: + iio_trigger_free(trig); +error_ret: + return ret; +} +EXPORT_SYMBOL(hid_sensor_setup_trigger); + +MODULE_AUTHOR("Srinivas Pandruvada "); +MODULE_DESCRIPTION("HID Sensor trigger processing"); +MODULE_LICENSE("GPL"); diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.h b/drivers/iio/common/hid-sensors/hid-sensor-trigger.h new file mode 100644 index 0000000..fd98297 --- /dev/null +++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.h @@ -0,0 +1,26 @@ +/* + * HID Sensors Driver + * Copyright (c) 2012, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ +#ifndef _HID_SENSOR_TRIGGER_H +#define _HID_SENSOR_TRIGGER_H + +int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name, + struct hid_sensor_iio_common *attrb); +void hid_sensor_remove_trigger(struct iio_dev *indio_dev); + +#endif -- cgit v0.10.2 From 45fe6f7d002c4ce11ae966bce74c6714816390d7 Mon Sep 17 00:00:00 2001 From: srinivas pandruvada Date: Wed, 5 Sep 2012 13:56:00 +0100 Subject: iio: hid-sensors: Added accelerometer 3D Added usage id processing for Accelerometer 3D.This uses IIO interfaces for triggered buffer to present data to user mode.This uses HID sensor framework for registering callback events from the sensor hub. Signed-off-by: srinivas pandruvada Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig index c402610..0e05b90 100644 --- a/drivers/iio/Kconfig +++ b/drivers/iio/Kconfig @@ -54,6 +54,7 @@ config IIO_CONSUMERS_PER_TRIGGER This value controls the maximum number of consumers that a given trigger may handle. Default is 2. +source "drivers/iio/accel/Kconfig" source "drivers/iio/adc/Kconfig" source "drivers/iio/amplifiers/Kconfig" source "drivers/iio/light/Kconfig" diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile index cfafb0d..b21215c 100644 --- a/drivers/iio/Makefile +++ b/drivers/iio/Makefile @@ -10,6 +10,7 @@ industrialio-$(CONFIG_IIO_TRIGGER) += industrialio-trigger.o obj-$(CONFIG_IIO_TRIGGERED_BUFFER) += industrialio-triggered-buffer.o obj-$(CONFIG_IIO_KFIFO_BUF) += kfifo_buf.o +obj-y += accel/ obj-y += adc/ obj-y += amplifiers/ obj-y += light/ diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig new file mode 100644 index 0000000..b2510c4 --- /dev/null +++ b/drivers/iio/accel/Kconfig @@ -0,0 +1,16 @@ +# +# Accelerometer drivers +# +menu "Accelerometers" + +config HID_SENSOR_ACCEL_3D + depends on HID_SENSOR_HUB + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER + select HID_SENSOR_IIO_COMMON + tristate "HID Acelerometers 3D" + help + Say yes here to build support for the HID SENSOR + accelerometers 3D. + +endmenu diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile new file mode 100644 index 0000000..5bc6855 --- /dev/null +++ b/drivers/iio/accel/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for industrial I/O accelerometer drivers +# + +obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c new file mode 100644 index 0000000..33aa97c --- /dev/null +++ b/drivers/iio/accel/hid-sensor-accel-3d.c @@ -0,0 +1,419 @@ +/* + * HID Sensors Driver + * Copyright (c) 2012, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../common/hid-sensors/hid-sensor-attributes.h" +#include "../common/hid-sensors/hid-sensor-trigger.h" + +/*Format: HID-SENSOR-usage_id_in_hex*/ +/*Usage ID from spec for Accelerometer-3D: 0x200073*/ +#define DRIVER_NAME "HID-SENSOR-200073" + +enum accel_3d_channel { + CHANNEL_SCAN_INDEX_X, + CHANNEL_SCAN_INDEX_Y, + CHANNEL_SCAN_INDEX_Z, + ACCEL_3D_CHANNEL_MAX, +}; + +struct accel_3d_state { + struct hid_sensor_hub_callbacks callbacks; + struct hid_sensor_iio_common common_attributes; + struct hid_sensor_hub_attribute_info accel[ACCEL_3D_CHANNEL_MAX]; + u32 accel_val[ACCEL_3D_CHANNEL_MAX]; +}; + +static const u32 accel_3d_addresses[ACCEL_3D_CHANNEL_MAX] = { + HID_USAGE_SENSOR_ACCEL_X_AXIS, + HID_USAGE_SENSOR_ACCEL_Y_AXIS, + HID_USAGE_SENSOR_ACCEL_Z_AXIS +}; + +/* Channel definitions */ +static const struct iio_chan_spec accel_3d_channels[] = { + { + .type = IIO_ACCEL, + .modified = 1, + .channel2 = IIO_MOD_X, + .info_mask = IIO_CHAN_INFO_OFFSET_SHARED_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT | + IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT | + IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT, + .scan_index = CHANNEL_SCAN_INDEX_X, + }, { + .type = IIO_ACCEL, + .modified = 1, + .channel2 = IIO_MOD_Y, + .info_mask = IIO_CHAN_INFO_OFFSET_SHARED_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT | + IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT | + IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT, + .scan_index = CHANNEL_SCAN_INDEX_Y, + }, { + .type = IIO_ACCEL, + .modified = 1, + .channel2 = IIO_MOD_Z, + .info_mask = IIO_CHAN_INFO_OFFSET_SHARED_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT | + IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT | + IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT, + .scan_index = CHANNEL_SCAN_INDEX_Z, + } +}; + +/* Adjust channel real bits based on report descriptor */ +static void accel_3d_adjust_channel_bit_mask(struct iio_chan_spec *channels, + int channel, int size) +{ + channels[channel].scan_type.sign = 's'; + /* Real storage bits will change based on the report desc. */ + channels[channel].scan_type.realbits = size * 8; + /* Maximum size of a sample to capture is u32 */ + channels[channel].scan_type.storagebits = sizeof(u32) * 8; +} + +/* Channel read_raw handler */ +static int accel_3d_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, + long mask) +{ + struct accel_3d_state *accel_state = iio_priv(indio_dev); + int report_id = -1; + u32 address; + int ret; + int ret_type; + + *val = 0; + *val2 = 0; + switch (mask) { + case 0: + report_id = accel_state->accel[chan->scan_index].report_id; + address = accel_3d_addresses[chan->scan_index]; + if (report_id >= 0) + *val = sensor_hub_input_attr_get_raw_value( + accel_state->common_attributes.hsdev, + HID_USAGE_SENSOR_ACCEL_3D, address, + report_id); + else { + *val = 0; + return -EINVAL; + } + ret_type = IIO_VAL_INT; + break; + case IIO_CHAN_INFO_SCALE: + *val = accel_state->accel[CHANNEL_SCAN_INDEX_X].units; + ret_type = IIO_VAL_INT; + break; + case IIO_CHAN_INFO_OFFSET: + *val = hid_sensor_convert_exponent( + accel_state->accel[CHANNEL_SCAN_INDEX_X].unit_expo); + ret_type = IIO_VAL_INT; + break; + case IIO_CHAN_INFO_SAMP_FREQ: + ret = hid_sensor_read_samp_freq_value( + &accel_state->common_attributes, val, val2); + ret_type = IIO_VAL_INT_PLUS_MICRO; + break; + case IIO_CHAN_INFO_HYSTERESIS: + ret = hid_sensor_read_raw_hyst_value( + &accel_state->common_attributes, val, val2); + ret_type = IIO_VAL_INT_PLUS_MICRO; + break; + default: + ret_type = -EINVAL; + break; + } + + return ret_type; +} + +/* Channel write_raw handler */ +static int accel_3d_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, + int val2, + long mask) +{ + struct accel_3d_state *accel_state = iio_priv(indio_dev); + int ret = 0; + + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: + ret = hid_sensor_write_samp_freq_value( + &accel_state->common_attributes, val, val2); + break; + case IIO_CHAN_INFO_HYSTERESIS: + ret = hid_sensor_write_raw_hyst_value( + &accel_state->common_attributes, val, val2); + break; + default: + ret = -EINVAL; + } + + return ret; +} + +static int accel_3d_write_raw_get_fmt(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + long mask) +{ + return IIO_VAL_INT_PLUS_MICRO; +} + +static const struct iio_info accel_3d_info = { + .driver_module = THIS_MODULE, + .read_raw = &accel_3d_read_raw, + .write_raw = &accel_3d_write_raw, + .write_raw_get_fmt = &accel_3d_write_raw_get_fmt, +}; + +/* Function to push data to buffer */ +static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len) +{ + struct iio_buffer *buffer = indio_dev->buffer; + s64 timestamp = iio_get_time_ns(); + int datum_sz; + + dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n"); + if (!buffer) { + dev_err(&indio_dev->dev, "Buffer == NULL\n"); + return; + } + datum_sz = buffer->access->get_bytes_per_datum(buffer); + if (len > datum_sz) { + dev_err(&indio_dev->dev, "Datum size mismatch %d:%d\n", len, + datum_sz); + return; + } + buffer->access->store_to(buffer, (u8 *)data, timestamp); +} + +/* Callback handler to send event after all samples are received and captured */ +static int accel_3d_proc_event(struct hid_sensor_hub_device *hsdev, + unsigned usage_id, + void *priv) +{ + struct iio_dev *indio_dev = platform_get_drvdata(priv); + struct accel_3d_state *accel_state = iio_priv(indio_dev); + + dev_dbg(&indio_dev->dev, "accel_3d_proc_event [%d]\n", + accel_state->common_attributes.data_ready); + if (accel_state->common_attributes.data_ready) + hid_sensor_push_data(indio_dev, + (u8 *)accel_state->accel_val, + sizeof(accel_state->accel_val)); + + return 0; +} + +/* Capture samples in local storage */ +static int accel_3d_capture_sample(struct hid_sensor_hub_device *hsdev, + unsigned usage_id, + size_t raw_len, char *raw_data, + void *priv) +{ + struct iio_dev *indio_dev = platform_get_drvdata(priv); + struct accel_3d_state *accel_state = iio_priv(indio_dev); + int offset; + int ret = -EINVAL; + + switch (usage_id) { + case HID_USAGE_SENSOR_ACCEL_X_AXIS: + case HID_USAGE_SENSOR_ACCEL_Y_AXIS: + case HID_USAGE_SENSOR_ACCEL_Z_AXIS: + offset = usage_id - HID_USAGE_SENSOR_ACCEL_X_AXIS; + accel_state->accel_val[CHANNEL_SCAN_INDEX_X + offset] = + *(u32 *)raw_data; + ret = 0; + break; + default: + break; + } + + return ret; +} + +/* Parse report which is specific to an usage id*/ +static int accel_3d_parse_report(struct platform_device *pdev, + struct hid_sensor_hub_device *hsdev, + struct iio_chan_spec *channels, + unsigned usage_id, + struct accel_3d_state *st) +{ + int ret; + int i; + + for (i = 0; i <= CHANNEL_SCAN_INDEX_Z; ++i) { + ret = sensor_hub_input_get_attribute_info(hsdev, + HID_INPUT_REPORT, + usage_id, + HID_USAGE_SENSOR_ACCEL_X_AXIS + i, + &st->accel[CHANNEL_SCAN_INDEX_X + i]); + if (ret < 0) + break; + accel_3d_adjust_channel_bit_mask(channels, + CHANNEL_SCAN_INDEX_X + i, + st->accel[CHANNEL_SCAN_INDEX_X + i].size); + } + dev_dbg(&pdev->dev, "accel_3d %x:%x, %x:%x, %x:%x\n", + st->accel[0].index, + st->accel[0].report_id, + st->accel[1].index, st->accel[1].report_id, + st->accel[2].index, st->accel[2].report_id); + + return ret; +} + +/* Function to initialize the processing for usage id */ +static int __devinit hid_accel_3d_probe(struct platform_device *pdev) +{ + int ret = 0; + static const char *name = "accel_3d"; + struct iio_dev *indio_dev; + struct accel_3d_state *accel_state; + struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; + struct iio_chan_spec *channels; + + indio_dev = iio_device_alloc(sizeof(struct accel_3d_state)); + if (indio_dev == NULL) { + ret = -ENOMEM; + goto error_ret; + } + platform_set_drvdata(pdev, indio_dev); + + accel_state = iio_priv(indio_dev); + accel_state->common_attributes.hsdev = hsdev; + accel_state->common_attributes.pdev = pdev; + + ret = hid_sensor_parse_common_attributes(hsdev, + HID_USAGE_SENSOR_ACCEL_3D, + &accel_state->common_attributes); + if (ret) { + dev_err(&pdev->dev, "failed to setup common attributes\n"); + goto error_free_dev; + } + + channels = kmemdup(accel_3d_channels, + sizeof(accel_3d_channels), + GFP_KERNEL); + if (!channels) { + dev_err(&pdev->dev, "failed to duplicate channels\n"); + goto error_free_dev; + } + + ret = accel_3d_parse_report(pdev, hsdev, channels, + HID_USAGE_SENSOR_ACCEL_3D, accel_state); + if (ret) { + dev_err(&pdev->dev, "failed to setup attributes\n"); + goto error_free_dev_mem; + } + + indio_dev->channels = channels; + indio_dev->num_channels = ARRAY_SIZE(accel_3d_channels); + indio_dev->dev.parent = &pdev->dev; + indio_dev->info = &accel_3d_info; + indio_dev->name = name; + indio_dev->modes = INDIO_DIRECT_MODE; + + ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, + NULL, NULL); + if (ret) { + dev_err(&pdev->dev, "failed to initialize trigger buffer\n"); + goto error_free_dev_mem; + } + accel_state->common_attributes.data_ready = false; + ret = hid_sensor_setup_trigger(indio_dev, name, + &accel_state->common_attributes); + if (ret < 0) { + dev_err(&pdev->dev, "trigger setup failed\n"); + goto error_unreg_buffer_funcs; + } + + ret = iio_device_register(indio_dev); + if (ret) { + dev_err(&pdev->dev, "device register failed\n"); + goto error_remove_trigger; + } + + accel_state->callbacks.send_event = accel_3d_proc_event; + accel_state->callbacks.capture_sample = accel_3d_capture_sample; + accel_state->callbacks.pdev = pdev; + ret = sensor_hub_register_callback(hsdev, HID_USAGE_SENSOR_ACCEL_3D, + &accel_state->callbacks); + if (ret < 0) { + dev_err(&pdev->dev, "callback reg failed\n"); + goto error_iio_unreg; + } + + return ret; + +error_iio_unreg: + iio_device_unregister(indio_dev); +error_remove_trigger: + hid_sensor_remove_trigger(indio_dev); +error_unreg_buffer_funcs: + iio_triggered_buffer_cleanup(indio_dev); +error_free_dev_mem: + kfree(indio_dev->channels); +error_free_dev: + iio_device_free(indio_dev); +error_ret: + return ret; +} + +/* Function to deinitialize the processing for usage id */ +static int __devinit hid_accel_3d_remove(struct platform_device *pdev) +{ + struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; + struct iio_dev *indio_dev = platform_get_drvdata(pdev); + + sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_ACCEL_3D); + iio_device_unregister(indio_dev); + hid_sensor_remove_trigger(indio_dev); + iio_triggered_buffer_cleanup(indio_dev); + kfree(indio_dev->channels); + iio_device_free(indio_dev); + + return 0; +} + +static struct platform_driver hid_accel_3d_platform_driver = { + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + }, + .probe = hid_accel_3d_probe, + .remove = hid_accel_3d_remove, +}; +module_platform_driver(hid_accel_3d_platform_driver); + +MODULE_DESCRIPTION("HID Sensor Accel 3D"); +MODULE_AUTHOR("Srinivas Pandruvada "); +MODULE_LICENSE("GPL"); -- cgit v0.10.2 From c5bdbef704ba4c71a4fa2edc94d1930afad3b4c6 Mon Sep 17 00:00:00 2001 From: srinivas pandruvada Date: Wed, 5 Sep 2012 13:56:00 +0100 Subject: iio: hid-sensors: Added Gyroscope 3D Added usage id processing for Gyroscope 3D. This uses IIO interfaces for triggered buffer to present data to user mode.This uses HID sensor framework for registering callback events from the sensor hub. Signed-off-by: srinivas pandruvada Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig index 0e05b90..417ade3 100644 --- a/drivers/iio/Kconfig +++ b/drivers/iio/Kconfig @@ -61,5 +61,6 @@ source "drivers/iio/light/Kconfig" source "drivers/iio/frequency/Kconfig" source "drivers/iio/dac/Kconfig" source "drivers/iio/common/Kconfig" +source "drivers/iio/gyro/Kconfig" endif # IIO diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile index b21215c..a6406f7 100644 --- a/drivers/iio/Makefile +++ b/drivers/iio/Makefile @@ -17,3 +17,4 @@ obj-y += light/ obj-y += frequency/ obj-y += dac/ obj-y += common/ +obj-y += gyro/ diff --git a/drivers/iio/gyro/Kconfig b/drivers/iio/gyro/Kconfig new file mode 100644 index 0000000..21e27e2 --- /dev/null +++ b/drivers/iio/gyro/Kconfig @@ -0,0 +1,16 @@ +# +# IIO Digital Gyroscope Sensor drivers configuration +# +menu "Digital gyroscope sensors" + +config HID_SENSOR_GYRO_3D + depends on HID_SENSOR_HUB + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER + select HID_SENSOR_IIO_COMMON + tristate "HID Gyroscope 3D" + help + Say yes here to build support for the HID SENSOR + Gyroscope 3D. + +endmenu diff --git a/drivers/iio/gyro/Makefile b/drivers/iio/gyro/Makefile new file mode 100644 index 0000000..8a895d9 --- /dev/null +++ b/drivers/iio/gyro/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for industrial I/O gyroscope sensor drivers +# + +obj-$(CONFIG_HID_SENSOR_GYRO_3D) += hid-sensor-gyro-3d.o diff --git a/drivers/iio/gyro/hid-sensor-gyro-3d.c b/drivers/iio/gyro/hid-sensor-gyro-3d.c new file mode 100644 index 0000000..50ec09b --- /dev/null +++ b/drivers/iio/gyro/hid-sensor-gyro-3d.c @@ -0,0 +1,419 @@ +/* + * HID Sensors Driver + * Copyright (c) 2012, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../common/hid-sensors/hid-sensor-attributes.h" +#include "../common/hid-sensors/hid-sensor-trigger.h" + +/*Format: HID-SENSOR-usage_id_in_hex*/ +/*Usage ID from spec for Gyro-3D: 0x200076*/ +#define DRIVER_NAME "HID-SENSOR-200076" + +enum gyro_3d_channel { + CHANNEL_SCAN_INDEX_X, + CHANNEL_SCAN_INDEX_Y, + CHANNEL_SCAN_INDEX_Z, + GYRO_3D_CHANNEL_MAX, +}; + +struct gyro_3d_state { + struct hid_sensor_hub_callbacks callbacks; + struct hid_sensor_iio_common common_attributes; + struct hid_sensor_hub_attribute_info gyro[GYRO_3D_CHANNEL_MAX]; + u32 gyro_val[GYRO_3D_CHANNEL_MAX]; +}; + +static const u32 gyro_3d_addresses[GYRO_3D_CHANNEL_MAX] = { + HID_USAGE_SENSOR_ANGL_VELOCITY_X_AXIS, + HID_USAGE_SENSOR_ANGL_VELOCITY_Y_AXIS, + HID_USAGE_SENSOR_ANGL_VELOCITY_Z_AXIS +}; + +/* Channel definitions */ +static const struct iio_chan_spec gyro_3d_channels[] = { + { + .type = IIO_ANGL_VEL, + .modified = 1, + .channel2 = IIO_MOD_X, + .info_mask = IIO_CHAN_INFO_OFFSET_SHARED_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT | + IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT | + IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT, + .scan_index = CHANNEL_SCAN_INDEX_X, + }, { + .type = IIO_ANGL_VEL, + .modified = 1, + .channel2 = IIO_MOD_Y, + .info_mask = IIO_CHAN_INFO_OFFSET_SHARED_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT | + IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT | + IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT, + .scan_index = CHANNEL_SCAN_INDEX_Y, + }, { + .type = IIO_ANGL_VEL, + .modified = 1, + .channel2 = IIO_MOD_Z, + .info_mask = IIO_CHAN_INFO_OFFSET_SHARED_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT | + IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT | + IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT, + .scan_index = CHANNEL_SCAN_INDEX_Z, + } +}; + +/* Adjust channel real bits based on report descriptor */ +static void gyro_3d_adjust_channel_bit_mask(struct iio_chan_spec *channels, + int channel, int size) +{ + channels[channel].scan_type.sign = 's'; + /* Real storage bits will change based on the report desc. */ + channels[channel].scan_type.realbits = size * 8; + /* Maximum size of a sample to capture is u32 */ + channels[channel].scan_type.storagebits = sizeof(u32) * 8; +} + +/* Channel read_raw handler */ +static int gyro_3d_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, + long mask) +{ + struct gyro_3d_state *gyro_state = iio_priv(indio_dev); + int report_id = -1; + u32 address; + int ret; + int ret_type; + + *val = 0; + *val2 = 0; + switch (mask) { + case 0: + report_id = gyro_state->gyro[chan->scan_index].report_id; + address = gyro_3d_addresses[chan->scan_index]; + if (report_id >= 0) + *val = sensor_hub_input_attr_get_raw_value( + gyro_state->common_attributes.hsdev, + HID_USAGE_SENSOR_GYRO_3D, address, + report_id); + else { + *val = 0; + return -EINVAL; + } + ret_type = IIO_VAL_INT; + break; + case IIO_CHAN_INFO_SCALE: + *val = gyro_state->gyro[CHANNEL_SCAN_INDEX_X].units; + ret_type = IIO_VAL_INT; + break; + case IIO_CHAN_INFO_OFFSET: + *val = hid_sensor_convert_exponent( + gyro_state->gyro[CHANNEL_SCAN_INDEX_X].unit_expo); + ret_type = IIO_VAL_INT; + break; + case IIO_CHAN_INFO_SAMP_FREQ: + ret = hid_sensor_read_samp_freq_value( + &gyro_state->common_attributes, val, val2); + ret_type = IIO_VAL_INT_PLUS_MICRO; + break; + case IIO_CHAN_INFO_HYSTERESIS: + ret = hid_sensor_read_raw_hyst_value( + &gyro_state->common_attributes, val, val2); + ret_type = IIO_VAL_INT_PLUS_MICRO; + break; + default: + ret_type = -EINVAL; + break; + } + + return ret_type; +} + +/* Channel write_raw handler */ +static int gyro_3d_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, + int val2, + long mask) +{ + struct gyro_3d_state *gyro_state = iio_priv(indio_dev); + int ret = 0; + + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: + ret = hid_sensor_write_samp_freq_value( + &gyro_state->common_attributes, val, val2); + break; + case IIO_CHAN_INFO_HYSTERESIS: + ret = hid_sensor_write_raw_hyst_value( + &gyro_state->common_attributes, val, val2); + break; + default: + ret = -EINVAL; + } + + return ret; +} + +static int gyro_3d_write_raw_get_fmt(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + long mask) +{ + return IIO_VAL_INT_PLUS_MICRO; +} + +static const struct iio_info gyro_3d_info = { + .driver_module = THIS_MODULE, + .read_raw = &gyro_3d_read_raw, + .write_raw = &gyro_3d_write_raw, + .write_raw_get_fmt = &gyro_3d_write_raw_get_fmt, +}; + +/* Function to push data to buffer */ +static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len) +{ + struct iio_buffer *buffer = indio_dev->buffer; + s64 timestamp = iio_get_time_ns(); + int datum_sz; + + dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n"); + if (!buffer) { + dev_err(&indio_dev->dev, "Buffer == NULL\n"); + return; + } + datum_sz = buffer->access->get_bytes_per_datum(buffer); + if (len > datum_sz) { + dev_err(&indio_dev->dev, "Datum size mismatch %d:%d\n", len, + datum_sz); + return; + } + buffer->access->store_to(buffer, (u8 *)data, timestamp); +} + +/* Callback handler to send event after all samples are received and captured */ +static int gyro_3d_proc_event(struct hid_sensor_hub_device *hsdev, + unsigned usage_id, + void *priv) +{ + struct iio_dev *indio_dev = platform_get_drvdata(priv); + struct gyro_3d_state *gyro_state = iio_priv(indio_dev); + + dev_dbg(&indio_dev->dev, "gyro_3d_proc_event [%d]\n", + gyro_state->common_attributes.data_ready); + if (gyro_state->common_attributes.data_ready) + hid_sensor_push_data(indio_dev, + (u8 *)gyro_state->gyro_val, + sizeof(gyro_state->gyro_val)); + + return 0; +} + +/* Capture samples in local storage */ +static int gyro_3d_capture_sample(struct hid_sensor_hub_device *hsdev, + unsigned usage_id, + size_t raw_len, char *raw_data, + void *priv) +{ + struct iio_dev *indio_dev = platform_get_drvdata(priv); + struct gyro_3d_state *gyro_state = iio_priv(indio_dev); + int offset; + int ret = -EINVAL; + + switch (usage_id) { + case HID_USAGE_SENSOR_ANGL_VELOCITY_X_AXIS: + case HID_USAGE_SENSOR_ANGL_VELOCITY_Y_AXIS: + case HID_USAGE_SENSOR_ANGL_VELOCITY_Z_AXIS: + offset = usage_id - HID_USAGE_SENSOR_ANGL_VELOCITY_X_AXIS; + gyro_state->gyro_val[CHANNEL_SCAN_INDEX_X + offset] = + *(u32 *)raw_data; + ret = 0; + break; + default: + break; + } + + return ret; +} + +/* Parse report which is specific to an usage id*/ +static int gyro_3d_parse_report(struct platform_device *pdev, + struct hid_sensor_hub_device *hsdev, + struct iio_chan_spec *channels, + unsigned usage_id, + struct gyro_3d_state *st) +{ + int ret; + int i; + + for (i = 0; i <= CHANNEL_SCAN_INDEX_Z; ++i) { + ret = sensor_hub_input_get_attribute_info(hsdev, + HID_INPUT_REPORT, + usage_id, + HID_USAGE_SENSOR_ANGL_VELOCITY_X_AXIS + i, + &st->gyro[CHANNEL_SCAN_INDEX_X + i]); + if (ret < 0) + break; + gyro_3d_adjust_channel_bit_mask(channels, + CHANNEL_SCAN_INDEX_X + i, + st->gyro[CHANNEL_SCAN_INDEX_X + i].size); + } + dev_dbg(&pdev->dev, "gyro_3d %x:%x, %x:%x, %x:%x\n", + st->gyro[0].index, + st->gyro[0].report_id, + st->gyro[1].index, st->gyro[1].report_id, + st->gyro[2].index, st->gyro[2].report_id); + + return ret; +} + +/* Function to initialize the processing for usage id */ +static int __devinit hid_gyro_3d_probe(struct platform_device *pdev) +{ + int ret = 0; + static const char *name = "gyro_3d"; + struct iio_dev *indio_dev; + struct gyro_3d_state *gyro_state; + struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; + struct iio_chan_spec *channels; + + indio_dev = iio_device_alloc(sizeof(struct gyro_3d_state)); + if (indio_dev == NULL) { + ret = -ENOMEM; + goto error_ret; + } + platform_set_drvdata(pdev, indio_dev); + + gyro_state = iio_priv(indio_dev); + gyro_state->common_attributes.hsdev = hsdev; + gyro_state->common_attributes.pdev = pdev; + + ret = hid_sensor_parse_common_attributes(hsdev, + HID_USAGE_SENSOR_GYRO_3D, + &gyro_state->common_attributes); + if (ret) { + dev_err(&pdev->dev, "failed to setup common attributes\n"); + goto error_free_dev; + } + + channels = kmemdup(gyro_3d_channels, + sizeof(gyro_3d_channels), + GFP_KERNEL); + if (!channels) { + dev_err(&pdev->dev, "failed to duplicate channels\n"); + goto error_free_dev; + } + + ret = gyro_3d_parse_report(pdev, hsdev, channels, + HID_USAGE_SENSOR_GYRO_3D, gyro_state); + if (ret) { + dev_err(&pdev->dev, "failed to setup attributes\n"); + goto error_free_dev_mem; + } + + indio_dev->channels = channels; + indio_dev->num_channels = ARRAY_SIZE(gyro_3d_channels); + indio_dev->dev.parent = &pdev->dev; + indio_dev->info = &gyro_3d_info; + indio_dev->name = name; + indio_dev->modes = INDIO_DIRECT_MODE; + + ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, + NULL, NULL); + if (ret) { + dev_err(&pdev->dev, "failed to initialize trigger buffer\n"); + goto error_free_dev_mem; + } + gyro_state->common_attributes.data_ready = false; + ret = hid_sensor_setup_trigger(indio_dev, name, + &gyro_state->common_attributes); + if (ret < 0) { + dev_err(&pdev->dev, "trigger setup failed\n"); + goto error_unreg_buffer_funcs; + } + + ret = iio_device_register(indio_dev); + if (ret) { + dev_err(&pdev->dev, "device register failed\n"); + goto error_remove_trigger; + } + + gyro_state->callbacks.send_event = gyro_3d_proc_event; + gyro_state->callbacks.capture_sample = gyro_3d_capture_sample; + gyro_state->callbacks.pdev = pdev; + ret = sensor_hub_register_callback(hsdev, HID_USAGE_SENSOR_GYRO_3D, + &gyro_state->callbacks); + if (ret < 0) { + dev_err(&pdev->dev, "callback reg failed\n"); + goto error_iio_unreg; + } + + return ret; + +error_iio_unreg: + iio_device_unregister(indio_dev); +error_remove_trigger: + hid_sensor_remove_trigger(indio_dev); +error_unreg_buffer_funcs: + iio_triggered_buffer_cleanup(indio_dev); +error_free_dev_mem: + kfree(indio_dev->channels); +error_free_dev: + iio_device_free(indio_dev); +error_ret: + return ret; +} + +/* Function to deinitialize the processing for usage id */ +static int __devinit hid_gyro_3d_remove(struct platform_device *pdev) +{ + struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; + struct iio_dev *indio_dev = platform_get_drvdata(pdev); + + sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_GYRO_3D); + iio_device_unregister(indio_dev); + hid_sensor_remove_trigger(indio_dev); + iio_triggered_buffer_cleanup(indio_dev); + kfree(indio_dev->channels); + iio_device_free(indio_dev); + + return 0; +} + +static struct platform_driver hid_gyro_3d_platform_driver = { + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + }, + .probe = hid_gyro_3d_probe, + .remove = hid_gyro_3d_remove, +}; +module_platform_driver(hid_gyro_3d_platform_driver); + +MODULE_DESCRIPTION("HID Sensor Gyroscope 3D"); +MODULE_AUTHOR("Srinivas Pandruvada "); +MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 13f7952f8f13fb1bbd18b85988e3a5bbbed00879 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 6 Sep 2012 11:21:48 -0700 Subject: staging: comedi: vmk80xx: fix compiler warning gcc complains about some potentially uninitalized variables here, yet it can not happen, due to an enumerated type (either the board is one type or the other.) Make the compiler happy by providing a default case option that makes the logic a bit simpler for it to determine that there really isn't a problem here. Cc: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c index f9fef26..df277aa 100644 --- a/drivers/staging/comedi/drivers/vmk80xx.c +++ b/drivers/staging/comedi/drivers/vmk80xx.c @@ -546,6 +546,7 @@ static int vmk80xx_ai_rinsn(struct comedi_device *cdev, reg[0] = VMK8055_AI2_REG; break; case VMK8061_MODEL: + default: reg[0] = VMK8061_AI_REG1; reg[1] = VMK8061_AI_REG2; dev->usb_tx_buf[0] = VMK8061_CMD_RD_AI; @@ -904,6 +905,7 @@ static int vmk80xx_cnt_rinsn(struct comedi_device *cdev, reg[0] = VMK8055_CNT2_REG; break; case VMK8061_MODEL: + default: reg[0] = VMK8061_CNT_REG; reg[1] = VMK8061_CNT_REG; dev->usb_tx_buf[0] = VMK8061_CMD_RD_CNT; -- cgit v0.10.2 From bc1d57ba0669877819822c05861961bb1f348840 Mon Sep 17 00:00:00 2001 From: srinivas pandruvada Date: Wed, 5 Sep 2012 13:56:00 +0100 Subject: iio: hid-sensors: Added Compass/Magnetometer 3D Added usage id processing for Compass 3D. This uses IIO interfaces for triggered buffer to present data to user mode.This uses HID sensor framework for registering callback events from the sensor hub. Signed-off-by: srinivas pandruvada Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig index 417ade3..fc937ac 100644 --- a/drivers/iio/Kconfig +++ b/drivers/iio/Kconfig @@ -62,5 +62,6 @@ source "drivers/iio/frequency/Kconfig" source "drivers/iio/dac/Kconfig" source "drivers/iio/common/Kconfig" source "drivers/iio/gyro/Kconfig" +source "drivers/iio/magnetometer/Kconfig" endif # IIO diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile index a6406f7..761f2b6 100644 --- a/drivers/iio/Makefile +++ b/drivers/iio/Makefile @@ -18,3 +18,4 @@ obj-y += frequency/ obj-y += dac/ obj-y += common/ obj-y += gyro/ +obj-y += magnetometer/ diff --git a/drivers/iio/magnetometer/Kconfig b/drivers/iio/magnetometer/Kconfig new file mode 100644 index 0000000..c1f0cdd --- /dev/null +++ b/drivers/iio/magnetometer/Kconfig @@ -0,0 +1,16 @@ +# +# Magnetometer sensors +# +menu "Magnetometer sensors" + +config HID_SENSOR_MAGNETOMETER_3D + depends on HID_SENSOR_HUB + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER + select HID_SENSOR_IIO_COMMON + tristate "HID Magenetometer 3D" + help + Say yes here to build support for the HID SENSOR + Magnetometer 3D. + +endmenu diff --git a/drivers/iio/magnetometer/Makefile b/drivers/iio/magnetometer/Makefile new file mode 100644 index 0000000..60dc4f2 --- /dev/null +++ b/drivers/iio/magnetometer/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for industrial I/O Magnetometer sensor drivers +# + +obj-$(CONFIG_HID_SENSOR_MAGNETOMETER_3D) += hid-sensor-magn-3d.o diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c b/drivers/iio/magnetometer/hid-sensor-magn-3d.c new file mode 100644 index 0000000..07591f4 --- /dev/null +++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c @@ -0,0 +1,420 @@ +/* + * HID Sensors Driver + * Copyright (c) 2012, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../common/hid-sensors/hid-sensor-attributes.h" +#include "../common/hid-sensors/hid-sensor-trigger.h" + +/*Format: HID-SENSOR-usage_id_in_hex*/ +/*Usage ID from spec for Magnetometer-3D: 0x200083*/ +#define DRIVER_NAME "HID-SENSOR-200083" + +enum magn_3d_channel { + CHANNEL_SCAN_INDEX_X, + CHANNEL_SCAN_INDEX_Y, + CHANNEL_SCAN_INDEX_Z, + MAGN_3D_CHANNEL_MAX, +}; + +struct magn_3d_state { + struct hid_sensor_hub_callbacks callbacks; + struct hid_sensor_iio_common common_attributes; + struct hid_sensor_hub_attribute_info magn[MAGN_3D_CHANNEL_MAX]; + u32 magn_val[MAGN_3D_CHANNEL_MAX]; +}; + +static const u32 magn_3d_addresses[MAGN_3D_CHANNEL_MAX] = { + HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS, + HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Y_AXIS, + HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS +}; + +/* Channel definitions */ +static const struct iio_chan_spec magn_3d_channels[] = { + { + .type = IIO_MAGN, + .modified = 1, + .channel2 = IIO_MOD_X, + .info_mask = IIO_CHAN_INFO_OFFSET_SHARED_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT | + IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT | + IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT, + .scan_index = CHANNEL_SCAN_INDEX_X, + }, { + .type = IIO_MAGN, + .modified = 1, + .channel2 = IIO_MOD_Y, + .info_mask = IIO_CHAN_INFO_OFFSET_SHARED_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT | + IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT | + IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT, + .scan_index = CHANNEL_SCAN_INDEX_Y, + }, { + .type = IIO_MAGN, + .modified = 1, + .channel2 = IIO_MOD_Z, + .info_mask = IIO_CHAN_INFO_OFFSET_SHARED_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT | + IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT | + IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT, + .scan_index = CHANNEL_SCAN_INDEX_Z, + } +}; + +/* Adjust channel real bits based on report descriptor */ +static void magn_3d_adjust_channel_bit_mask(struct iio_chan_spec *channels, + int channel, int size) +{ + channels[channel].scan_type.sign = 's'; + /* Real storage bits will change based on the report desc. */ + channels[channel].scan_type.realbits = size * 8; + /* Maximum size of a sample to capture is u32 */ + channels[channel].scan_type.storagebits = sizeof(u32) * 8; +} + +/* Channel read_raw handler */ +static int magn_3d_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, + long mask) +{ + struct magn_3d_state *magn_state = iio_priv(indio_dev); + int report_id = -1; + u32 address; + int ret; + int ret_type; + + *val = 0; + *val2 = 0; + switch (mask) { + case 0: + report_id = + magn_state->magn[chan->scan_index].report_id; + address = magn_3d_addresses[chan->scan_index]; + if (report_id >= 0) + *val = sensor_hub_input_attr_get_raw_value( + magn_state->common_attributes.hsdev, + HID_USAGE_SENSOR_COMPASS_3D, address, + report_id); + else { + *val = 0; + return -EINVAL; + } + ret_type = IIO_VAL_INT; + break; + case IIO_CHAN_INFO_SCALE: + *val = magn_state->magn[CHANNEL_SCAN_INDEX_X].units; + ret_type = IIO_VAL_INT; + break; + case IIO_CHAN_INFO_OFFSET: + *val = hid_sensor_convert_exponent( + magn_state->magn[CHANNEL_SCAN_INDEX_X].unit_expo); + ret_type = IIO_VAL_INT; + break; + case IIO_CHAN_INFO_SAMP_FREQ: + ret = hid_sensor_read_samp_freq_value( + &magn_state->common_attributes, val, val2); + ret_type = IIO_VAL_INT_PLUS_MICRO; + break; + case IIO_CHAN_INFO_HYSTERESIS: + ret = hid_sensor_read_raw_hyst_value( + &magn_state->common_attributes, val, val2); + ret_type = IIO_VAL_INT_PLUS_MICRO; + break; + default: + ret_type = -EINVAL; + break; + } + + return ret_type; +} + +/* Channel write_raw handler */ +static int magn_3d_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, + int val2, + long mask) +{ + struct magn_3d_state *magn_state = iio_priv(indio_dev); + int ret = 0; + + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: + ret = hid_sensor_write_samp_freq_value( + &magn_state->common_attributes, val, val2); + break; + case IIO_CHAN_INFO_HYSTERESIS: + ret = hid_sensor_write_raw_hyst_value( + &magn_state->common_attributes, val, val2); + break; + default: + ret = -EINVAL; + } + + return ret; +} + +static int magn_3d_write_raw_get_fmt(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + long mask) +{ + return IIO_VAL_INT_PLUS_MICRO; +} + +static const struct iio_info magn_3d_info = { + .driver_module = THIS_MODULE, + .read_raw = &magn_3d_read_raw, + .write_raw = &magn_3d_write_raw, + .write_raw_get_fmt = &magn_3d_write_raw_get_fmt, +}; + +/* Function to push data to buffer */ +static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len) +{ + struct iio_buffer *buffer = indio_dev->buffer; + s64 timestamp = iio_get_time_ns(); + int datum_sz; + + dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n"); + if (!buffer) { + dev_err(&indio_dev->dev, "Buffer == NULL\n"); + return; + } + datum_sz = buffer->access->get_bytes_per_datum(buffer); + if (len > datum_sz) { + dev_err(&indio_dev->dev, "Datum size mismatch %d:%d\n", len, + datum_sz); + return; + } + buffer->access->store_to(buffer, (u8 *)data, timestamp); +} + +/* Callback handler to send event after all samples are received and captured */ +static int magn_3d_proc_event(struct hid_sensor_hub_device *hsdev, + unsigned usage_id, + void *priv) +{ + struct iio_dev *indio_dev = platform_get_drvdata(priv); + struct magn_3d_state *magn_state = iio_priv(indio_dev); + + dev_dbg(&indio_dev->dev, "magn_3d_proc_event [%d]\n", + magn_state->common_attributes.data_ready); + if (magn_state->common_attributes.data_ready) + hid_sensor_push_data(indio_dev, + (u8 *)magn_state->magn_val, + sizeof(magn_state->magn_val)); + + return 0; +} + +/* Capture samples in local storage */ +static int magn_3d_capture_sample(struct hid_sensor_hub_device *hsdev, + unsigned usage_id, + size_t raw_len, char *raw_data, + void *priv) +{ + struct iio_dev *indio_dev = platform_get_drvdata(priv); + struct magn_3d_state *magn_state = iio_priv(indio_dev); + int offset; + int ret = -EINVAL; + + switch (usage_id) { + case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS: + case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Y_AXIS: + case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS: + offset = usage_id - HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS; + magn_state->magn_val[CHANNEL_SCAN_INDEX_X + offset] = + *(u32 *)raw_data; + ret = 0; + break; + default: + break; + } + + return ret; +} + +/* Parse report which is specific to an usage id*/ +static int magn_3d_parse_report(struct platform_device *pdev, + struct hid_sensor_hub_device *hsdev, + struct iio_chan_spec *channels, + unsigned usage_id, + struct magn_3d_state *st) +{ + int ret; + int i; + + for (i = 0; i <= CHANNEL_SCAN_INDEX_Z; ++i) { + ret = sensor_hub_input_get_attribute_info(hsdev, + HID_INPUT_REPORT, + usage_id, + HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS + i, + &st->magn[CHANNEL_SCAN_INDEX_X + i]); + if (ret < 0) + break; + magn_3d_adjust_channel_bit_mask(channels, + CHANNEL_SCAN_INDEX_X + i, + st->magn[CHANNEL_SCAN_INDEX_X + i].size); + } + dev_dbg(&pdev->dev, "magn_3d %x:%x, %x:%x, %x:%x\n", + st->magn[0].index, + st->magn[0].report_id, + st->magn[1].index, st->magn[1].report_id, + st->magn[2].index, st->magn[2].report_id); + + return ret; +} + +/* Function to initialize the processing for usage id */ +static int __devinit hid_magn_3d_probe(struct platform_device *pdev) +{ + int ret = 0; + static char *name = "magn_3d"; + struct iio_dev *indio_dev; + struct magn_3d_state *magn_state; + struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; + struct iio_chan_spec *channels; + + indio_dev = iio_device_alloc(sizeof(struct magn_3d_state)); + if (indio_dev == NULL) { + ret = -ENOMEM; + goto error_ret; + } + platform_set_drvdata(pdev, indio_dev); + + magn_state = iio_priv(indio_dev); + magn_state->common_attributes.hsdev = hsdev; + magn_state->common_attributes.pdev = pdev; + + ret = hid_sensor_parse_common_attributes(hsdev, + HID_USAGE_SENSOR_COMPASS_3D, + &magn_state->common_attributes); + if (ret) { + dev_err(&pdev->dev, "failed to setup common attributes\n"); + goto error_free_dev; + } + + channels = kmemdup(magn_3d_channels, + sizeof(magn_3d_channels), + GFP_KERNEL); + if (!channels) { + dev_err(&pdev->dev, "failed to duplicate channels\n"); + goto error_free_dev; + } + + ret = magn_3d_parse_report(pdev, hsdev, channels, + HID_USAGE_SENSOR_COMPASS_3D, magn_state); + if (ret) { + dev_err(&pdev->dev, "failed to setup attributes\n"); + goto error_free_dev_mem; + } + + indio_dev->channels = channels; + indio_dev->num_channels = ARRAY_SIZE(magn_3d_channels); + indio_dev->dev.parent = &pdev->dev; + indio_dev->info = &magn_3d_info; + indio_dev->name = name; + indio_dev->modes = INDIO_DIRECT_MODE; + + ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, + NULL, NULL); + if (ret) { + dev_err(&pdev->dev, "failed to initialize trigger buffer\n"); + goto error_free_dev_mem; + } + magn_state->common_attributes.data_ready = false; + ret = hid_sensor_setup_trigger(indio_dev, name, + &magn_state->common_attributes); + if (ret < 0) { + dev_err(&pdev->dev, "trigger setup failed\n"); + goto error_unreg_buffer_funcs; + } + + ret = iio_device_register(indio_dev); + if (ret) { + dev_err(&pdev->dev, "device register failed\n"); + goto error_remove_trigger; + } + + magn_state->callbacks.send_event = magn_3d_proc_event; + magn_state->callbacks.capture_sample = magn_3d_capture_sample; + magn_state->callbacks.pdev = pdev; + ret = sensor_hub_register_callback(hsdev, HID_USAGE_SENSOR_COMPASS_3D, + &magn_state->callbacks); + if (ret < 0) { + dev_err(&pdev->dev, "callback reg failed\n"); + goto error_iio_unreg; + } + + return ret; + +error_iio_unreg: + iio_device_unregister(indio_dev); +error_remove_trigger: + hid_sensor_remove_trigger(indio_dev); +error_unreg_buffer_funcs: + iio_triggered_buffer_cleanup(indio_dev); +error_free_dev_mem: + kfree(indio_dev->channels); +error_free_dev: + iio_device_free(indio_dev); +error_ret: + return ret; +} + +/* Function to deinitialize the processing for usage id */ +static int __devinit hid_magn_3d_remove(struct platform_device *pdev) +{ + struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; + struct iio_dev *indio_dev = platform_get_drvdata(pdev); + + sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_COMPASS_3D); + iio_device_unregister(indio_dev); + hid_sensor_remove_trigger(indio_dev); + iio_triggered_buffer_cleanup(indio_dev); + kfree(indio_dev->channels); + iio_device_free(indio_dev); + + return 0; +} + +static struct platform_driver hid_magn_3d_platform_driver = { + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + }, + .probe = hid_magn_3d_probe, + .remove = hid_magn_3d_remove, +}; +module_platform_driver(hid_magn_3d_platform_driver); + +MODULE_DESCRIPTION("HID Sensor Magnetometer 3D"); +MODULE_AUTHOR("Srinivas Pandruvada "); +MODULE_LICENSE("GPL"); -- cgit v0.10.2 From ed5514c925a0e1266e70630092a77bd0c89aee1f Mon Sep 17 00:00:00 2001 From: srinivas pandruvada Date: Wed, 5 Sep 2012 13:56:00 +0100 Subject: iio: hid-sensors: Added ALS Added usage id processing for ALS. This uses IIO interfaces for triggered buffer to present data to user mode.This uses HID sensor framework for registering callback events from the sensor hub. Signed-off-by: srinivas pandruvada Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig index fc937ac..6e3f143 100644 --- a/drivers/iio/Kconfig +++ b/drivers/iio/Kconfig @@ -62,6 +62,7 @@ source "drivers/iio/frequency/Kconfig" source "drivers/iio/dac/Kconfig" source "drivers/iio/common/Kconfig" source "drivers/iio/gyro/Kconfig" +source "drivers/iio/light/Kconfig" source "drivers/iio/magnetometer/Kconfig" endif # IIO diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile index 761f2b6..f7fa3c0 100644 --- a/drivers/iio/Makefile +++ b/drivers/iio/Makefile @@ -18,4 +18,5 @@ obj-y += frequency/ obj-y += dac/ obj-y += common/ obj-y += gyro/ +obj-y += light/ obj-y += magnetometer/ diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig index 91d15d2..1763c9b 100644 --- a/drivers/iio/light/Kconfig +++ b/drivers/iio/light/Kconfig @@ -42,4 +42,14 @@ config VCNL4000 To compile this driver as a module, choose M here: the module will be called vcnl4000. +config HID_SENSOR_ALS + depends on HID_SENSOR_HUB + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER + select HID_SENSOR_IIO_COMMON + tristate "HID ALS" + help + Say yes here to build support for the HID SENSOR + Ambient light sensor. + endmenu diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile index 13f8a78..21a8f0d 100644 --- a/drivers/iio/light/Makefile +++ b/drivers/iio/light/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_ADJD_S311) += adjd_s311.o obj-$(CONFIG_SENSORS_LM3533) += lm3533-als.o obj-$(CONFIG_VCNL4000) += vcnl4000.o +obj-$(CONFIG_HID_SENSOR_ALS) += hid-sensor-als.o diff --git a/drivers/iio/light/hid-sensor-als.c b/drivers/iio/light/hid-sensor-als.c new file mode 100644 index 0000000..2cff7d5 --- /dev/null +++ b/drivers/iio/light/hid-sensor-als.c @@ -0,0 +1,386 @@ +/* + * HID Sensors Driver + * Copyright (c) 2012, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../common/hid-sensors/hid-sensor-attributes.h" +#include "../common/hid-sensors/hid-sensor-trigger.h" + +/*Format: HID-SENSOR-usage_id_in_hex*/ +/*Usage ID from spec for Accelerometer-3D: 0x200041*/ +#define DRIVER_NAME "HID-SENSOR-200041" + +#define CHANNEL_SCAN_INDEX_ILLUM 0 + +struct als_state { + struct hid_sensor_hub_callbacks callbacks; + struct hid_sensor_iio_common common_attributes; + struct hid_sensor_hub_attribute_info als_illum; + u32 illum; +}; + +/* Channel definitions */ +static const struct iio_chan_spec als_channels[] = { + { + .type = IIO_INTENSITY, + .modified = 1, + .channel2 = IIO_MOD_LIGHT_BOTH, + .info_mask = IIO_CHAN_INFO_OFFSET_SHARED_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT | + IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT | + IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT, + .scan_index = CHANNEL_SCAN_INDEX_ILLUM, + } +}; + +/* Adjust channel real bits based on report descriptor */ +static void als_adjust_channel_bit_mask(struct iio_chan_spec *channels, + int channel, int size) +{ + channels[channel].scan_type.sign = 's'; + /* Real storage bits will change based on the report desc. */ + channels[channel].scan_type.realbits = size * 8; + /* Maximum size of a sample to capture is u32 */ + channels[channel].scan_type.storagebits = sizeof(u32) * 8; +} + +/* Channel read_raw handler */ +static int als_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, + long mask) +{ + struct als_state *als_state = iio_priv(indio_dev); + int report_id = -1; + u32 address; + int ret; + int ret_type; + + *val = 0; + *val2 = 0; + switch (mask) { + case 0: + switch (chan->scan_index) { + case CHANNEL_SCAN_INDEX_ILLUM: + report_id = als_state->als_illum.report_id; + address = + HID_USAGE_SENSOR_LIGHT_ILLUM; + break; + default: + report_id = -1; + break; + } + if (report_id >= 0) + *val = sensor_hub_input_attr_get_raw_value( + als_state->common_attributes.hsdev, + HID_USAGE_SENSOR_ALS, address, + report_id); + else { + *val = 0; + return -EINVAL; + } + ret_type = IIO_VAL_INT; + break; + case IIO_CHAN_INFO_SCALE: + *val = als_state->als_illum.units; + ret_type = IIO_VAL_INT; + break; + case IIO_CHAN_INFO_OFFSET: + *val = hid_sensor_convert_exponent( + als_state->als_illum.unit_expo); + ret_type = IIO_VAL_INT; + break; + case IIO_CHAN_INFO_SAMP_FREQ: + ret = hid_sensor_read_samp_freq_value( + &als_state->common_attributes, val, val2); + ret_type = IIO_VAL_INT_PLUS_MICRO; + break; + case IIO_CHAN_INFO_HYSTERESIS: + ret = hid_sensor_read_raw_hyst_value( + &als_state->common_attributes, val, val2); + ret_type = IIO_VAL_INT_PLUS_MICRO; + break; + default: + ret_type = -EINVAL; + break; + } + + return ret_type; +} + +/* Channel write_raw handler */ +static int als_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, + int val2, + long mask) +{ + struct als_state *als_state = iio_priv(indio_dev); + int ret = 0; + + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: + ret = hid_sensor_write_samp_freq_value( + &als_state->common_attributes, val, val2); + break; + case IIO_CHAN_INFO_HYSTERESIS: + ret = hid_sensor_write_raw_hyst_value( + &als_state->common_attributes, val, val2); + break; + default: + ret = -EINVAL; + } + + return ret; +} + +static int als_write_raw_get_fmt(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + long mask) +{ + return IIO_VAL_INT_PLUS_MICRO; +} + +static const struct iio_info als_info = { + .driver_module = THIS_MODULE, + .read_raw = &als_read_raw, + .write_raw = &als_write_raw, + .write_raw_get_fmt = &als_write_raw_get_fmt, +}; + +/* Function to push data to buffer */ +static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len) +{ + struct iio_buffer *buffer = indio_dev->buffer; + s64 timestamp = iio_get_time_ns(); + int datum_sz; + + dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n"); + if (!buffer) { + dev_err(&indio_dev->dev, "Buffer == NULL\n"); + return; + } + datum_sz = buffer->access->get_bytes_per_datum(buffer); + if (len > datum_sz) { + dev_err(&indio_dev->dev, "Datum size mismatch %d:%d\n", len, + datum_sz); + return; + } + buffer->access->store_to(buffer, (u8 *)data, timestamp); +} + +/* Callback handler to send event after all samples are received and captured */ +static int als_proc_event(struct hid_sensor_hub_device *hsdev, + unsigned usage_id, + void *priv) +{ + struct iio_dev *indio_dev = platform_get_drvdata(priv); + struct als_state *als_state = iio_priv(indio_dev); + + dev_dbg(&indio_dev->dev, "als_proc_event [%d]\n", + als_state->common_attributes.data_ready); + if (als_state->common_attributes.data_ready) + hid_sensor_push_data(indio_dev, + (u8 *)&als_state->illum, + sizeof(als_state->illum)); + + return 0; +} + +/* Capture samples in local storage */ +static int als_capture_sample(struct hid_sensor_hub_device *hsdev, + unsigned usage_id, + size_t raw_len, char *raw_data, + void *priv) +{ + struct iio_dev *indio_dev = platform_get_drvdata(priv); + struct als_state *als_state = iio_priv(indio_dev); + int ret = -EINVAL; + + switch (usage_id) { + case HID_USAGE_SENSOR_LIGHT_ILLUM: + als_state->illum = *(u32 *)raw_data; + ret = 0; + break; + default: + break; + } + + return ret; +} + +/* Parse report which is specific to an usage id*/ +static int als_parse_report(struct platform_device *pdev, + struct hid_sensor_hub_device *hsdev, + struct iio_chan_spec *channels, + unsigned usage_id, + struct als_state *st) +{ + int ret; + + ret = sensor_hub_input_get_attribute_info(hsdev, HID_INPUT_REPORT, + usage_id, + HID_USAGE_SENSOR_LIGHT_ILLUM, + &st->als_illum); + if (ret < 0) + return ret; + als_adjust_channel_bit_mask(channels, CHANNEL_SCAN_INDEX_ILLUM, + st->als_illum.size); + + dev_dbg(&pdev->dev, "als %x:%x\n", st->als_illum.index, + st->als_illum.report_id); + + return ret; +} + +/* Function to initialize the processing for usage id */ +static int __devinit hid_als_probe(struct platform_device *pdev) +{ + int ret = 0; + static const char *name = "als"; + struct iio_dev *indio_dev; + struct als_state *als_state; + struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; + struct iio_chan_spec *channels; + + indio_dev = iio_device_alloc(sizeof(struct als_state)); + if (indio_dev == NULL) { + ret = -ENOMEM; + goto error_ret; + } + platform_set_drvdata(pdev, indio_dev); + + als_state = iio_priv(indio_dev); + als_state->common_attributes.hsdev = hsdev; + als_state->common_attributes.pdev = pdev; + + ret = hid_sensor_parse_common_attributes(hsdev, HID_USAGE_SENSOR_ALS, + &als_state->common_attributes); + if (ret) { + dev_err(&pdev->dev, "failed to setup common attributes\n"); + goto error_free_dev; + } + + channels = kmemdup(als_channels, + sizeof(als_channels), + GFP_KERNEL); + if (!channels) { + dev_err(&pdev->dev, "failed to duplicate channels\n"); + goto error_free_dev; + } + + ret = als_parse_report(pdev, hsdev, channels, + HID_USAGE_SENSOR_ALS, als_state); + if (ret) { + dev_err(&pdev->dev, "failed to setup attributes\n"); + goto error_free_dev_mem; + } + + indio_dev->channels = channels; + indio_dev->num_channels = + ARRAY_SIZE(als_channels); + indio_dev->dev.parent = &pdev->dev; + indio_dev->info = &als_info; + indio_dev->name = name; + indio_dev->modes = INDIO_DIRECT_MODE; + + ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, + NULL, NULL); + if (ret) { + dev_err(&pdev->dev, "failed to initialize trigger buffer\n"); + goto error_free_dev_mem; + } + als_state->common_attributes.data_ready = false; + ret = hid_sensor_setup_trigger(indio_dev, name, + &als_state->common_attributes); + if (ret < 0) { + dev_err(&pdev->dev, "trigger setup failed\n"); + goto error_unreg_buffer_funcs; + } + + ret = iio_device_register(indio_dev); + if (ret) { + dev_err(&pdev->dev, "device register failed\n"); + goto error_remove_trigger; + } + + als_state->callbacks.send_event = als_proc_event; + als_state->callbacks.capture_sample = als_capture_sample; + als_state->callbacks.pdev = pdev; + ret = sensor_hub_register_callback(hsdev, HID_USAGE_SENSOR_ALS, + &als_state->callbacks); + if (ret < 0) { + dev_err(&pdev->dev, "callback reg failed\n"); + goto error_iio_unreg; + } + + return ret; + +error_iio_unreg: + iio_device_unregister(indio_dev); +error_remove_trigger: + hid_sensor_remove_trigger(indio_dev); +error_unreg_buffer_funcs: + iio_triggered_buffer_cleanup(indio_dev); +error_free_dev_mem: + kfree(indio_dev->channels); +error_free_dev: + iio_device_free(indio_dev); +error_ret: + return ret; +} + +/* Function to deinitialize the processing for usage id */ +static int __devinit hid_als_remove(struct platform_device *pdev) +{ + struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; + struct iio_dev *indio_dev = platform_get_drvdata(pdev); + + sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_ALS); + iio_device_unregister(indio_dev); + hid_sensor_remove_trigger(indio_dev); + iio_triggered_buffer_cleanup(indio_dev); + kfree(indio_dev->channels); + iio_device_free(indio_dev); + + return 0; +} + +static struct platform_driver hid_als_platform_driver = { + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + }, + .probe = hid_als_probe, + .remove = hid_als_remove, +}; +module_platform_driver(hid_als_platform_driver); + +MODULE_DESCRIPTION("HID Sensor ALS"); +MODULE_AUTHOR("Srinivas Pandruvada "); +MODULE_LICENSE("GPL"); -- cgit v0.10.2 From f38bc926d022ebd67baad6ac7fc22c95fbc6238c Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 6 Sep 2012 10:05:00 +0100 Subject: staging:iio:sysfs-trigger: Use irq_work to properly active trigger Since iio_trigger_poll() calls generic_handle_irq() it need to be called from hardirq context. The sysfs trigger is kicked from userspace, so it is obviously not possible to fulfill this requirement by calling iio_trigger_poll directly. As a workaround commit 1f785681 ("staging:iio:trigger sysfs userspace trigger rework.") added iio_trigger_poll_chained() which uses handle_nested_irq instead of generic_handle_irq. This in itself is a hack and only works by chance. handle_nested_irq is intended to be called from the threaded interrupt handler of the parent IRQ. Using handle_nested_irq is also problematic since it will only call the threaded handler of the IRQ. But quite a few IIO drivers rely on their hardirq handler being called or undefined behaviour will occur. This patch uses the irq_work framework to schedule the call to iio_trigger_poll() from hardirq context, which fixes the issues described above. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/trigger/Kconfig b/drivers/staging/iio/trigger/Kconfig index b8abf54..7d32075 100644 --- a/drivers/staging/iio/trigger/Kconfig +++ b/drivers/staging/iio/trigger/Kconfig @@ -21,6 +21,8 @@ config IIO_GPIO_TRIGGER config IIO_SYSFS_TRIGGER tristate "SYSFS trigger" depends on SYSFS + depends on HAVE_IRQ_WORK + select IRQ_WORK help Provides support for using SYSFS entry as IIO triggers. If unsure, say N (but it's safe to say "Y"). diff --git a/drivers/staging/iio/trigger/iio-trig-sysfs.c b/drivers/staging/iio/trigger/iio-trig-sysfs.c index fee4746..3bac972 100644 --- a/drivers/staging/iio/trigger/iio-trig-sysfs.c +++ b/drivers/staging/iio/trigger/iio-trig-sysfs.c @@ -10,12 +10,14 @@ #include #include #include +#include #include #include struct iio_sysfs_trig { struct iio_trigger *trig; + struct irq_work work; int id; struct list_head l; }; @@ -89,11 +91,21 @@ static struct device iio_sysfs_trig_dev = { .release = &iio_trigger_sysfs_release, }; +static void iio_sysfs_trigger_work(struct irq_work *work) +{ + struct iio_sysfs_trig *trig = container_of(work, struct iio_sysfs_trig, + work); + + iio_trigger_poll(trig->trig, 0); +} + static ssize_t iio_sysfs_trigger_poll(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct iio_trigger *trig = to_iio_trigger(dev); - iio_trigger_poll_chained(trig, 0); + struct iio_sysfs_trig *sysfs_trig = trig->private_data; + + irq_work_queue(&sysfs_trig->work); return count; } @@ -148,6 +160,9 @@ static int iio_sysfs_trigger_probe(int id) t->trig->dev.groups = iio_sysfs_trigger_attr_groups; t->trig->ops = &iio_sysfs_trigger_ops; t->trig->dev.parent = &iio_sysfs_trig_dev; + t->trig->private_data = t; + + init_irq_work(&t->work, iio_sysfs_trigger_work); ret = iio_trigger_register(t->trig); if (ret) -- cgit v0.10.2 From 00176b360ce44bcc5dea2bcd0c8ff5ba9309685f Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 4 Sep 2012 12:35:00 +0100 Subject: staging:iio: Use iio_push_to_buffer Consistently use iio_push_to_buffer instead of manually calling the buffers store_to callback. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/accel/adis16201_ring.c b/drivers/staging/iio/accel/adis16201_ring.c index 03fcf6e..884dcf8 100644 --- a/drivers/staging/iio/accel/adis16201_ring.c +++ b/drivers/staging/iio/accel/adis16201_ring.c @@ -62,7 +62,6 @@ static irqreturn_t adis16201_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct adis16201_state *st = iio_priv(indio_dev); - struct iio_buffer *ring = indio_dev->buffer; int i = 0; s16 *data; @@ -83,7 +82,7 @@ static irqreturn_t adis16201_trigger_handler(int irq, void *p) if (indio_dev->scan_timestamp) *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; - ring->access->store_to(ring, (u8 *)data, pf->timestamp); + iio_push_to_buffer(indio_dev->buffer, (u8 *)data, pf->timestamp); kfree(data); done: diff --git a/drivers/staging/iio/accel/adis16203_ring.c b/drivers/staging/iio/accel/adis16203_ring.c index c16b2b7..a7ff804 100644 --- a/drivers/staging/iio/accel/adis16203_ring.c +++ b/drivers/staging/iio/accel/adis16203_ring.c @@ -61,7 +61,6 @@ static irqreturn_t adis16203_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct adis16203_state *st = iio_priv(indio_dev); - struct iio_buffer *ring = indio_dev->buffer; int i = 0; s16 *data; @@ -82,9 +81,7 @@ static irqreturn_t adis16203_trigger_handler(int irq, void *p) if (indio_dev->scan_timestamp) *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; - ring->access->store_to(ring, - (u8 *)data, - pf->timestamp); + iio_push_to_buffer(indio_dev->buffer, (u8 *)data, pf->timestamp); kfree(data); done: diff --git a/drivers/staging/iio/accel/adis16204_ring.c b/drivers/staging/iio/accel/adis16204_ring.c index 1d2b31c..16e36e3 100644 --- a/drivers/staging/iio/accel/adis16204_ring.c +++ b/drivers/staging/iio/accel/adis16204_ring.c @@ -59,7 +59,6 @@ static irqreturn_t adis16204_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct adis16204_state *st = iio_priv(indio_dev); - struct iio_buffer *ring = indio_dev->buffer; int i = 0; s16 *data; @@ -79,7 +78,7 @@ static irqreturn_t adis16204_trigger_handler(int irq, void *p) if (indio_dev->scan_timestamp) *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; - ring->access->store_to(ring, (u8 *)data, pf->timestamp); + iio_push_to_buffer(indio_dev->buffer, (u8 *)data, pf->timestamp); kfree(data); done: diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c index 1a4a55c..5cfeff4 100644 --- a/drivers/staging/iio/accel/adis16209_ring.c +++ b/drivers/staging/iio/accel/adis16209_ring.c @@ -59,7 +59,6 @@ static irqreturn_t adis16209_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct adis16209_state *st = iio_priv(indio_dev); - struct iio_buffer *ring = indio_dev->buffer; int i = 0; s16 *data; @@ -79,7 +78,7 @@ static irqreturn_t adis16209_trigger_handler(int irq, void *p) if (indio_dev->scan_timestamp) *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; - ring->access->store_to(ring, (u8 *)data, pf->timestamp); + iio_push_to_buffer(indio_dev->buffer, (u8 *)data, pf->timestamp); kfree(data); done: diff --git a/drivers/staging/iio/accel/adis16240_ring.c b/drivers/staging/iio/accel/adis16240_ring.c index 360dfed..d5ec43e 100644 --- a/drivers/staging/iio/accel/adis16240_ring.c +++ b/drivers/staging/iio/accel/adis16240_ring.c @@ -56,7 +56,6 @@ static irqreturn_t adis16240_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct adis16240_state *st = iio_priv(indio_dev); - struct iio_buffer *ring = indio_dev->buffer; int i = 0; s16 *data; @@ -77,7 +76,7 @@ static irqreturn_t adis16240_trigger_handler(int irq, void *p) if (indio_dev->scan_timestamp) *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; - ring->access->store_to(ring, (u8 *)data, pf->timestamp); + iio_push_to_buffer(indio_dev->buffer, (u8 *)data, pf->timestamp); kfree(data); done: diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c index 7da2703..9332762 100644 --- a/drivers/staging/iio/accel/lis3l02dq_ring.c +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c @@ -135,7 +135,6 @@ static irqreturn_t lis3l02dq_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; - struct iio_buffer *buffer = indio_dev->buffer; int len = 0; char *data; @@ -153,7 +152,7 @@ static irqreturn_t lis3l02dq_trigger_handler(int irq, void *p) if (indio_dev->scan_timestamp) *(s64 *)((u8 *)data + ALIGN(len, sizeof(s64))) = pf->timestamp; - buffer->access->store_to(buffer, (u8 *)data, pf->timestamp); + iio_push_to_buffer(indio_dev->buffer, (u8 *)data, pf->timestamp); kfree(data); done: diff --git a/drivers/staging/iio/adc/ad7298_ring.c b/drivers/staging/iio/adc/ad7298_ring.c index 506016f..9fce404 100644 --- a/drivers/staging/iio/adc/ad7298_ring.c +++ b/drivers/staging/iio/adc/ad7298_ring.c @@ -75,7 +75,6 @@ static irqreturn_t ad7298_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct ad7298_state *st = iio_priv(indio_dev); - struct iio_buffer *ring = indio_dev->buffer; s64 time_ns = 0; __u16 buf[16]; int b_sent, i; @@ -94,7 +93,7 @@ static irqreturn_t ad7298_trigger_handler(int irq, void *p) indio_dev->masklength); i++) buf[i] = be16_to_cpu(st->rx_buf[i]); - indio_dev->buffer->access->store_to(ring, (u8 *)buf, time_ns); + iio_push_to_buffer(indio_dev->buffer, (u8 *)buf, time_ns); done: iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/staging/iio/adc/ad7476_ring.c b/drivers/staging/iio/adc/ad7476_ring.c index d087b21..3741ac6 100644 --- a/drivers/staging/iio/adc/ad7476_ring.c +++ b/drivers/staging/iio/adc/ad7476_ring.c @@ -44,7 +44,7 @@ static irqreturn_t ad7476_trigger_handler(int irq, void *p) memcpy(rxbuf + indio_dev->scan_bytes - sizeof(s64), &time_ns, sizeof(time_ns)); - indio_dev->buffer->access->store_to(indio_dev->buffer, rxbuf, time_ns); + iio_push_to_buffer(indio_dev->buffer, rxbuf, time_ns); done: iio_trigger_notify_done(indio_dev->trig); kfree(rxbuf); diff --git a/drivers/staging/iio/adc/ad7606_ring.c b/drivers/staging/iio/adc/ad7606_ring.c index f15afe4..f4b009e 100644 --- a/drivers/staging/iio/adc/ad7606_ring.c +++ b/drivers/staging/iio/adc/ad7606_ring.c @@ -46,7 +46,6 @@ static void ad7606_poll_bh_to_ring(struct work_struct *work_s) struct ad7606_state *st = container_of(work_s, struct ad7606_state, poll_work); struct iio_dev *indio_dev = iio_priv_to_dev(st); - struct iio_buffer *ring = indio_dev->buffer; s64 time_ns; __u8 *buf; int ret; @@ -84,7 +83,7 @@ static void ad7606_poll_bh_to_ring(struct work_struct *work_s) if (indio_dev->scan_timestamp) *((s64 *)(buf + indio_dev->scan_bytes - sizeof(s64))) = time_ns; - ring->access->store_to(indio_dev->buffer, buf, time_ns); + iio_push_to_buffer(indio_dev->buffer, buf, time_ns); done: gpio_set_value(st->pdata->gpio_convst, 0); iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/staging/iio/adc/ad7887_ring.c b/drivers/staging/iio/adc/ad7887_ring.c index c76fdb5..a4ff493 100644 --- a/drivers/staging/iio/adc/ad7887_ring.c +++ b/drivers/staging/iio/adc/ad7887_ring.c @@ -95,7 +95,7 @@ static irqreturn_t ad7887_trigger_handler(int irq, void *p) memcpy(buf + indio_dev->scan_bytes - sizeof(s64), &time_ns, sizeof(time_ns)); - indio_dev->buffer->access->store_to(indio_dev->buffer, buf, time_ns); + iio_push_to_buffer(indio_dev->buffer, buf, time_ns); done: kfree(buf); iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/staging/iio/adc/ad799x_ring.c b/drivers/staging/iio/adc/ad799x_ring.c index 858a685..84275c3 100644 --- a/drivers/staging/iio/adc/ad799x_ring.c +++ b/drivers/staging/iio/adc/ad799x_ring.c @@ -35,7 +35,6 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct ad799x_state *st = iio_priv(indio_dev); - struct iio_buffer *ring = indio_dev->buffer; s64 time_ns; __u8 *rxbuf; int b_sent; @@ -78,7 +77,7 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p) memcpy(rxbuf + indio_dev->scan_bytes - sizeof(s64), &time_ns, sizeof(time_ns)); - ring->access->store_to(indio_dev->buffer, rxbuf, time_ns); + iio_push_to_buffer(indio_dev->buffer, rxbuf, time_ns); done: kfree(rxbuf); out: diff --git a/drivers/staging/iio/gyro/adis16260_ring.c b/drivers/staging/iio/gyro/adis16260_ring.c index eeee8e7..e6e2345 100644 --- a/drivers/staging/iio/gyro/adis16260_ring.c +++ b/drivers/staging/iio/gyro/adis16260_ring.c @@ -62,7 +62,6 @@ static irqreturn_t adis16260_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct adis16260_state *st = iio_priv(indio_dev); - struct iio_buffer *ring = indio_dev->buffer; int i = 0; s16 *data; @@ -82,7 +81,7 @@ static irqreturn_t adis16260_trigger_handler(int irq, void *p) if (indio_dev->scan_timestamp) *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; - ring->access->store_to(ring, (u8 *)data, pf->timestamp); + iio_push_to_buffer(indio_dev->buffer, (u8 *)data, pf->timestamp); kfree(data); done: diff --git a/drivers/staging/iio/iio_simple_dummy_buffer.c b/drivers/staging/iio/iio_simple_dummy_buffer.c index bd628de..e080213 100644 --- a/drivers/staging/iio/iio_simple_dummy_buffer.c +++ b/drivers/staging/iio/iio_simple_dummy_buffer.c @@ -87,7 +87,7 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p) if (indio_dev->scan_timestamp) *(s64 *)((u8 *)data + ALIGN(len, sizeof(s64))) = iio_get_time_ns(); - buffer->access->store_to(buffer, (u8 *)data, pf->timestamp); + iio_push_to_buffer(buffer, (u8 *)data, pf->timestamp); kfree(data); diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c index e239ea9..39a9be8 100644 --- a/drivers/staging/iio/impedance-analyzer/ad5933.c +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c @@ -678,7 +678,7 @@ static void ad5933_work(struct work_struct *work) buf[0] = be16_to_cpu(buf[0]); } /* save datum to the ring */ - ring->access->store_to(ring, (u8 *)buf, iio_get_time_ns()); + iio_push_to_buffer(ring, (u8 *)buf, iio_get_time_ns()); } else { /* no data available - try again later */ schedule_delayed_work(&st->work, st->poll_time_jiffies); diff --git a/drivers/staging/iio/imu/adis16400_ring.c b/drivers/staging/iio/imu/adis16400_ring.c index beec650..6b71788 100644 --- a/drivers/staging/iio/imu/adis16400_ring.c +++ b/drivers/staging/iio/imu/adis16400_ring.c @@ -150,7 +150,7 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p) /* Guaranteed to be aligned with 8 byte boundary */ if (ring->scan_timestamp) *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; - ring->access->store_to(indio_dev->buffer, (u8 *) data, pf->timestamp); + iio_push_to_buffer(ring, (u8 *) data, pf->timestamp); done: kfree(data); diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c index 1ce10b2..23c107a 100644 --- a/drivers/staging/iio/meter/ade7758_ring.c +++ b/drivers/staging/iio/meter/ade7758_ring.c @@ -61,7 +61,6 @@ static irqreturn_t ade7758_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; - struct iio_buffer *ring = indio_dev->buffer; struct ade7758_state *st = iio_priv(indio_dev); s64 dat64[2]; u32 *dat32 = (u32 *)dat64; @@ -74,7 +73,7 @@ static irqreturn_t ade7758_trigger_handler(int irq, void *p) if (indio_dev->scan_timestamp) dat64[1] = pf->timestamp; - ring->access->store_to(ring, (u8 *)dat64, pf->timestamp); + iio_push_to_buffer(indio_dev->buffer, (u8 *)dat64, pf->timestamp); iio_trigger_notify_done(indio_dev->trig); -- cgit v0.10.2 From 7953e44cefe1359032d1148de69b966bcd2e5233 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Thu, 6 Sep 2012 21:45:18 +0200 Subject: staging: ipack: only build on platforms that provide ioread/iowrite. Do so by depending on HAS_IOMEM. Reported-by: Geert Uytterhoeven Signed-off-by: Jens Taprogge Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/Kconfig b/drivers/staging/ipack/Kconfig index af32178..4cf4706 100644 --- a/drivers/staging/ipack/Kconfig +++ b/drivers/staging/ipack/Kconfig @@ -4,6 +4,7 @@ menuconfig IPACK_BUS tristate "IndustryPack bus support" + depends on HAS_IOMEM ---help--- If you say Y here you get support for the IndustryPack Framework for drivers for many types of boards that support this industrial -- cgit v0.10.2 From 5948ae27fb4f0e87ce8543ca1934599b83929a3e Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Fri, 7 Sep 2012 10:29:19 +0200 Subject: staging/ipack: Fix bug introduced by IPack device matching MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ~0 can not be casted to u8. Instead of using the IPACK_ANY_ID for the format field we introduce a new IPACK_ANY_FORMAT specifically for that field and defined as 0xff. Reported-by: Dan Carpenter Signed-off-by: Jens Taprogge Acked-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c index b3736c0..659aadc 100644 --- a/drivers/staging/ipack/ipack.c +++ b/drivers/staging/ipack/ipack.c @@ -31,7 +31,8 @@ static inline const struct ipack_device_id * ipack_match_one_device(const struct ipack_device_id *id, const struct ipack_device *device) { - if ((id->format == IPACK_ANY_ID || id->format == device->id_format) && + if ((id->format == IPACK_ANY_FORMAT || + id->format == device->id_format) && (id->vendor == IPACK_ANY_ID || id->vendor == device->id_vendor) && (id->device == IPACK_ANY_ID || id->device == device->id_device)) return id; diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 999c4c2..70c6a35 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -600,6 +600,7 @@ struct x86_cpu_id { #define X86_MODEL_ANY 0 #define X86_FEATURE_ANY 0 /* Same as FPU, you can't test for that */ +#define IPACK_ANY_FORMAT 0xff #define IPACK_ANY_ID (~0) struct ipack_device_id { __u8 format; /* Format version or IPACK_ANY_ID */ diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 3c22bda..df4fc23 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -973,7 +973,7 @@ static int do_ipack_entry(const char *filename, id->vendor = TO_NATIVE(id->vendor); id->device = TO_NATIVE(id->device); strcpy(alias, "ipack:"); - ADD(alias, "f", id->format != IPACK_ANY_ID, id->format); + ADD(alias, "f", id->format != IPACK_ANY_FORMAT, id->format); ADD(alias, "v", id->vendor != IPACK_ANY_ID, id->vendor); ADD(alias, "d", id->device != IPACK_ANY_ID, id->device); add_wildcard(alias); -- cgit v0.10.2 From a0d7bf7dd1b37ccd6804cd62ca037c1efe3b2e27 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Thu, 6 Sep 2012 22:12:53 +0100 Subject: staging:iio: hid-sensors Use iio_push_to_buffer Consistently use iio_push_to_buffer instead of manually calling the buffers store_to callback. These crossed with Lars-Peter's patch set doing every other case. Signed-off-by: Jonathan Cameron Acked-by: srinivas pandruvada diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c index 33aa97c..c593eb23 100644 --- a/drivers/iio/accel/hid-sensor-accel-3d.c +++ b/drivers/iio/accel/hid-sensor-accel-3d.c @@ -212,7 +212,7 @@ static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len) datum_sz); return; } - buffer->access->store_to(buffer, (u8 *)data, timestamp); + iio_push_to_buffer(buffer, (u8 *)data, timestamp); } /* Callback handler to send event after all samples are received and captured */ diff --git a/drivers/iio/gyro/hid-sensor-gyro-3d.c b/drivers/iio/gyro/hid-sensor-gyro-3d.c index 50ec09b..94a4740 100644 --- a/drivers/iio/gyro/hid-sensor-gyro-3d.c +++ b/drivers/iio/gyro/hid-sensor-gyro-3d.c @@ -212,7 +212,7 @@ static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len) datum_sz); return; } - buffer->access->store_to(buffer, (u8 *)data, timestamp); + iio_push_to_buffer(buffer, (u8 *)data, timestamp); } /* Callback handler to send event after all samples are received and captured */ diff --git a/drivers/iio/light/hid-sensor-als.c b/drivers/iio/light/hid-sensor-als.c index 2cff7d5..b3c8e91 100644 --- a/drivers/iio/light/hid-sensor-als.c +++ b/drivers/iio/light/hid-sensor-als.c @@ -191,7 +191,7 @@ static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len) datum_sz); return; } - buffer->access->store_to(buffer, (u8 *)data, timestamp); + iio_push_to_buffer(buffer, (u8 *)data, timestamp); } /* Callback handler to send event after all samples are received and captured */ diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c b/drivers/iio/magnetometer/hid-sensor-magn-3d.c index 07591f4..397704e 100644 --- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c +++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c @@ -213,7 +213,7 @@ static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len) datum_sz); return; } - buffer->access->store_to(buffer, (u8 *)data, timestamp); + iio_push_to_buffer(buffer, (u8 *)data, timestamp); } /* Callback handler to send event after all samples are received and captured */ -- cgit v0.10.2 From 82933302306e8e7d7354a8fdfb242f33506bd892 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:38:30 -0700 Subject: staging: comedi: me4000: remove ME4000_BOARD_VERSIONS Remove the terminating entry in the boardinfo so that ARRAY_SIZE works correctly. Then remove ME4000_BOARD_VERSIONS and just use ARRAY_SIZE in the probe. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 050f0e4..028c20f 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -81,12 +81,8 @@ static const struct me4000_board me4000_boards[] = { {"ME-4680i", 0x4681, {4, 4}, {32, 0, 16, 1}, {4}, {3} }, {"ME-4680s", 0x4682, {4, 4}, {32, 8, 16, 1}, {4}, {3} }, {"ME-4680is", 0x4683, {4, 4}, {32, 8, 16, 1}, {4}, {3} }, - - {0}, }; -#define ME4000_BOARD_VERSIONS (ARRAY_SIZE(me4000_boards) - 1) - /*----------------------------------------------------------------------------- Meilhaus function prototypes ---------------------------------------------------------------------------*/ @@ -136,7 +132,7 @@ static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it) */ for_each_pci_dev(pci_device) { if (pci_device->vendor == PCI_VENDOR_ID_MEILHAUS) { - for (i = 0; i < ME4000_BOARD_VERSIONS; i++) { + for (i = 0; i < ARRAY_SIZE(me4000_boards); i++) { if (me4000_boards[i].device_id == pci_device->device) { /* -- cgit v0.10.2 From 035d432a51853b258343c5e91e5ce43667deb8dd Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:38:52 -0700 Subject: staging: comedi: me4000: convert boardinfo initialization to C99 format Convert the boardinfo initialization to C99 format to make it less error prone and easier to maintain. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 028c20f..4a22fe3 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -65,22 +65,254 @@ broken. #endif static const struct me4000_board me4000_boards[] = { - {"ME-4650", 0x4650, {0, 0}, {16, 0, 0, 0}, {4}, {0} }, - - {"ME-4660", 0x4660, {0, 0}, {32, 0, 16, 0}, {4}, {3} }, - {"ME-4660i", 0x4661, {0, 0}, {32, 0, 16, 0}, {4}, {3} }, - {"ME-4660s", 0x4662, {0, 0}, {32, 8, 16, 0}, {4}, {3} }, - {"ME-4660is", 0x4663, {0, 0}, {32, 8, 16, 0}, {4}, {3} }, - - {"ME-4670", 0x4670, {4, 0}, {32, 0, 16, 1}, {4}, {3} }, - {"ME-4670i", 0x4671, {4, 0}, {32, 0, 16, 1}, {4}, {3} }, - {"ME-4670s", 0x4672, {4, 0}, {32, 8, 16, 1}, {4}, {3} }, - {"ME-4670is", 0x4673, {4, 0}, {32, 8, 16, 1}, {4}, {3} }, - - {"ME-4680", 0x4680, {4, 4}, {32, 0, 16, 1}, {4}, {3} }, - {"ME-4680i", 0x4681, {4, 4}, {32, 0, 16, 1}, {4}, {3} }, - {"ME-4680s", 0x4682, {4, 4}, {32, 8, 16, 1}, {4}, {3} }, - {"ME-4680is", 0x4683, {4, 4}, {32, 8, 16, 1}, {4}, {3} }, + { + .name = "ME-4650", + .device_id = 0x4650, + .ao = { + .count = 0, + .fifo_count = 0, + }, + .ai = { + .count = 16, + .sh_count = 0, + .diff_count = 0, + .ex_trig_analog = 0, + }, + .dio = { + .count = 4, + }, + .cnt = { + .count = 0, + }, + }, { + .name = "ME-4660", + .device_id = 0x4660, + .ao = { + .count = 0, + .fifo_count = 0, + }, + .ai = { + .count = 32, + .sh_count = 0, + .diff_count = 16, + .ex_trig_analog = 0, + }, + .dio = { + .count = 4, + }, + .cnt = { + .count = 3, + }, + }, { + .name = "ME-4660i", + .device_id = 0x4661, + .ao = { + .count = 0, + .fifo_count = 0, + }, + .ai = { + .count = 32, + .sh_count = 0, + .diff_count = 16, + .ex_trig_analog = 0, + }, + .dio = { + .count = 4, + }, + .cnt = { + .count = 3, + }, + }, { + .name = "ME-4660s", + .device_id = 0x4662, + .ao = { + .count = 0, + .fifo_count = 0, + }, + .ai = { + .count = 32, + .sh_count = 8, + .diff_count = 16, + .ex_trig_analog = 0, + }, + .dio = { + .count = 4, + }, + .cnt = { + .count = 3, + }, + }, { + .name = "ME-4660is", + .device_id = 0x4663, + .ao = { + .count = 0, + .fifo_count = 0, + }, + .ai = { + .count = 32, + .sh_count = 8, + .diff_count = 16, + .ex_trig_analog = 0, + }, + .dio = { + .count = 4, + }, + .cnt = { + .count = 3, + }, + }, { + .name = "ME-4670", + .device_id = 0x4670, + .ao = { + .count = 4, + .fifo_count = 0, + }, + .ai = { + .count = 32, + .sh_count = 0, + .diff_count = 16, + .ex_trig_analog = 1, + }, + .dio = { + .count = 4, + }, + .cnt = { + .count = 3, + }, + }, { + .name = "ME-4670i", + .device_id = 0x4671, + .ao = { + .count = 4, + .fifo_count = 0, + }, + .ai = { + .count = 32, + .sh_count = 0, + .diff_count = 16, + .ex_trig_analog = 1, + }, + .dio = { + .count = 4, + }, + .cnt = { + .count = 3, + }, + }, { + .name = "ME-4670s", + .device_id = 0x4672, + .ao = { + .count = 4, + .fifo_count = 0, + }, + .ai = { + .count = 32, + .sh_count = 8, + .diff_count = 16, + .ex_trig_analog = 1, + }, + .dio = { + .count = 4, + }, + .cnt = { + .count = 3, + }, + }, { + .name = "ME-4670is", + .device_id = 0x4673, + .ao = { + .count = 4, + .fifo_count = 0, + }, + .ai = { + .count = 32, + .sh_count = 8, + .diff_count = 16, + .ex_trig_analog = 1, + }, + .dio = { + .count = 4, + }, + .cnt = { + .count = 3, + }, + }, { + .name = "ME-4680", + .device_id = 0x4680, + .ao = { + .count = 4, + .fifo_count = 4, + }, + .ai = { + .count = 32, + .sh_count = 0, + .diff_count = 16, + .ex_trig_analog = 1, + }, + .dio = { + .count = 4, + }, + .cnt = { + .count = 3, + }, + }, { + .name = "ME-4680i", + .device_id = 0x4681, + .ao = { + .count = 4, + .fifo_count = 4, + }, + .ai = { + .count = 32, + .sh_count = 0, + .diff_count = 16, + .ex_trig_analog = 1, + }, + .dio = { + .count = 4, + }, + .cnt = { + .count = 3, + }, + }, { + .name = "ME-4680s", + .device_id = 0x4682, + .ao = { + .count = 4, + .fifo_count = 4, + }, + .ai = { + .count = 32, + .sh_count = 8, + .diff_count = 16, + .ex_trig_analog = 1, + }, + .dio = { + .count = 4, + }, + .cnt = { + .count = 3, + }, + }, { + .name = "ME-4680is", + .device_id = 0x4683, + .ao = { + .count = 4, + .fifo_count = 4, + }, + .ai = { + .count = 32, + .sh_count = 8, + .diff_count = 16, + .ex_trig_analog = 1, + }, + .dio = { + .count = 4, + }, + .cnt = { + .count = 3, + }, + }, }; /*----------------------------------------------------------------------------- -- cgit v0.10.2 From 556e451d0d1ee7f9f40d4d83b39743176b8b39e4 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:39:11 -0700 Subject: staging: comedi: me4000: remove the '0' boardinfo data Remove all the boardinfo data that is set to '0'. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 4a22fe3..1983fa7 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -68,34 +68,18 @@ static const struct me4000_board me4000_boards[] = { { .name = "ME-4650", .device_id = 0x4650, - .ao = { - .count = 0, - .fifo_count = 0, - }, .ai = { .count = 16, - .sh_count = 0, - .diff_count = 0, - .ex_trig_analog = 0, }, .dio = { .count = 4, }, - .cnt = { - .count = 0, - }, }, { .name = "ME-4660", .device_id = 0x4660, - .ao = { - .count = 0, - .fifo_count = 0, - }, .ai = { .count = 32, - .sh_count = 0, .diff_count = 16, - .ex_trig_analog = 0, }, .dio = { .count = 4, @@ -106,15 +90,9 @@ static const struct me4000_board me4000_boards[] = { }, { .name = "ME-4660i", .device_id = 0x4661, - .ao = { - .count = 0, - .fifo_count = 0, - }, .ai = { .count = 32, - .sh_count = 0, .diff_count = 16, - .ex_trig_analog = 0, }, .dio = { .count = 4, @@ -125,15 +103,10 @@ static const struct me4000_board me4000_boards[] = { }, { .name = "ME-4660s", .device_id = 0x4662, - .ao = { - .count = 0, - .fifo_count = 0, - }, .ai = { .count = 32, .sh_count = 8, .diff_count = 16, - .ex_trig_analog = 0, }, .dio = { .count = 4, @@ -144,15 +117,10 @@ static const struct me4000_board me4000_boards[] = { }, { .name = "ME-4660is", .device_id = 0x4663, - .ao = { - .count = 0, - .fifo_count = 0, - }, .ai = { .count = 32, .sh_count = 8, .diff_count = 16, - .ex_trig_analog = 0, }, .dio = { .count = 4, @@ -165,11 +133,9 @@ static const struct me4000_board me4000_boards[] = { .device_id = 0x4670, .ao = { .count = 4, - .fifo_count = 0, }, .ai = { .count = 32, - .sh_count = 0, .diff_count = 16, .ex_trig_analog = 1, }, @@ -184,11 +150,9 @@ static const struct me4000_board me4000_boards[] = { .device_id = 0x4671, .ao = { .count = 4, - .fifo_count = 0, }, .ai = { .count = 32, - .sh_count = 0, .diff_count = 16, .ex_trig_analog = 1, }, @@ -203,7 +167,6 @@ static const struct me4000_board me4000_boards[] = { .device_id = 0x4672, .ao = { .count = 4, - .fifo_count = 0, }, .ai = { .count = 32, @@ -222,7 +185,6 @@ static const struct me4000_board me4000_boards[] = { .device_id = 0x4673, .ao = { .count = 4, - .fifo_count = 0, }, .ai = { .count = 32, @@ -245,7 +207,6 @@ static const struct me4000_board me4000_boards[] = { }, .ai = { .count = 32, - .sh_count = 0, .diff_count = 16, .ex_trig_analog = 1, }, @@ -264,7 +225,6 @@ static const struct me4000_board me4000_boards[] = { }, .ai = { .count = 32, - .sh_count = 0, .diff_count = 16, .ex_trig_analog = 1, }, -- cgit v0.10.2 From eedf4299b5af712ee6f1db031308abe1a4dd7c82 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:39:31 -0700 Subject: staging: comedi: me4000: remove struct me4000_cnt_info The me4000_cnt_info in the boardinfo struct is used to indicate that the board has an 8254 counter. Add a 'has_counter' field to struct me4000_board and remove the struct me4000_cnt_info. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 1983fa7..492b47e 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -84,9 +84,7 @@ static const struct me4000_board me4000_boards[] = { .dio = { .count = 4, }, - .cnt = { - .count = 3, - }, + .has_counter = 1, }, { .name = "ME-4660i", .device_id = 0x4661, @@ -97,9 +95,7 @@ static const struct me4000_board me4000_boards[] = { .dio = { .count = 4, }, - .cnt = { - .count = 3, - }, + .has_counter = 1, }, { .name = "ME-4660s", .device_id = 0x4662, @@ -111,9 +107,7 @@ static const struct me4000_board me4000_boards[] = { .dio = { .count = 4, }, - .cnt = { - .count = 3, - }, + .has_counter = 1, }, { .name = "ME-4660is", .device_id = 0x4663, @@ -125,9 +119,7 @@ static const struct me4000_board me4000_boards[] = { .dio = { .count = 4, }, - .cnt = { - .count = 3, - }, + .has_counter = 1, }, { .name = "ME-4670", .device_id = 0x4670, @@ -142,9 +134,7 @@ static const struct me4000_board me4000_boards[] = { .dio = { .count = 4, }, - .cnt = { - .count = 3, - }, + .has_counter = 1, }, { .name = "ME-4670i", .device_id = 0x4671, @@ -159,9 +149,7 @@ static const struct me4000_board me4000_boards[] = { .dio = { .count = 4, }, - .cnt = { - .count = 3, - }, + .has_counter = 1, }, { .name = "ME-4670s", .device_id = 0x4672, @@ -177,9 +165,7 @@ static const struct me4000_board me4000_boards[] = { .dio = { .count = 4, }, - .cnt = { - .count = 3, - }, + .has_counter = 1, }, { .name = "ME-4670is", .device_id = 0x4673, @@ -195,9 +181,7 @@ static const struct me4000_board me4000_boards[] = { .dio = { .count = 4, }, - .cnt = { - .count = 3, - }, + .has_counter = 1, }, { .name = "ME-4680", .device_id = 0x4680, @@ -213,9 +197,7 @@ static const struct me4000_board me4000_boards[] = { .dio = { .count = 4, }, - .cnt = { - .count = 3, - }, + .has_counter = 1, }, { .name = "ME-4680i", .device_id = 0x4681, @@ -231,9 +213,7 @@ static const struct me4000_board me4000_boards[] = { .dio = { .count = 4, }, - .cnt = { - .count = 3, - }, + .has_counter = 1, }, { .name = "ME-4680s", .device_id = 0x4682, @@ -250,9 +230,7 @@ static const struct me4000_board me4000_boards[] = { .dio = { .count = 4, }, - .cnt = { - .count = 3, - }, + .has_counter = 1, }, { .name = "ME-4680is", .device_id = 0x4683, @@ -269,9 +247,7 @@ static const struct me4000_board me4000_boards[] = { .dio = { .count = 4, }, - .cnt = { - .count = 3, - }, + .has_counter = 1, }, }; @@ -2290,10 +2266,10 @@ static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it) s = &dev->subdevices[3]; - if (thisboard->cnt.count) { + if (thisboard->has_counter) { s->type = COMEDI_SUBD_COUNTER; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = thisboard->cnt.count; + s->n_chan = 3; s->maxdata = 0xFFFF; /* 16 bit counters */ s->insn_read = me4000_cnt_insn_read; s->insn_write = me4000_cnt_insn_write; diff --git a/drivers/staging/comedi/drivers/me4000.h b/drivers/staging/comedi/drivers/me4000.h index 5a4df4e..2b609d7 100644 --- a/drivers/staging/comedi/drivers/me4000.h +++ b/drivers/staging/comedi/drivers/me4000.h @@ -272,17 +272,13 @@ struct me4000_dio_info { int count; }; -struct me4000_cnt_info { - int count; -}; - struct me4000_board { const char *name; unsigned short device_id; struct me4000_ao_info ao; struct me4000_ai_info ai; struct me4000_dio_info dio; - struct me4000_cnt_info cnt; + int has_counter; }; #define thisboard ((const struct me4000_board *)dev->board_ptr) -- cgit v0.10.2 From 898f51910d38053eb12e0adc7c04119e6ad8ac6e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:39:50 -0700 Subject: staging: comedi: me4000: remove struct me4000_dio_info The me4000_dio_info in the boardinfo struct is used to indicate the number of 8 bit dio ports the the board has. Add a 'dio_nchan' field to struct me4000_board and remove the struct me4000_dio_info. The 'dio_nchan' value can then be used directly in the attach of the board when setting the subdevice number of channels. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 492b47e..8ca0230 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -71,9 +71,7 @@ static const struct me4000_board me4000_boards[] = { .ai = { .count = 16, }, - .dio = { - .count = 4, - }, + .dio_nchan = 32, }, { .name = "ME-4660", .device_id = 0x4660, @@ -81,9 +79,7 @@ static const struct me4000_board me4000_boards[] = { .count = 32, .diff_count = 16, }, - .dio = { - .count = 4, - }, + .dio_nchan = 32, .has_counter = 1, }, { .name = "ME-4660i", @@ -92,9 +88,7 @@ static const struct me4000_board me4000_boards[] = { .count = 32, .diff_count = 16, }, - .dio = { - .count = 4, - }, + .dio_nchan = 32, .has_counter = 1, }, { .name = "ME-4660s", @@ -104,9 +98,7 @@ static const struct me4000_board me4000_boards[] = { .sh_count = 8, .diff_count = 16, }, - .dio = { - .count = 4, - }, + .dio_nchan = 32, .has_counter = 1, }, { .name = "ME-4660is", @@ -116,9 +108,7 @@ static const struct me4000_board me4000_boards[] = { .sh_count = 8, .diff_count = 16, }, - .dio = { - .count = 4, - }, + .dio_nchan = 32, .has_counter = 1, }, { .name = "ME-4670", @@ -131,9 +121,7 @@ static const struct me4000_board me4000_boards[] = { .diff_count = 16, .ex_trig_analog = 1, }, - .dio = { - .count = 4, - }, + .dio_nchan = 32, .has_counter = 1, }, { .name = "ME-4670i", @@ -146,9 +134,7 @@ static const struct me4000_board me4000_boards[] = { .diff_count = 16, .ex_trig_analog = 1, }, - .dio = { - .count = 4, - }, + .dio_nchan = 32, .has_counter = 1, }, { .name = "ME-4670s", @@ -162,9 +148,7 @@ static const struct me4000_board me4000_boards[] = { .diff_count = 16, .ex_trig_analog = 1, }, - .dio = { - .count = 4, - }, + .dio_nchan = 32, .has_counter = 1, }, { .name = "ME-4670is", @@ -178,9 +162,7 @@ static const struct me4000_board me4000_boards[] = { .diff_count = 16, .ex_trig_analog = 1, }, - .dio = { - .count = 4, - }, + .dio_nchan = 32, .has_counter = 1, }, { .name = "ME-4680", @@ -194,9 +176,7 @@ static const struct me4000_board me4000_boards[] = { .diff_count = 16, .ex_trig_analog = 1, }, - .dio = { - .count = 4, - }, + .dio_nchan = 32, .has_counter = 1, }, { .name = "ME-4680i", @@ -210,9 +190,7 @@ static const struct me4000_board me4000_boards[] = { .diff_count = 16, .ex_trig_analog = 1, }, - .dio = { - .count = 4, - }, + .dio_nchan = 32, .has_counter = 1, }, { .name = "ME-4680s", @@ -227,9 +205,7 @@ static const struct me4000_board me4000_boards[] = { .diff_count = 16, .ex_trig_analog = 1, }, - .dio = { - .count = 4, - }, + .dio_nchan = 32, .has_counter = 1, }, { .name = "ME-4680is", @@ -244,9 +220,7 @@ static const struct me4000_board me4000_boards[] = { .diff_count = 16, .ex_trig_analog = 1, }, - .dio = { - .count = 4, - }, + .dio_nchan = 32, .has_counter = 1, }, }; @@ -2239,10 +2213,10 @@ static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it) s = &dev->subdevices[2]; - if (thisboard->dio.count) { + if (thisboard->dio_nchan) { s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = thisboard->dio.count * 8; + s->n_chan = thisboard->dio_nchan; s->maxdata = 1; s->range_table = &range_digital; s->insn_bits = me4000_dio_insn_bits; diff --git a/drivers/staging/comedi/drivers/me4000.h b/drivers/staging/comedi/drivers/me4000.h index 2b609d7..12b5c1f 100644 --- a/drivers/staging/comedi/drivers/me4000.h +++ b/drivers/staging/comedi/drivers/me4000.h @@ -268,16 +268,12 @@ struct me4000_ai_info { int ex_trig_analog; }; -struct me4000_dio_info { - int count; -}; - struct me4000_board { const char *name; unsigned short device_id; struct me4000_ao_info ao; struct me4000_ai_info ai; - struct me4000_dio_info dio; + int dio_nchan; int has_counter; }; -- cgit v0.10.2 From 6ba8dfef57b07c9ed6684805e16041e69b42d484 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:40:06 -0700 Subject: staging: comedi: me4000: remove struct me4000_ai_info The me4000_aio_info in the boardinfo struct is used to indicate the number of analog input channels and a couple other details about them. Remove the extra struct and absorb the data into the boardinfo struct. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 8ca0230..cd001c3 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -68,46 +68,36 @@ static const struct me4000_board me4000_boards[] = { { .name = "ME-4650", .device_id = 0x4650, - .ai = { - .count = 16, - }, + .ai_nchan = 16, .dio_nchan = 32, }, { .name = "ME-4660", .device_id = 0x4660, - .ai = { - .count = 32, - .diff_count = 16, - }, + .ai_nchan = 32, + .ai_diff_nchan = 16, .dio_nchan = 32, .has_counter = 1, }, { .name = "ME-4660i", .device_id = 0x4661, - .ai = { - .count = 32, - .diff_count = 16, - }, + .ai_nchan = 32, + .ai_diff_nchan = 16, .dio_nchan = 32, .has_counter = 1, }, { .name = "ME-4660s", .device_id = 0x4662, - .ai = { - .count = 32, - .sh_count = 8, - .diff_count = 16, - }, + .ai_nchan = 32, + .ai_diff_nchan = 16, + .ai_sh_nchan = 8, .dio_nchan = 32, .has_counter = 1, }, { .name = "ME-4660is", .device_id = 0x4663, - .ai = { - .count = 32, - .sh_count = 8, - .diff_count = 16, - }, + .ai_nchan = 32, + .ai_diff_nchan = 16, + .ai_sh_nchan = 8, .dio_nchan = 32, .has_counter = 1, }, { @@ -116,11 +106,9 @@ static const struct me4000_board me4000_boards[] = { .ao = { .count = 4, }, - .ai = { - .count = 32, - .diff_count = 16, - .ex_trig_analog = 1, - }, + .ai_nchan = 32, + .ai_diff_nchan = 16, + .ex_trig_analog = 1, .dio_nchan = 32, .has_counter = 1, }, { @@ -129,11 +117,9 @@ static const struct me4000_board me4000_boards[] = { .ao = { .count = 4, }, - .ai = { - .count = 32, - .diff_count = 16, - .ex_trig_analog = 1, - }, + .ai_nchan = 32, + .ai_diff_nchan = 16, + .ex_trig_analog = 1, .dio_nchan = 32, .has_counter = 1, }, { @@ -142,12 +128,10 @@ static const struct me4000_board me4000_boards[] = { .ao = { .count = 4, }, - .ai = { - .count = 32, - .sh_count = 8, - .diff_count = 16, - .ex_trig_analog = 1, - }, + .ai_nchan = 32, + .ai_diff_nchan = 16, + .ai_sh_nchan = 8, + .ex_trig_analog = 1, .dio_nchan = 32, .has_counter = 1, }, { @@ -156,12 +140,10 @@ static const struct me4000_board me4000_boards[] = { .ao = { .count = 4, }, - .ai = { - .count = 32, - .sh_count = 8, - .diff_count = 16, - .ex_trig_analog = 1, - }, + .ai_nchan = 32, + .ai_diff_nchan = 16, + .ai_sh_nchan = 8, + .ex_trig_analog = 1, .dio_nchan = 32, .has_counter = 1, }, { @@ -171,11 +153,9 @@ static const struct me4000_board me4000_boards[] = { .count = 4, .fifo_count = 4, }, - .ai = { - .count = 32, - .diff_count = 16, - .ex_trig_analog = 1, - }, + .ai_nchan = 32, + .ai_diff_nchan = 16, + .ex_trig_analog = 1, .dio_nchan = 32, .has_counter = 1, }, { @@ -185,11 +165,9 @@ static const struct me4000_board me4000_boards[] = { .count = 4, .fifo_count = 4, }, - .ai = { - .count = 32, - .diff_count = 16, - .ex_trig_analog = 1, - }, + .ai_nchan = 32, + .ai_diff_nchan = 16, + .ex_trig_analog = 1, .dio_nchan = 32, .has_counter = 1, }, { @@ -199,12 +177,10 @@ static const struct me4000_board me4000_boards[] = { .count = 4, .fifo_count = 4, }, - .ai = { - .count = 32, - .sh_count = 8, - .diff_count = 16, - .ex_trig_analog = 1, - }, + .ai_nchan = 32, + .ai_diff_nchan = 16, + .ai_sh_nchan = 8, + .ex_trig_analog = 1, .dio_nchan = 32, .has_counter = 1, }, { @@ -214,12 +190,10 @@ static const struct me4000_board me4000_boards[] = { .count = 4, .fifo_count = 4, }, - .ai = { - .count = 32, - .sh_count = 8, - .diff_count = 16, - .ex_trig_analog = 1, - }, + .ai_nchan = 32, + .ai_diff_nchan = 16, + .ai_sh_nchan = 8, + .ex_trig_analog = 1, .dio_nchan = 32, .has_counter = 1, }, @@ -809,7 +783,7 @@ static int me4000_ai_insn_read(struct comedi_device *dev, switch (aref) { case AREF_GROUND: case AREF_COMMON: - if (chan >= thisboard->ai.count) { + if (chan >= thisboard->ai_nchan) { printk(KERN_ERR "comedi%d: me4000: me4000_ai_insn_read(): " "Analog input is not available\n", dev->minor); @@ -827,7 +801,7 @@ static int me4000_ai_insn_read(struct comedi_device *dev, return -EINVAL; } - if (chan >= thisboard->ai.diff_count) { + if (chan >= thisboard->ai_diff_nchan) { printk(KERN_ERR "comedi%d: me4000: me4000_ai_insn_read(): " "Analog input is not available\n", dev->minor); @@ -949,7 +923,7 @@ static int ai_check_chanlist(struct comedi_device *dev, if (aref == SDF_DIFF) { for (i = 0; i < cmd->chanlist_len; i++) { if (CR_CHAN(cmd->chanlist[i]) >= - thisboard->ai.diff_count) { + thisboard->ai_diff_nchan) { printk(KERN_ERR "comedi%d: me4000: ai_check_chanlist():" " Channel number to high\n", dev->minor); @@ -958,7 +932,7 @@ static int ai_check_chanlist(struct comedi_device *dev, } } else { for (i = 0; i < cmd->chanlist_len; i++) { - if (CR_CHAN(cmd->chanlist[i]) >= thisboard->ai.count) { + if (CR_CHAN(cmd->chanlist[i]) >= thisboard->ai_nchan) { printk(KERN_ERR "comedi%d: me4000: ai_check_chanlist(): " "Channel number to high\n", dev->minor); @@ -2157,11 +2131,11 @@ static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it) s = &dev->subdevices[0]; - if (thisboard->ai.count) { + if (thisboard->ai_nchan) { s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF; - s->n_chan = thisboard->ai.count; + s->n_chan = thisboard->ai_nchan; s->maxdata = 0xFFFF; /* 16 bit ADC */ s->len_chanlist = ME4000_AI_CHANNEL_LIST_COUNT; s->range_table = &me4000_ai_range; diff --git a/drivers/staging/comedi/drivers/me4000.h b/drivers/staging/comedi/drivers/me4000.h index 12b5c1f..cbf8c6b 100644 --- a/drivers/staging/comedi/drivers/me4000.h +++ b/drivers/staging/comedi/drivers/me4000.h @@ -261,18 +261,14 @@ struct me4000_ao_info { int fifo_count; }; -struct me4000_ai_info { - int count; - int sh_count; - int diff_count; - int ex_trig_analog; -}; - struct me4000_board { const char *name; unsigned short device_id; struct me4000_ao_info ao; - struct me4000_ai_info ai; + int ai_nchan; + int ai_diff_nchan; + int ai_sh_nchan; + int ex_trig_analog; int dio_nchan; int has_counter; }; -- cgit v0.10.2 From 2d504528f2b6a067c2d49885bc15345238dbaaba Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:40:25 -0700 Subject: staging: comedi: me4000: remove struct me4000_ao_info The me4000_ao_info in the boardinfo struct is used to indicate the number of analog output channels and a couple other details about them. Remove the extra struct and absorb the data into the boardinfo struct. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index cd001c3..3ffaa39 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -103,9 +103,7 @@ static const struct me4000_board me4000_boards[] = { }, { .name = "ME-4670", .device_id = 0x4670, - .ao = { - .count = 4, - }, + .ao_nchan = 4, .ai_nchan = 32, .ai_diff_nchan = 16, .ex_trig_analog = 1, @@ -114,9 +112,7 @@ static const struct me4000_board me4000_boards[] = { }, { .name = "ME-4670i", .device_id = 0x4671, - .ao = { - .count = 4, - }, + .ao_nchan = 4, .ai_nchan = 32, .ai_diff_nchan = 16, .ex_trig_analog = 1, @@ -125,9 +121,7 @@ static const struct me4000_board me4000_boards[] = { }, { .name = "ME-4670s", .device_id = 0x4672, - .ao = { - .count = 4, - }, + .ao_nchan = 4, .ai_nchan = 32, .ai_diff_nchan = 16, .ai_sh_nchan = 8, @@ -137,9 +131,7 @@ static const struct me4000_board me4000_boards[] = { }, { .name = "ME-4670is", .device_id = 0x4673, - .ao = { - .count = 4, - }, + .ao_nchan = 4, .ai_nchan = 32, .ai_diff_nchan = 16, .ai_sh_nchan = 8, @@ -149,10 +141,8 @@ static const struct me4000_board me4000_boards[] = { }, { .name = "ME-4680", .device_id = 0x4680, - .ao = { - .count = 4, - .fifo_count = 4, - }, + .ao_nchan = 4, + .ao_fifo = 4, .ai_nchan = 32, .ai_diff_nchan = 16, .ex_trig_analog = 1, @@ -161,10 +151,8 @@ static const struct me4000_board me4000_boards[] = { }, { .name = "ME-4680i", .device_id = 0x4681, - .ao = { - .count = 4, - .fifo_count = 4, - }, + .ao_nchan = 4, + .ao_fifo = 4, .ai_nchan = 32, .ai_diff_nchan = 16, .ex_trig_analog = 1, @@ -173,10 +161,8 @@ static const struct me4000_board me4000_boards[] = { }, { .name = "ME-4680s", .device_id = 0x4682, - .ao = { - .count = 4, - .fifo_count = 4, - }, + .ao_nchan = 4, + .ao_fifo = 4, .ai_nchan = 32, .ai_diff_nchan = 16, .ai_sh_nchan = 8, @@ -186,10 +172,8 @@ static const struct me4000_board me4000_boards[] = { }, { .name = "ME-4680is", .device_id = 0x4683, - .ao = { - .count = 4, - .fifo_count = 4, - }, + .ao_nchan = 4, + .ao_fifo = 4, .ai_nchan = 32, .ai_diff_nchan = 16, .ai_sh_nchan = 8, @@ -463,7 +447,7 @@ static int init_ao_context(struct comedi_device *dev) { int i; - for (i = 0; i < thisboard->ao.count; i++) { + for (i = 0; i < thisboard->ao_nchan; i++) { /* spin_lock_init(&info->ao_context[i].use_lock); */ info->ao_context[i].irq = info->irq; @@ -1689,7 +1673,7 @@ static int me4000_ao_insn_write(struct comedi_device *dev, return -EINVAL; } - if (chan >= thisboard->ao.count) { + if (chan >= thisboard->ao_nchan) { printk(KERN_ERR "comedi%d: me4000: me4000_ao_insn_write(): " "Invalid channel %d\n", dev->minor, insn->n); @@ -2169,10 +2153,10 @@ static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it) s = &dev->subdevices[1]; - if (thisboard->ao.count) { + if (thisboard->ao_nchan) { s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITEABLE | SDF_COMMON | SDF_GROUND; - s->n_chan = thisboard->ao.count; + s->n_chan = thisboard->ao_nchan; s->maxdata = 0xFFFF; /* 16 bit DAC */ s->range_table = &me4000_ao_range; s->insn_write = me4000_ao_insn_write; diff --git a/drivers/staging/comedi/drivers/me4000.h b/drivers/staging/comedi/drivers/me4000.h index cbf8c6b..ab6094a 100644 --- a/drivers/staging/comedi/drivers/me4000.h +++ b/drivers/staging/comedi/drivers/me4000.h @@ -256,15 +256,11 @@ Information about the hardware capabilities ===========================================================================*/ -struct me4000_ao_info { - int count; - int fifo_count; -}; - struct me4000_board { const char *name; unsigned short device_id; - struct me4000_ao_info ao; + int ao_nchan; + int ao_fifo; int ai_nchan; int ai_diff_nchan; int ai_sh_nchan; -- cgit v0.10.2 From 8407593ac3961d2da7ebc01541a993ed0dc6d029 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:40:40 -0700 Subject: staging: comedi: me4000: remove thisboard macro This macro relies on a local variable having a specific name. Remove it and use the comedi_board() helper to get the pointer. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 3ffaa39..a3d9136 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -221,7 +221,7 @@ static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it) { struct pci_dev *pci_device = NULL; int result, i; - struct me4000_board *board; + const struct me4000_board *board; /* Allocate private memory */ if (alloc_private(dev, sizeof(struct me4000_info)) < 0) @@ -254,9 +254,7 @@ static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it) } } dev->board_ptr = me4000_boards + i; - board = - (struct me4000_board *) - dev->board_ptr; + board = comedi_board(dev); info->pci_dev_p = pci_device; goto found; } @@ -445,6 +443,7 @@ static int init_board_info(struct comedi_device *dev, struct pci_dev *pci_dev_p) static int init_ao_context(struct comedi_device *dev) { + const struct me4000_board *thisboard = comedi_board(dev); int i; for (i = 0; i < thisboard->ao_nchan; i++) { @@ -726,7 +725,7 @@ static int me4000_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *subdevice, struct comedi_insn *insn, unsigned int *data) { - + const struct me4000_board *thisboard = comedi_board(dev); int chan = CR_CHAN(insn->chanspec); int rang = CR_RANGE(insn->chanspec); int aref = CR_AREF(insn->chanspec); @@ -864,6 +863,7 @@ static int me4000_ai_cancel(struct comedi_device *dev, static int ai_check_chanlist(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { + const struct me4000_board *thisboard = comedi_board(dev); int aref; int i; @@ -1658,7 +1658,7 @@ static int me4000_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - + const struct me4000_board *thisboard = comedi_board(dev); int chan = CR_CHAN(insn->chanspec); int rang = CR_RANGE(insn->chanspec); int aref = CR_AREF(insn->chanspec); @@ -2098,12 +2098,14 @@ static int me4000_cnt_insn_write(struct comedi_device *dev, static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct me4000_board *thisboard; struct comedi_subdevice *s; int result; result = me4000_probe(dev, it); if (result) return result; + thisboard = comedi_board(dev); result = comedi_alloc_subdevices(dev, 4); if (result) diff --git a/drivers/staging/comedi/drivers/me4000.h b/drivers/staging/comedi/drivers/me4000.h index ab6094a..b2cfecb 100644 --- a/drivers/staging/comedi/drivers/me4000.h +++ b/drivers/staging/comedi/drivers/me4000.h @@ -269,8 +269,6 @@ struct me4000_board { int has_counter; }; -#define thisboard ((const struct me4000_board *)dev->board_ptr) - /*============================================================================= Global board and subdevice information structures ===========================================================================*/ -- cgit v0.10.2 From 06b60981aa66cf5373a3fdcf2e3395db690874f6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:40:59 -0700 Subject: staging: comedi: me4000: move struct me4000_board definition Move the struct me4000_board definition from the header to the c file. It's not used by any other source. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index a3d9136..0eb3926 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -64,6 +64,19 @@ broken. #include "me4000_fw.h" #endif +struct me4000_board { + const char *name; + unsigned short device_id; + int ao_nchan; + int ao_fifo; + int ai_nchan; + int ai_diff_nchan; + int ai_sh_nchan; + int ex_trig_analog; + int dio_nchan; + int has_counter; +}; + static const struct me4000_board me4000_boards[] = { { .name = "ME-4650", diff --git a/drivers/staging/comedi/drivers/me4000.h b/drivers/staging/comedi/drivers/me4000.h index b2cfecb..6a92c15 100644 --- a/drivers/staging/comedi/drivers/me4000.h +++ b/drivers/staging/comedi/drivers/me4000.h @@ -253,23 +253,6 @@ #define ME4000_DIO_CTRL_BIT_FIFO_HIGH_3 0x2000 /*============================================================================= - Information about the hardware capabilities - ===========================================================================*/ - -struct me4000_board { - const char *name; - unsigned short device_id; - int ao_nchan; - int ao_fifo; - int ai_nchan; - int ai_diff_nchan; - int ai_sh_nchan; - int ex_trig_analog; - int dio_nchan; - int has_counter; -}; - -/*============================================================================= Global board and subdevice information structures ===========================================================================*/ -- cgit v0.10.2 From 9e07273124d5586c4a59c4191cdd1e3743e978f3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:41:19 -0700 Subject: staging: comedi: me4000: move pci vendor/device ids to source Move the pci vendor/device ids from the header to the c file and actually use them. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 0eb3926..bdc0603 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -64,6 +64,22 @@ broken. #include "me4000_fw.h" #endif +#define PCI_VENDOR_ID_MEILHAUS 0x1402 + +#define PCI_DEVICE_ID_MEILHAUS_ME4650 0x4650 +#define PCI_DEVICE_ID_MEILHAUS_ME4660 0x4660 +#define PCI_DEVICE_ID_MEILHAUS_ME4660I 0x4661 +#define PCI_DEVICE_ID_MEILHAUS_ME4660S 0x4662 +#define PCI_DEVICE_ID_MEILHAUS_ME4660IS 0x4663 +#define PCI_DEVICE_ID_MEILHAUS_ME4670 0x4670 +#define PCI_DEVICE_ID_MEILHAUS_ME4670I 0x4671 +#define PCI_DEVICE_ID_MEILHAUS_ME4670S 0x4672 +#define PCI_DEVICE_ID_MEILHAUS_ME4670IS 0x4673 +#define PCI_DEVICE_ID_MEILHAUS_ME4680 0x4680 +#define PCI_DEVICE_ID_MEILHAUS_ME4680I 0x4681 +#define PCI_DEVICE_ID_MEILHAUS_ME4680S 0x4682 +#define PCI_DEVICE_ID_MEILHAUS_ME4680IS 0x4683 + struct me4000_board { const char *name; unsigned short device_id; @@ -80,26 +96,26 @@ struct me4000_board { static const struct me4000_board me4000_boards[] = { { .name = "ME-4650", - .device_id = 0x4650, + .device_id = PCI_DEVICE_ID_MEILHAUS_ME4650, .ai_nchan = 16, .dio_nchan = 32, }, { .name = "ME-4660", - .device_id = 0x4660, + .device_id = PCI_DEVICE_ID_MEILHAUS_ME4660, .ai_nchan = 32, .ai_diff_nchan = 16, .dio_nchan = 32, .has_counter = 1, }, { .name = "ME-4660i", - .device_id = 0x4661, + .device_id = PCI_DEVICE_ID_MEILHAUS_ME4660I, .ai_nchan = 32, .ai_diff_nchan = 16, .dio_nchan = 32, .has_counter = 1, }, { .name = "ME-4660s", - .device_id = 0x4662, + .device_id = PCI_DEVICE_ID_MEILHAUS_ME4660S, .ai_nchan = 32, .ai_diff_nchan = 16, .ai_sh_nchan = 8, @@ -107,7 +123,7 @@ static const struct me4000_board me4000_boards[] = { .has_counter = 1, }, { .name = "ME-4660is", - .device_id = 0x4663, + .device_id = PCI_DEVICE_ID_MEILHAUS_ME4660IS, .ai_nchan = 32, .ai_diff_nchan = 16, .ai_sh_nchan = 8, @@ -115,7 +131,7 @@ static const struct me4000_board me4000_boards[] = { .has_counter = 1, }, { .name = "ME-4670", - .device_id = 0x4670, + .device_id = PCI_DEVICE_ID_MEILHAUS_ME4670, .ao_nchan = 4, .ai_nchan = 32, .ai_diff_nchan = 16, @@ -124,7 +140,7 @@ static const struct me4000_board me4000_boards[] = { .has_counter = 1, }, { .name = "ME-4670i", - .device_id = 0x4671, + .device_id = PCI_DEVICE_ID_MEILHAUS_ME4670I, .ao_nchan = 4, .ai_nchan = 32, .ai_diff_nchan = 16, @@ -133,7 +149,7 @@ static const struct me4000_board me4000_boards[] = { .has_counter = 1, }, { .name = "ME-4670s", - .device_id = 0x4672, + .device_id = PCI_DEVICE_ID_MEILHAUS_ME4670S, .ao_nchan = 4, .ai_nchan = 32, .ai_diff_nchan = 16, @@ -143,7 +159,7 @@ static const struct me4000_board me4000_boards[] = { .has_counter = 1, }, { .name = "ME-4670is", - .device_id = 0x4673, + .device_id = PCI_DEVICE_ID_MEILHAUS_ME4670IS, .ao_nchan = 4, .ai_nchan = 32, .ai_diff_nchan = 16, @@ -153,7 +169,7 @@ static const struct me4000_board me4000_boards[] = { .has_counter = 1, }, { .name = "ME-4680", - .device_id = 0x4680, + .device_id = PCI_DEVICE_ID_MEILHAUS_ME4680, .ao_nchan = 4, .ao_fifo = 4, .ai_nchan = 32, @@ -163,7 +179,7 @@ static const struct me4000_board me4000_boards[] = { .has_counter = 1, }, { .name = "ME-4680i", - .device_id = 0x4681, + .device_id = PCI_DEVICE_ID_MEILHAUS_ME4680I, .ao_nchan = 4, .ao_fifo = 4, .ai_nchan = 32, @@ -173,7 +189,7 @@ static const struct me4000_board me4000_boards[] = { .has_counter = 1, }, { .name = "ME-4680s", - .device_id = 0x4682, + .device_id = PCI_DEVICE_ID_MEILHAUS_ME4680S, .ao_nchan = 4, .ao_fifo = 4, .ai_nchan = 32, @@ -184,7 +200,7 @@ static const struct me4000_board me4000_boards[] = { .has_counter = 1, }, { .name = "ME-4680is", - .device_id = 0x4683, + .device_id = PCI_DEVICE_ID_MEILHAUS_ME4680IS, .ao_nchan = 4, .ao_fifo = 4, .ai_nchan = 32, @@ -2259,20 +2275,20 @@ static void __devexit me4000_pci_remove(struct pci_dev *dev) } static DEFINE_PCI_DEVICE_TABLE(me4000_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4650) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4660) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4661) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4662) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4663) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4670) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4671) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4672) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4673) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4680) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4681) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4682) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4683) }, - { 0 } + {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4650)}, + {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4660)}, + {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4660I)}, + {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4660S)}, + {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4660IS)}, + {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4670)}, + {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4670I)}, + {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4670S)}, + {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4670IS)}, + {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4680)}, + {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4680I)}, + {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4680S)}, + {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4680IS)}, + {0} }; MODULE_DEVICE_TABLE(pci, me4000_pci_table); diff --git a/drivers/staging/comedi/drivers/me4000.h b/drivers/staging/comedi/drivers/me4000.h index 6a92c15..a631308 100644 --- a/drivers/staging/comedi/drivers/me4000.h +++ b/drivers/staging/comedi/drivers/me4000.h @@ -25,29 +25,6 @@ #define _ME4000_H_ /*============================================================================= - PCI vendor and device IDs - ===========================================================================*/ - -#define PCI_VENDOR_ID_MEILHAUS 0x1402 - -#define PCI_DEVICE_ID_MEILHAUS_ME4650 0x4650 /* Low Cost version */ - -#define PCI_DEVICE_ID_MEILHAUS_ME4660 0x4660 /* Standard version */ -#define PCI_DEVICE_ID_MEILHAUS_ME4660I 0x4661 /* Isolated version */ -#define PCI_DEVICE_ID_MEILHAUS_ME4660S 0x4662 /* Standard version with Sample and Hold */ -#define PCI_DEVICE_ID_MEILHAUS_ME4660IS 0x4663 /* Isolated version with Sample and Hold */ - -#define PCI_DEVICE_ID_MEILHAUS_ME4670 0x4670 /* Standard version */ -#define PCI_DEVICE_ID_MEILHAUS_ME4670I 0x4671 /* Isolated version */ -#define PCI_DEVICE_ID_MEILHAUS_ME4670S 0x4672 /* Standard version with Sample and Hold */ -#define PCI_DEVICE_ID_MEILHAUS_ME4670IS 0x4673 /* Isolated version with Sample and Hold */ - -#define PCI_DEVICE_ID_MEILHAUS_ME4680 0x4680 /* Standard version */ -#define PCI_DEVICE_ID_MEILHAUS_ME4680I 0x4681 /* Isolated version */ -#define PCI_DEVICE_ID_MEILHAUS_ME4680S 0x4682 /* Standard version with Sample and Hold */ -#define PCI_DEVICE_ID_MEILHAUS_ME4680IS 0x4683 /* Isolated version with Sample and Hold */ - -/*============================================================================= ME-4000 base register offsets ===========================================================================*/ -- cgit v0.10.2 From ba98ab03f762696180227e015a13f1bac0a11f60 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:41:37 -0700 Subject: staging: comedi: me4000: remove struct me4000_cnt_context The me4000_cnt_contect simply holds the unsigned long i/o addresses used to read/write the counter registers. Thes can be calculated as needed. Remove the struct and the associated field in the private data. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index bdc0603..081e509 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -221,7 +221,6 @@ static int init_board_info(struct comedi_device *dev, static int init_ao_context(struct comedi_device *dev); static int init_ai_context(struct comedi_device *dev); static int init_dio_context(struct comedi_device *dev); -static int init_cnt_context(struct comedi_device *dev); static int xilinx_download(struct comedi_device *dev); static int reset_board(struct comedi_device *dev); @@ -361,15 +360,6 @@ found: return result; } - /* Init counter context */ - result = init_cnt_context(dev); - if (result) { - printk(KERN_ERR - "comedi%d: me4000: me4000_probe(): " - "Cannot init cnt context\n", dev->minor); - return result; - } - /* Download the xilinx firmware */ result = xilinx_download(dev); if (result) { @@ -599,19 +589,6 @@ static int init_dio_context(struct comedi_device *dev) return 0; } -static int init_cnt_context(struct comedi_device *dev) -{ - info->cnt_context.ctrl_reg = info->timer_regbase + ME4000_CNT_CTRL_REG; - info->cnt_context.counter_0_reg = - info->timer_regbase + ME4000_CNT_COUNTER_0_REG; - info->cnt_context.counter_1_reg = - info->timer_regbase + ME4000_CNT_COUNTER_1_REG; - info->cnt_context.counter_2_reg = - info->timer_regbase + ME4000_CNT_COUNTER_2_REG; - - return 0; -} - #define FIRMWARE_NOT_AVAILABLE 1 #if FIRMWARE_NOT_AVAILABLE extern unsigned char *xilinx_firm; @@ -1907,19 +1884,19 @@ static int cnt_reset(struct comedi_device *dev, unsigned int channel) { switch (channel) { case 0: - outb(0x30, info->cnt_context.ctrl_reg); - outb(0x00, info->cnt_context.counter_0_reg); - outb(0x00, info->cnt_context.counter_0_reg); + outb(0x30, info->timer_regbase + ME4000_CNT_CTRL_REG); + outb(0x00, info->timer_regbase + ME4000_CNT_COUNTER_0_REG); + outb(0x00, info->timer_regbase + ME4000_CNT_COUNTER_0_REG); break; case 1: - outb(0x70, info->cnt_context.ctrl_reg); - outb(0x00, info->cnt_context.counter_1_reg); - outb(0x00, info->cnt_context.counter_1_reg); + outb(0x70, info->timer_regbase + ME4000_CNT_CTRL_REG); + outb(0x00, info->timer_regbase + ME4000_CNT_COUNTER_1_REG); + outb(0x00, info->timer_regbase + ME4000_CNT_COUNTER_1_REG); break; case 2: - outb(0xB0, info->cnt_context.ctrl_reg); - outb(0x00, info->cnt_context.counter_2_reg); - outb(0x00, info->cnt_context.counter_2_reg); + outb(0xB0, info->timer_regbase + ME4000_CNT_CTRL_REG); + outb(0x00, info->timer_regbase + ME4000_CNT_COUNTER_2_REG); + outb(0x00, info->timer_regbase + ME4000_CNT_COUNTER_2_REG); break; default: printk(KERN_ERR @@ -1981,7 +1958,7 @@ static int cnt_config(struct comedi_device *dev, unsigned int channel, /* Write the control word */ tmp |= 0x30; - outb(tmp, info->cnt_context.ctrl_reg); + outb(tmp, info->timer_regbase + ME4000_CNT_CTRL_REG); return 0; } @@ -2050,21 +2027,21 @@ static int me4000_cnt_insn_read(struct comedi_device *dev, switch (insn->chanspec) { case 0: - tmp = inb(info->cnt_context.counter_0_reg); + tmp = inb(info->timer_regbase + ME4000_CNT_COUNTER_0_REG); data[0] = tmp; - tmp = inb(info->cnt_context.counter_0_reg); + tmp = inb(info->timer_regbase + ME4000_CNT_COUNTER_0_REG); data[0] |= tmp << 8; break; case 1: - tmp = inb(info->cnt_context.counter_1_reg); + tmp = inb(info->timer_regbase + ME4000_CNT_COUNTER_1_REG); data[0] = tmp; - tmp = inb(info->cnt_context.counter_1_reg); + tmp = inb(info->timer_regbase + ME4000_CNT_COUNTER_1_REG); data[0] |= tmp << 8; break; case 2: - tmp = inb(info->cnt_context.counter_2_reg); + tmp = inb(info->timer_regbase + ME4000_CNT_COUNTER_2_REG); data[0] = tmp; - tmp = inb(info->cnt_context.counter_2_reg); + tmp = inb(info->timer_regbase + ME4000_CNT_COUNTER_2_REG); data[0] |= tmp << 8; break; default: @@ -2098,21 +2075,21 @@ static int me4000_cnt_insn_write(struct comedi_device *dev, switch (insn->chanspec) { case 0: tmp = data[0] & 0xFF; - outb(tmp, info->cnt_context.counter_0_reg); + outb(tmp, info->timer_regbase + ME4000_CNT_COUNTER_0_REG); tmp = (data[0] >> 8) & 0xFF; - outb(tmp, info->cnt_context.counter_0_reg); + outb(tmp, info->timer_regbase + ME4000_CNT_COUNTER_0_REG); break; case 1: tmp = data[0] & 0xFF; - outb(tmp, info->cnt_context.counter_1_reg); + outb(tmp, info->timer_regbase + ME4000_CNT_COUNTER_1_REG); tmp = (data[0] >> 8) & 0xFF; - outb(tmp, info->cnt_context.counter_1_reg); + outb(tmp, info->timer_regbase + ME4000_CNT_COUNTER_1_REG); break; case 2: tmp = data[0] & 0xFF; - outb(tmp, info->cnt_context.counter_2_reg); + outb(tmp, info->timer_regbase + ME4000_CNT_COUNTER_2_REG); tmp = (data[0] >> 8) & 0xFF; - outb(tmp, info->cnt_context.counter_2_reg); + outb(tmp, info->timer_regbase + ME4000_CNT_COUNTER_2_REG); break; default: printk(KERN_ERR diff --git a/drivers/staging/comedi/drivers/me4000.h b/drivers/staging/comedi/drivers/me4000.h index a631308..6c03d54 100644 --- a/drivers/staging/comedi/drivers/me4000.h +++ b/drivers/staging/comedi/drivers/me4000.h @@ -274,13 +274,6 @@ struct me4000_dio_context { unsigned long port_3_reg; }; -struct me4000_cnt_context { - unsigned long ctrl_reg; - unsigned long counter_0_reg; - unsigned long counter_1_reg; - unsigned long counter_2_reg; -}; - struct me4000_info { unsigned long plx_regbase; /* PLX configuration space base address */ unsigned long me4000_regbase; /* Base address of the ME4000 */ @@ -304,7 +297,6 @@ struct me4000_info { struct me4000_ai_context ai_context; /* Analog input specific context */ struct me4000_ao_context ao_context[4]; /* Vector with analog output specific context */ struct me4000_dio_context dio_context; /* Digital I/O specific context */ - struct me4000_cnt_context cnt_context; /* Counter specific context */ }; #define info ((struct me4000_info *)dev->private) -- cgit v0.10.2 From 0818dc0a35571c294540cc8531f071e01f915205 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:41:55 -0700 Subject: staging: comedi: me4000: don't save the pci resource sizes There is no need to get the resource size for each pci bar. Nothing in the driver uses it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 081e509..eeca971 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -392,7 +392,6 @@ static int get_registers(struct comedi_device *dev, struct pci_dev *pci_dev_p) "PCI base address 1 is not available\n", dev->minor); return -ENODEV; } - info->plx_regbase_size = pci_resource_len(pci_dev_p, 1); /*--------------------------- me4000 regbase ----------------------------*/ @@ -403,7 +402,6 @@ static int get_registers(struct comedi_device *dev, struct pci_dev *pci_dev_p) "PCI base address 2 is not available\n", dev->minor); return -ENODEV; } - info->me4000_regbase_size = pci_resource_len(pci_dev_p, 2); /*--------------------------- timer regbase ------------------------------*/ @@ -414,7 +412,6 @@ static int get_registers(struct comedi_device *dev, struct pci_dev *pci_dev_p) "PCI base address 3 is not available\n", dev->minor); return -ENODEV; } - info->timer_regbase_size = pci_resource_len(pci_dev_p, 3); /*--------------------------- program regbase ----------------------------*/ @@ -425,7 +422,6 @@ static int get_registers(struct comedi_device *dev, struct pci_dev *pci_dev_p) "PCI base address 5 is not available\n", dev->minor); return -ENODEV; } - info->program_regbase_size = pci_resource_len(pci_dev_p, 5); return 0; } diff --git a/drivers/staging/comedi/drivers/me4000.h b/drivers/staging/comedi/drivers/me4000.h index 6c03d54..169fed8 100644 --- a/drivers/staging/comedi/drivers/me4000.h +++ b/drivers/staging/comedi/drivers/me4000.h @@ -280,11 +280,6 @@ struct me4000_info { unsigned long timer_regbase; /* Base address of the timer circuit */ unsigned long program_regbase; /* Base address to set the program pin for the xilinx */ - unsigned long plx_regbase_size; /* PLX register set space */ - unsigned long me4000_regbase_size; /* ME4000 register set space */ - unsigned long timer_regbase_size; /* Timer circuit register set space */ - unsigned long program_regbase_size; /* Size of program base address of the ME4000 */ - unsigned int serial_no; /* Serial number of the board */ unsigned char hw_revision; /* Hardware revision of the board */ unsigned short vendor_id; /* Meilhaus vendor id */ -- cgit v0.10.2 From 9c943f4ed479d58a2814239815e45fc0b61f4116 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:42:12 -0700 Subject: staging: comedi: me4000: remove the pci resource error messages Remove the error messages about the pci base address not being available. They are just noise. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index eeca971..71ca75f 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -383,45 +383,21 @@ found: static int get_registers(struct comedi_device *dev, struct pci_dev *pci_dev_p) { - /*--------------------------- plx regbase -------------------------------*/ - info->plx_regbase = pci_resource_start(pci_dev_p, 1); - if (info->plx_regbase == 0) { - printk(KERN_ERR - "comedi%d: me4000: get_registers(): " - "PCI base address 1 is not available\n", dev->minor); + if (!info->plx_regbase) return -ENODEV; - } - - /*--------------------------- me4000 regbase ----------------------------*/ info->me4000_regbase = pci_resource_start(pci_dev_p, 2); - if (info->me4000_regbase == 0) { - printk(KERN_ERR - "comedi%d: me4000: get_registers(): " - "PCI base address 2 is not available\n", dev->minor); + if (!info->me4000_regbase) return -ENODEV; - } - - /*--------------------------- timer regbase ------------------------------*/ info->timer_regbase = pci_resource_start(pci_dev_p, 3); - if (info->timer_regbase == 0) { - printk(KERN_ERR - "comedi%d: me4000: get_registers(): " - "PCI base address 3 is not available\n", dev->minor); + if (!info->timer_regbase) return -ENODEV; - } - - /*--------------------------- program regbase ----------------------------*/ info->program_regbase = pci_resource_start(pci_dev_p, 5); - if (info->program_regbase == 0) { - printk(KERN_ERR - "comedi%d: me4000: get_registers(): " - "PCI base address 5 is not available\n", dev->minor); + if (!info->program_regbase) return -ENODEV; - } return 0; } -- cgit v0.10.2 From d5cd01fee1c6ccd363eb6b0d40143173ffa23ef5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:42:30 -0700 Subject: staging: comedi: me4000: absorb get_registers() into its caller The get_registers() function reads the pci base addresses used in the driver. It's simple enough, just move the code into the function that calls it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 71ca75f..f7ef0cb 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -215,7 +215,6 @@ static const struct me4000_board me4000_boards[] = { /*----------------------------------------------------------------------------- Meilhaus function prototypes ---------------------------------------------------------------------------*/ -static int get_registers(struct comedi_device *dev, struct pci_dev *pci_dev_p); static int init_board_info(struct comedi_device *dev, struct pci_dev *pci_dev_p); static int init_ao_context(struct comedi_device *dev); @@ -316,14 +315,22 @@ found: return result; } - /* Get the PCI base registers */ - result = get_registers(dev, pci_device); - if (result) { - printk(KERN_ERR - "comedi%d: me4000: me4000_probe(): " - "Cannot get registers\n", dev->minor); - return result; - } + info->plx_regbase = pci_resource_start(pci_device, 1); + if (!info->plx_regbase) + return -ENODEV; + + info->me4000_regbase = pci_resource_start(pci_device, 2); + if (!info->me4000_regbase) + return -ENODEV; + + info->timer_regbase = pci_resource_start(pci_device, 3); + if (!info->timer_regbase) + return -ENODEV; + + info->program_regbase = pci_resource_start(pci_device, 5); + if (!info->program_regbase) + return -ENODEV; + /* Initialize board info */ result = init_board_info(dev, pci_device); if (result) { @@ -381,27 +388,6 @@ found: return 0; } -static int get_registers(struct comedi_device *dev, struct pci_dev *pci_dev_p) -{ - info->plx_regbase = pci_resource_start(pci_dev_p, 1); - if (!info->plx_regbase) - return -ENODEV; - - info->me4000_regbase = pci_resource_start(pci_dev_p, 2); - if (!info->me4000_regbase) - return -ENODEV; - - info->timer_regbase = pci_resource_start(pci_dev_p, 3); - if (!info->timer_regbase) - return -ENODEV; - - info->program_regbase = pci_resource_start(pci_dev_p, 5); - if (!info->program_regbase) - return -ENODEV; - - return 0; -} - static int init_board_info(struct comedi_device *dev, struct pci_dev *pci_dev_p) { int result; -- cgit v0.10.2 From 2cb847b2a9d62ef1a1d5652ae17ff0b263377469 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:42:48 -0700 Subject: staging: comedi: me4000: remove the noise when probing the card The me4000_probe() function has a bunch of error messages that are displayed when various parts of the probe fail. These are just added noise. Remove them. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index f7ef0cb..1801934 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -288,32 +288,14 @@ static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it) } } } - - printk(KERN_ERR - "comedi%d: me4000: me4000_probe(): " - "No supported board found (req. bus/slot : %d/%d)\n", - dev->minor, it->options[0], it->options[1]); return -ENODEV; found: - - printk(KERN_INFO - "comedi%d: me4000: me4000_probe(): " - "Found %s at PCI bus %d, slot %d\n", - dev->minor, me4000_boards[i].name, pci_device->bus->number, - PCI_SLOT(pci_device->devfn)); - - /* Set data in device structure */ dev->board_name = board->name; - /* Enable PCI device and request regions */ result = comedi_pci_enable(pci_device, dev->board_name); - if (result) { - printk(KERN_ERR - "comedi%d: me4000: me4000_probe(): Cannot enable PCI " - "device and request I/O regions\n", dev->minor); + if (result) return result; - } info->plx_regbase = pci_resource_start(pci_device, 1); if (!info->plx_regbase) @@ -331,59 +313,29 @@ found: if (!info->program_regbase) return -ENODEV; - /* Initialize board info */ result = init_board_info(dev, pci_device); - if (result) { - printk(KERN_ERR - "comedi%d: me4000: me4000_probe(): " - "Cannot init baord info\n", dev->minor); + if (result) return result; - } - /* Init analog output context */ result = init_ao_context(dev); - if (result) { - printk(KERN_ERR - "comedi%d: me4000: me4000_probe(): " - "Cannot init ao context\n", dev->minor); + if (result) return result; - } - /* Init analog input context */ result = init_ai_context(dev); - if (result) { - printk(KERN_ERR - "comedi%d: me4000: me4000_probe(): " - "Cannot init ai context\n", dev->minor); + if (result) return result; - } - /* Init digital I/O context */ result = init_dio_context(dev); - if (result) { - printk(KERN_ERR - "comedi%d: me4000: me4000_probe(): " - "Cannot init dio context\n", dev->minor); + if (result) return result; - } - /* Download the xilinx firmware */ result = xilinx_download(dev); - if (result) { - printk(KERN_ERR - "comedi%d: me4000: me4000_probe(): " - "Can't download firmware\n", dev->minor); + if (result) return result; - } - /* Make a hardware reset */ result = reset_board(dev); - if (result) { - printk(KERN_ERR - "comedi%d: me4000: me4000_probe(): Can't reset board\n", - dev->minor); + if (result) return result; - } return 0; } -- cgit v0.10.2 From 362bcbdee89f33ed3e5a96c945ebc6e61c1bc988 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:43:04 -0700 Subject: staging: comedi: me4000: use dev->iobase for the card base address Use the iobase variable provided in the comedi_device for the main base address used in the driver. Remove the me4000_regbase variable from the private data. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 1801934..123732b 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -301,8 +301,8 @@ found: if (!info->plx_regbase) return -ENODEV; - info->me4000_regbase = pci_resource_start(pci_device, 2); - if (!info->me4000_regbase) + dev->iobase = pci_resource_start(pci_device, 2); + if (!dev->iobase) return -ENODEV; info->timer_regbase = pci_resource_start(pci_device, 3); @@ -382,67 +382,67 @@ static int init_ao_context(struct comedi_device *dev) switch (i) { case 0: info->ao_context[i].ctrl_reg = - info->me4000_regbase + ME4000_AO_00_CTRL_REG; + dev->iobase + ME4000_AO_00_CTRL_REG; info->ao_context[i].status_reg = - info->me4000_regbase + ME4000_AO_00_STATUS_REG; + dev->iobase + ME4000_AO_00_STATUS_REG; info->ao_context[i].fifo_reg = - info->me4000_regbase + ME4000_AO_00_FIFO_REG; + dev->iobase + ME4000_AO_00_FIFO_REG; info->ao_context[i].single_reg = - info->me4000_regbase + ME4000_AO_00_SINGLE_REG; + dev->iobase + ME4000_AO_00_SINGLE_REG; info->ao_context[i].timer_reg = - info->me4000_regbase + ME4000_AO_00_TIMER_REG; + dev->iobase + ME4000_AO_00_TIMER_REG; info->ao_context[i].irq_status_reg = - info->me4000_regbase + ME4000_IRQ_STATUS_REG; + dev->iobase + ME4000_IRQ_STATUS_REG; info->ao_context[i].preload_reg = - info->me4000_regbase + ME4000_AO_LOADSETREG_XX; + dev->iobase + ME4000_AO_LOADSETREG_XX; break; case 1: info->ao_context[i].ctrl_reg = - info->me4000_regbase + ME4000_AO_01_CTRL_REG; + dev->iobase + ME4000_AO_01_CTRL_REG; info->ao_context[i].status_reg = - info->me4000_regbase + ME4000_AO_01_STATUS_REG; + dev->iobase + ME4000_AO_01_STATUS_REG; info->ao_context[i].fifo_reg = - info->me4000_regbase + ME4000_AO_01_FIFO_REG; + dev->iobase + ME4000_AO_01_FIFO_REG; info->ao_context[i].single_reg = - info->me4000_regbase + ME4000_AO_01_SINGLE_REG; + dev->iobase + ME4000_AO_01_SINGLE_REG; info->ao_context[i].timer_reg = - info->me4000_regbase + ME4000_AO_01_TIMER_REG; + dev->iobase + ME4000_AO_01_TIMER_REG; info->ao_context[i].irq_status_reg = - info->me4000_regbase + ME4000_IRQ_STATUS_REG; + dev->iobase + ME4000_IRQ_STATUS_REG; info->ao_context[i].preload_reg = - info->me4000_regbase + ME4000_AO_LOADSETREG_XX; + dev->iobase + ME4000_AO_LOADSETREG_XX; break; case 2: info->ao_context[i].ctrl_reg = - info->me4000_regbase + ME4000_AO_02_CTRL_REG; + dev->iobase + ME4000_AO_02_CTRL_REG; info->ao_context[i].status_reg = - info->me4000_regbase + ME4000_AO_02_STATUS_REG; + dev->iobase + ME4000_AO_02_STATUS_REG; info->ao_context[i].fifo_reg = - info->me4000_regbase + ME4000_AO_02_FIFO_REG; + dev->iobase + ME4000_AO_02_FIFO_REG; info->ao_context[i].single_reg = - info->me4000_regbase + ME4000_AO_02_SINGLE_REG; + dev->iobase + ME4000_AO_02_SINGLE_REG; info->ao_context[i].timer_reg = - info->me4000_regbase + ME4000_AO_02_TIMER_REG; + dev->iobase + ME4000_AO_02_TIMER_REG; info->ao_context[i].irq_status_reg = - info->me4000_regbase + ME4000_IRQ_STATUS_REG; + dev->iobase + ME4000_IRQ_STATUS_REG; info->ao_context[i].preload_reg = - info->me4000_regbase + ME4000_AO_LOADSETREG_XX; + dev->iobase + ME4000_AO_LOADSETREG_XX; break; case 3: info->ao_context[i].ctrl_reg = - info->me4000_regbase + ME4000_AO_03_CTRL_REG; + dev->iobase + ME4000_AO_03_CTRL_REG; info->ao_context[i].status_reg = - info->me4000_regbase + ME4000_AO_03_STATUS_REG; + dev->iobase + ME4000_AO_03_STATUS_REG; info->ao_context[i].fifo_reg = - info->me4000_regbase + ME4000_AO_03_FIFO_REG; + dev->iobase + ME4000_AO_03_FIFO_REG; info->ao_context[i].single_reg = - info->me4000_regbase + ME4000_AO_03_SINGLE_REG; + dev->iobase + ME4000_AO_03_SINGLE_REG; info->ao_context[i].timer_reg = - info->me4000_regbase + ME4000_AO_03_TIMER_REG; + dev->iobase + ME4000_AO_03_TIMER_REG; info->ao_context[i].irq_status_reg = - info->me4000_regbase + ME4000_IRQ_STATUS_REG; + dev->iobase + ME4000_IRQ_STATUS_REG; info->ao_context[i].preload_reg = - info->me4000_regbase + ME4000_AO_LOADSETREG_XX; + dev->iobase + ME4000_AO_LOADSETREG_XX; break; default: break; @@ -456,45 +456,45 @@ static int init_ai_context(struct comedi_device *dev) { info->ai_context.irq = info->irq; - info->ai_context.ctrl_reg = info->me4000_regbase + ME4000_AI_CTRL_REG; + info->ai_context.ctrl_reg = dev->iobase + ME4000_AI_CTRL_REG; info->ai_context.status_reg = - info->me4000_regbase + ME4000_AI_STATUS_REG; + dev->iobase + ME4000_AI_STATUS_REG; info->ai_context.channel_list_reg = - info->me4000_regbase + ME4000_AI_CHANNEL_LIST_REG; - info->ai_context.data_reg = info->me4000_regbase + ME4000_AI_DATA_REG; + dev->iobase + ME4000_AI_CHANNEL_LIST_REG; + info->ai_context.data_reg = dev->iobase + ME4000_AI_DATA_REG; info->ai_context.chan_timer_reg = - info->me4000_regbase + ME4000_AI_CHAN_TIMER_REG; + dev->iobase + ME4000_AI_CHAN_TIMER_REG; info->ai_context.chan_pre_timer_reg = - info->me4000_regbase + ME4000_AI_CHAN_PRE_TIMER_REG; + dev->iobase + ME4000_AI_CHAN_PRE_TIMER_REG; info->ai_context.scan_timer_low_reg = - info->me4000_regbase + ME4000_AI_SCAN_TIMER_LOW_REG; + dev->iobase + ME4000_AI_SCAN_TIMER_LOW_REG; info->ai_context.scan_timer_high_reg = - info->me4000_regbase + ME4000_AI_SCAN_TIMER_HIGH_REG; + dev->iobase + ME4000_AI_SCAN_TIMER_HIGH_REG; info->ai_context.scan_pre_timer_low_reg = - info->me4000_regbase + ME4000_AI_SCAN_PRE_TIMER_LOW_REG; + dev->iobase + ME4000_AI_SCAN_PRE_TIMER_LOW_REG; info->ai_context.scan_pre_timer_high_reg = - info->me4000_regbase + ME4000_AI_SCAN_PRE_TIMER_HIGH_REG; - info->ai_context.start_reg = info->me4000_regbase + ME4000_AI_START_REG; + dev->iobase + ME4000_AI_SCAN_PRE_TIMER_HIGH_REG; + info->ai_context.start_reg = dev->iobase + ME4000_AI_START_REG; info->ai_context.irq_status_reg = - info->me4000_regbase + ME4000_IRQ_STATUS_REG; + dev->iobase + ME4000_IRQ_STATUS_REG; info->ai_context.sample_counter_reg = - info->me4000_regbase + ME4000_AI_SAMPLE_COUNTER_REG; + dev->iobase + ME4000_AI_SAMPLE_COUNTER_REG; return 0; } static int init_dio_context(struct comedi_device *dev) { - info->dio_context.dir_reg = info->me4000_regbase + ME4000_DIO_DIR_REG; - info->dio_context.ctrl_reg = info->me4000_regbase + ME4000_DIO_CTRL_REG; + info->dio_context.dir_reg = dev->iobase + ME4000_DIO_DIR_REG; + info->dio_context.ctrl_reg = dev->iobase + ME4000_DIO_CTRL_REG; info->dio_context.port_0_reg = - info->me4000_regbase + ME4000_DIO_PORT_0_REG; + dev->iobase + ME4000_DIO_PORT_0_REG; info->dio_context.port_1_reg = - info->me4000_regbase + ME4000_DIO_PORT_1_REG; + dev->iobase + ME4000_DIO_PORT_1_REG; info->dio_context.port_2_reg = - info->me4000_regbase + ME4000_DIO_PORT_2_REG; + dev->iobase + ME4000_DIO_PORT_2_REG; info->dio_context.port_3_reg = - info->me4000_regbase + ME4000_DIO_PORT_3_REG; + dev->iobase + ME4000_DIO_PORT_3_REG; return 0; } @@ -597,38 +597,38 @@ static int reset_board(struct comedi_device *dev) outl(icr, info->plx_regbase + PLX_ICR); /* 0x8000 to the DACs means an output voltage of 0V */ - outl(0x8000, info->me4000_regbase + ME4000_AO_00_SINGLE_REG); - outl(0x8000, info->me4000_regbase + ME4000_AO_01_SINGLE_REG); - outl(0x8000, info->me4000_regbase + ME4000_AO_02_SINGLE_REG); - outl(0x8000, info->me4000_regbase + ME4000_AO_03_SINGLE_REG); + outl(0x8000, dev->iobase + ME4000_AO_00_SINGLE_REG); + outl(0x8000, dev->iobase + ME4000_AO_01_SINGLE_REG); + outl(0x8000, dev->iobase + ME4000_AO_02_SINGLE_REG); + outl(0x8000, dev->iobase + ME4000_AO_03_SINGLE_REG); /* Set both stop bits in the analog input control register */ outl(ME4000_AI_CTRL_BIT_IMMEDIATE_STOP | ME4000_AI_CTRL_BIT_STOP, - info->me4000_regbase + ME4000_AI_CTRL_REG); + dev->iobase + ME4000_AI_CTRL_REG); /* Set both stop bits in the analog output control register */ outl(ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP, - info->me4000_regbase + ME4000_AO_00_CTRL_REG); + dev->iobase + ME4000_AO_00_CTRL_REG); outl(ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP, - info->me4000_regbase + ME4000_AO_01_CTRL_REG); + dev->iobase + ME4000_AO_01_CTRL_REG); outl(ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP, - info->me4000_regbase + ME4000_AO_02_CTRL_REG); + dev->iobase + ME4000_AO_02_CTRL_REG); outl(ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP, - info->me4000_regbase + ME4000_AO_03_CTRL_REG); + dev->iobase + ME4000_AO_03_CTRL_REG); /* Enable interrupts on the PLX */ outl(0x43, info->plx_regbase + PLX_INTCSR); /* Set the adustment register for AO demux */ outl(ME4000_AO_DEMUX_ADJUST_VALUE, - info->me4000_regbase + ME4000_AO_DEMUX_ADJUST_REG); + dev->iobase + ME4000_AO_DEMUX_ADJUST_REG); /* * Set digital I/O direction for port 0 * to output on isolated versions */ - if (!(inl(info->me4000_regbase + ME4000_DIO_DIR_REG) & 0x1)) - outl(0x1, info->me4000_regbase + ME4000_DIO_CTRL_REG); + if (!(inl(dev->iobase + ME4000_DIO_DIR_REG) & 0x1)) + outl(0x1, dev->iobase + ME4000_DIO_CTRL_REG); return 0; } diff --git a/drivers/staging/comedi/drivers/me4000.h b/drivers/staging/comedi/drivers/me4000.h index 169fed8..188e964 100644 --- a/drivers/staging/comedi/drivers/me4000.h +++ b/drivers/staging/comedi/drivers/me4000.h @@ -276,7 +276,6 @@ struct me4000_dio_context { struct me4000_info { unsigned long plx_regbase; /* PLX configuration space base address */ - unsigned long me4000_regbase; /* Base address of the ME4000 */ unsigned long timer_regbase; /* Base address of the timer circuit */ unsigned long program_regbase; /* Base address to set the program pin for the xilinx */ -- cgit v0.10.2 From da755d15295ce810130f60e55c9f6fb287ec73b8 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:43:21 -0700 Subject: staging: comedi: me4000: remove dio context The dio context is a struct containing all the register addresses used with the dio subdevice. These can easily be calculated when needed. Remove the me4000_dio_context struct, its intialization function, and it's variable in the private data. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 123732b..b6effb0 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -219,7 +219,6 @@ static int init_board_info(struct comedi_device *dev, struct pci_dev *pci_dev_p); static int init_ao_context(struct comedi_device *dev); static int init_ai_context(struct comedi_device *dev); -static int init_dio_context(struct comedi_device *dev); static int xilinx_download(struct comedi_device *dev); static int reset_board(struct comedi_device *dev); @@ -325,10 +324,6 @@ found: if (result) return result; - result = init_dio_context(dev); - if (result) - return result; - result = xilinx_download(dev); if (result) return result; @@ -483,22 +478,6 @@ static int init_ai_context(struct comedi_device *dev) return 0; } -static int init_dio_context(struct comedi_device *dev) -{ - info->dio_context.dir_reg = dev->iobase + ME4000_DIO_DIR_REG; - info->dio_context.ctrl_reg = dev->iobase + ME4000_DIO_CTRL_REG; - info->dio_context.port_0_reg = - dev->iobase + ME4000_DIO_PORT_0_REG; - info->dio_context.port_1_reg = - dev->iobase + ME4000_DIO_PORT_1_REG; - info->dio_context.port_2_reg = - dev->iobase + ME4000_DIO_PORT_2_REG; - info->dio_context.port_3_reg = - dev->iobase + ME4000_DIO_PORT_3_REG; - - return 0; -} - #define FIRMWARE_NOT_AVAILABLE 1 #if FIRMWARE_NOT_AVAILABLE extern unsigned char *xilinx_firm; @@ -1671,21 +1650,21 @@ static int me4000_dio_insn_bits(struct comedi_device *dev, /* Write out the new digital output lines */ outl((s->state >> 0) & 0xFF, - info->dio_context.port_0_reg); + dev->iobase + ME4000_DIO_PORT_0_REG); outl((s->state >> 8) & 0xFF, - info->dio_context.port_1_reg); + dev->iobase + ME4000_DIO_PORT_1_REG); outl((s->state >> 16) & 0xFF, - info->dio_context.port_2_reg); + dev->iobase + ME4000_DIO_PORT_2_REG); outl((s->state >> 24) & 0xFF, - info->dio_context.port_3_reg); + dev->iobase + ME4000_DIO_PORT_3_REG); } /* On return, data[1] contains the value of the digital input and output lines. */ - data[1] = ((inl(info->dio_context.port_0_reg) & 0xFF) << 0) | - ((inl(info->dio_context.port_1_reg) & 0xFF) << 8) | - ((inl(info->dio_context.port_2_reg) & 0xFF) << 16) | - ((inl(info->dio_context.port_3_reg) & 0xFF) << 24); + data[1] = ((inl(dev->iobase + ME4000_DIO_PORT_0_REG) & 0xFF) << 0) | + ((inl(dev->iobase + ME4000_DIO_PORT_1_REG) & 0xFF) << 8) | + ((inl(dev->iobase + ME4000_DIO_PORT_2_REG) & 0xFF) << 16) | + ((inl(dev->iobase + ME4000_DIO_PORT_3_REG) & 0xFF) << 24); return insn->n; } @@ -1717,7 +1696,7 @@ static int me4000_dio_insn_config(struct comedi_device *dev, * On the ME-4000 it is only possible to switch port wise (8 bit) */ - tmp = inl(info->dio_context.ctrl_reg); + tmp = inl(dev->iobase + ME4000_DIO_CTRL_REG); if (data[0] == INSN_CONFIG_DIO_OUTPUT) { if (chan < 8) { @@ -1731,7 +1710,7 @@ static int me4000_dio_insn_config(struct comedi_device *dev, * If one the first port is a fixed output * port and the second is a fixed input port. */ - if (!inl(info->dio_context.dir_reg)) + if (!inl(dev->iobase + ME4000_DIO_DIR_REG)) return -ENODEV; s->io_bits |= 0xFF00; @@ -1758,7 +1737,7 @@ static int me4000_dio_insn_config(struct comedi_device *dev, * If one the first port is a fixed output * port and the second is a fixed input port. */ - if (!inl(info->dio_context.dir_reg)) + if (!inl(dev->iobase + ME4000_DIO_DIR_REG)) return -ENODEV; s->io_bits &= ~0xFF; @@ -1781,7 +1760,7 @@ static int me4000_dio_insn_config(struct comedi_device *dev, } } - outl(tmp, info->dio_context.ctrl_reg); + outl(tmp, dev->iobase + ME4000_DIO_CTRL_REG); return 1; } @@ -2105,9 +2084,10 @@ static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it) * Check for optoisolated ME-4000 version. If one the first * port is a fixed output port and the second is a fixed input port. */ - if (!inl(info->dio_context.dir_reg)) { + if (!inl(dev->iobase + ME4000_DIO_DIR_REG)) { s->io_bits |= 0xFF; - outl(ME4000_DIO_CTRL_BIT_MODE_0, info->dio_context.dir_reg); + outl(ME4000_DIO_CTRL_BIT_MODE_0, + dev->iobase + ME4000_DIO_DIR_REG); } /*========================================================================= diff --git a/drivers/staging/comedi/drivers/me4000.h b/drivers/staging/comedi/drivers/me4000.h index 188e964..c7187f1 100644 --- a/drivers/staging/comedi/drivers/me4000.h +++ b/drivers/staging/comedi/drivers/me4000.h @@ -265,15 +265,6 @@ struct me4000_ai_context { unsigned long sample_counter_reg; }; -struct me4000_dio_context { - unsigned long dir_reg; - unsigned long ctrl_reg; - unsigned long port_0_reg; - unsigned long port_1_reg; - unsigned long port_2_reg; - unsigned long port_3_reg; -}; - struct me4000_info { unsigned long plx_regbase; /* PLX configuration space base address */ unsigned long timer_regbase; /* Base address of the timer circuit */ @@ -290,7 +281,6 @@ struct me4000_info { struct me4000_ai_context ai_context; /* Analog input specific context */ struct me4000_ao_context ao_context[4]; /* Vector with analog output specific context */ - struct me4000_dio_context dio_context; /* Digital I/O specific context */ }; #define info ((struct me4000_info *)dev->private) -- cgit v0.10.2 From b08bfa38c06e0edbf6f434f6db3943e82d32239f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:43:36 -0700 Subject: staging: comedi: me4000: remove ai context The ai context is a struct containing all the register addresses used with the ai subdevice. These can easily be calculated when needed. Remove the me4000_ai_context struct, its intialization function, and it's variable in the private data. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index b6effb0..5d696d6 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -218,7 +218,6 @@ static const struct me4000_board me4000_boards[] = { static int init_board_info(struct comedi_device *dev, struct pci_dev *pci_dev_p); static int init_ao_context(struct comedi_device *dev); -static int init_ai_context(struct comedi_device *dev); static int xilinx_download(struct comedi_device *dev); static int reset_board(struct comedi_device *dev); @@ -320,10 +319,6 @@ found: if (result) return result; - result = init_ai_context(dev); - if (result) - return result; - result = xilinx_download(dev); if (result) return result; @@ -447,37 +442,6 @@ static int init_ao_context(struct comedi_device *dev) return 0; } -static int init_ai_context(struct comedi_device *dev) -{ - info->ai_context.irq = info->irq; - - info->ai_context.ctrl_reg = dev->iobase + ME4000_AI_CTRL_REG; - info->ai_context.status_reg = - dev->iobase + ME4000_AI_STATUS_REG; - info->ai_context.channel_list_reg = - dev->iobase + ME4000_AI_CHANNEL_LIST_REG; - info->ai_context.data_reg = dev->iobase + ME4000_AI_DATA_REG; - info->ai_context.chan_timer_reg = - dev->iobase + ME4000_AI_CHAN_TIMER_REG; - info->ai_context.chan_pre_timer_reg = - dev->iobase + ME4000_AI_CHAN_PRE_TIMER_REG; - info->ai_context.scan_timer_low_reg = - dev->iobase + ME4000_AI_SCAN_TIMER_LOW_REG; - info->ai_context.scan_timer_high_reg = - dev->iobase + ME4000_AI_SCAN_TIMER_HIGH_REG; - info->ai_context.scan_pre_timer_low_reg = - dev->iobase + ME4000_AI_SCAN_PRE_TIMER_LOW_REG; - info->ai_context.scan_pre_timer_high_reg = - dev->iobase + ME4000_AI_SCAN_PRE_TIMER_HIGH_REG; - info->ai_context.start_reg = dev->iobase + ME4000_AI_START_REG; - info->ai_context.irq_status_reg = - dev->iobase + ME4000_IRQ_STATUS_REG; - info->ai_context.sample_counter_reg = - dev->iobase + ME4000_AI_SAMPLE_COUNTER_REG; - - return 0; -} - #define FIRMWARE_NOT_AVAILABLE 1 #if FIRMWARE_NOT_AVAILABLE extern unsigned char *xilinx_firm; @@ -697,34 +661,34 @@ static int me4000_ai_insn_read(struct comedi_device *dev, entry |= ME4000_AI_LIST_LAST_ENTRY; /* Clear channel list, data fifo and both stop bits */ - tmp = inl(info->ai_context.ctrl_reg); + tmp = inl(dev->iobase + ME4000_AI_CTRL_REG); tmp &= ~(ME4000_AI_CTRL_BIT_CHANNEL_FIFO | ME4000_AI_CTRL_BIT_DATA_FIFO | ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP); - outl(tmp, info->ai_context.ctrl_reg); + outl(tmp, dev->iobase + ME4000_AI_CTRL_REG); /* Set the acquisition mode to single */ tmp &= ~(ME4000_AI_CTRL_BIT_MODE_0 | ME4000_AI_CTRL_BIT_MODE_1 | ME4000_AI_CTRL_BIT_MODE_2); - outl(tmp, info->ai_context.ctrl_reg); + outl(tmp, dev->iobase + ME4000_AI_CTRL_REG); /* Enable channel list and data fifo */ tmp |= ME4000_AI_CTRL_BIT_CHANNEL_FIFO | ME4000_AI_CTRL_BIT_DATA_FIFO; - outl(tmp, info->ai_context.ctrl_reg); + outl(tmp, dev->iobase + ME4000_AI_CTRL_REG); /* Generate channel list entry */ - outl(entry, info->ai_context.channel_list_reg); + outl(entry, dev->iobase + ME4000_AI_CHANNEL_LIST_REG); /* Set the timer to maximum sample rate */ - outl(ME4000_AI_MIN_TICKS, info->ai_context.chan_timer_reg); - outl(ME4000_AI_MIN_TICKS, info->ai_context.chan_pre_timer_reg); + outl(ME4000_AI_MIN_TICKS, dev->iobase + ME4000_AI_CHAN_TIMER_REG); + outl(ME4000_AI_MIN_TICKS, dev->iobase + ME4000_AI_CHAN_PRE_TIMER_REG); /* Start conversion by dummy read */ - inl(info->ai_context.start_reg); + inl(dev->iobase + ME4000_AI_START_REG); /* Wait until ready */ udelay(10); - if (!(inl(info->ai_context.status_reg) & + if (!(inl(dev->iobase + ME4000_AI_STATUS_REG) & ME4000_AI_STATUS_BIT_EF_DATA)) { printk(KERN_ERR "comedi%d: me4000: me4000_ai_insn_read(): " @@ -733,7 +697,7 @@ static int me4000_ai_insn_read(struct comedi_device *dev, } /* Read value from data fifo */ - lval = inl(info->ai_context.data_reg) & 0xFFFF; + lval = inl(dev->iobase + ME4000_AI_DATA_REG) & 0xFFFF; data[0] = lval ^ 0x8000; return 1; @@ -745,12 +709,12 @@ static int me4000_ai_cancel(struct comedi_device *dev, unsigned long tmp; /* Stop any running conversion */ - tmp = inl(info->ai_context.ctrl_reg); + tmp = inl(dev->iobase + ME4000_AI_CTRL_REG); tmp &= ~(ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP); - outl(tmp, info->ai_context.ctrl_reg); + outl(tmp, dev->iobase + ME4000_AI_CTRL_REG); /* Clear the control register */ - outl(0x0, info->ai_context.ctrl_reg); + outl(0x0, dev->iobase + ME4000_AI_CTRL_REG); return 0; } @@ -897,16 +861,16 @@ static void ai_write_timer(struct comedi_device *dev, unsigned int init_ticks, unsigned int scan_ticks, unsigned int chan_ticks) { - outl(init_ticks - 1, info->ai_context.scan_pre_timer_low_reg); - outl(0x0, info->ai_context.scan_pre_timer_high_reg); + outl(init_ticks - 1, dev->iobase + ME4000_AI_SCAN_PRE_TIMER_LOW_REG); + outl(0x0, dev->iobase + ME4000_AI_SCAN_PRE_TIMER_HIGH_REG); if (scan_ticks) { - outl(scan_ticks - 1, info->ai_context.scan_timer_low_reg); - outl(0x0, info->ai_context.scan_timer_high_reg); + outl(scan_ticks - 1, dev->iobase + ME4000_AI_SCAN_TIMER_LOW_REG); + outl(0x0, dev->iobase + ME4000_AI_SCAN_TIMER_HIGH_REG); } - outl(chan_ticks - 1, info->ai_context.chan_pre_timer_reg); - outl(chan_ticks - 1, info->ai_context.chan_timer_reg); + outl(chan_ticks - 1, dev->iobase + ME4000_AI_CHAN_PRE_TIMER_REG); + outl(chan_ticks - 1, dev->iobase + ME4000_AI_CHAN_TIMER_REG); } static int ai_prepare(struct comedi_device *dev, @@ -922,7 +886,7 @@ static int ai_prepare(struct comedi_device *dev, ai_write_timer(dev, init_ticks, scan_ticks, chan_ticks); /* Reset control register */ - outl(tmp, info->ai_context.ctrl_reg); + outl(tmp, dev->iobase + ME4000_AI_CTRL_REG); /* Start sources */ if ((cmd->start_src == TRIG_EXT && @@ -956,19 +920,19 @@ static int ai_prepare(struct comedi_device *dev, /* Stop triggers */ if (cmd->stop_src == TRIG_COUNT) { outl(cmd->chanlist_len * cmd->stop_arg, - info->ai_context.sample_counter_reg); + dev->iobase + ME4000_AI_SAMPLE_COUNTER_REG); tmp |= ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ; } else if (cmd->stop_src == TRIG_NONE && cmd->scan_end_src == TRIG_COUNT) { outl(cmd->scan_end_arg, - info->ai_context.sample_counter_reg); + dev->iobase + ME4000_AI_SAMPLE_COUNTER_REG); tmp |= ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ; } else { tmp |= ME4000_AI_CTRL_BIT_HF_IRQ; } /* Write the setup to the control register */ - outl(tmp, info->ai_context.ctrl_reg); + outl(tmp, dev->iobase + ME4000_AI_CTRL_REG); /* Write the channel list */ ai_write_chanlist(dev, s, cmd); @@ -1006,7 +970,7 @@ static int ai_write_chanlist(struct comedi_device *dev, else entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED; - outl(entry, info->ai_context.channel_list_reg); + outl(entry, dev->iobase + ME4000_AI_CHANNEL_LIST_REG); } return 0; @@ -1038,7 +1002,7 @@ static int me4000_ai_do_cmd(struct comedi_device *dev, return err; /* Start acquistion by dummy read */ - inl(info->ai_context.start_reg); + inl(dev->iobase + ME4000_AI_START_REG); return 0; } @@ -1402,7 +1366,6 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) unsigned int tmp; struct comedi_device *dev = dev_id; struct comedi_subdevice *s = &dev->subdevices[0]; - struct me4000_ai_context *ai_context = &info->ai_context; int i; int c = 0; long lval; @@ -1414,17 +1377,17 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) s->async->events = 0; /* Check if irq number is right */ - if (irq != ai_context->irq) { + if (irq != info->irq) { printk(KERN_ERR "comedi%d: me4000: me4000_ai_isr(): " "Incorrect interrupt num: %d\n", dev->minor, irq); return IRQ_HANDLED; } - if (inl(ai_context->irq_status_reg) & + if (inl(dev->iobase + ME4000_IRQ_STATUS_REG) & ME4000_IRQ_STATUS_BIT_AI_HF) { /* Read status register to find out what happened */ - tmp = inl(ai_context->ctrl_reg); + tmp = inl(dev->iobase + ME4000_AI_CTRL_REG); if (!(tmp & ME4000_AI_STATUS_BIT_FF_DATA) && !(tmp & ME4000_AI_STATUS_BIT_HF_DATA) && @@ -1438,7 +1401,7 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP; tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ); - outl(tmp, ai_context->ctrl_reg); + outl(tmp, dev->iobase + ME4000_AI_CTRL_REG); s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; @@ -1464,7 +1427,7 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP; tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ); - outl(tmp, ai_context->ctrl_reg); + outl(tmp, dev->iobase + ME4000_AI_CTRL_REG); s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; @@ -1475,7 +1438,7 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) for (i = 0; i < c; i++) { /* Read value from data fifo */ - lval = inl(ai_context->data_reg) & 0xFFFF; + lval = inl(dev->iobase + ME4000_AI_DATA_REG) & 0xFFFF; lval ^= 0x8000; if (!comedi_buf_put(s->async, lval)) { @@ -1486,7 +1449,7 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP; tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ); - outl(tmp, ai_context->ctrl_reg); + outl(tmp, dev->iobase + ME4000_AI_CTRL_REG); s->async->events |= COMEDI_CB_OVERFLOW; @@ -1500,27 +1463,29 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) /* Work is done, so reset the interrupt */ tmp |= ME4000_AI_CTRL_BIT_HF_IRQ_RESET; - outl(tmp, ai_context->ctrl_reg); + outl(tmp, dev->iobase + ME4000_AI_CTRL_REG); tmp &= ~ME4000_AI_CTRL_BIT_HF_IRQ_RESET; - outl(tmp, ai_context->ctrl_reg); + outl(tmp, dev->iobase + ME4000_AI_CTRL_REG); } - if (inl(ai_context->irq_status_reg) & ME4000_IRQ_STATUS_BIT_SC) { + if (inl(dev->iobase + ME4000_IRQ_STATUS_REG) & + ME4000_IRQ_STATUS_BIT_SC) { s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOA; /* * Acquisition is complete, so stop * conversion and disable all interrupts */ - tmp = inl(ai_context->ctrl_reg); + tmp = inl(dev->iobase + ME4000_AI_CTRL_REG); tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP; tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ); - outl(tmp, ai_context->ctrl_reg); + outl(tmp, dev->iobase + ME4000_AI_CTRL_REG); /* Poll data until fifo empty */ - while (inl(ai_context->ctrl_reg) & ME4000_AI_STATUS_BIT_EF_DATA) { + while (inl(dev->iobase + ME4000_AI_CTRL_REG) & + ME4000_AI_STATUS_BIT_EF_DATA) { /* Read value from data fifo */ - lval = inl(ai_context->data_reg) & 0xFFFF; + lval = inl(dev->iobase + ME4000_AI_DATA_REG) & 0xFFFF; lval ^= 0x8000; if (!comedi_buf_put(s->async, lval)) { @@ -1534,9 +1499,9 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) /* Work is done, so reset the interrupt */ tmp |= ME4000_AI_CTRL_BIT_SC_IRQ_RESET; - outl(tmp, ai_context->ctrl_reg); + outl(tmp, dev->iobase + ME4000_AI_CTRL_REG); tmp &= ~ME4000_AI_CTRL_BIT_SC_IRQ_RESET; - outl(tmp, ai_context->ctrl_reg); + outl(tmp, dev->iobase + ME4000_AI_CTRL_REG); } if (s->async->events) diff --git a/drivers/staging/comedi/drivers/me4000.h b/drivers/staging/comedi/drivers/me4000.h index c7187f1..0cb0fea 100644 --- a/drivers/staging/comedi/drivers/me4000.h +++ b/drivers/staging/comedi/drivers/me4000.h @@ -247,24 +247,6 @@ struct me4000_ao_context { unsigned long preload_reg; }; -struct me4000_ai_context { - int irq; - - unsigned long ctrl_reg; - unsigned long status_reg; - unsigned long channel_list_reg; - unsigned long data_reg; - unsigned long chan_timer_reg; - unsigned long chan_pre_timer_reg; - unsigned long scan_timer_low_reg; - unsigned long scan_timer_high_reg; - unsigned long scan_pre_timer_low_reg; - unsigned long scan_pre_timer_high_reg; - unsigned long start_reg; - unsigned long irq_status_reg; - unsigned long sample_counter_reg; -}; - struct me4000_info { unsigned long plx_regbase; /* PLX configuration space base address */ unsigned long timer_regbase; /* Base address of the timer circuit */ @@ -279,7 +261,6 @@ struct me4000_info { unsigned int irq; /* IRQ assigned from the PCI BIOS */ - struct me4000_ai_context ai_context; /* Analog input specific context */ struct me4000_ao_context ao_context[4]; /* Vector with analog output specific context */ }; -- cgit v0.10.2 From c1db9a3090c8418088a9e12454144299359884f5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:43:54 -0700 Subject: staging: comedi: me4000: remove serial_no from the private data This value is read from the pci config space but it is never used. Just remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 5d696d6..dfee15d 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -338,11 +338,6 @@ static int init_board_info(struct comedi_device *dev, struct pci_dev *pci_dev_p) /* spin_lock_init(&info->preload_lock); */ /* spin_lock_init(&info->ai_ctrl_lock); */ - /* Get the serial number */ - result = pci_read_config_dword(pci_dev_p, 0x2C, &info->serial_no); - if (result != PCIBIOS_SUCCESSFUL) - return result; - /* Get the hardware revision */ result = pci_read_config_byte(pci_dev_p, 0x08, &info->hw_revision); if (result != PCIBIOS_SUCCESSFUL) diff --git a/drivers/staging/comedi/drivers/me4000.h b/drivers/staging/comedi/drivers/me4000.h index 0cb0fea..8aa05f8 100644 --- a/drivers/staging/comedi/drivers/me4000.h +++ b/drivers/staging/comedi/drivers/me4000.h @@ -252,7 +252,6 @@ struct me4000_info { unsigned long timer_regbase; /* Base address of the timer circuit */ unsigned long program_regbase; /* Base address to set the program pin for the xilinx */ - unsigned int serial_no; /* Serial number of the board */ unsigned char hw_revision; /* Hardware revision of the board */ unsigned short vendor_id; /* Meilhaus vendor id */ unsigned short device_id; /* Device id */ -- cgit v0.10.2 From 395d6d0f234d164f443f2bfd098091c39d60e6a5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:44:10 -0700 Subject: staging: comedi: me4000: remove hw_revision from the private data This value is read from the pci config space but it is never used. Just remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index dfee15d..8394718 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -332,17 +332,10 @@ found: static int init_board_info(struct comedi_device *dev, struct pci_dev *pci_dev_p) { - int result; - /* Init spin locks */ /* spin_lock_init(&info->preload_lock); */ /* spin_lock_init(&info->ai_ctrl_lock); */ - /* Get the hardware revision */ - result = pci_read_config_byte(pci_dev_p, 0x08, &info->hw_revision); - if (result != PCIBIOS_SUCCESSFUL) - return result; - /* Get the vendor id */ info->vendor_id = pci_dev_p->vendor; diff --git a/drivers/staging/comedi/drivers/me4000.h b/drivers/staging/comedi/drivers/me4000.h index 8aa05f8..afe91b1 100644 --- a/drivers/staging/comedi/drivers/me4000.h +++ b/drivers/staging/comedi/drivers/me4000.h @@ -252,7 +252,6 @@ struct me4000_info { unsigned long timer_regbase; /* Base address of the timer circuit */ unsigned long program_regbase; /* Base address to set the program pin for the xilinx */ - unsigned char hw_revision; /* Hardware revision of the board */ unsigned short vendor_id; /* Meilhaus vendor id */ unsigned short device_id; /* Device id */ -- cgit v0.10.2 From cfb2cb167ab57a3237a0b8f0a1dc0b92afe62c87 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:44:27 -0700 Subject: staging: comedi: me4000: remove {vendor, device}_id from the private data These values are never used. Just remove them. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 8394718..9cd24d2 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -336,12 +336,6 @@ static int init_board_info(struct comedi_device *dev, struct pci_dev *pci_dev_p) /* spin_lock_init(&info->preload_lock); */ /* spin_lock_init(&info->ai_ctrl_lock); */ - /* Get the vendor id */ - info->vendor_id = pci_dev_p->vendor; - - /* Get the device id */ - info->device_id = pci_dev_p->device; - /* Get the irq assigned to the board */ info->irq = pci_dev_p->irq; diff --git a/drivers/staging/comedi/drivers/me4000.h b/drivers/staging/comedi/drivers/me4000.h index afe91b1..80bc51e 100644 --- a/drivers/staging/comedi/drivers/me4000.h +++ b/drivers/staging/comedi/drivers/me4000.h @@ -252,9 +252,6 @@ struct me4000_info { unsigned long timer_regbase; /* Base address of the timer circuit */ unsigned long program_regbase; /* Base address to set the program pin for the xilinx */ - unsigned short vendor_id; /* Meilhaus vendor id */ - unsigned short device_id; /* Device id */ - struct pci_dev *pci_dev_p; /* General PCI information */ unsigned int irq; /* IRQ assigned from the PCI BIOS */ -- cgit v0.10.2 From e1d7ccb770b9b231c177bb7477a89cea9682d61a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:45:08 -0700 Subject: staging: comedi: me4000: remove ao context The ao context is a struct containing all the register addresses used with the ao subdevice. These can easily be calculated when needed. Remove the me4000_ao_context struct, its initialization function, and it's variable in the private data. The last value written to the ao channels still needs to be saved in the private data for readback. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 9cd24d2..418a679 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -217,7 +217,6 @@ static const struct me4000_board me4000_boards[] = { ---------------------------------------------------------------------------*/ static int init_board_info(struct comedi_device *dev, struct pci_dev *pci_dev_p); -static int init_ao_context(struct comedi_device *dev); static int xilinx_download(struct comedi_device *dev); static int reset_board(struct comedi_device *dev); @@ -315,10 +314,6 @@ found: if (result) return result; - result = init_ao_context(dev); - if (result) - return result; - result = xilinx_download(dev); if (result) return result; @@ -342,88 +337,6 @@ static int init_board_info(struct comedi_device *dev, struct pci_dev *pci_dev_p) return 0; } -static int init_ao_context(struct comedi_device *dev) -{ - const struct me4000_board *thisboard = comedi_board(dev); - int i; - - for (i = 0; i < thisboard->ao_nchan; i++) { - /* spin_lock_init(&info->ao_context[i].use_lock); */ - info->ao_context[i].irq = info->irq; - - switch (i) { - case 0: - info->ao_context[i].ctrl_reg = - dev->iobase + ME4000_AO_00_CTRL_REG; - info->ao_context[i].status_reg = - dev->iobase + ME4000_AO_00_STATUS_REG; - info->ao_context[i].fifo_reg = - dev->iobase + ME4000_AO_00_FIFO_REG; - info->ao_context[i].single_reg = - dev->iobase + ME4000_AO_00_SINGLE_REG; - info->ao_context[i].timer_reg = - dev->iobase + ME4000_AO_00_TIMER_REG; - info->ao_context[i].irq_status_reg = - dev->iobase + ME4000_IRQ_STATUS_REG; - info->ao_context[i].preload_reg = - dev->iobase + ME4000_AO_LOADSETREG_XX; - break; - case 1: - info->ao_context[i].ctrl_reg = - dev->iobase + ME4000_AO_01_CTRL_REG; - info->ao_context[i].status_reg = - dev->iobase + ME4000_AO_01_STATUS_REG; - info->ao_context[i].fifo_reg = - dev->iobase + ME4000_AO_01_FIFO_REG; - info->ao_context[i].single_reg = - dev->iobase + ME4000_AO_01_SINGLE_REG; - info->ao_context[i].timer_reg = - dev->iobase + ME4000_AO_01_TIMER_REG; - info->ao_context[i].irq_status_reg = - dev->iobase + ME4000_IRQ_STATUS_REG; - info->ao_context[i].preload_reg = - dev->iobase + ME4000_AO_LOADSETREG_XX; - break; - case 2: - info->ao_context[i].ctrl_reg = - dev->iobase + ME4000_AO_02_CTRL_REG; - info->ao_context[i].status_reg = - dev->iobase + ME4000_AO_02_STATUS_REG; - info->ao_context[i].fifo_reg = - dev->iobase + ME4000_AO_02_FIFO_REG; - info->ao_context[i].single_reg = - dev->iobase + ME4000_AO_02_SINGLE_REG; - info->ao_context[i].timer_reg = - dev->iobase + ME4000_AO_02_TIMER_REG; - info->ao_context[i].irq_status_reg = - dev->iobase + ME4000_IRQ_STATUS_REG; - info->ao_context[i].preload_reg = - dev->iobase + ME4000_AO_LOADSETREG_XX; - break; - case 3: - info->ao_context[i].ctrl_reg = - dev->iobase + ME4000_AO_03_CTRL_REG; - info->ao_context[i].status_reg = - dev->iobase + ME4000_AO_03_STATUS_REG; - info->ao_context[i].fifo_reg = - dev->iobase + ME4000_AO_03_FIFO_REG; - info->ao_context[i].single_reg = - dev->iobase + ME4000_AO_03_SINGLE_REG; - info->ao_context[i].timer_reg = - dev->iobase + ME4000_AO_03_TIMER_REG; - info->ao_context[i].irq_status_reg = - dev->iobase + ME4000_IRQ_STATUS_REG; - info->ao_context[i].preload_reg = - dev->iobase + ME4000_AO_LOADSETREG_XX; - break; - default: - break; - } - } - - return 0; -} - #define FIRMWARE_NOT_AVAILABLE 1 #if FIRMWARE_NOT_AVAILABLE extern unsigned char *xilinx_firm; @@ -512,34 +425,28 @@ static int xilinx_download(struct comedi_device *dev) static int reset_board(struct comedi_device *dev) { - unsigned long icr; + unsigned long val; + int chan; /* Make a hardware reset */ - icr = inl(info->plx_regbase + PLX_ICR); - icr |= 0x40000000; - outl(icr, info->plx_regbase + PLX_ICR); - icr &= ~0x40000000; - outl(icr, info->plx_regbase + PLX_ICR); + val = inl(info->plx_regbase + PLX_ICR); + val |= 0x40000000; + outl(val, info->plx_regbase + PLX_ICR); + val &= ~0x40000000; + outl(val , info->plx_regbase + PLX_ICR); /* 0x8000 to the DACs means an output voltage of 0V */ - outl(0x8000, dev->iobase + ME4000_AO_00_SINGLE_REG); - outl(0x8000, dev->iobase + ME4000_AO_01_SINGLE_REG); - outl(0x8000, dev->iobase + ME4000_AO_02_SINGLE_REG); - outl(0x8000, dev->iobase + ME4000_AO_03_SINGLE_REG); + for (chan = 0; chan < 4; chan++) + outl(0x8000, dev->iobase + ME4000_AO_SINGLE_REG(chan)); /* Set both stop bits in the analog input control register */ outl(ME4000_AI_CTRL_BIT_IMMEDIATE_STOP | ME4000_AI_CTRL_BIT_STOP, dev->iobase + ME4000_AI_CTRL_REG); /* Set both stop bits in the analog output control register */ - outl(ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP, - dev->iobase + ME4000_AO_00_CTRL_REG); - outl(ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP, - dev->iobase + ME4000_AO_01_CTRL_REG); - outl(ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP, - dev->iobase + ME4000_AO_02_CTRL_REG); - outl(ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP, - dev->iobase + ME4000_AO_03_CTRL_REG); + val = ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP; + for (chan = 0; chan < 4; chan++) + outl(val, dev->iobase + ME4000_AO_CTRL_REG(chan)); /* Enable interrupts on the PLX */ outl(0x43, info->plx_regbase + PLX_INTCSR); @@ -1537,18 +1444,18 @@ static int me4000_ao_insn_write(struct comedi_device *dev, } /* Stop any running conversion */ - tmp = inl(info->ao_context[chan].ctrl_reg); + tmp = inl(dev->iobase + ME4000_AO_CTRL_REG(chan)); tmp |= ME4000_AO_CTRL_BIT_IMMEDIATE_STOP; - outl(tmp, info->ao_context[chan].ctrl_reg); + outl(tmp, dev->iobase + ME4000_AO_CTRL_REG(chan)); /* Clear control register and set to single mode */ - outl(0x0, info->ao_context[chan].ctrl_reg); + outl(0x0, dev->iobase + ME4000_AO_CTRL_REG(chan)); /* Write data value */ - outl(data[0], info->ao_context[chan].single_reg); + outl(data[0], dev->iobase + ME4000_AO_SINGLE_REG(chan)); /* Store in the mirror */ - info->ao_context[chan].mirror = data[0]; + info->ao_readback[chan] = data[0]; return 1; } @@ -1568,7 +1475,7 @@ static int me4000_ao_insn_read(struct comedi_device *dev, return -EINVAL; } - data[0] = info->ao_context[chan].mirror; + data[0] = info->ao_readback[chan]; return 1; } diff --git a/drivers/staging/comedi/drivers/me4000.h b/drivers/staging/comedi/drivers/me4000.h index 80bc51e..042ec4c 100644 --- a/drivers/staging/comedi/drivers/me4000.h +++ b/drivers/staging/comedi/drivers/me4000.h @@ -28,29 +28,13 @@ ME-4000 base register offsets ===========================================================================*/ -#define ME4000_AO_00_CTRL_REG 0x00 /* R/W */ -#define ME4000_AO_00_STATUS_REG 0x04 /* R/_ */ -#define ME4000_AO_00_FIFO_REG 0x08 /* _/W */ -#define ME4000_AO_00_SINGLE_REG 0x0C /* R/W */ -#define ME4000_AO_00_TIMER_REG 0x10 /* _/W */ - -#define ME4000_AO_01_CTRL_REG 0x18 /* R/W */ -#define ME4000_AO_01_STATUS_REG 0x1C /* R/_ */ -#define ME4000_AO_01_FIFO_REG 0x20 /* _/W */ -#define ME4000_AO_01_SINGLE_REG 0x24 /* R/W */ -#define ME4000_AO_01_TIMER_REG 0x28 /* _/W */ - -#define ME4000_AO_02_CTRL_REG 0x30 /* R/W */ -#define ME4000_AO_02_STATUS_REG 0x34 /* R/_ */ -#define ME4000_AO_02_FIFO_REG 0x38 /* _/W */ -#define ME4000_AO_02_SINGLE_REG 0x3C /* R/W */ -#define ME4000_AO_02_TIMER_REG 0x40 /* _/W */ - -#define ME4000_AO_03_CTRL_REG 0x48 /* R/W */ -#define ME4000_AO_03_STATUS_REG 0x4C /* R/_ */ -#define ME4000_AO_03_FIFO_REG 0x50 /* _/W */ -#define ME4000_AO_03_SINGLE_REG 0x54 /* R/W */ -#define ME4000_AO_03_TIMER_REG 0x58 /* _/W */ +#define ME4000_AO_CHAN(x) ((x) * 0x18) + +#define ME4000_AO_CTRL_REG(x) (0x00 + ME4000_AO_CHAN(x)) +#define ME4000_AO_STATUS_REG(x) (0x04 + ME4000_AO_CHAN(x)) +#define ME4000_AO_FIFO_REG(x) (0x08 + ME4000_AO_CHAN(x)) +#define ME4000_AO_SINGLE_REG(x) (0x0c + ME4000_AO_CHAN(x)) +#define ME4000_AO_TIMER_REG(x) (0x10 + ME4000_AO_CHAN(x)) #define ME4000_AI_CTRL_REG 0x74 /* _/W */ #define ME4000_AI_STATUS_REG 0x74 /* R/_ */ @@ -233,20 +217,6 @@ Global board and subdevice information structures ===========================================================================*/ -struct me4000_ao_context { - int irq; - - unsigned long mirror; /* Store the last written value */ - - unsigned long ctrl_reg; - unsigned long status_reg; - unsigned long fifo_reg; - unsigned long single_reg; - unsigned long timer_reg; - unsigned long irq_status_reg; - unsigned long preload_reg; -}; - struct me4000_info { unsigned long plx_regbase; /* PLX configuration space base address */ unsigned long timer_regbase; /* Base address of the timer circuit */ @@ -256,7 +226,7 @@ struct me4000_info { unsigned int irq; /* IRQ assigned from the PCI BIOS */ - struct me4000_ao_context ao_context[4]; /* Vector with analog output specific context */ + unsigned int ao_readback[4]; }; #define info ((struct me4000_info *)dev->private) -- cgit v0.10.2 From 109daa79807a47dc56d7533a7fdcd0dc72c862b2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:45:26 -0700 Subject: staging: comedi: me4000: use dev->irq to save the irq number Use the irq variable provided in the comedi_device to save the irq number and remove it from the private data. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 418a679..a041054 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -332,7 +332,7 @@ static int init_board_info(struct comedi_device *dev, struct pci_dev *pci_dev_p) /* spin_lock_init(&info->ai_ctrl_lock); */ /* Get the irq assigned to the board */ - info->irq = pci_dev_p->irq; + dev->irq = pci_dev_p->irq; return 0; } @@ -1266,7 +1266,7 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) s->async->events = 0; /* Check if irq number is right */ - if (irq != info->irq) { + if (irq != dev->irq) { printk(KERN_ERR "comedi%d: me4000: me4000_ai_isr(): " "Incorrect interrupt num: %d\n", dev->minor, irq); @@ -1876,8 +1876,8 @@ static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->range_table = &me4000_ai_range; s->insn_read = me4000_ai_insn_read; - if (info->irq > 0) { - if (request_irq(info->irq, me4000_ai_isr, + if (dev->irq > 0) { + if (request_irq(dev->irq, me4000_ai_isr, IRQF_SHARED, "ME-4000", dev)) { printk ("comedi%d: me4000: me4000_attach(): " diff --git a/drivers/staging/comedi/drivers/me4000.h b/drivers/staging/comedi/drivers/me4000.h index 042ec4c..57b02e1 100644 --- a/drivers/staging/comedi/drivers/me4000.h +++ b/drivers/staging/comedi/drivers/me4000.h @@ -224,8 +224,6 @@ struct me4000_info { struct pci_dev *pci_dev_p; /* General PCI information */ - unsigned int irq; /* IRQ assigned from the PCI BIOS */ - unsigned int ao_readback[4]; }; -- cgit v0.10.2 From b3ca977f083db063c9e53db04d8b12373ded8867 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:45:42 -0700 Subject: staging: comedi: me4000: absorb init_board_info() into its caller The init_board_info() function only gets the irq number from the pci_dev. Just move the code into the function that calls it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index a041054..f76f8da 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -215,8 +215,6 @@ static const struct me4000_board me4000_boards[] = { /*----------------------------------------------------------------------------- Meilhaus function prototypes ---------------------------------------------------------------------------*/ -static int init_board_info(struct comedi_device *dev, - struct pci_dev *pci_dev_p); static int xilinx_download(struct comedi_device *dev); static int reset_board(struct comedi_device *dev); @@ -310,9 +308,7 @@ found: if (!info->program_regbase) return -ENODEV; - result = init_board_info(dev, pci_device); - if (result) - return result; + dev->irq = pci_device->irq; result = xilinx_download(dev); if (result) @@ -325,18 +321,6 @@ found: return 0; } -static int init_board_info(struct comedi_device *dev, struct pci_dev *pci_dev_p) -{ - /* Init spin locks */ - /* spin_lock_init(&info->preload_lock); */ - /* spin_lock_init(&info->ai_ctrl_lock); */ - - /* Get the irq assigned to the board */ - dev->irq = pci_dev_p->irq; - - return 0; -} - #define FIRMWARE_NOT_AVAILABLE 1 #if FIRMWARE_NOT_AVAILABLE extern unsigned char *xilinx_firm; -- cgit v0.10.2 From 09253b396d6b6ae97e50af917ba13935a51266fc Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:45:56 -0700 Subject: staging: comedi: me4000: remove info macro This macro relies on a local variable having a specific name. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index f76f8da..ee028a3 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -241,13 +241,16 @@ static const struct comedi_lrange me4000_ao_range = { static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it) { + struct me4000_info *info; struct pci_dev *pci_device = NULL; int result, i; const struct me4000_board *board; /* Allocate private memory */ - if (alloc_private(dev, sizeof(struct me4000_info)) < 0) - return -ENOMEM; + result = alloc_private(dev, sizeof(*info)); + if (result) + return result; + info = dev->private; /* * Probe the device to determine what device in the series it is. @@ -328,6 +331,7 @@ extern unsigned char *xilinx_firm; static int xilinx_download(struct comedi_device *dev) { + struct me4000_info *info = dev->private; u32 value = 0; wait_queue_head_t queue; int idx = 0; @@ -409,6 +413,7 @@ static int xilinx_download(struct comedi_device *dev) static int reset_board(struct comedi_device *dev) { + struct me4000_info *info = dev->private; unsigned long val; int chan; @@ -1392,6 +1397,7 @@ static int me4000_ao_insn_write(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { const struct me4000_board *thisboard = comedi_board(dev); + struct me4000_info *info = dev->private; int chan = CR_CHAN(insn->chanspec); int rang = CR_RANGE(insn->chanspec); int aref = CR_AREF(insn->chanspec); @@ -1448,6 +1454,7 @@ static int me4000_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct me4000_info *info = dev->private; int chan = CR_CHAN(insn->chanspec); if (insn->n == 0) { @@ -1609,6 +1616,8 @@ static int me4000_dio_insn_config(struct comedi_device *dev, static int cnt_reset(struct comedi_device *dev, unsigned int channel) { + struct me4000_info *info = dev->private; + switch (channel) { case 0: outb(0x30, info->timer_regbase + ME4000_CNT_CTRL_REG); @@ -1638,6 +1647,7 @@ static int cnt_reset(struct comedi_device *dev, unsigned int channel) static int cnt_config(struct comedi_device *dev, unsigned int channel, unsigned int mode) { + struct me4000_info *info = dev->private; int tmp = 0; switch (channel) { @@ -1738,7 +1748,7 @@ static int me4000_cnt_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - + struct me4000_info *info = dev->private; unsigned short tmp; if (insn->n == 0) @@ -1786,7 +1796,7 @@ static int me4000_cnt_insn_write(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - + struct me4000_info *info = dev->private; unsigned short tmp; if (insn->n == 0) { @@ -1951,6 +1961,8 @@ static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void me4000_detach(struct comedi_device *dev) { + struct me4000_info *info = dev->private; + if (info) { if (info->pci_dev_p) { reset_board(dev); diff --git a/drivers/staging/comedi/drivers/me4000.h b/drivers/staging/comedi/drivers/me4000.h index 57b02e1..a04c209 100644 --- a/drivers/staging/comedi/drivers/me4000.h +++ b/drivers/staging/comedi/drivers/me4000.h @@ -227,8 +227,6 @@ struct me4000_info { unsigned int ao_readback[4]; }; -#define info ((struct me4000_info *)dev->private) - /*----------------------------------------------------------------------------- Defines for analog input ----------------------------------------------------------------------------*/ -- cgit v0.10.2 From 4683f9f8010523701d87eb56643a85bec947939f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:46:12 -0700 Subject: staging: comedi: me4000: remove me4000_ao_range Use range_bipolar10, which is exported by the comedi core, instead of creating a local symbol for an identical range. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index ee028a3..e8ab3f5 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -232,13 +232,6 @@ static const struct comedi_lrange me4000_ai_range = { } }; -static const struct comedi_lrange me4000_ao_range = { - 1, - { - BIP_RANGE(10), - } -}; - static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it) { struct me4000_info *info; @@ -1903,7 +1896,7 @@ static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->subdev_flags = SDF_WRITEABLE | SDF_COMMON | SDF_GROUND; s->n_chan = thisboard->ao_nchan; s->maxdata = 0xFFFF; /* 16 bit DAC */ - s->range_table = &me4000_ao_range; + s->range_table = &range_bipolar10; s->insn_write = me4000_ao_insn_write; s->insn_read = me4000_ao_insn_read; } else { -- cgit v0.10.2 From 4b2f15f138f75c15f42015110af111a95f30ed22 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:46:32 -0700 Subject: staging: comedi: me4000: remove forward declarations Move some of the functions to avoid the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index e8ab3f5..01557e2 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -212,16 +212,6 @@ static const struct me4000_board me4000_boards[] = { }, }; -/*----------------------------------------------------------------------------- - Meilhaus function prototypes - ---------------------------------------------------------------------------*/ -static int xilinx_download(struct comedi_device *dev); -static int reset_board(struct comedi_device *dev); - -static int ai_write_chanlist(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_cmd *cmd); - static const struct comedi_lrange me4000_ai_range = { 4, { @@ -232,91 +222,6 @@ static const struct comedi_lrange me4000_ai_range = { } }; -static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it) -{ - struct me4000_info *info; - struct pci_dev *pci_device = NULL; - int result, i; - const struct me4000_board *board; - - /* Allocate private memory */ - result = alloc_private(dev, sizeof(*info)); - if (result) - return result; - info = dev->private; - - /* - * Probe the device to determine what device in the series it is. - */ - for_each_pci_dev(pci_device) { - if (pci_device->vendor == PCI_VENDOR_ID_MEILHAUS) { - for (i = 0; i < ARRAY_SIZE(me4000_boards); i++) { - if (me4000_boards[i].device_id == - pci_device->device) { - /* - * Was a particular - * bus/slot requested? - */ - if ((it->options[0] != 0) - || (it->options[1] != 0)) { - /* - * Are we on the wrong - * bus/slot? - */ - if (pci_device->bus->number != - it->options[0] - || - PCI_SLOT(pci_device->devfn) - != it->options[1]) { - continue; - } - } - dev->board_ptr = me4000_boards + i; - board = comedi_board(dev); - info->pci_dev_p = pci_device; - goto found; - } - } - } - } - return -ENODEV; - -found: - dev->board_name = board->name; - - result = comedi_pci_enable(pci_device, dev->board_name); - if (result) - return result; - - info->plx_regbase = pci_resource_start(pci_device, 1); - if (!info->plx_regbase) - return -ENODEV; - - dev->iobase = pci_resource_start(pci_device, 2); - if (!dev->iobase) - return -ENODEV; - - info->timer_regbase = pci_resource_start(pci_device, 3); - if (!info->timer_regbase) - return -ENODEV; - - info->program_regbase = pci_resource_start(pci_device, 5); - if (!info->program_regbase) - return -ENODEV; - - dev->irq = pci_device->irq; - - result = xilinx_download(dev); - if (result) - return result; - - result = reset_board(dev); - if (result) - return result; - - return 0; -} - #define FIRMWARE_NOT_AVAILABLE 1 #if FIRMWARE_NOT_AVAILABLE extern unsigned char *xilinx_firm; @@ -744,6 +649,42 @@ static void ai_write_timer(struct comedi_device *dev, outl(chan_ticks - 1, dev->iobase + ME4000_AI_CHAN_TIMER_REG); } +static int ai_write_chanlist(struct comedi_device *dev, + struct comedi_subdevice *s, struct comedi_cmd *cmd) +{ + unsigned int entry; + unsigned int chan; + unsigned int rang; + unsigned int aref; + int i; + + for (i = 0; i < cmd->chanlist_len; i++) { + chan = CR_CHAN(cmd->chanlist[i]); + rang = CR_RANGE(cmd->chanlist[i]); + aref = CR_AREF(cmd->chanlist[i]); + + entry = chan; + + if (rang == 0) + entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_2_5; + else if (rang == 1) + entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_10; + else if (rang == 2) + entry |= ME4000_AI_LIST_RANGE_BIPOLAR_2_5; + else + entry |= ME4000_AI_LIST_RANGE_BIPOLAR_10; + + if (aref == SDF_DIFF) + entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL; + else + entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED; + + outl(entry, dev->iobase + ME4000_AI_CHANNEL_LIST_REG); + } + + return 0; +} + static int ai_prepare(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd, @@ -811,42 +752,6 @@ static int ai_prepare(struct comedi_device *dev, return 0; } -static int ai_write_chanlist(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_cmd *cmd) -{ - unsigned int entry; - unsigned int chan; - unsigned int rang; - unsigned int aref; - int i; - - for (i = 0; i < cmd->chanlist_len; i++) { - chan = CR_CHAN(cmd->chanlist[i]); - rang = CR_RANGE(cmd->chanlist[i]); - aref = CR_AREF(cmd->chanlist[i]); - - entry = chan; - - if (rang == 0) - entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_2_5; - else if (rang == 1) - entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_10; - else if (rang == 2) - entry |= ME4000_AI_LIST_RANGE_BIPOLAR_2_5; - else - entry |= ME4000_AI_LIST_RANGE_BIPOLAR_10; - - if (aref == SDF_DIFF) - entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL; - else - entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED; - - outl(entry, dev->iobase + ME4000_AI_CHANNEL_LIST_REG); - } - - return 0; -} - static int me4000_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { @@ -1832,6 +1737,91 @@ static int me4000_cnt_insn_write(struct comedi_device *dev, return 1; } +static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it) +{ + struct me4000_info *info; + struct pci_dev *pci_device = NULL; + int result, i; + const struct me4000_board *board; + + /* Allocate private memory */ + result = alloc_private(dev, sizeof(*info)); + if (result) + return result; + info = dev->private; + + /* + * Probe the device to determine what device in the series it is. + */ + for_each_pci_dev(pci_device) { + if (pci_device->vendor == PCI_VENDOR_ID_MEILHAUS) { + for (i = 0; i < ARRAY_SIZE(me4000_boards); i++) { + if (me4000_boards[i].device_id == + pci_device->device) { + /* + * Was a particular + * bus/slot requested? + */ + if ((it->options[0] != 0) + || (it->options[1] != 0)) { + /* + * Are we on the wrong + * bus/slot? + */ + if (pci_device->bus->number != + it->options[0] + || + PCI_SLOT(pci_device->devfn) + != it->options[1]) { + continue; + } + } + dev->board_ptr = me4000_boards + i; + board = comedi_board(dev); + info->pci_dev_p = pci_device; + goto found; + } + } + } + } + return -ENODEV; + +found: + dev->board_name = board->name; + + result = comedi_pci_enable(pci_device, dev->board_name); + if (result) + return result; + + info->plx_regbase = pci_resource_start(pci_device, 1); + if (!info->plx_regbase) + return -ENODEV; + + dev->iobase = pci_resource_start(pci_device, 2); + if (!dev->iobase) + return -ENODEV; + + info->timer_regbase = pci_resource_start(pci_device, 3); + if (!info->timer_regbase) + return -ENODEV; + + info->program_regbase = pci_resource_start(pci_device, 5); + if (!info->program_regbase) + return -ENODEV; + + dev->irq = pci_device->irq; + + result = xilinx_download(dev); + if (result) + return result; + + result = reset_board(dev); + if (result) + return result; + + return 0; +} + static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct me4000_board *thisboard; -- cgit v0.10.2 From f4c772f0c3d6477ab18af8bd8ac239049a1af6a5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:46:51 -0700 Subject: staging: comedi: me4000: store the pci_dev in the comedi_device Use the hw_dev pointer in the comedi_device struct to hold the pci_dev instead of carrying it in the private data. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 01557e2..39eb775 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -1778,7 +1778,6 @@ static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it) } dev->board_ptr = me4000_boards + i; board = comedi_board(dev); - info->pci_dev_p = pci_device; goto found; } } @@ -1787,6 +1786,7 @@ static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it) return -ENODEV; found: + comedi_set_hw_dev(dev, &pci_device->dev); dev->board_name = board->name; result = comedi_pci_enable(pci_device, dev->board_name); @@ -1944,15 +1944,14 @@ static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void me4000_detach(struct comedi_device *dev) { - struct me4000_info *info = dev->private; + struct pci_dev *pcidev = comedi_to_pci_dev(dev); - if (info) { - if (info->pci_dev_p) { + if (pcidev) { + if (dev->iobase) { reset_board(dev); - if (info->plx_regbase) - comedi_pci_disable(info->pci_dev_p); - pci_dev_put(info->pci_dev_p); + comedi_pci_disable(pcidev); } + pci_dev_put(pcidev); } } diff --git a/drivers/staging/comedi/drivers/me4000.h b/drivers/staging/comedi/drivers/me4000.h index a04c209..b6d8e3b 100644 --- a/drivers/staging/comedi/drivers/me4000.h +++ b/drivers/staging/comedi/drivers/me4000.h @@ -222,8 +222,6 @@ struct me4000_info { unsigned long timer_regbase; /* Base address of the timer circuit */ unsigned long program_regbase; /* Base address to set the program pin for the xilinx */ - struct pci_dev *pci_dev_p; /* General PCI information */ - unsigned int ao_readback[4]; }; -- cgit v0.10.2 From ba5cb4ba57053153959587b67881eecec89eb08f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:47:20 -0700 Subject: staging: comedi: me4000: cleanup me4000_probe() Move the non pci probe related code out of the me4000_probe function and back into the me4000_attach function in preparation of converting this driver to the 'attach_pci' callback. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 39eb775..948f04a 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -1737,18 +1737,11 @@ static int me4000_cnt_insn_write(struct comedi_device *dev, return 1; } -static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it) +static struct pci_dev *me4000_probe(struct comedi_device *dev, + struct comedi_devconfig *it) { - struct me4000_info *info; struct pci_dev *pci_device = NULL; - int result, i; - const struct me4000_board *board; - - /* Allocate private memory */ - result = alloc_private(dev, sizeof(*info)); - if (result) - return result; - info = dev->private; + int i; /* * Probe the device to determine what device in the series it is. @@ -1777,39 +1770,55 @@ static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it) } } dev->board_ptr = me4000_boards + i; - board = comedi_board(dev); - goto found; + return pci_device; } } } } - return -ENODEV; + return NULL; +} + +static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it) +{ + const struct me4000_board *thisboard; + struct me4000_info *info; + struct pci_dev *pcidev; + struct comedi_subdevice *s; + int result; -found: - comedi_set_hw_dev(dev, &pci_device->dev); - dev->board_name = board->name; + pcidev = me4000_probe(dev, it); + if (!pcidev) + return -ENODEV; + comedi_set_hw_dev(dev, &pcidev->dev); + thisboard = comedi_board(dev); + dev->board_name = thisboard->name; - result = comedi_pci_enable(pci_device, dev->board_name); + result = alloc_private(dev, sizeof(*info)); if (result) return result; + info = dev->private; - info->plx_regbase = pci_resource_start(pci_device, 1); + result = comedi_pci_enable(pcidev, dev->board_name); + if (result) + return result; + + info->plx_regbase = pci_resource_start(pcidev, 1); if (!info->plx_regbase) return -ENODEV; - dev->iobase = pci_resource_start(pci_device, 2); + dev->iobase = pci_resource_start(pcidev, 2); if (!dev->iobase) return -ENODEV; - info->timer_regbase = pci_resource_start(pci_device, 3); + info->timer_regbase = pci_resource_start(pcidev, 3); if (!info->timer_regbase) return -ENODEV; - info->program_regbase = pci_resource_start(pci_device, 5); + info->program_regbase = pci_resource_start(pcidev, 5); if (!info->program_regbase) return -ENODEV; - dev->irq = pci_device->irq; + dev->irq = pcidev->irq; result = xilinx_download(dev); if (result) @@ -1819,20 +1828,6 @@ found: if (result) return result; - return 0; -} - -static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it) -{ - const struct me4000_board *thisboard; - struct comedi_subdevice *s; - int result; - - result = me4000_probe(dev, it); - if (result) - return result; - thisboard = comedi_board(dev); - result = comedi_alloc_subdevices(dev, 4); if (result) return result; -- cgit v0.10.2 From 5f8f8d43506652a361f81abc5ccd18c608dfc84d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:47:41 -0700 Subject: staging: comedi: me4000: use attach_pci callback Convert this PCI driver to use the comedi PCI auto config attach mechanism by adding an 'attach_pci' callback function. Since the driver does not require any external configuration options, and the legacy 'attach' callback is now optional, remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 948f04a..12b3cf8 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -35,13 +35,7 @@ Supports: - Digital I/O - Counter -Configuration Options: - - [0] - PCI bus number (optional) - [1] - PCI slot number (optional) - - If bus/slot is not specified, the first available PCI - device will be used. +Configuration Options: not applicable, uses PCI auto config The firmware required by these boards is available in the comedi_nonfree_firmware tarball available from @@ -1737,60 +1731,34 @@ static int me4000_cnt_insn_write(struct comedi_device *dev, return 1; } -static struct pci_dev *me4000_probe(struct comedi_device *dev, - struct comedi_devconfig *it) +static const void *me4000_find_boardinfo(struct comedi_device *dev, + struct pci_dev *pcidev) { - struct pci_dev *pci_device = NULL; + const struct me4000_board *thisboard; int i; - /* - * Probe the device to determine what device in the series it is. - */ - for_each_pci_dev(pci_device) { - if (pci_device->vendor == PCI_VENDOR_ID_MEILHAUS) { - for (i = 0; i < ARRAY_SIZE(me4000_boards); i++) { - if (me4000_boards[i].device_id == - pci_device->device) { - /* - * Was a particular - * bus/slot requested? - */ - if ((it->options[0] != 0) - || (it->options[1] != 0)) { - /* - * Are we on the wrong - * bus/slot? - */ - if (pci_device->bus->number != - it->options[0] - || - PCI_SLOT(pci_device->devfn) - != it->options[1]) { - continue; - } - } - dev->board_ptr = me4000_boards + i; - return pci_device; - } - } - } + for (i = 0; i < ARRAY_SIZE(me4000_boards); i++) { + thisboard = &me4000_boards[i]; + if (thisboard->device_id == pcidev->device) + return thisboard; } return NULL; } -static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it) +static int me4000_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) { const struct me4000_board *thisboard; struct me4000_info *info; - struct pci_dev *pcidev; struct comedi_subdevice *s; int result; - pcidev = me4000_probe(dev, it); - if (!pcidev) - return -ENODEV; comedi_set_hw_dev(dev, &pcidev->dev); - thisboard = comedi_board(dev); + + thisboard = me4000_find_boardinfo(dev, pcidev); + if (!thisboard) + return -ENODEV; + dev->board_ptr = thisboard; dev->board_name = thisboard->name; result = alloc_private(dev, sizeof(*info)); @@ -1946,14 +1914,13 @@ static void me4000_detach(struct comedi_device *dev) reset_board(dev); comedi_pci_disable(pcidev); } - pci_dev_put(pcidev); } } static struct comedi_driver me4000_driver = { .driver_name = "me4000", .module = THIS_MODULE, - .attach = me4000_attach, + .attach_pci = me4000_attach_pci, .detach = me4000_detach, }; -- cgit v0.10.2 From fe531d12acff926628df11df6d476474383a9f3f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:48:09 -0700 Subject: staging: comedi: me4000: remove program_regbase from private data The program_regbase variable in the private data is only used when the board is first attached. This variable holds the pci base address used to read/write the xilinx part to upload the firmware. Use a local variable in the xilinx_download() function to hold this address and remove program_regbase from the private data. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 12b3cf8..f2c8d04 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -223,12 +223,17 @@ extern unsigned char *xilinx_firm; static int xilinx_download(struct comedi_device *dev) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct me4000_info *info = dev->private; + unsigned long xilinx_iobase = pci_resource_start(pcidev, 5); u32 value = 0; wait_queue_head_t queue; int idx = 0; int size = 0; + if (!xilinx_iobase) + return -ENODEV; + init_waitqueue_head(&queue); /* @@ -243,7 +248,7 @@ static int xilinx_download(struct comedi_device *dev) outl(value, info->plx_regbase + PLX_ICR); /* Init Xilinx with CS1 */ - inb(info->program_regbase + 0xC8); + inb(xilinx_iobase + 0xC8); /* Wait until /INIT pin is set */ udelay(20); @@ -269,7 +274,7 @@ static int xilinx_download(struct comedi_device *dev) udelay(10); for (idx = 0; idx < size; idx++) { - outb(xilinx_firm[16 + idx], info->program_regbase); + outb(xilinx_firm[16 + idx], xilinx_iobase); udelay(10); /* Check if BUSY flag is low */ @@ -1782,10 +1787,6 @@ static int me4000_attach_pci(struct comedi_device *dev, if (!info->timer_regbase) return -ENODEV; - info->program_regbase = pci_resource_start(pcidev, 5); - if (!info->program_regbase) - return -ENODEV; - dev->irq = pcidev->irq; result = xilinx_download(dev); diff --git a/drivers/staging/comedi/drivers/me4000.h b/drivers/staging/comedi/drivers/me4000.h index b6d8e3b..7feb574 100644 --- a/drivers/staging/comedi/drivers/me4000.h +++ b/drivers/staging/comedi/drivers/me4000.h @@ -220,7 +220,6 @@ struct me4000_info { unsigned long plx_regbase; /* PLX configuration space base address */ unsigned long timer_regbase; /* Base address of the timer circuit */ - unsigned long program_regbase; /* Base address to set the program pin for the xilinx */ unsigned int ao_readback[4]; }; -- cgit v0.10.2 From 39780a1caf92342c4deb0d14d39703cf5c70cdac Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:48:26 -0700 Subject: staging: comedi: me4000: combine the checks for valid io addresses Combine the sanity checks for valid io addresses into one if(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index f2c8d04..219ad6c 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -1776,15 +1776,9 @@ static int me4000_attach_pci(struct comedi_device *dev, return result; info->plx_regbase = pci_resource_start(pcidev, 1); - if (!info->plx_regbase) - return -ENODEV; - dev->iobase = pci_resource_start(pcidev, 2); - if (!dev->iobase) - return -ENODEV; - info->timer_regbase = pci_resource_start(pcidev, 3); - if (!info->timer_regbase) + if (!info->plx_regbase || !dev->iobase || !info->timer_regbase) return -ENODEV; dev->irq = pcidev->irq; -- cgit v0.10.2 From b179748d21562decdf323f2d686920b836b3f272 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:48:48 -0700 Subject: staging: comedi: me4000: fix the interrupt request/free Only set the dev->irq when the request_irq is successful. Use the dev->board_name for the name passed to request_irq. Change the printk messages into dev_warn(). Make sure free_irq is called in the detach. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 219ad6c..7d22aea 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -1781,8 +1781,6 @@ static int me4000_attach_pci(struct comedi_device *dev, if (!info->plx_regbase || !dev->iobase || !info->timer_regbase) return -ENODEV; - dev->irq = pcidev->irq; - result = xilinx_download(dev); if (result) return result; @@ -1811,23 +1809,22 @@ static int me4000_attach_pci(struct comedi_device *dev, s->range_table = &me4000_ai_range; s->insn_read = me4000_ai_insn_read; - if (dev->irq > 0) { - if (request_irq(dev->irq, me4000_ai_isr, - IRQF_SHARED, "ME-4000", dev)) { - printk - ("comedi%d: me4000: me4000_attach(): " - "Unable to allocate irq\n", dev->minor); + if (pcidev->irq > 0) { + if (request_irq(pcidev->irq, me4000_ai_isr, + IRQF_SHARED, dev->board_name, dev)) { + dev_warn(dev->class_dev, + "request_irq failed\n"); } else { dev->read_subdev = s; s->subdev_flags |= SDF_CMD_READ; s->cancel = me4000_ai_cancel; s->do_cmdtest = me4000_ai_do_cmd_test; s->do_cmd = me4000_ai_do_cmd; + + dev->irq = pcidev->irq; } } else { - printk(KERN_WARNING - "comedi%d: me4000: me4000_attach(): " - "No interrupt available\n", dev->minor); + dev_warn(dev->class_dev, "No interrupt available\n"); } } else { s->type = COMEDI_SUBD_UNUSED; @@ -1904,6 +1901,8 @@ static void me4000_detach(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); + if (dev->irq) + free_irq(dev->irq, dev); if (pcidev) { if (dev->iobase) { reset_board(dev); -- cgit v0.10.2 From 2f348ecd2b2a3e014908a820a420e22431650c93 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:49:05 -0700 Subject: staging: comedi: me4000: add namespace to reset_board() Rename reset_board() to me4000_reset() so it has namespace associated with this driver. Change it's return type to void, it always succeeds. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 7d22aea..8f8e0b8 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -308,7 +308,7 @@ static int xilinx_download(struct comedi_device *dev) return 0; } -static int reset_board(struct comedi_device *dev) +static void me4000_reset(struct comedi_device *dev) { struct me4000_info *info = dev->private; unsigned long val; @@ -347,8 +347,6 @@ static int reset_board(struct comedi_device *dev) */ if (!(inl(dev->iobase + ME4000_DIO_DIR_REG) & 0x1)) outl(0x1, dev->iobase + ME4000_DIO_CTRL_REG); - - return 0; } /*============================================================================= @@ -1785,9 +1783,7 @@ static int me4000_attach_pci(struct comedi_device *dev, if (result) return result; - result = reset_board(dev); - if (result) - return result; + me4000_reset(dev); result = comedi_alloc_subdevices(dev, 4); if (result) @@ -1905,7 +1901,7 @@ static void me4000_detach(struct comedi_device *dev) free_irq(dev->irq, dev); if (pcidev) { if (dev->iobase) { - reset_board(dev); + me4000_reset(dev); comedi_pci_disable(pcidev); } } -- cgit v0.10.2 From db9132e03054f1332952961ecc0db4fa955a46a5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:49:21 -0700 Subject: staging: comedi: me4000: use the 8253 helper functions The counter subdevice of this board is a standard 8254 compatible counter/timer. Instead of open-coding the 8254 timer io, use the helper functions provided by 8253.h. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 8f8e0b8..27535cc 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -52,6 +52,7 @@ broken. #include #include +#include "8253.h" #include "me4000.h" #if 0 /* file removed due to GPL incompatibility */ @@ -1513,28 +1514,8 @@ static int cnt_reset(struct comedi_device *dev, unsigned int channel) { struct me4000_info *info = dev->private; - switch (channel) { - case 0: - outb(0x30, info->timer_regbase + ME4000_CNT_CTRL_REG); - outb(0x00, info->timer_regbase + ME4000_CNT_COUNTER_0_REG); - outb(0x00, info->timer_regbase + ME4000_CNT_COUNTER_0_REG); - break; - case 1: - outb(0x70, info->timer_regbase + ME4000_CNT_CTRL_REG); - outb(0x00, info->timer_regbase + ME4000_CNT_COUNTER_1_REG); - outb(0x00, info->timer_regbase + ME4000_CNT_COUNTER_1_REG); - break; - case 2: - outb(0xB0, info->timer_regbase + ME4000_CNT_CTRL_REG); - outb(0x00, info->timer_regbase + ME4000_CNT_COUNTER_2_REG); - outb(0x00, info->timer_regbase + ME4000_CNT_COUNTER_2_REG); - break; - default: - printk(KERN_ERR - "comedi%d: me4000: cnt_reset(): Invalid channel\n", - dev->minor); - return -EINVAL; - } + i8254_load(info->timer_regbase, 0, channel, 0, + I8254_MODE0 | I8254_BINARY); return 0; } @@ -1543,54 +1524,9 @@ static int cnt_config(struct comedi_device *dev, unsigned int channel, unsigned int mode) { struct me4000_info *info = dev->private; - int tmp = 0; - - switch (channel) { - case 0: - tmp |= ME4000_CNT_COUNTER_0; - break; - case 1: - tmp |= ME4000_CNT_COUNTER_1; - break; - case 2: - tmp |= ME4000_CNT_COUNTER_2; - break; - default: - printk(KERN_ERR - "comedi%d: me4000: cnt_config(): Invalid channel\n", - dev->minor); - return -EINVAL; - } - - switch (mode) { - case 0: - tmp |= ME4000_CNT_MODE_0; - break; - case 1: - tmp |= ME4000_CNT_MODE_1; - break; - case 2: - tmp |= ME4000_CNT_MODE_2; - break; - case 3: - tmp |= ME4000_CNT_MODE_3; - break; - case 4: - tmp |= ME4000_CNT_MODE_4; - break; - case 5: - tmp |= ME4000_CNT_MODE_5; - break; - default: - printk(KERN_ERR - "comedi%d: me4000: cnt_config(): Invalid counter mode\n", - dev->minor); - return -EINVAL; - } - /* Write the control word */ - tmp |= 0x30; - outb(tmp, info->timer_regbase + ME4000_CNT_CTRL_REG); + i8254_set_mode(info->timer_regbase, 0, channel, + (mode << 1) | I8254_BINARY); return 0; } @@ -1644,7 +1580,6 @@ static int me4000_cnt_insn_read(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { struct me4000_info *info = dev->private; - unsigned short tmp; if (insn->n == 0) return 0; @@ -1657,32 +1592,7 @@ static int me4000_cnt_insn_read(struct comedi_device *dev, return -EINVAL; } - switch (insn->chanspec) { - case 0: - tmp = inb(info->timer_regbase + ME4000_CNT_COUNTER_0_REG); - data[0] = tmp; - tmp = inb(info->timer_regbase + ME4000_CNT_COUNTER_0_REG); - data[0] |= tmp << 8; - break; - case 1: - tmp = inb(info->timer_regbase + ME4000_CNT_COUNTER_1_REG); - data[0] = tmp; - tmp = inb(info->timer_regbase + ME4000_CNT_COUNTER_1_REG); - data[0] |= tmp << 8; - break; - case 2: - tmp = inb(info->timer_regbase + ME4000_CNT_COUNTER_2_REG); - data[0] = tmp; - tmp = inb(info->timer_regbase + ME4000_CNT_COUNTER_2_REG); - data[0] |= tmp << 8; - break; - default: - printk(KERN_ERR - "comedi%d: me4000: me4000_cnt_insn_read(): " - "Invalid channel %d\n", - dev->minor, insn->chanspec); - return -EINVAL; - } + data[0] = i8254_read(info->timer_regbase, 0, insn->chanspec); return 1; } @@ -1692,7 +1602,6 @@ static int me4000_cnt_insn_write(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { struct me4000_info *info = dev->private; - unsigned short tmp; if (insn->n == 0) { return 0; @@ -1704,32 +1613,7 @@ static int me4000_cnt_insn_write(struct comedi_device *dev, return -EINVAL; } - switch (insn->chanspec) { - case 0: - tmp = data[0] & 0xFF; - outb(tmp, info->timer_regbase + ME4000_CNT_COUNTER_0_REG); - tmp = (data[0] >> 8) & 0xFF; - outb(tmp, info->timer_regbase + ME4000_CNT_COUNTER_0_REG); - break; - case 1: - tmp = data[0] & 0xFF; - outb(tmp, info->timer_regbase + ME4000_CNT_COUNTER_1_REG); - tmp = (data[0] >> 8) & 0xFF; - outb(tmp, info->timer_regbase + ME4000_CNT_COUNTER_1_REG); - break; - case 2: - tmp = data[0] & 0xFF; - outb(tmp, info->timer_regbase + ME4000_CNT_COUNTER_2_REG); - tmp = (data[0] >> 8) & 0xFF; - outb(tmp, info->timer_regbase + ME4000_CNT_COUNTER_2_REG); - break; - default: - printk(KERN_ERR - "comedi%d: me4000: me4000_cnt_insn_write(): " - "Invalid channel %d\n", - dev->minor, insn->chanspec); - return -EINVAL; - } + i8254_write(info->timer_regbase, 0, insn->chanspec, data[0]); return 1; } -- cgit v0.10.2 From 83eef17c7845d08eb40e5792ed40b387eb555bdd Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:49:37 -0700 Subject: staging: comedi: me4000: cleanup me4000_cnt_insn_config() Absorb the cnt_reset and cnt_config helper functions. They are now both just single line routines. Remove the printk noise about "Invalid instruction length". Fix the return value, the value should be the number of data values used to perform the instruction. The GPCT_RESET instruction only has one parameter. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 27535cc..4ba0835 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -1510,69 +1510,38 @@ static int me4000_dio_insn_config(struct comedi_device *dev, Counter section ===========================================================================*/ -static int cnt_reset(struct comedi_device *dev, unsigned int channel) -{ - struct me4000_info *info = dev->private; - - i8254_load(info->timer_regbase, 0, channel, 0, - I8254_MODE0 | I8254_BINARY); - - return 0; -} - -static int cnt_config(struct comedi_device *dev, unsigned int channel, - unsigned int mode) -{ - struct me4000_info *info = dev->private; - - i8254_set_mode(info->timer_regbase, 0, channel, - (mode << 1) | I8254_BINARY); - - return 0; -} - static int me4000_cnt_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_insn *insn, + unsigned int *data) { - + struct me4000_info *info = dev->private; int err; switch (data[0]) { case GPCT_RESET: - if (insn->n != 1) { - printk(KERN_ERR - "comedi%d: me4000: me4000_cnt_insn_config(): " - "Invalid instruction length%d\n", - dev->minor, insn->n); + if (insn->n != 1) return -EINVAL; - } - err = cnt_reset(dev, insn->chanspec); + err = i8254_load(info->timer_regbase, 0, insn->chanspec, 0, + I8254_MODE0 | I8254_BINARY); if (err) return err; break; case GPCT_SET_OPERATION: - if (insn->n != 2) { - printk(KERN_ERR - "comedi%d: me4000: me4000_cnt_insn_config(): " - "Invalid instruction length%d\n", - dev->minor, insn->n); + if (insn->n != 2) return -EINVAL; - } - err = cnt_config(dev, insn->chanspec, data[1]); + err = i8254_set_mode(info->timer_regbase, 0, insn->chanspec, + (data[1] << 1) | I8254_BINARY); if (err) return err; break; default: - printk(KERN_ERR - "comedi%d: me4000: me4000_cnt_insn_config(): " - "Invalid instruction\n", dev->minor); return -EINVAL; } - return 2; + return insn->n; } static int me4000_cnt_insn_read(struct comedi_device *dev, -- cgit v0.10.2 From 523c5d8e699bbfb576dc33a12524d0e8ae0bbc78 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:50:01 -0700 Subject: staging: comedi: me4000: remove ME4000_CNT_* defines Since this driver is using the 8253.h helpers, these defines are no longer needed. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.h b/drivers/staging/comedi/drivers/me4000.h index 7feb574..103a2a4 100644 --- a/drivers/staging/comedi/drivers/me4000.h +++ b/drivers/staging/comedi/drivers/me4000.h @@ -71,15 +71,6 @@ #define ME4000_AO_DEMUX_ADJUST_VALUE 0x4C /*============================================================================= - Counter base register offsets - ===========================================================================*/ - -#define ME4000_CNT_COUNTER_0_REG 0x00 -#define ME4000_CNT_COUNTER_1_REG 0x01 -#define ME4000_CNT_COUNTER_2_REG 0x02 -#define ME4000_CNT_CTRL_REG 0x03 - -/*============================================================================= PLX base register offsets ===========================================================================*/ @@ -248,19 +239,4 @@ struct me4000_info { #define ME4000_AI_LIST_LAST_ENTRY 0x100 -/*----------------------------------------------------------------------------- - Defines for counters - ----------------------------------------------------------------------------*/ - -#define ME4000_CNT_COUNTER_0 0x00 -#define ME4000_CNT_COUNTER_1 0x40 -#define ME4000_CNT_COUNTER_2 0x80 - -#define ME4000_CNT_MODE_0 0x00 /* Change state if zero crossing */ -#define ME4000_CNT_MODE_1 0x02 /* Retriggerable One-Shot */ -#define ME4000_CNT_MODE_2 0x04 /* Asymmetrical divider */ -#define ME4000_CNT_MODE_3 0x06 /* Symmetrical divider */ -#define ME4000_CNT_MODE_4 0x08 /* Counter start by software trigger */ -#define ME4000_CNT_MODE_5 0x0A /* Counter start by hardware trigger */ - #endif -- cgit v0.10.2 From cc6f3336fa8f8730ec517d2677849ceb256c5b70 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:50:19 -0700 Subject: staging: comedi: me4000: move struct me4000_info definition Move the struct me4000_info definition from the header to the c file. This struct is not used by any other file. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 4ba0835..6247ee3 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -75,6 +75,13 @@ broken. #define PCI_DEVICE_ID_MEILHAUS_ME4680S 0x4682 #define PCI_DEVICE_ID_MEILHAUS_ME4680IS 0x4683 +struct me4000_info { + unsigned long plx_regbase; + unsigned long timer_regbase; + + unsigned int ao_readback[4]; +}; + struct me4000_board { const char *name; unsigned short device_id; diff --git a/drivers/staging/comedi/drivers/me4000.h b/drivers/staging/comedi/drivers/me4000.h index 103a2a4..2478933 100644 --- a/drivers/staging/comedi/drivers/me4000.h +++ b/drivers/staging/comedi/drivers/me4000.h @@ -204,17 +204,6 @@ #define ME4000_DIO_CTRL_BIT_FIFO_HIGH_2 0x1000 #define ME4000_DIO_CTRL_BIT_FIFO_HIGH_3 0x2000 -/*============================================================================= - Global board and subdevice information structures - ===========================================================================*/ - -struct me4000_info { - unsigned long plx_regbase; /* PLX configuration space base address */ - unsigned long timer_regbase; /* Base address of the timer circuit */ - - unsigned int ao_readback[4]; -}; - /*----------------------------------------------------------------------------- Defines for analog input ----------------------------------------------------------------------------*/ -- cgit v0.10.2 From 81dd181161b88c28d212727120149f959da4bacf Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:50:39 -0700 Subject: staging: comedi: me4000: remove me4000.h Move the remaining defines in this header to the c file. Nothing in the header is needed by any other file. While moving the defines, reorder them so that the bit defines are associated with the register they go with. Also, convert the bit defines to bit shifts to make them a bit clearer. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 6247ee3..bb724b1 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -53,7 +53,7 @@ broken. #include #include "8253.h" -#include "me4000.h" + #if 0 /* file removed due to GPL incompatibility */ #include "me4000_fw.h" @@ -75,6 +75,144 @@ broken. #define PCI_DEVICE_ID_MEILHAUS_ME4680S 0x4682 #define PCI_DEVICE_ID_MEILHAUS_ME4680IS 0x4683 +/* + * ME4000 Register map and bit defines + */ +#define ME4000_AO_CHAN(x) ((x) * 0x18) + +#define ME4000_AO_CTRL_REG(x) (0x00 + ME4000_AO_CHAN(x)) +#define ME4000_AO_CTRL_BIT_MODE_0 (1 << 0) +#define ME4000_AO_CTRL_BIT_MODE_1 (1 << 1) +#define ME4000_AO_CTRL_MASK_MODE (3 << 0) +#define ME4000_AO_CTRL_BIT_STOP (1 << 2) +#define ME4000_AO_CTRL_BIT_ENABLE_FIFO (1 << 3) +#define ME4000_AO_CTRL_BIT_ENABLE_EX_TRIG (1 << 4) +#define ME4000_AO_CTRL_BIT_EX_TRIG_EDGE (1 << 5) +#define ME4000_AO_CTRL_BIT_IMMEDIATE_STOP (1 << 7) +#define ME4000_AO_CTRL_BIT_ENABLE_DO (1 << 8) +#define ME4000_AO_CTRL_BIT_ENABLE_IRQ (1 << 9) +#define ME4000_AO_CTRL_BIT_RESET_IRQ (1 << 10) +#define ME4000_AO_STATUS_REG(x) (0x04 + ME4000_AO_CHAN(x)) +#define ME4000_AO_STATUS_BIT_FSM (1 << 0) +#define ME4000_AO_STATUS_BIT_FF (1 << 1) +#define ME4000_AO_STATUS_BIT_HF (1 << 2) +#define ME4000_AO_STATUS_BIT_EF (1 << 3) +#define ME4000_AO_FIFO_REG(x) (0x08 + ME4000_AO_CHAN(x)) +#define ME4000_AO_SINGLE_REG(x) (0x0c + ME4000_AO_CHAN(x)) +#define ME4000_AO_TIMER_REG(x) (0x10 + ME4000_AO_CHAN(x)) +#define ME4000_AI_CTRL_REG 0x74 +#define ME4000_AI_STATUS_REG 0x74 +#define ME4000_AI_CTRL_BIT_MODE_0 (1 << 0) +#define ME4000_AI_CTRL_BIT_MODE_1 (1 << 1) +#define ME4000_AI_CTRL_BIT_MODE_2 (1 << 2) +#define ME4000_AI_CTRL_BIT_SAMPLE_HOLD (1 << 3) +#define ME4000_AI_CTRL_BIT_IMMEDIATE_STOP (1 << 4) +#define ME4000_AI_CTRL_BIT_STOP (1 << 5) +#define ME4000_AI_CTRL_BIT_CHANNEL_FIFO (1 << 6) +#define ME4000_AI_CTRL_BIT_DATA_FIFO (1 << 7) +#define ME4000_AI_CTRL_BIT_FULLSCALE (1 << 8) +#define ME4000_AI_CTRL_BIT_OFFSET (1 << 9) +#define ME4000_AI_CTRL_BIT_EX_TRIG_ANALOG (1 << 10) +#define ME4000_AI_CTRL_BIT_EX_TRIG (1 << 11) +#define ME4000_AI_CTRL_BIT_EX_TRIG_FALLING (1 << 12) +#define ME4000_AI_CTRL_BIT_EX_IRQ (1 << 13) +#define ME4000_AI_CTRL_BIT_EX_IRQ_RESET (1 << 14) +#define ME4000_AI_CTRL_BIT_LE_IRQ (1 << 15) +#define ME4000_AI_CTRL_BIT_LE_IRQ_RESET (1 << 16) +#define ME4000_AI_CTRL_BIT_HF_IRQ (1 << 17) +#define ME4000_AI_CTRL_BIT_HF_IRQ_RESET (1 << 18) +#define ME4000_AI_CTRL_BIT_SC_IRQ (1 << 19) +#define ME4000_AI_CTRL_BIT_SC_IRQ_RESET (1 << 20) +#define ME4000_AI_CTRL_BIT_SC_RELOAD (1 << 21) +#define ME4000_AI_STATUS_BIT_EF_CHANNEL (1 << 22) +#define ME4000_AI_STATUS_BIT_HF_CHANNEL (1 << 23) +#define ME4000_AI_STATUS_BIT_FF_CHANNEL (1 << 24) +#define ME4000_AI_STATUS_BIT_EF_DATA (1 << 25) +#define ME4000_AI_STATUS_BIT_HF_DATA (1 << 26) +#define ME4000_AI_STATUS_BIT_FF_DATA (1 << 27) +#define ME4000_AI_STATUS_BIT_LE (1 << 28) +#define ME4000_AI_STATUS_BIT_FSM (1 << 29) +#define ME4000_AI_CTRL_BIT_EX_TRIG_BOTH (1 << 31) +#define ME4000_AI_CHANNEL_LIST_REG 0x78 +#define ME4000_AI_LIST_INPUT_SINGLE_ENDED (0 << 5) +#define ME4000_AI_LIST_INPUT_DIFFERENTIAL (1 << 5) +#define ME4000_AI_LIST_RANGE_BIPOLAR_10 (0 << 6) +#define ME4000_AI_LIST_RANGE_BIPOLAR_2_5 (1 << 6) +#define ME4000_AI_LIST_RANGE_UNIPOLAR_10 (2 << 6) +#define ME4000_AI_LIST_RANGE_UNIPOLAR_2_5 (3 << 6) +#define ME4000_AI_LIST_LAST_ENTRY (1 << 8) +#define ME4000_AI_DATA_REG 0x7c +#define ME4000_AI_CHAN_TIMER_REG 0x80 +#define ME4000_AI_CHAN_PRE_TIMER_REG 0x84 +#define ME4000_AI_SCAN_TIMER_LOW_REG 0x88 +#define ME4000_AI_SCAN_TIMER_HIGH_REG 0x8c +#define ME4000_AI_SCAN_PRE_TIMER_LOW_REG 0x90 +#define ME4000_AI_SCAN_PRE_TIMER_HIGH_REG 0x94 +#define ME4000_AI_START_REG 0x98 +#define ME4000_IRQ_STATUS_REG 0x9c +#define ME4000_IRQ_STATUS_BIT_EX (1 << 0) +#define ME4000_IRQ_STATUS_BIT_LE (1 << 1) +#define ME4000_IRQ_STATUS_BIT_AI_HF (1 << 2) +#define ME4000_IRQ_STATUS_BIT_AO_0_HF (1 << 3) +#define ME4000_IRQ_STATUS_BIT_AO_1_HF (1 << 4) +#define ME4000_IRQ_STATUS_BIT_AO_2_HF (1 << 5) +#define ME4000_IRQ_STATUS_BIT_AO_3_HF (1 << 6) +#define ME4000_IRQ_STATUS_BIT_SC (1 << 7) +#define ME4000_DIO_PORT_0_REG 0xa0 +#define ME4000_DIO_PORT_1_REG 0xa4 +#define ME4000_DIO_PORT_2_REG 0xa8 +#define ME4000_DIO_PORT_3_REG 0xac +#define ME4000_DIO_DIR_REG 0xb0 +#define ME4000_AO_LOADSETREG_XX 0xb4 +#define ME4000_DIO_CTRL_REG 0xb8 +#define ME4000_DIO_CTRL_BIT_MODE_0 (1 << 0) +#define ME4000_DIO_CTRL_BIT_MODE_1 (1 << 1) +#define ME4000_DIO_CTRL_BIT_MODE_2 (1 << 2) +#define ME4000_DIO_CTRL_BIT_MODE_3 (1 << 3) +#define ME4000_DIO_CTRL_BIT_MODE_4 (1 << 4) +#define ME4000_DIO_CTRL_BIT_MODE_5 (1 << 5) +#define ME4000_DIO_CTRL_BIT_MODE_6 (1 << 6) +#define ME4000_DIO_CTRL_BIT_MODE_7 (1 << 7) +#define ME4000_DIO_CTRL_BIT_FUNCTION_0 (1 << 8) +#define ME4000_DIO_CTRL_BIT_FUNCTION_1 (1 << 9) +#define ME4000_DIO_CTRL_BIT_FIFO_HIGH_0 (1 << 10) +#define ME4000_DIO_CTRL_BIT_FIFO_HIGH_1 (1 << 11) +#define ME4000_DIO_CTRL_BIT_FIFO_HIGH_2 (1 << 12) +#define ME4000_DIO_CTRL_BIT_FIFO_HIGH_3 (1 << 13) +#define ME4000_AO_DEMUX_ADJUST_REG 0xbc +#define ME4000_AO_DEMUX_ADJUST_VALUE 0x4c +#define ME4000_AI_SAMPLE_COUNTER_REG 0xc0 + +/* + * PLX Register map and bit defines + */ +#define PLX_INTCSR 0x4c +#define PLX_INTCSR_LOCAL_INT1_EN (1 << 0) +#define PLX_INTCSR_LOCAL_INT1_POL (1 << 1) +#define PLX_INTCSR_LOCAL_INT1_STATE (1 << 2) +#define PLX_INTCSR_LOCAL_INT2_EN (1 << 3) +#define PLX_INTCSR_LOCAL_INT2_POL (1 << 4) +#define PLX_INTCSR_LOCAL_INT2_STATE (1 << 5) +#define PLX_INTCSR_PCI_INT_EN (1 << 6) +#define PLX_INTCSR_SOFT_INT (1 << 7) +#define PLX_ICR 0x50 +#define PLX_ICR_BIT_EEPROM_CLOCK_SET (1 << 24) +#define PLX_ICR_BIT_EEPROM_CHIP_SELECT (1 << 25) +#define PLX_ICR_BIT_EEPROM_WRITE (1 << 26) +#define PLX_ICR_BIT_EEPROM_READ (1 << 27) +#define PLX_ICR_BIT_EEPROM_VALID (1 << 28) +#define PLX_ICR_MASK_EEPROM (0x1f << 24) + +#define EEPROM_DELAY 1 + +#define ME4000_AI_FIFO_COUNT 2048 + +#define ME4000_AI_MIN_TICKS 66 +#define ME4000_AI_MIN_SAMPLE_TIME 2000 +#define ME4000_AI_BASE_FREQUENCY (unsigned int) 33E6 + +#define ME4000_AI_CHANNEL_LIST_COUNT 1024 + struct me4000_info { unsigned long plx_regbase; unsigned long timer_regbase; diff --git a/drivers/staging/comedi/drivers/me4000.h b/drivers/staging/comedi/drivers/me4000.h deleted file mode 100644 index 2478933..0000000 --- a/drivers/staging/comedi/drivers/me4000.h +++ /dev/null @@ -1,231 +0,0 @@ -/* - me4000.h - Register descriptions and defines for the ME-4000 board family - - COMEDI - Linux Control and Measurement Device Interface - Copyright (C) 1998-9 David A. Schleef - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef _ME4000_H_ -#define _ME4000_H_ - -/*============================================================================= - ME-4000 base register offsets - ===========================================================================*/ - -#define ME4000_AO_CHAN(x) ((x) * 0x18) - -#define ME4000_AO_CTRL_REG(x) (0x00 + ME4000_AO_CHAN(x)) -#define ME4000_AO_STATUS_REG(x) (0x04 + ME4000_AO_CHAN(x)) -#define ME4000_AO_FIFO_REG(x) (0x08 + ME4000_AO_CHAN(x)) -#define ME4000_AO_SINGLE_REG(x) (0x0c + ME4000_AO_CHAN(x)) -#define ME4000_AO_TIMER_REG(x) (0x10 + ME4000_AO_CHAN(x)) - -#define ME4000_AI_CTRL_REG 0x74 /* _/W */ -#define ME4000_AI_STATUS_REG 0x74 /* R/_ */ -#define ME4000_AI_CHANNEL_LIST_REG 0x78 /* _/W */ -#define ME4000_AI_DATA_REG 0x7C /* R/_ */ -#define ME4000_AI_CHAN_TIMER_REG 0x80 /* _/W */ -#define ME4000_AI_CHAN_PRE_TIMER_REG 0x84 /* _/W */ -#define ME4000_AI_SCAN_TIMER_LOW_REG 0x88 /* _/W */ -#define ME4000_AI_SCAN_TIMER_HIGH_REG 0x8C /* _/W */ -#define ME4000_AI_SCAN_PRE_TIMER_LOW_REG 0x90 /* _/W */ -#define ME4000_AI_SCAN_PRE_TIMER_HIGH_REG 0x94 /* _/W */ -#define ME4000_AI_START_REG 0x98 /* R/_ */ - -#define ME4000_IRQ_STATUS_REG 0x9C /* R/_ */ - -#define ME4000_DIO_PORT_0_REG 0xA0 /* R/W */ -#define ME4000_DIO_PORT_1_REG 0xA4 /* R/W */ -#define ME4000_DIO_PORT_2_REG 0xA8 /* R/W */ -#define ME4000_DIO_PORT_3_REG 0xAC /* R/W */ -#define ME4000_DIO_DIR_REG 0xB0 /* R/W */ - -#define ME4000_AO_LOADSETREG_XX 0xB4 /* R/W */ - -#define ME4000_DIO_CTRL_REG 0xB8 /* R/W */ - -#define ME4000_AO_DEMUX_ADJUST_REG 0xBC /* -/W */ - -#define ME4000_AI_SAMPLE_COUNTER_REG 0xC0 /* _/W */ - -/*============================================================================= - Value to adjust Demux - ===========================================================================*/ - -#define ME4000_AO_DEMUX_ADJUST_VALUE 0x4C - -/*============================================================================= - PLX base register offsets - ===========================================================================*/ - -#define PLX_INTCSR 0x4C /* Interrupt control and status register */ -#define PLX_ICR 0x50 /* Initialization control register */ - -/*============================================================================= - Bits for the PLX_ICSR register - ===========================================================================*/ - -#define PLX_INTCSR_LOCAL_INT1_EN 0x01 /* If set, local interrupt 1 is enabled (r/w) */ -#define PLX_INTCSR_LOCAL_INT1_POL 0x02 /* If set, local interrupt 1 polarity is active high (r/w) */ -#define PLX_INTCSR_LOCAL_INT1_STATE 0x04 /* If set, local interrupt 1 is active (r/_) */ -#define PLX_INTCSR_LOCAL_INT2_EN 0x08 /* If set, local interrupt 2 is enabled (r/w) */ -#define PLX_INTCSR_LOCAL_INT2_POL 0x10 /* If set, local interrupt 2 polarity is active high (r/w) */ -#define PLX_INTCSR_LOCAL_INT2_STATE 0x20 /* If set, local interrupt 2 is active (r/_) */ -#define PLX_INTCSR_PCI_INT_EN 0x40 /* If set, PCI interrupt is enabled (r/w) */ -#define PLX_INTCSR_SOFT_INT 0x80 /* If set, a software interrupt is generated (r/w) */ - -/*============================================================================= - Bits for the PLX_ICR register - ===========================================================================*/ - -#define PLX_ICR_BIT_EEPROM_CLOCK_SET 0x01000000 -#define PLX_ICR_BIT_EEPROM_CHIP_SELECT 0x02000000 -#define PLX_ICR_BIT_EEPROM_WRITE 0x04000000 -#define PLX_ICR_BIT_EEPROM_READ 0x08000000 -#define PLX_ICR_BIT_EEPROM_VALID 0x10000000 - -#define PLX_ICR_MASK_EEPROM 0x1F000000 - -#define EEPROM_DELAY 1 - -/*============================================================================= - Bits for the ME4000_AO_CTRL_REG register - ===========================================================================*/ - -#define ME4000_AO_CTRL_BIT_MODE_0 0x001 -#define ME4000_AO_CTRL_BIT_MODE_1 0x002 -#define ME4000_AO_CTRL_MASK_MODE 0x003 -#define ME4000_AO_CTRL_BIT_STOP 0x004 -#define ME4000_AO_CTRL_BIT_ENABLE_FIFO 0x008 -#define ME4000_AO_CTRL_BIT_ENABLE_EX_TRIG 0x010 -#define ME4000_AO_CTRL_BIT_EX_TRIG_EDGE 0x020 -#define ME4000_AO_CTRL_BIT_IMMEDIATE_STOP 0x080 -#define ME4000_AO_CTRL_BIT_ENABLE_DO 0x100 -#define ME4000_AO_CTRL_BIT_ENABLE_IRQ 0x200 -#define ME4000_AO_CTRL_BIT_RESET_IRQ 0x400 - -/*============================================================================= - Bits for the ME4000_AO_STATUS_REG register - ===========================================================================*/ - -#define ME4000_AO_STATUS_BIT_FSM 0x01 -#define ME4000_AO_STATUS_BIT_FF 0x02 -#define ME4000_AO_STATUS_BIT_HF 0x04 -#define ME4000_AO_STATUS_BIT_EF 0x08 - -/*============================================================================= - Bits for the ME4000_AI_CTRL_REG register - ===========================================================================*/ - -#define ME4000_AI_CTRL_BIT_MODE_0 0x00000001 -#define ME4000_AI_CTRL_BIT_MODE_1 0x00000002 -#define ME4000_AI_CTRL_BIT_MODE_2 0x00000004 -#define ME4000_AI_CTRL_BIT_SAMPLE_HOLD 0x00000008 -#define ME4000_AI_CTRL_BIT_IMMEDIATE_STOP 0x00000010 -#define ME4000_AI_CTRL_BIT_STOP 0x00000020 -#define ME4000_AI_CTRL_BIT_CHANNEL_FIFO 0x00000040 -#define ME4000_AI_CTRL_BIT_DATA_FIFO 0x00000080 -#define ME4000_AI_CTRL_BIT_FULLSCALE 0x00000100 -#define ME4000_AI_CTRL_BIT_OFFSET 0x00000200 -#define ME4000_AI_CTRL_BIT_EX_TRIG_ANALOG 0x00000400 -#define ME4000_AI_CTRL_BIT_EX_TRIG 0x00000800 -#define ME4000_AI_CTRL_BIT_EX_TRIG_FALLING 0x00001000 -#define ME4000_AI_CTRL_BIT_EX_IRQ 0x00002000 -#define ME4000_AI_CTRL_BIT_EX_IRQ_RESET 0x00004000 -#define ME4000_AI_CTRL_BIT_LE_IRQ 0x00008000 -#define ME4000_AI_CTRL_BIT_LE_IRQ_RESET 0x00010000 -#define ME4000_AI_CTRL_BIT_HF_IRQ 0x00020000 -#define ME4000_AI_CTRL_BIT_HF_IRQ_RESET 0x00040000 -#define ME4000_AI_CTRL_BIT_SC_IRQ 0x00080000 -#define ME4000_AI_CTRL_BIT_SC_IRQ_RESET 0x00100000 -#define ME4000_AI_CTRL_BIT_SC_RELOAD 0x00200000 -#define ME4000_AI_CTRL_BIT_EX_TRIG_BOTH 0x80000000 - -/*============================================================================= - Bits for the ME4000_AI_STATUS_REG register - ===========================================================================*/ - -#define ME4000_AI_STATUS_BIT_EF_CHANNEL 0x00400000 -#define ME4000_AI_STATUS_BIT_HF_CHANNEL 0x00800000 -#define ME4000_AI_STATUS_BIT_FF_CHANNEL 0x01000000 -#define ME4000_AI_STATUS_BIT_EF_DATA 0x02000000 -#define ME4000_AI_STATUS_BIT_HF_DATA 0x04000000 -#define ME4000_AI_STATUS_BIT_FF_DATA 0x08000000 -#define ME4000_AI_STATUS_BIT_LE 0x10000000 -#define ME4000_AI_STATUS_BIT_FSM 0x20000000 - -/*============================================================================= - Bits for the ME4000_IRQ_STATUS_REG register - ===========================================================================*/ - -#define ME4000_IRQ_STATUS_BIT_EX 0x01 -#define ME4000_IRQ_STATUS_BIT_LE 0x02 -#define ME4000_IRQ_STATUS_BIT_AI_HF 0x04 -#define ME4000_IRQ_STATUS_BIT_AO_0_HF 0x08 -#define ME4000_IRQ_STATUS_BIT_AO_1_HF 0x10 -#define ME4000_IRQ_STATUS_BIT_AO_2_HF 0x20 -#define ME4000_IRQ_STATUS_BIT_AO_3_HF 0x40 -#define ME4000_IRQ_STATUS_BIT_SC 0x80 - -/*============================================================================= - Bits for the ME4000_DIO_CTRL_REG register - ===========================================================================*/ - -#define ME4000_DIO_CTRL_BIT_MODE_0 0x0001 -#define ME4000_DIO_CTRL_BIT_MODE_1 0x0002 -#define ME4000_DIO_CTRL_BIT_MODE_2 0x0004 -#define ME4000_DIO_CTRL_BIT_MODE_3 0x0008 -#define ME4000_DIO_CTRL_BIT_MODE_4 0x0010 -#define ME4000_DIO_CTRL_BIT_MODE_5 0x0020 -#define ME4000_DIO_CTRL_BIT_MODE_6 0x0040 -#define ME4000_DIO_CTRL_BIT_MODE_7 0x0080 - -#define ME4000_DIO_CTRL_BIT_FUNCTION_0 0x0100 -#define ME4000_DIO_CTRL_BIT_FUNCTION_1 0x0200 - -#define ME4000_DIO_CTRL_BIT_FIFO_HIGH_0 0x0400 -#define ME4000_DIO_CTRL_BIT_FIFO_HIGH_1 0x0800 -#define ME4000_DIO_CTRL_BIT_FIFO_HIGH_2 0x1000 -#define ME4000_DIO_CTRL_BIT_FIFO_HIGH_3 0x2000 - -/*----------------------------------------------------------------------------- - Defines for analog input - ----------------------------------------------------------------------------*/ - -/* General stuff */ -#define ME4000_AI_FIFO_COUNT 2048 - -#define ME4000_AI_MIN_TICKS 66 -#define ME4000_AI_MIN_SAMPLE_TIME 2000 /* Minimum sample time [ns] */ -#define ME4000_AI_BASE_FREQUENCY (unsigned int) 33E6 - -/* Channel list defines and masks */ -#define ME4000_AI_CHANNEL_LIST_COUNT 1024 - -#define ME4000_AI_LIST_INPUT_SINGLE_ENDED 0x000 -#define ME4000_AI_LIST_INPUT_DIFFERENTIAL 0x020 - -#define ME4000_AI_LIST_RANGE_BIPOLAR_10 0x000 -#define ME4000_AI_LIST_RANGE_BIPOLAR_2_5 0x040 -#define ME4000_AI_LIST_RANGE_UNIPOLAR_10 0x080 -#define ME4000_AI_LIST_RANGE_UNIPOLAR_2_5 0x0C0 - -#define ME4000_AI_LIST_LAST_ENTRY 0x100 - -#endif -- cgit v0.10.2 From 5da80ee8d863c32719e3431054e26a0ef1a02a51 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 Sep 2012 17:50:58 -0700 Subject: staging: comedi: me4000: convert printk's to dev_printk's A lot of the messages produced by this driver are just noise and need to be removed. For now just convert them all to dev_printk's. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index bb724b1..d7c5146 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -399,9 +399,7 @@ static int xilinx_download(struct comedi_device *dev) /* Wait until /INIT pin is set */ udelay(20); if (!(inl(info->plx_regbase + PLX_INTCSR) & 0x20)) { - printk(KERN_ERR - "comedi%d: me4000: xilinx_download(): " - "Can't init Xilinx\n", dev->minor); + dev_err(dev->class_dev, "Can't init Xilinx\n"); return -EIO; } @@ -410,8 +408,8 @@ static int xilinx_download(struct comedi_device *dev) value &= ~0x100; outl(value, info->plx_regbase + PLX_ICR); if (FIRMWARE_NOT_AVAILABLE) { - comedi_error(dev, "xilinx firmware unavailable " - "due to licensing, aborting"); + dev_err(dev->class_dev, + "xilinx firmware unavailable due to licensing, aborting"); return -EIO; } else { /* Download Xilinx firmware */ @@ -425,10 +423,9 @@ static int xilinx_download(struct comedi_device *dev) /* Check if BUSY flag is low */ if (inl(info->plx_regbase + PLX_ICR) & 0x20) { - printk(KERN_ERR - "comedi%d: me4000: xilinx_download(): " - "Xilinx is still busy (idx = %d)\n", - dev->minor, idx); + dev_err(dev->class_dev, + "Xilinx is still busy (idx = %d)\n", + idx); return -EIO; } } @@ -437,12 +434,8 @@ static int xilinx_download(struct comedi_device *dev) /* If done flag is high download was successful */ if (inl(info->plx_regbase + PLX_ICR) & 0x4) { } else { - printk(KERN_ERR - "comedi%d: me4000: xilinx_download(): " - "DONE flag is not set\n", dev->minor); - printk(KERN_ERR - "comedi%d: me4000: xilinx_download(): " - "Download not successful\n", dev->minor); + dev_err(dev->class_dev, "DONE flag is not set\n"); + dev_err(dev->class_dev, "Download not successful\n"); return -EIO; } @@ -515,9 +508,8 @@ static int me4000_ai_insn_read(struct comedi_device *dev, if (insn->n == 0) { return 0; } else if (insn->n > 1) { - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_insn_read(): " - "Invalid instruction length %d\n", dev->minor, insn->n); + dev_err(dev->class_dev, "Invalid instruction length %d\n", + insn->n); return -EINVAL; } @@ -535,9 +527,7 @@ static int me4000_ai_insn_read(struct comedi_device *dev, entry |= ME4000_AI_LIST_RANGE_BIPOLAR_10; break; default: - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_insn_read(): " - "Invalid range specified\n", dev->minor); + dev_err(dev->class_dev, "Invalid range specified\n"); return -EINVAL; } @@ -545,9 +535,8 @@ static int me4000_ai_insn_read(struct comedi_device *dev, case AREF_GROUND: case AREF_COMMON: if (chan >= thisboard->ai_nchan) { - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_insn_read(): " - "Analog input is not available\n", dev->minor); + dev_err(dev->class_dev, + "Analog input is not available\n"); return -EINVAL; } entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED | chan; @@ -555,25 +544,20 @@ static int me4000_ai_insn_read(struct comedi_device *dev, case AREF_DIFF: if (rang == 0 || rang == 1) { - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_insn_read(): " - "Range must be bipolar when aref = diff\n", - dev->minor); + dev_err(dev->class_dev, + "Range must be bipolar when aref = diff\n"); return -EINVAL; } if (chan >= thisboard->ai_diff_nchan) { - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_insn_read(): " - "Analog input is not available\n", dev->minor); + dev_err(dev->class_dev, + "Analog input is not available\n"); return -EINVAL; } entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL | chan; break; default: - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_insn_read(): " - "Invalid aref specified\n", dev->minor); + dev_err(dev->class_dev, "Invalid aref specified\n"); return -EINVAL; } @@ -609,9 +593,7 @@ static int me4000_ai_insn_read(struct comedi_device *dev, udelay(10); if (!(inl(dev->iobase + ME4000_AI_STATUS_REG) & ME4000_AI_STATUS_BIT_EF_DATA)) { - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_insn_read(): " - "Value not available after wait\n", dev->minor); + dev_err(dev->class_dev, "Value not available after wait\n"); return -EIO; } @@ -647,25 +629,19 @@ static int ai_check_chanlist(struct comedi_device *dev, /* Check whether a channel list is available */ if (!cmd->chanlist_len) { - printk(KERN_ERR - "comedi%d: me4000: ai_check_chanlist(): " - "No channel list available\n", dev->minor); + dev_err(dev->class_dev, "No channel list available\n"); return -EINVAL; } /* Check the channel list size */ if (cmd->chanlist_len > ME4000_AI_CHANNEL_LIST_COUNT) { - printk(KERN_ERR - "comedi%d: me4000: ai_check_chanlist(): " - "Channel list is to large\n", dev->minor); + dev_err(dev->class_dev, "Channel list is to large\n"); return -EINVAL; } /* Check the pointer */ if (!cmd->chanlist) { - printk(KERN_ERR - "comedi%d: me4000: ai_check_chanlist(): " - "NULL pointer to channel list\n", dev->minor); + dev_err(dev->class_dev, "NULL pointer to channel list\n"); return -EFAULT; } @@ -673,10 +649,8 @@ static int ai_check_chanlist(struct comedi_device *dev, aref = CR_AREF(cmd->chanlist[0]); for (i = 0; i < cmd->chanlist_len; i++) { if (CR_AREF(cmd->chanlist[i]) != aref) { - printk(KERN_ERR - "comedi%d: me4000: ai_check_chanlist(): " - "Mode is not equal for all entries\n", - dev->minor); + dev_err(dev->class_dev, + "Mode is not equal for all entries\n"); return -EINVAL; } } @@ -686,18 +660,16 @@ static int ai_check_chanlist(struct comedi_device *dev, for (i = 0; i < cmd->chanlist_len; i++) { if (CR_CHAN(cmd->chanlist[i]) >= thisboard->ai_diff_nchan) { - printk(KERN_ERR - "comedi%d: me4000: ai_check_chanlist():" - " Channel number to high\n", dev->minor); + dev_err(dev->class_dev, + "Channel number to high\n"); return -EINVAL; } } } else { for (i = 0; i < cmd->chanlist_len; i++) { if (CR_CHAN(cmd->chanlist[i]) >= thisboard->ai_nchan) { - printk(KERN_ERR - "comedi%d: me4000: ai_check_chanlist(): " - "Channel number to high\n", dev->minor); + dev_err(dev->class_dev, + "Channel number to high\n"); return -EINVAL; } } @@ -708,11 +680,8 @@ static int ai_check_chanlist(struct comedi_device *dev, for (i = 0; i < cmd->chanlist_len; i++) { if (CR_RANGE(cmd->chanlist[i]) != 1 && CR_RANGE(cmd->chanlist[i]) != 2) { - printk(KERN_ERR - "comedi%d: me4000: ai_check_chanlist(): " - "Bipolar is not selected in " - "differential mode\n", - dev->minor); + dev_err(dev->class_dev, + "Bipolar is not selected in differential mode\n"); return -EINVAL; } } @@ -966,9 +935,7 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev, err++; break; default: - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_do_cmd_test(): " - "Invalid start source\n", dev->minor); + dev_err(dev->class_dev, "Invalid start source\n"); cmd->start_src = TRIG_NOW; err++; } @@ -982,9 +949,7 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev, err++; break; default: - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_do_cmd_test(): " - "Invalid scan begin source\n", dev->minor); + dev_err(dev->class_dev, "Invalid scan begin source\n"); cmd->scan_begin_src = TRIG_FOLLOW; err++; } @@ -997,9 +962,7 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev, err++; break; default: - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_do_cmd_test(): " - "Invalid convert source\n", dev->minor); + dev_err(dev->class_dev, "Invalid convert source\n"); cmd->convert_src = TRIG_TIMER; err++; } @@ -1012,9 +975,7 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev, err++; break; default: - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_do_cmd_test(): " - "Invalid scan end source\n", dev->minor); + dev_err(dev->class_dev, "Invalid scan end source\n"); cmd->scan_end_src = TRIG_NONE; err++; } @@ -1027,9 +988,7 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev, err++; break; default: - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_do_cmd_test(): " - "Invalid stop source\n", dev->minor); + dev_err(dev->class_dev, "Invalid stop source\n"); cmd->stop_src = TRIG_NONE; err++; } @@ -1058,9 +1017,7 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev, cmd->scan_begin_src == TRIG_EXT && cmd->convert_src == TRIG_EXT) { } else { - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_do_cmd_test(): " - "Invalid start trigger combination\n", dev->minor); + dev_err(dev->class_dev, "Invalid start trigger combination\n"); cmd->start_src = TRIG_NOW; cmd->scan_begin_src = TRIG_FOLLOW; cmd->convert_src = TRIG_TIMER; @@ -1075,9 +1032,7 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev, } else if (cmd->stop_src == TRIG_COUNT && cmd->scan_end_src == TRIG_COUNT) { } else { - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_do_cmd_test(): " - "Invalid stop trigger combination\n", dev->minor); + dev_err(dev->class_dev, "Invalid stop trigger combination\n"); cmd->stop_src = TRIG_NONE; cmd->scan_end_src = TRIG_NONE; err++; @@ -1089,30 +1044,22 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev, * Stage 3. Check if arguments are generally valid. */ if (cmd->chanlist_len < 1) { - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_do_cmd_test(): " - "No channel list\n", dev->minor); + dev_err(dev->class_dev, "No channel list\n"); cmd->chanlist_len = 1; err++; } if (init_ticks < 66) { - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_do_cmd_test(): " - "Start arg to low\n", dev->minor); + dev_err(dev->class_dev, "Start arg to low\n"); cmd->start_arg = 2000; err++; } if (scan_ticks && scan_ticks < 67) { - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_do_cmd_test(): " - "Scan begin arg to low\n", dev->minor); + dev_err(dev->class_dev, "Scan begin arg to low\n"); cmd->scan_begin_arg = 2031; err++; } if (chan_ticks < 66) { - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_do_cmd_test(): " - "Convert arg to low\n", dev->minor); + dev_err(dev->class_dev, "Convert arg to low\n"); cmd->convert_arg = 2000; err++; } @@ -1129,23 +1076,17 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev, /* Check timer arguments */ if (init_ticks < ME4000_AI_MIN_TICKS) { - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_do_cmd_test(): " - "Invalid start arg\n", dev->minor); + dev_err(dev->class_dev, "Invalid start arg\n"); cmd->start_arg = 2000; /* 66 ticks at least */ err++; } if (chan_ticks < ME4000_AI_MIN_TICKS) { - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_do_cmd_test(): " - "Invalid convert arg\n", dev->minor); + dev_err(dev->class_dev, "Invalid convert arg\n"); cmd->convert_arg = 2000; /* 66 ticks at least */ err++; } if (scan_ticks <= cmd->chanlist_len * chan_ticks) { - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_do_cmd_test(): " - "Invalid scan end arg\n", dev->minor); + dev_err(dev->class_dev, "Invalid scan end arg\n"); /* At least one tick more */ cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31; @@ -1157,16 +1098,12 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev, /* Check timer arguments */ if (init_ticks < ME4000_AI_MIN_TICKS) { - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_do_cmd_test(): " - "Invalid start arg\n", dev->minor); + dev_err(dev->class_dev, "Invalid start arg\n"); cmd->start_arg = 2000; /* 66 ticks at least */ err++; } if (chan_ticks < ME4000_AI_MIN_TICKS) { - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_do_cmd_test(): " - "Invalid convert arg\n", dev->minor); + dev_err(dev->class_dev, "Invalid convert arg\n"); cmd->convert_arg = 2000; /* 66 ticks at least */ err++; } @@ -1176,23 +1113,17 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev, /* Check timer arguments */ if (init_ticks < ME4000_AI_MIN_TICKS) { - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_do_cmd_test(): " - "Invalid start arg\n", dev->minor); + dev_err(dev->class_dev, "Invalid start arg\n"); cmd->start_arg = 2000; /* 66 ticks at least */ err++; } if (chan_ticks < ME4000_AI_MIN_TICKS) { - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_do_cmd_test(): " - "Invalid convert arg\n", dev->minor); + dev_err(dev->class_dev, "Invalid convert arg\n"); cmd->convert_arg = 2000; /* 66 ticks at least */ err++; } if (scan_ticks <= cmd->chanlist_len * chan_ticks) { - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_do_cmd_test(): " - "Invalid scan end arg\n", dev->minor); + dev_err(dev->class_dev, "Invalid scan end arg\n"); /* At least one tick more */ cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31; @@ -1204,16 +1135,12 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev, /* Check timer arguments */ if (init_ticks < ME4000_AI_MIN_TICKS) { - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_do_cmd_test(): " - "Invalid start arg\n", dev->minor); + dev_err(dev->class_dev, "Invalid start arg\n"); cmd->start_arg = 2000; /* 66 ticks at least */ err++; } if (chan_ticks < ME4000_AI_MIN_TICKS) { - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_do_cmd_test(): " - "Invalid convert arg\n", dev->minor); + dev_err(dev->class_dev, "Invalid convert arg\n"); cmd->convert_arg = 2000; /* 66 ticks at least */ err++; } @@ -1223,16 +1150,12 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev, /* Check timer arguments */ if (init_ticks < ME4000_AI_MIN_TICKS) { - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_do_cmd_test(): " - "Invalid start arg\n", dev->minor); + dev_err(dev->class_dev, "Invalid start arg\n"); cmd->start_arg = 2000; /* 66 ticks at least */ err++; } if (chan_ticks < ME4000_AI_MIN_TICKS) { - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_do_cmd_test(): " - "Invalid convert arg\n", dev->minor); + dev_err(dev->class_dev, "Invalid convert arg\n"); cmd->convert_arg = 2000; /* 66 ticks at least */ err++; } @@ -1242,27 +1165,21 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev, /* Check timer arguments */ if (init_ticks < ME4000_AI_MIN_TICKS) { - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_do_cmd_test(): " - "Invalid start arg\n", dev->minor); + dev_err(dev->class_dev, "Invalid start arg\n"); cmd->start_arg = 2000; /* 66 ticks at least */ err++; } } if (cmd->stop_src == TRIG_COUNT) { if (cmd->stop_arg == 0) { - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_do_cmd_test(): " - "Invalid stop arg\n", dev->minor); + dev_err(dev->class_dev, "Invalid stop arg\n"); cmd->stop_arg = 1; err++; } } if (cmd->scan_end_src == TRIG_COUNT) { if (cmd->scan_end_arg == 0) { - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_do_cmd_test(): " - "Invalid scan end arg\n", dev->minor); + dev_err(dev->class_dev, "Invalid scan end arg\n"); cmd->scan_end_arg = 1; err++; } @@ -1297,9 +1214,7 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) /* Check if irq number is right */ if (irq != dev->irq) { - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_isr(): " - "Incorrect interrupt num: %d\n", dev->minor, irq); + dev_err(dev->class_dev, "Incorrect interrupt num: %d\n", irq); return IRQ_HANDLED; } @@ -1324,9 +1239,7 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_isr(): " - "FIFO overflow\n", dev->minor); + dev_err(dev->class_dev, "FIFO overflow\n"); } else if ((tmp & ME4000_AI_STATUS_BIT_FF_DATA) && !(tmp & ME4000_AI_STATUS_BIT_HF_DATA) && (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) { @@ -1334,9 +1247,8 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) c = ME4000_AI_FIFO_COUNT / 2; } else { - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_isr(): " - "Can't determine state of fifo\n", dev->minor); + dev_err(dev->class_dev, + "Can't determine state of fifo\n"); c = 0; /* @@ -1350,9 +1262,7 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_isr(): " - "Undefined FIFO state\n", dev->minor); + dev_err(dev->class_dev, "Undefined FIFO state\n"); } for (i = 0; i < c; i++) { @@ -1372,9 +1282,7 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) s->async->events |= COMEDI_CB_OVERFLOW; - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_isr(): " - "Buffer overflow\n", dev->minor); + dev_err(dev->class_dev, "Buffer overflow\n"); break; } @@ -1408,9 +1316,7 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) lval ^= 0x8000; if (!comedi_buf_put(s->async, lval)) { - printk(KERN_ERR - "comedi%d: me4000: me4000_ai_isr(): " - "Buffer overflow\n", dev->minor); + dev_err(dev->class_dev, "Buffer overflow\n"); s->async->events |= COMEDI_CB_OVERFLOW; break; } @@ -1447,30 +1353,23 @@ static int me4000_ao_insn_write(struct comedi_device *dev, if (insn->n == 0) { return 0; } else if (insn->n > 1) { - printk(KERN_ERR - "comedi%d: me4000: me4000_ao_insn_write(): " - "Invalid instruction length %d\n", dev->minor, insn->n); + dev_err(dev->class_dev, "Invalid instruction length %d\n", + insn->n); return -EINVAL; } if (chan >= thisboard->ao_nchan) { - printk(KERN_ERR - "comedi%d: me4000: me4000_ao_insn_write(): " - "Invalid channel %d\n", dev->minor, insn->n); + dev_err(dev->class_dev, "Invalid channel %d\n", insn->n); return -EINVAL; } if (rang != 0) { - printk(KERN_ERR - "comedi%d: me4000: me4000_ao_insn_write(): " - "Invalid range %d\n", dev->minor, insn->n); + dev_err(dev->class_dev, "Invalid range %d\n", insn->n); return -EINVAL; } if (aref != AREF_GROUND && aref != AREF_COMMON) { - printk(KERN_ERR - "comedi%d: me4000: me4000_ao_insn_write(): " - "Invalid aref %d\n", dev->minor, insn->n); + dev_err(dev->class_dev, "Invalid aref %d\n", insn->n); return -EINVAL; } @@ -1501,9 +1400,7 @@ static int me4000_ao_insn_read(struct comedi_device *dev, if (insn->n == 0) { return 0; } else if (insn->n > 1) { - printk - ("comedi%d: me4000: me4000_ao_insn_read(): " - "Invalid instruction length\n", dev->minor); + dev_err(dev->class_dev, "Invalid instruction length\n"); return -EINVAL; } @@ -1699,10 +1596,8 @@ static int me4000_cnt_insn_read(struct comedi_device *dev, return 0; if (insn->n > 1) { - printk(KERN_ERR - "comedi%d: me4000: me4000_cnt_insn_read(): " - "Invalid instruction length %d\n", - dev->minor, insn->n); + dev_err(dev->class_dev, "Invalid instruction length %d\n", + insn->n); return -EINVAL; } @@ -1720,10 +1615,8 @@ static int me4000_cnt_insn_write(struct comedi_device *dev, if (insn->n == 0) { return 0; } else if (insn->n > 1) { - printk(KERN_ERR - "comedi%d: me4000: me4000_cnt_insn_write(): " - "Invalid instruction length %d\n", - dev->minor, insn->n); + dev_err(dev->class_dev, "Invalid instruction length %d\n", + insn->n); return -EINVAL; } -- cgit v0.10.2 From e89a3370b0aaf197016eceefa2e710517c83e445 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 7 Sep 2012 14:59:15 +0800 Subject: staging: tidspbridge: move the dereference below the NULL test The dereference should be moved below the NULL test. spatch with a semantic match is used to found this. (http://coccinelle.lip6.fr/) Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/tidspbridge/core/chnl_sm.c b/drivers/staging/tidspbridge/core/chnl_sm.c index f38950e..16fa346 100644 --- a/drivers/staging/tidspbridge/core/chnl_sm.c +++ b/drivers/staging/tidspbridge/core/chnl_sm.c @@ -94,7 +94,7 @@ int bridge_chnl_add_io_req(struct chnl_object *chnl_obj, void *host_buf, struct dev_object *dev_obj; u8 dw_state; bool is_eos; - struct chnl_mgr *chnl_mgr_obj = pchnl->chnl_mgr_obj; + struct chnl_mgr *chnl_mgr_obj; u8 *host_sys_buf = NULL; bool sched_dpc = false; u16 mb_val = 0; @@ -153,6 +153,7 @@ func_cont: * If DPC is scheduled in process context (iosm_schedule) and any * non-mailbox interrupt occurs, that DPC will run and break CS. Hence * we disable ALL DPCs. We will try to disable ONLY IO DPC later. */ + chnl_mgr_obj = pchnl->chnl_mgr_obj; spin_lock_bh(&chnl_mgr_obj->chnl_mgr_lock); omap_mbox_disable_irq(dev_ctxt->mbox, IRQ_RX); if (pchnl->chnl_type == CHNL_PCPY) { -- cgit v0.10.2 From 20659455402fca01a92de7a70a45f43785804fa7 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 7 Sep 2012 08:50:54 -0700 Subject: staging: tpci200: fix section mismatch warning PCI probe routines have to be named _probe to avoid section mismatch warning. Found when doing 'make allmodconfig' Signed-off-by: Stephen Hemminger Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index b81a8c9..0d61090 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -560,8 +560,8 @@ static int tpci200_install(struct tpci200_board *tpci200) return 0; } -static int tpci200_pciprobe(struct pci_dev *pdev, - const struct pci_device_id *id) +static int tpci200_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *id) { int ret, i; struct tpci200_board *tpci200; @@ -684,7 +684,7 @@ MODULE_DEVICE_TABLE(pci, tpci200_idtable); static struct pci_driver tpci200_pci_drv = { .name = "tpci200", .id_table = tpci200_idtable, - .probe = tpci200_pciprobe, + .probe = tpci200_pci_probe, .remove = __devexit_p(tpci200_pci_remove), }; -- cgit v0.10.2 From 7892e560d463a556664f82188602ab3425533049 Mon Sep 17 00:00:00 2001 From: Dan Magenheimer Date: Thu, 6 Sep 2012 10:01:14 -0700 Subject: staging: ramster: fix build warnings Fix build warnings resulting from in-progress work that was not entirely ifdef'd out. Signed-off-by: Dan Magenheimer Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ramster/zcache-main.c b/drivers/staging/ramster/zcache-main.c index 86e19d6..a09dd5c 100644 --- a/drivers/staging/ramster/zcache-main.c +++ b/drivers/staging/ramster/zcache-main.c @@ -449,16 +449,18 @@ static struct page *zcache_alloc_page(void) return page; } +#ifdef FRONTSWAP_HAS_UNUSE static void zcache_unacct_page(void) { zcache_pageframes_freed = atomic_inc_return(&zcache_pageframes_freed_atomic); } +#endif static void zcache_free_page(struct page *page) { long curr_pageframes; - static long max_pageframes, min_pageframes, total_freed; + static long max_pageframes, min_pageframes; if (page == NULL) BUG(); @@ -965,9 +967,10 @@ out: return page; } +#ifdef FRONTSWAP_HAS_UNUSE static void unswiz(struct tmem_oid oid, u32 index, unsigned *type, pgoff_t *offset); -#ifdef FRONTSWAP_HAS_UNUSE + /* * Choose an LRU persistent pageframe and attempt to "unuse" it by * calling frontswap_unuse on both zpages. @@ -1060,7 +1063,9 @@ static int shrink_zcache_memory(struct shrinker *shrink, int nr_evict = 0; int nr_unuse = 0; struct page *page; +#ifdef FRONTSWAP_HAS_UNUSE int unuse_ret; +#endif if (nr <= 0) goto skip_evict; @@ -1519,6 +1524,7 @@ static inline struct tmem_oid oswiz(unsigned type, u32 ind) return oid; } +#ifdef FRONTSWAP_HAS_UNUSE static void unswiz(struct tmem_oid oid, u32 index, unsigned *type, pgoff_t *offset) { @@ -1526,6 +1532,7 @@ static void unswiz(struct tmem_oid oid, u32 index, *offset = (pgoff_t)((index << SWIZ_BITS) | (oid.oid[0] & SWIZ_MASK)); } +#endif static int zcache_frontswap_put_page(unsigned type, pgoff_t offset, struct page *page) @@ -1535,7 +1542,6 @@ static int zcache_frontswap_put_page(unsigned type, pgoff_t offset, struct tmem_oid oid = oswiz(type, ind); int ret = -1; unsigned long flags; - int unuse_ret; BUG_ON(!PageLocked(page)); if (!disable_frontswap_ignore_nonactive && !PageWasActive(page)) { -- cgit v0.10.2 From 3ac9e0fd2a7fcd4eccbb79909b421b4284ed9520 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Fri, 7 Sep 2012 00:08:02 +0530 Subject: staging: vt6655: fix coding style warnings a) replace spaces with tabs b) put the opening brace of get_chip_name below it Signed-off-by: Devendra Naga Acked-by: Marcos Paulo de Souza Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 697617f..e0a9c08 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -347,21 +347,22 @@ static int Config_FileGetParameter(unsigned char *string, -static char* get_chip_name(int chip_id) { - int i; - for (i=0;chip_info_table[i].name!=NULL;i++) - if (chip_info_table[i].chip_id==chip_id) - break; - return chip_info_table[i].name; +static char* get_chip_name(int chip_id) +{ + int i; + for (i = 0; chip_info_table[i].name != NULL; i++) + if (chip_info_table[i].chip_id == chip_id) + break; + return chip_info_table[i].name; } static void __devexit vt6655_remove(struct pci_dev *pcid) { - PSDevice pDevice=pci_get_drvdata(pcid); + PSDevice pDevice = pci_get_drvdata(pcid); - if (pDevice==NULL) - return; - device_free_info(pDevice); + if (pDevice == NULL) + return; + device_free_info(pDevice); } -- cgit v0.10.2 From bf76ebd9cfd0018be820657da781201e2f74cf5d Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Fri, 7 Sep 2012 00:08:03 +0530 Subject: staging: vt6655: fix coding style issues in device_get_options a) put the device_get_options functions' opening brace below b) replace spaces with tabs Signed-off-by: Devendra Naga Acked-by: Marcos Paulo de Souza Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index e0a9c08..bb0b0cf 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -398,31 +398,29 @@ device_set_bool_opt(unsigned int *opt, int val,bool def,u32 flag, char* name,cha } } */ -static void -device_get_options(PSDevice pDevice, int index, char* devname) { - - POPTIONS pOpts = &(pDevice->sOpts); - pOpts->nRxDescs0=RX_DESC_DEF0; - pOpts->nRxDescs1=RX_DESC_DEF1; - pOpts->nTxDescs[0]=TX_DESC_DEF0; - pOpts->nTxDescs[1]=TX_DESC_DEF1; -pOpts->flags|=DEVICE_FLAGS_IP_ALIGN; - pOpts->int_works=INT_WORKS_DEF; - pOpts->rts_thresh=RTS_THRESH_DEF; - pOpts->frag_thresh=FRAG_THRESH_DEF; - pOpts->data_rate=DATA_RATE_DEF; - pOpts->channel_num=CHANNEL_DEF; - -pOpts->flags|=DEVICE_FLAGS_PREAMBLE_TYPE; -pOpts->flags|=DEVICE_FLAGS_OP_MODE; -//pOpts->flags|=DEVICE_FLAGS_PS_MODE; - pOpts->short_retry=SHORT_RETRY_DEF; - pOpts->long_retry=LONG_RETRY_DEF; - pOpts->bbp_type=BBP_TYPE_DEF; -pOpts->flags|=DEVICE_FLAGS_80211h_MODE; -pOpts->flags|=DEVICE_FLAGS_DiversityANT; - - +static void device_get_options(PSDevice pDevice, int index, char* devname) +{ + POPTIONS pOpts = &(pDevice->sOpts); + + pOpts->nRxDescs0 = RX_DESC_DEF0; + pOpts->nRxDescs1 = RX_DESC_DEF1; + pOpts->nTxDescs[0] = TX_DESC_DEF0; + pOpts->nTxDescs[1] = TX_DESC_DEF1; + pOpts->flags |= DEVICE_FLAGS_IP_ALIGN; + pOpts->int_works = INT_WORKS_DEF; + pOpts->rts_thresh = RTS_THRESH_DEF; + pOpts->frag_thresh = FRAG_THRESH_DEF; + pOpts->data_rate = DATA_RATE_DEF; + pOpts->channel_num = CHANNEL_DEF; + + pOpts->flags |= DEVICE_FLAGS_PREAMBLE_TYPE; + pOpts->flags |= DEVICE_FLAGS_OP_MODE; + //pOpts->flags|=DEVICE_FLAGS_PS_MODE; + pOpts->short_retry = SHORT_RETRY_DEF; + pOpts->long_retry = LONG_RETRY_DEF; + pOpts->bbp_type = BBP_TYPE_DEF; + pOpts->flags |= DEVICE_FLAGS_80211h_MODE; + pOpts->flags |= DEVICE_FLAGS_DiversityANT; } static void -- cgit v0.10.2 From 502eb5369f51539aaee6ec173165be28d916a3ca Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Fri, 7 Sep 2012 00:08:04 +0530 Subject: staging: vt6655: fix coding style problem at assigning netdev_ops we are using spaces at the beginning of the line, we should use tabs instead Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index bb0b0cf..493866a 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -893,18 +893,15 @@ static bool device_release_WPADEV(PSDevice pDevice) return true; } - static const struct net_device_ops device_netdev_ops = { - .ndo_open = device_open, - .ndo_stop = device_close, - .ndo_do_ioctl = device_ioctl, - .ndo_get_stats = device_get_stats, - .ndo_start_xmit = device_xmit, - .ndo_set_rx_mode = device_set_multi, + .ndo_open = device_open, + .ndo_stop = device_close, + .ndo_do_ioctl = device_ioctl, + .ndo_get_stats = device_get_stats, + .ndo_start_xmit = device_xmit, + .ndo_set_rx_mode = device_set_multi, }; - - static int __devinit vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent) { -- cgit v0.10.2 From cfd1fc1f5f1f3a588c6d326738dcb6b9f7b820fa Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Fri, 7 Sep 2012 00:08:05 +0530 Subject: staging: vt6655: return ENOMEM rather than ENODEV when alloc_etherdev fail when alloc_etherdev fails we should be returning ENOMEM, not ENODEV Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 493866a..4ee5f38 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -922,7 +922,7 @@ vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent) if (dev == NULL) { printk(KERN_ERR DEVICE_NAME ": allocate net device failed \n"); - return -ENODEV; + return -ENOMEM; } // Chain it all together -- cgit v0.10.2 From 960cf81187833ed3f19850551d46377323043876 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Fri, 7 Sep 2012 00:08:06 +0530 Subject: staging: vt6655: vt6655_init_info function must be void type this is because it doesn't fail anywhere and returning a value from it will be completely unnecesary. Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 4ee5f38..9e3b3f2b 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -290,7 +290,7 @@ DEFINE_PCI_DEVICE_TABLE(vt6655_pci_id_table) = { static int vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent); -static bool vt6655_init_info(struct pci_dev* pcid, PSDevice* ppDevice, PCHIP_INFO); +static void vt6655_init_info(struct pci_dev* pcid, PSDevice* ppDevice, PCHIP_INFO); static void device_free_info(PSDevice pDevice); static bool device_get_pci_info(PSDevice, struct pci_dev* pcid); static void device_print_info(PSDevice pDevice); @@ -935,9 +935,7 @@ vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent) bFirst=false; } - if (!vt6655_init_info(pcid, &pDevice, pChip_info)) { - return -ENOMEM; - } + vt6655_init_info(pcid, &pDevice, pChip_info); pDevice->dev = dev; pDevice->next_module = root_device_dev; root_device_dev = dev; @@ -1101,7 +1099,7 @@ static void device_print_info(PSDevice pDevice) } -static bool __devinit vt6655_init_info(struct pci_dev* pcid, PSDevice* ppDevice, +static void __devinit vt6655_init_info(struct pci_dev* pcid, PSDevice* ppDevice, PCHIP_INFO pChip_info) { PSDevice p; @@ -1125,8 +1123,6 @@ static bool __devinit vt6655_init_info(struct pci_dev* pcid, PSDevice* ppDevice, (*ppDevice)->multicast_limit =32; spin_lock_init(&((*ppDevice)->lock)); - - return true; } static bool device_get_pci_info(PSDevice pDevice, struct pci_dev* pcid) { -- cgit v0.10.2 From 7040e556c90aefd7b0e1341f7490de20a33340d7 Mon Sep 17 00:00:00 2001 From: DanielC Date: Thu, 6 Sep 2012 19:59:06 -0700 Subject: staging: add Silicom Bypass driver The Silicom Bypass Network Interface Cards (NICs) are network cards with paired ports (2 or 4). The pairs either act as a "wire" allowing the network packets to pass or insert the device in between the two ports. When paired with the on-board hardware watchdog or other failsafe, they provide high availability for the network in the face of software outages or maintenance. Signed-off-by: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index e12f5a3..08d279f 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -136,4 +136,6 @@ source "drivers/staging/omap-thermal/Kconfig" source "drivers/staging/ramster/Kconfig" +source "drivers/staging/silicom/Kconfig" + endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index ce42832..0f04a28 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -60,3 +60,4 @@ obj-$(CONFIG_WIMAX_GDM72XX) += gdm72xx/ obj-$(CONFIG_CSR_WIFI) += csr/ obj-$(CONFIG_OMAP_BANDGAP) += omap-thermal/ obj-$(CONFIG_ZCACHE2) += ramster/ +obj-$(CONFIG_NET_VENDOR_SILICOM) += silicom/ diff --git a/drivers/staging/silicom/Kconfig b/drivers/staging/silicom/Kconfig new file mode 100644 index 0000000..3493ee8 --- /dev/null +++ b/drivers/staging/silicom/Kconfig @@ -0,0 +1,43 @@ +# +# Silicom device configuration +# + +config NET_VENDOR_SILICOM + bool "Silicom devices" + default y + depends on (SSB_POSSIBLE && HAS_DMA) || PCI + ---help--- + If you have a network card (Ethernet) belonging to this class, + say Y. + + Note that the answer to this question does not directly affect + the kernel: saying N will just case the configurator to skip all + the questions regarding Silicom chipsets. If you say Y, you will be asked + for your specific chipset/driver in the following questions. + +if NET_VENDOR_SILICOM + +config SBYPASS + tristate "Silicom BypassCTL library support" + ---help--- + If you have a network (Ethernet) controller of this type, say Y + + To compile this driver as a module, choose M here. The module + will be called bypass. + +config BPCTL + tristate "Silicom BypassCTL net support" + depends on PCI + select SBYPASS + select NET_CORE + select MII + ---help--- + If you have a network (Ethernet) controller of this type, say Y + or M and read the Ethernet-HOWTO, available from + . + + To compile this driver as a module, choose M here. The module + will be called bpctl_mod. + + +endif # NET_VENDOR_SILICOM diff --git a/drivers/staging/silicom/Makefile b/drivers/staging/silicom/Makefile new file mode 100644 index 0000000..80e6d12 --- /dev/null +++ b/drivers/staging/silicom/Makefile @@ -0,0 +1,9 @@ +# +# Makefile for the Bypass network device drivers. +# + +obj-$(CONFIG_BPCTL) += bpctl_mod.o +obj-$(CONFIG_SBYPASS) += bypasslib/ + + +bpctl_mod-objs := bp_mod.o bp_proc.o diff --git a/drivers/staging/silicom/README b/drivers/staging/silicom/README new file mode 100644 index 0000000..ae970b3 --- /dev/null +++ b/drivers/staging/silicom/README @@ -0,0 +1,14 @@ + +Theory of Operation: + +The Silicom Bypass Network Interface Cards (NICs) are network cards with paired ports (2 or 4). +The pairs either act as a "wire" allowing the network packets to pass or insert the device in +between the two ports. When paired with the on-board hardware watchdog or other failsafe, +they provide high availability for the network in the face of software outages or maintenance. + +The software requirements are for a kernel level driver that interfaces with the bypass and watchdog, +as well as for control software. User control can be either the provided standalone executable +(/bin/bpctl) or the API exposed by the Silicom library. + + + diff --git a/drivers/staging/silicom/TODO b/drivers/staging/silicom/TODO new file mode 100644 index 0000000..bf60714 --- /dev/null +++ b/drivers/staging/silicom/TODO @@ -0,0 +1,7 @@ +TODO: + - checkpatch.pl cleanups + - locking audit + - single module with all functionality + - userland + + diff --git a/drivers/staging/silicom/bits.h b/drivers/staging/silicom/bits.h new file mode 100644 index 0000000..8c411d0 --- /dev/null +++ b/drivers/staging/silicom/bits.h @@ -0,0 +1,56 @@ +/******************************************************************************/ +/* */ +/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 - 2004 Broadcom */ +/* Corporation. */ +/* All rights reserved. */ +/* */ +/* This program is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation, located in the file LICENSE. */ +/* */ +/* History: */ +/* 02/25/00 Hav Khauv Initial version. */ +/******************************************************************************/ + +#ifndef BITS_H +#define BITS_H + +/******************************************************************************/ +/* Bit Mask definitions */ +/******************************************************************************/ + +#define BIT_NONE 0x00 +#define BIT_0 0x01 +#define BIT_1 0x02 +#define BIT_2 0x04 +#define BIT_3 0x08 +#define BIT_4 0x10 +#define BIT_5 0x20 +#define BIT_6 0x40 +#define BIT_7 0x80 +#define BIT_8 0x0100 +#define BIT_9 0x0200 +#define BIT_10 0x0400 +#define BIT_11 0x0800 +#define BIT_12 0x1000 +#define BIT_13 0x2000 +#define BIT_14 0x4000 +#define BIT_15 0x8000 +#define BIT_16 0x010000 +#define BIT_17 0x020000 +#define BIT_18 0x040000 +#define BIT_19 0x080000 +#define BIT_20 0x100000 +#define BIT_21 0x200000 +#define BIT_22 0x400000 +#define BIT_23 0x800000 +#define BIT_24 0x01000000 +#define BIT_25 0x02000000 +#define BIT_26 0x04000000 +#define BIT_27 0x08000000 +#define BIT_28 0x10000000 +#define BIT_29 0x20000000 +#define BIT_30 0x40000000 +#define BIT_31 0x80000000 + +#endif /* BITS_H */ diff --git a/drivers/staging/silicom/bp_ioctl.h b/drivers/staging/silicom/bp_ioctl.h new file mode 100644 index 0000000..b592221 --- /dev/null +++ b/drivers/staging/silicom/bp_ioctl.h @@ -0,0 +1,141 @@ +/******************************************************************************/ +/* */ +/* Silicom Bypass Control Utility, Copyright (c) 2005-2007 Silicom */ +/* All rights reserved. */ +/* */ +/* This program is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation, located in the file LICENSE. */ +/* */ +/* */ +/******************************************************************************/ + +#ifndef BP_IOCTL_H +#define BP_IOCTL_H + +#define BP_CAP 0x01 //BIT_0 +#define BP_STATUS_CAP 0x02 //BIT_1 +#define BP_STATUS_CHANGE_CAP 0x04 //BIT_2 +#define SW_CTL_CAP 0x08 //BIT_3 +#define BP_DIS_CAP 0x10 //BIT_4 +#define BP_DIS_STATUS_CAP 0x20 //BIT_5 +#define STD_NIC_CAP 0x40 //BIT_6 +#define BP_PWOFF_ON_CAP 0x80 //BIT_7 +#define BP_PWOFF_OFF_CAP 0x0100 //BIT_8 +#define BP_PWOFF_CTL_CAP 0x0200 //BIT_9 +#define BP_PWUP_ON_CAP 0x0400 //BIT_10 +#define BP_PWUP_OFF_CAP 0x0800 //BIT_11 +#define BP_PWUP_CTL_CAP 0x1000 //BIT_12 +#define WD_CTL_CAP 0x2000 //BIT_13 +#define WD_STATUS_CAP 0x4000 //BIT_14 +#define WD_TIMEOUT_CAP 0x8000 //BIT_15 +#define TX_CTL_CAP 0x10000 //BIT_16 +#define TX_STATUS_CAP 0x20000 //BIT_17 +#define TAP_CAP 0x40000 //BIT_18 +#define TAP_STATUS_CAP 0x80000 //BIT_19 +#define TAP_STATUS_CHANGE_CAP 0x100000 //BIT_20 +#define TAP_DIS_CAP 0x200000 //BIT_21 +#define TAP_DIS_STATUS_CAP 0x400000 //BIT_22 +#define TAP_PWUP_ON_CAP 0x800000 //BIT_23 +#define TAP_PWUP_OFF_CAP 0x1000000 //BIT 24 +#define TAP_PWUP_CTL_CAP 0x2000000 //BIT 25 +#define NIC_CAP_NEG 0x4000000 //BIT 26 +#define TPL_CAP 0x8000000 //BIT 27 +#define DISC_CAP 0x10000000 //BIT 28 +#define DISC_DIS_CAP 0x20000000 //BIT 29 +#define DISC_PWUP_CTL_CAP 0x40000000 //BIT 30 + +#define TPL2_CAP_EX 0x01 +#define DISC_PORT_CAP_EX 0x02 + +#define WD_MIN_TIME_MASK(val) (val & 0xf) +#define WD_STEP_COUNT_MASK(val) ((val & 0xf) << 5) +#define WDT_STEP_TIME 0x10 //BIT_4 + +#define WD_MIN_TIME_GET(desc) (desc & 0xf) +#define WD_STEP_COUNT_GET(desc) (desc>>5) & 0xf + +typedef enum { + IF_SCAN, + GET_DEV_NUM, + IS_BYPASS, + GET_BYPASS_SLAVE, + GET_BYPASS_CAPS, + GET_WD_SET_CAPS, + SET_BYPASS, + GET_BYPASS, + GET_BYPASS_CHANGE, + SET_BYPASS_WD, + GET_BYPASS_WD, + GET_WD_EXPIRE_TIME, + RESET_BYPASS_WD_TIMER, + SET_DIS_BYPASS, + GET_DIS_BYPASS, + SET_BYPASS_PWOFF, + GET_BYPASS_PWOFF, + SET_BYPASS_PWUP, + GET_BYPASS_PWUP, + SET_STD_NIC, + GET_STD_NIC, + SET_TX, + GET_TX, + SET_TAP, + GET_TAP, + GET_TAP_CHANGE, + SET_DIS_TAP, + GET_DIS_TAP, + SET_TAP_PWUP, + GET_TAP_PWUP, + SET_WD_EXP_MODE, + GET_WD_EXP_MODE, + SET_WD_AUTORESET, + GET_WD_AUTORESET, + SET_TPL, + GET_TPL, + SET_DISC, + GET_DISC, + GET_DISC_CHANGE, + SET_DIS_DISC, + GET_DIS_DISC, + SET_DISC_PWUP, + GET_DISC_PWUP, + GET_BYPASS_INFO = 100, + GET_BP_WAIT_AT_PWUP, + SET_BP_WAIT_AT_PWUP, + GET_BP_HW_RESET, + SET_BP_HW_RESET, + SET_DISC_PORT, + GET_DISC_PORT, + SET_DISC_PORT_PWUP, + GET_DISC_PORT_PWUP, + SET_BP_FORCE_LINK, + GET_BP_FORCE_LINK, +#ifdef BP_SELF_TEST + SET_BP_SELF_TEST = 200, + GET_BP_SELF_TEST, +#endif + +} CMND_TYPE_SD; + +/* +* The major device number. We can't rely on dynamic +* registration any more, because ioctls need to know +* it. +*/ + +#define MAGIC_NUM 'J' + +/* for passing single values */ +struct bpctl_cmd { + int status; + int data[8]; + int in_param[8]; + int out_param[8]; +}; + +#define IOCTL_TX_MSG(cmd) _IOWR(MAGIC_NUM, cmd, struct bpctl_cmd) + +#define DEVICE_NODE "/dev/bpctl0" +#define DEVICE_NAME "bpctl" + +#endif diff --git a/drivers/staging/silicom/bp_mod.c b/drivers/staging/silicom/bp_mod.c new file mode 100644 index 0000000..0d96196 --- /dev/null +++ b/drivers/staging/silicom/bp_mod.c @@ -0,0 +1,9012 @@ +/******************************************************************************/ +/* */ +/* Bypass Control utility, Copyright (c) 2005-20011 Silicom */ +/* */ +/* This program is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation, located in the file LICENSE. */ +/* Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. */ +/* */ +/* */ +/******************************************************************************/ +#include +#if defined(CONFIG_SMP) && ! defined(__SMP__) +#define __SMP__ +#endif + +#include /* We're doing kernel work */ +#include /* Specifically, a module */ +#include +#include +#include +#include +#include +#include +#include + +#include /* for get_user and put_user */ +#include +#include +#include + +#include "bp_ioctl.h" +#include "bp_mod.h" +#include "bypass.h" +#include "libbp_sd.h" + +#define SUCCESS 0 +#define BP_MOD_VER "9.0.4" +#define BP_MOD_DESCR "Silicom Bypass-SD Control driver" +#define BP_SYNC_FLAG 1 + +static int Device_Open = 0; +static int major_num = 0; + +MODULE_AUTHOR("Anna Lukin, annal@silicom.co.il"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION(BP_MOD_DESCR); +MODULE_VERSION(BP_MOD_VER); +spinlock_t bpvm_lock; + +#define lock_bpctl() \ +if (down_interruptible(&bpctl_sema)) { \ + return -ERESTARTSYS; \ +} \ + +#define unlock_bpctl() \ + up(&bpctl_sema); + +/* Media Types */ +typedef enum { + bp_copper = 0, + bp_fiber, + bp_cx4, + bp_none, +} bp_media_type; + +struct pfs_unit_sd { + struct proc_dir_entry *proc_entry; + char proc_name[32]; +}; + +struct bypass_pfs_sd { + char dir_name[32]; + struct proc_dir_entry *bypass_entry; + struct pfs_unit_sd bypass_info; + struct pfs_unit_sd bypass_slave; + struct pfs_unit_sd bypass_caps; + struct pfs_unit_sd wd_set_caps; + struct pfs_unit_sd bypass; + struct pfs_unit_sd bypass_change; + struct pfs_unit_sd bypass_wd; + struct pfs_unit_sd wd_expire_time; + struct pfs_unit_sd reset_bypass_wd; + struct pfs_unit_sd dis_bypass; + struct pfs_unit_sd bypass_pwup; + struct pfs_unit_sd bypass_pwoff; + struct pfs_unit_sd std_nic; + struct pfs_unit_sd tap; + struct pfs_unit_sd dis_tap; + struct pfs_unit_sd tap_pwup; + struct pfs_unit_sd tap_change; + struct pfs_unit_sd wd_exp_mode; + struct pfs_unit_sd wd_autoreset; + struct pfs_unit_sd tpl; + +}; + +typedef struct _bpctl_dev { + char *name; + char *desc; + struct pci_dev *pdev; /* PCI device */ + struct net_device *ndev; /* net device */ + unsigned long mem_map; + uint8_t bus; + uint8_t slot; + uint8_t func; + u_int32_t device; + u_int32_t vendor; + u_int32_t subvendor; + u_int32_t subdevice; + int ifindex; + uint32_t bp_caps; + uint32_t bp_caps_ex; + uint8_t bp_fw_ver; + int bp_ext_ver; + int wdt_status; + unsigned long bypass_wdt_on_time; + uint32_t bypass_timer_interval; + struct timer_list bp_timer; + uint32_t reset_time; + uint8_t bp_status_un; + atomic_t wdt_busy; + bp_media_type media_type; + int bp_tpl_flag; + struct timer_list bp_tpl_timer; + spinlock_t bypass_wr_lock; + int bp_10g; + int bp_10gb; + int bp_fiber5; + int bp_10g9; + int bp_i80; + int bp_540; + +// selftest stanza + int (*hard_start_xmit_save) (struct sk_buff * skb, + struct net_device * dev); + const struct net_device_ops *old_ops; + struct net_device_ops new_ops; + int bp_self_test_flag; + char *bp_tx_data; +// end selftest stanza +// + struct bypass_pfs_sd bypass_pfs_set; + +} bpctl_dev_t; + +static bpctl_dev_t *bpctl_dev_arr; + +static struct semaphore bpctl_sema; +static int device_num = 0; + +static int get_dev_idx(int ifindex); +static bpctl_dev_t *get_master_port_fn(bpctl_dev_t * pbpctl_dev); +static int disc_status(bpctl_dev_t * pbpctl_dev); +static int bypass_status(bpctl_dev_t * pbpctl_dev); +static int wdt_timer(bpctl_dev_t * pbpctl_dev, int *time_left); +static bpctl_dev_t *get_status_port_fn(bpctl_dev_t * pbpctl_dev); +static void if_scan_init(void); + +int bypass_proc_create_dev_sd(bpctl_dev_t * pbp_device_block); +int bypass_proc_remove_dev_sd(bpctl_dev_t * pbp_device_block); +int bp_proc_create(void); + +int is_bypass_fn(bpctl_dev_t * pbpctl_dev); +int get_dev_idx_bsf(int bus, int slot, int func); + +static unsigned long str_to_hex(char *p); +static int bp_device_event(struct notifier_block *unused, + unsigned long event, void *ptr) +{ + struct net_device *dev = ptr; + static bpctl_dev_t *pbpctl_dev = NULL, *pbpctl_dev_m = NULL; + int dev_num = 0, ret = 0, ret_d = 0, time_left = 0; + //printk("BP_PROC_SUPPORT event =%d %s %d\n", event,dev->name, dev->ifindex ); + //return NOTIFY_DONE; + if (!dev) + return NOTIFY_DONE; + if (event == NETDEV_REGISTER) { + { + struct ethtool_drvinfo drvinfo; + // char *str=NULL; + char cbuf[32]; + char *buf = NULL; + char res[10]; + int i = 0, ifindex, idx_dev = 0; + int bus = 0, slot = 0, func = 0; + ifindex = dev->ifindex; + + memset(res, 0, 10); + memset(&drvinfo, 0, sizeof(struct ethtool_drvinfo)); + + if (dev->ethtool_ops && dev->ethtool_ops->get_drvinfo) { + memset(&drvinfo, 0, sizeof(drvinfo)); + dev->ethtool_ops->get_drvinfo(dev, &drvinfo); + } else + return NOTIFY_DONE; + if (!drvinfo.bus_info) + return NOTIFY_DONE; + if (!strcmp(drvinfo.bus_info, "N/A")) + return NOTIFY_DONE; + memcpy(&cbuf, drvinfo.bus_info, 32); + buf = &cbuf[0]; + + // while(*buf++){ + + /*if(*buf==':'){ + buf++; + break; + } */ + //} + while (*buf++ != ':') ; + for (i = 0; i < 10; i++, buf++) { + if (*buf == ':') + break; + res[i] = *buf; + + } + buf++; + bus = str_to_hex(res); + memset(res, 0, 10); + + for (i = 0; i < 10; i++, buf++) { + if (*buf == '.') + break; + res[i] = *buf; + + } + buf++; + slot = str_to_hex(res); + func = str_to_hex(buf); + idx_dev = get_dev_idx_bsf(bus, slot, func); + + if (idx_dev != -1) { + + bpctl_dev_arr[idx_dev].ifindex = ifindex; + bpctl_dev_arr[idx_dev].ndev = dev; + + bypass_proc_remove_dev_sd(&bpctl_dev_arr + [idx_dev]); + bypass_proc_create_dev_sd(&bpctl_dev_arr + [idx_dev]); + + } + + } + return NOTIFY_DONE; + + } + if (event == NETDEV_UNREGISTER) { + int idx_dev = 0; + //if_scan(); + for (idx_dev = 0; + ((bpctl_dev_arr[idx_dev].pdev != NULL) + && (idx_dev < device_num)); idx_dev++) { + if (bpctl_dev_arr[idx_dev].ndev == dev) { + bypass_proc_remove_dev_sd(&bpctl_dev_arr + [idx_dev]); + bpctl_dev_arr[idx_dev].ndev = NULL; + + return NOTIFY_DONE; + + } + + } + return NOTIFY_DONE; + } + if (event == NETDEV_CHANGENAME) { + int idx_dev = 0; + //if_scan(); + for (idx_dev = 0; + ((bpctl_dev_arr[idx_dev].pdev != NULL) + && (idx_dev < device_num)); idx_dev++) { + if (bpctl_dev_arr[idx_dev].ndev == dev) { + bypass_proc_remove_dev_sd(&bpctl_dev_arr + [idx_dev]); + bypass_proc_create_dev_sd(&bpctl_dev_arr + [idx_dev]); + + return NOTIFY_DONE; + + } + + } + return NOTIFY_DONE; + + } + //return NOTIFY_DONE; + + switch (event) { + + case NETDEV_CHANGE:{ + if (netif_carrier_ok(dev)) + return NOTIFY_DONE; + + //if_scan(); + if (((dev_num = get_dev_idx(dev->ifindex)) == -1) || + (!(pbpctl_dev = &bpctl_dev_arr[dev_num]))) + return NOTIFY_DONE; + + if ((is_bypass_fn(pbpctl_dev)) == 1) + pbpctl_dev_m = pbpctl_dev; + else + pbpctl_dev_m = get_master_port_fn(pbpctl_dev); + if (!pbpctl_dev_m) + return NOTIFY_DONE; + ret = bypass_status(pbpctl_dev_m); + if (ret == 1) + printk("bpmod: %s is in the Bypass mode now", + dev->name); + ret_d = disc_status(pbpctl_dev_m); + if (ret_d == 1) + printk + ("bpmod: %s is in the Disconnect mode now", + dev->name); + if (ret || ret_d) { + wdt_timer(pbpctl_dev_m, &time_left); + if (time_left == -1) + printk("; WDT has expired"); + printk(".\n"); + + } + return NOTIFY_DONE; + + } + + default: + return NOTIFY_DONE; + + } + return NOTIFY_DONE; + +} + +static struct notifier_block bp_notifier_block = { + .notifier_call = bp_device_event, +}; + +static int device_open(struct inode *inode, struct file *file) +{ +#ifdef DEBUG + printk("device_open(%p)\n", file); +#endif + Device_Open++; +/* +* Initialize the message +*/ + return SUCCESS; +} + +static int device_release(struct inode *inode, struct file *file) +{ +#ifdef DEBUG + printk("device_release(%p,%p)\n", inode, file); +#endif + Device_Open--; + return SUCCESS; +} + +int is_bypass_fn(bpctl_dev_t * pbpctl_dev); +int wdt_time_left(bpctl_dev_t * pbpctl_dev); + +static void write_pulse(bpctl_dev_t * pbpctl_dev, + unsigned int ctrl_ext, + unsigned char value, unsigned char len) +{ + unsigned char ctrl_val = 0; + unsigned int i = len; + unsigned int ctrl = 0; + bpctl_dev_t *pbpctl_dev_c = NULL; + + if (pbpctl_dev->bp_i80) + ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); + if (pbpctl_dev->bp_540) + ctrl = BP10G_READ_REG(pbpctl_dev, ESDP); + + if (pbpctl_dev->bp_10g9) { + if (!(pbpctl_dev_c = get_status_port_fn(pbpctl_dev))) + return; + ctrl = BP10G_READ_REG(pbpctl_dev_c, ESDP); + } + + while (i--) { + ctrl_val = (value >> i) & 0x1; + if (ctrl_val) { + if (pbpctl_dev->bp_10g9) { + + /* To start management : MCLK 1, MDIO 1, output */ + /* DATA 1 CLK 1 */ + /*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext|BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9)); */ + BP10G_WRITE_REG(pbpctl_dev, I2CCTL, + ctrl_ext | + BP10G_MDIO_DATA_OUT9); + BP10G_WRITE_REG(pbpctl_dev_c, ESDP, + (ctrl | BP10G_MCLK_DATA_OUT9 | + BP10G_MCLK_DIR_OUT9)); + + } else if (pbpctl_dev->bp_fiber5) { + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, (ctrl_ext | + BPCTLI_CTRL_EXT_MCLK_DIR5 + | + BPCTLI_CTRL_EXT_MDIO_DIR5 + | + BPCTLI_CTRL_EXT_MDIO_DATA5 + | + BPCTLI_CTRL_EXT_MCLK_DATA5)); + + } else if (pbpctl_dev->bp_i80) { + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, (ctrl_ext | + BPCTLI_CTRL_EXT_MDIO_DIR80 + | + BPCTLI_CTRL_EXT_MDIO_DATA80)); + + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, (ctrl | + BPCTLI_CTRL_EXT_MCLK_DIR80 + | + BPCTLI_CTRL_EXT_MCLK_DATA80)); + + } else if (pbpctl_dev->bp_540) { + BP10G_WRITE_REG(pbpctl_dev, ESDP, (ctrl | + BP540_MDIO_DIR + | + BP540_MDIO_DATA + | + BP540_MCLK_DIR + | + BP540_MCLK_DATA)); + + } else if (pbpctl_dev->bp_10gb) { + BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, + (ctrl_ext | BP10GB_MDIO_SET | + BP10GB_MCLK_SET) & + ~(BP10GB_MCLK_DIR | + BP10GB_MDIO_DIR | + BP10GB_MDIO_CLR | + BP10GB_MCLK_CLR)); + + } else if (!pbpctl_dev->bp_10g) + /* To start management : MCLK 1, MDIO 1, output */ + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, + (ctrl_ext | + BPCTLI_CTRL_EXT_MCLK_DIR | + BPCTLI_CTRL_EXT_MDIO_DIR | + BPCTLI_CTRL_EXT_MDIO_DATA | + BPCTLI_CTRL_EXT_MCLK_DATA)); + else { + +/* To start management : MCLK 1, MDIO 1, output*/ + //writel((0x2|0x8), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ; + BP10G_WRITE_REG(pbpctl_dev, EODSDP, + (ctrl_ext | BP10G_MCLK_DATA_OUT + | BP10G_MDIO_DATA_OUT)); + //BP10G_WRITE_REG(pbpctl_dev, ESDP, (ctrl | BP10G_MDIO_DATA | BP10G_MDIO_DIR)); + + } + + usec_delay(PULSE_TIME); + if (pbpctl_dev->bp_10g9) { + + /*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, ((ctrl_ext|BP10G_MDIO_DATA_OUT9)&~(BP10G_MCLK_DATA_OUT9))); */ + /* DATA 1 CLK 0 */ + BP10G_WRITE_REG(pbpctl_dev, I2CCTL, + ctrl_ext | + BP10G_MDIO_DATA_OUT9); + BP10G_WRITE_REG(pbpctl_dev_c, ESDP, + (ctrl | BP10G_MCLK_DIR_OUT9) & + ~BP10G_MCLK_DATA_OUT9); + + } else if (pbpctl_dev->bp_fiber5) { + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, + ((ctrl_ext | + BPCTLI_CTRL_EXT_MCLK_DIR5 | + BPCTLI_CTRL_EXT_MDIO_DIR5 | + BPCTLI_CTRL_EXT_MDIO_DATA5) + & + ~ + (BPCTLI_CTRL_EXT_MCLK_DATA5))); + + } else if (pbpctl_dev->bp_i80) { + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, (ctrl_ext | + BPCTLI_CTRL_EXT_MDIO_DIR80 + | + BPCTLI_CTRL_EXT_MDIO_DATA80)); + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, + ((ctrl | + BPCTLI_CTRL_EXT_MCLK_DIR80) + & + ~ + (BPCTLI_CTRL_EXT_MCLK_DATA80))); + + } else if (pbpctl_dev->bp_540) { + BP10G_WRITE_REG(pbpctl_dev, ESDP, + (ctrl | BP540_MDIO_DIR | + BP540_MDIO_DATA | + BP540_MCLK_DIR) & + ~(BP540_MCLK_DATA)); + + } else if (pbpctl_dev->bp_10gb) { + + BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, + (ctrl_ext | BP10GB_MDIO_SET | + BP10GB_MCLK_CLR) & + ~(BP10GB_MCLK_DIR | + BP10GB_MDIO_DIR | + BP10GB_MDIO_CLR | + BP10GB_MCLK_SET)); + + } else if (!pbpctl_dev->bp_10g) + + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, + ((ctrl_ext | + BPCTLI_CTRL_EXT_MCLK_DIR | + BPCTLI_CTRL_EXT_MDIO_DIR | + BPCTLI_CTRL_EXT_MDIO_DATA) + & + ~ + (BPCTLI_CTRL_EXT_MCLK_DATA))); + else { + + //writel((0x2), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ; + BP10G_WRITE_REG(pbpctl_dev, EODSDP, + ((ctrl_ext | + BP10G_MDIO_DATA_OUT) & + ~(BP10G_MCLK_DATA_OUT))); + // BP10G_WRITE_REG(pbpctl_dev, ESDP, (ctrl |BP10G_MDIO_DIR|BP10G_MDIO_DATA)); + } + + usec_delay(PULSE_TIME); + + } else { + if (pbpctl_dev->bp_10g9) { + /* DATA 0 CLK 1 */ + /*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, ((ctrl_ext|BP10G_MCLK_DATA_OUT9)&~BP10G_MDIO_DATA_OUT9)); */ + BP10G_WRITE_REG(pbpctl_dev, I2CCTL, + (ctrl_ext & + ~BP10G_MDIO_DATA_OUT9)); + BP10G_WRITE_REG(pbpctl_dev_c, ESDP, + (ctrl | BP10G_MCLK_DATA_OUT9 | + BP10G_MCLK_DIR_OUT9)); + + } else if (pbpctl_dev->bp_fiber5) { + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, + ((ctrl_ext | + BPCTLI_CTRL_EXT_MCLK_DIR5 | + BPCTLI_CTRL_EXT_MDIO_DIR5 | + BPCTLI_CTRL_EXT_MCLK_DATA5) + & + ~ + (BPCTLI_CTRL_EXT_MDIO_DATA5))); + + } else if (pbpctl_dev->bp_i80) { + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, + ((ctrl_ext | + BPCTLI_CTRL_EXT_MDIO_DIR80) + & + ~ + (BPCTLI_CTRL_EXT_MDIO_DATA80))); + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, + (ctrl | + BPCTLI_CTRL_EXT_MCLK_DIR80 | + BPCTLI_CTRL_EXT_MCLK_DATA80)); + + } else if (pbpctl_dev->bp_540) { + BP10G_WRITE_REG(pbpctl_dev, ESDP, + ((ctrl | BP540_MCLK_DIR | + BP540_MCLK_DATA | + BP540_MDIO_DIR) & + ~(BP540_MDIO_DATA))); + + } else if (pbpctl_dev->bp_10gb) { + BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, + (ctrl_ext | BP10GB_MDIO_CLR | + BP10GB_MCLK_SET) & + ~(BP10GB_MCLK_DIR | + BP10GB_MDIO_DIR | + BP10GB_MDIO_SET | + BP10GB_MCLK_CLR)); + + } else if (!pbpctl_dev->bp_10g) + + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, + ((ctrl_ext | + BPCTLI_CTRL_EXT_MCLK_DIR | + BPCTLI_CTRL_EXT_MDIO_DIR | + BPCTLI_CTRL_EXT_MCLK_DATA) + & + ~ + (BPCTLI_CTRL_EXT_MDIO_DATA))); + else { + + // writel((0x8), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ; + BP10G_WRITE_REG(pbpctl_dev, EODSDP, + ((ctrl_ext | + BP10G_MCLK_DATA_OUT) & + ~BP10G_MDIO_DATA_OUT)); + // BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA)); + + } + usec_delay(PULSE_TIME); + if (pbpctl_dev->bp_10g9) { + /* DATA 0 CLK 0 */ + /*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext&~(BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9))); */ + BP10G_WRITE_REG(pbpctl_dev, I2CCTL, + (ctrl_ext & + ~BP10G_MDIO_DATA_OUT9)); + BP10G_WRITE_REG(pbpctl_dev_c, ESDP, + ((ctrl | BP10G_MCLK_DIR_OUT9) & + ~(BP10G_MCLK_DATA_OUT9))); + + } else if (pbpctl_dev->bp_fiber5) { + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, + ((ctrl_ext | + BPCTLI_CTRL_EXT_MCLK_DIR5 | + BPCTLI_CTRL_EXT_MDIO_DIR5) + & + ~(BPCTLI_CTRL_EXT_MCLK_DATA5 + | + BPCTLI_CTRL_EXT_MDIO_DATA5))); + + } else if (pbpctl_dev->bp_i80) { + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, + ((ctrl_ext | + BPCTLI_CTRL_EXT_MDIO_DIR80) + & + ~BPCTLI_CTRL_EXT_MDIO_DATA80)); + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, + ((ctrl | + BPCTLI_CTRL_EXT_MCLK_DIR80) + & + ~ + (BPCTLI_CTRL_EXT_MCLK_DATA80))); + + } else if (pbpctl_dev->bp_540) { + BP10G_WRITE_REG(pbpctl_dev, ESDP, + ((ctrl | BP540_MCLK_DIR | + BP540_MDIO_DIR) & + ~(BP540_MDIO_DATA | + BP540_MCLK_DATA))); + } else if (pbpctl_dev->bp_10gb) { + + BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, + (ctrl_ext | BP10GB_MDIO_CLR | + BP10GB_MCLK_CLR) & + ~(BP10GB_MCLK_DIR | + BP10GB_MDIO_DIR | + BP10GB_MDIO_SET | + BP10GB_MCLK_SET)); + + } else if (!pbpctl_dev->bp_10g) + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, + ((ctrl_ext | + BPCTLI_CTRL_EXT_MCLK_DIR | + BPCTLI_CTRL_EXT_MDIO_DIR) & + ~(BPCTLI_CTRL_EXT_MCLK_DATA + | + BPCTLI_CTRL_EXT_MDIO_DATA))); + else { + + //writel((0x0), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ; + BP10G_WRITE_REG(pbpctl_dev, EODSDP, + (ctrl_ext & + ~(BP10G_MCLK_DATA_OUT | + BP10G_MDIO_DATA_OUT))); + //BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA)); + } + + usec_delay(PULSE_TIME); + } + + } +} + +static int read_pulse(bpctl_dev_t * pbpctl_dev, unsigned int ctrl_ext, + unsigned char len) +{ + unsigned char ctrl_val = 0; + unsigned int i = len; + unsigned int ctrl = 0; + bpctl_dev_t *pbpctl_dev_c = NULL; + + if (pbpctl_dev->bp_i80) + ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); + if (pbpctl_dev->bp_540) + ctrl = BP10G_READ_REG(pbpctl_dev, ESDP); + if (pbpctl_dev->bp_10g9) { + if (!(pbpctl_dev_c = get_status_port_fn(pbpctl_dev))) + return -1; + ctrl = BP10G_READ_REG(pbpctl_dev_c, ESDP); + } + + //ctrl_ext=BP10G_READ_REG(pbpctl_dev,EODSDP); + + while (i--) { + if (pbpctl_dev->bp_10g9) { + /*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, ((ctrl_ext|BP10G_MDIO_DATA_OUT9)&~BP10G_MCLK_DATA_OUT9)); */ + /* DATA ? CLK 0 */ + BP10G_WRITE_REG(pbpctl_dev_c, ESDP, + ((ctrl | BP10G_MCLK_DIR_OUT9) & + ~(BP10G_MCLK_DATA_OUT9))); + + } else if (pbpctl_dev->bp_fiber5) { + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext | + BPCTLI_CTRL_EXT_MCLK_DIR5) + & + ~ + (BPCTLI_CTRL_EXT_MDIO_DIR5 + | + BPCTLI_CTRL_EXT_MCLK_DATA5))); + + } else if (pbpctl_dev->bp_i80) { + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, + (ctrl_ext & + ~BPCTLI_CTRL_EXT_MDIO_DIR80)); + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, + ((ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80) + & ~(BPCTLI_CTRL_EXT_MCLK_DATA80))); + + } else if (pbpctl_dev->bp_540) { + BP10G_WRITE_REG(pbpctl_dev, ESDP, + ((ctrl | BP540_MCLK_DIR) & + ~(BP540_MDIO_DIR | BP540_MCLK_DATA))); + + } else if (pbpctl_dev->bp_10gb) { + + BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, + (ctrl_ext | BP10GB_MDIO_DIR | + BP10GB_MCLK_CLR) & ~(BP10GB_MCLK_DIR | + BP10GB_MDIO_CLR | + BP10GB_MDIO_SET | + BP10GB_MCLK_SET)); + + } else if (!pbpctl_dev->bp_10g) + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | + BPCTLI_CTRL_EXT_MCLK_DIR) + & + ~ + (BPCTLI_CTRL_EXT_MDIO_DIR + | + BPCTLI_CTRL_EXT_MCLK_DATA))); + else { + + // writel(( 0/*0x1*/), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ; + BP10G_WRITE_REG(pbpctl_dev, EODSDP, ((ctrl_ext | BP10G_MDIO_DATA_OUT) & ~BP10G_MCLK_DATA_OUT)); /* ? */ + // printk("0x28=0x%x\n",BP10G_READ_REG(pbpctl_dev,EODSDP);); + //BP10G_WRITE_REG(pbpctl_dev, ESDP, (ctrl &~BP10G_MDIO_DIR)); + + } + + usec_delay(PULSE_TIME); + if (pbpctl_dev->bp_10g9) { + /*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext|BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9)); */ + /* DATA ? CLK 1 */ + BP10G_WRITE_REG(pbpctl_dev_c, ESDP, + (ctrl | BP10G_MCLK_DATA_OUT9 | + BP10G_MCLK_DIR_OUT9)); + + } else if (pbpctl_dev->bp_fiber5) { + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext | + BPCTLI_CTRL_EXT_MCLK_DIR5 + | + BPCTLI_CTRL_EXT_MCLK_DATA5) + & + ~ + (BPCTLI_CTRL_EXT_MDIO_DIR5))); + + } else if (pbpctl_dev->bp_i80) { + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, + (ctrl_ext & + ~(BPCTLI_CTRL_EXT_MDIO_DIR80))); + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, + (ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80 | + BPCTLI_CTRL_EXT_MCLK_DATA80)); + + } else if (pbpctl_dev->bp_540) { + BP10G_WRITE_REG(pbpctl_dev, ESDP, + ((ctrl | BP540_MCLK_DIR | + BP540_MCLK_DATA) & + ~(BP540_MDIO_DIR))); + + } else if (pbpctl_dev->bp_10gb) { + BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, + (ctrl_ext | BP10GB_MDIO_DIR | + BP10GB_MCLK_SET) & ~(BP10GB_MCLK_DIR | + BP10GB_MDIO_CLR | + BP10GB_MDIO_SET | + BP10GB_MCLK_CLR)); + + } else if (!pbpctl_dev->bp_10g) + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | + BPCTLI_CTRL_EXT_MCLK_DIR + | + BPCTLI_CTRL_EXT_MCLK_DATA) + & + ~ + (BPCTLI_CTRL_EXT_MDIO_DIR))); + else { + + // writel((0x8 /*|0x1*/ ), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ; + BP10G_WRITE_REG(pbpctl_dev, EODSDP, + (ctrl_ext | BP10G_MCLK_DATA_OUT | + BP10G_MDIO_DATA_OUT)); + //BP10G_WRITE_REG(pbpctl_dev, ESDP, (ctrl &~BP10G_MDIO_DIR)); + + } + if (pbpctl_dev->bp_10g9) { + ctrl_ext = BP10G_READ_REG(pbpctl_dev, I2CCTL); + + } else if ((pbpctl_dev->bp_fiber5) || (pbpctl_dev->bp_i80)) { + ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL); + } else if (pbpctl_dev->bp_540) { + ctrl_ext = BP10G_READ_REG(pbpctl_dev, ESDP); + } else if (pbpctl_dev->bp_10gb) + ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO); + + else if (!pbpctl_dev->bp_10g) + ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); + else + ctrl_ext = BP10G_READ_REG(pbpctl_dev, EODSDP); + //ctrl_ext =readl((void *)((pbpctl_dev)->mem_map) + 0x28); + + usec_delay(PULSE_TIME); + if (pbpctl_dev->bp_10g9) { + if (ctrl_ext & BP10G_MDIO_DATA_IN9) + ctrl_val |= 1 << i; + + } else if (pbpctl_dev->bp_fiber5) { + if (ctrl_ext & BPCTLI_CTRL_EXT_MDIO_DATA5) + ctrl_val |= 1 << i; + } else if (pbpctl_dev->bp_i80) { + if (ctrl_ext & BPCTLI_CTRL_EXT_MDIO_DATA80) + ctrl_val |= 1 << i; + } else if (pbpctl_dev->bp_540) { + if (ctrl_ext & BP540_MDIO_DATA) + ctrl_val |= 1 << i; + } else if (pbpctl_dev->bp_10gb) { + if (ctrl_ext & BP10GB_MDIO_DATA) + ctrl_val |= 1 << i; + + } else if (!pbpctl_dev->bp_10g) { + + if (ctrl_ext & BPCTLI_CTRL_EXT_MDIO_DATA) + ctrl_val |= 1 << i; + } else { + + if (ctrl_ext & BP10G_MDIO_DATA_IN) + ctrl_val |= 1 << i; + } + + } + + return ctrl_val; +} + +static void write_reg(bpctl_dev_t * pbpctl_dev, unsigned char value, + unsigned char addr) +{ + uint32_t ctrl_ext = 0, ctrl = 0; + bpctl_dev_t *pbpctl_dev_c = NULL; + unsigned long flags; + if (pbpctl_dev->bp_10g9) { + if (!(pbpctl_dev_c = get_status_port_fn(pbpctl_dev))) + return; + } + if ((pbpctl_dev->wdt_status == WDT_STATUS_EN) && + (pbpctl_dev->bp_ext_ver < PXG4BPFI_VER)) + wdt_time_left(pbpctl_dev); + +#ifdef BP_SYNC_FLAG + spin_lock_irqsave(&pbpctl_dev->bypass_wr_lock, flags); +#else + atomic_set(&pbpctl_dev->wdt_busy, 1); +#endif + if (pbpctl_dev->bp_10g9) { + + ctrl_ext = BP10G_READ_REG(pbpctl_dev, I2CCTL); + ctrl = BP10G_READ_REG(pbpctl_dev_c, ESDP); + /* DATA 0 CLK 0 */ + /* BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext&~(BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9))); */ + BP10G_WRITE_REG(pbpctl_dev, I2CCTL, + (ctrl_ext & ~BP10G_MDIO_DATA_OUT9)); + BP10G_WRITE_REG(pbpctl_dev_c, ESDP, + ((ctrl | BP10G_MCLK_DIR_OUT9) & + ~(BP10G_MCLK_DATA_OUT9))); + + } else if (pbpctl_dev->bp_fiber5) { + ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL); + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext | + BPCTLI_CTRL_EXT_MCLK_DIR5 + | + BPCTLI_CTRL_EXT_MDIO_DIR5) + & + ~ + (BPCTLI_CTRL_EXT_MDIO_DATA5 + | + BPCTLI_CTRL_EXT_MCLK_DATA5))); + } else if (pbpctl_dev->bp_i80) { + ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL); + ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext | + BPCTLI_CTRL_EXT_MDIO_DIR80) + & + ~BPCTLI_CTRL_EXT_MDIO_DATA80)); + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, + ((ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80) & + ~BPCTLI_CTRL_EXT_MCLK_DATA80)); + + } else if (pbpctl_dev->bp_540) { + ctrl = ctrl_ext = BP10G_READ_REG(pbpctl_dev, ESDP); + BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl | + BP540_MDIO_DIR | + BP540_MCLK_DIR) & + ~(BP540_MDIO_DATA | + BP540_MCLK_DATA))); + + } else if (pbpctl_dev->bp_10gb) { + ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO); + + BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, + (ctrl_ext | BP10GB_MDIO_CLR | BP10GB_MCLK_CLR) + & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_DIR | + BP10GB_MDIO_SET | BP10GB_MCLK_SET)); + + } else if (!pbpctl_dev->bp_10g) { + + ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | + BPCTLI_CTRL_EXT_MCLK_DIR + | + BPCTLI_CTRL_EXT_MDIO_DIR) + & + ~ + (BPCTLI_CTRL_EXT_MDIO_DATA + | + BPCTLI_CTRL_EXT_MCLK_DATA))); + } else { + ctrl = BP10G_READ_REG(pbpctl_dev, ESDP); + ctrl_ext = BP10G_READ_REG(pbpctl_dev, EODSDP); + BP10G_WRITE_REG(pbpctl_dev, EODSDP, + (ctrl_ext & + ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT))); + //BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA)); + //writel((0x0), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ; + } + usec_delay(CMND_INTERVAL); + + /*send sync cmd */ + write_pulse(pbpctl_dev, ctrl_ext, SYNC_CMD_VAL, SYNC_CMD_LEN); + /*send wr cmd */ + write_pulse(pbpctl_dev, ctrl_ext, WR_CMD_VAL, WR_CMD_LEN); + write_pulse(pbpctl_dev, ctrl_ext, addr, ADDR_CMD_LEN); + + /*write data */ + write_pulse(pbpctl_dev, ctrl_ext, value, WR_DATA_LEN); + if (pbpctl_dev->bp_10g9) { + /*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext&~(BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9))); */ + /* DATA 0 CLK 0 */ + BP10G_WRITE_REG(pbpctl_dev, I2CCTL, + (ctrl_ext & ~BP10G_MDIO_DATA_OUT9)); + BP10G_WRITE_REG(pbpctl_dev_c, ESDP, + ((ctrl | BP10G_MCLK_DIR_OUT9) & + ~(BP10G_MCLK_DATA_OUT9))); + + } else if (pbpctl_dev->bp_fiber5) { + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext | + BPCTLI_CTRL_EXT_MCLK_DIR5 + | + BPCTLI_CTRL_EXT_MDIO_DIR5) + & + ~ + (BPCTLI_CTRL_EXT_MDIO_DATA5 + | + BPCTLI_CTRL_EXT_MCLK_DATA5))); + } else if (pbpctl_dev->bp_i80) { + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext | + BPCTLI_CTRL_EXT_MDIO_DIR80) + & + ~BPCTLI_CTRL_EXT_MDIO_DATA80)); + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, + ((ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80) & + ~BPCTLI_CTRL_EXT_MCLK_DATA80)); + } else if (pbpctl_dev->bp_540) { + BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl | + BP540_MDIO_DIR | + BP540_MCLK_DIR) & + ~(BP540_MDIO_DATA | + BP540_MCLK_DATA))); + } else if (pbpctl_dev->bp_10gb) { + BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, + (ctrl_ext | BP10GB_MDIO_CLR | BP10GB_MCLK_CLR) + & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_DIR | + BP10GB_MDIO_SET | BP10GB_MCLK_SET)); + + } else if (!pbpctl_dev->bp_10g) + + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | + BPCTLI_CTRL_EXT_MCLK_DIR + | + BPCTLI_CTRL_EXT_MDIO_DIR) + & + ~ + (BPCTLI_CTRL_EXT_MDIO_DATA + | + BPCTLI_CTRL_EXT_MCLK_DATA))); + else { + BP10G_WRITE_REG(pbpctl_dev, EODSDP, + (ctrl_ext & + ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT))); + // BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA)); + + // writel((0x0), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ; + } + + usec_delay(CMND_INTERVAL * 4); + + if ((pbpctl_dev->wdt_status == WDT_STATUS_EN) && + (pbpctl_dev->bp_ext_ver < PXG4BPFI_VER) && (addr == CMND_REG_ADDR)) + pbpctl_dev->bypass_wdt_on_time = jiffies; +#ifdef BP_SYNC_FLAG + spin_unlock_irqrestore(&pbpctl_dev->bypass_wr_lock, flags); +#else + atomic_set(&pbpctl_dev->wdt_busy, 0); +#endif + +} + +static void write_data(bpctl_dev_t * pbpctl_dev, unsigned char value) +{ + write_reg(pbpctl_dev, value, CMND_REG_ADDR); +} + +static int read_reg(bpctl_dev_t * pbpctl_dev, unsigned char addr) +{ + uint32_t ctrl_ext = 0, ctrl = 0, ctrl_value = 0; + bpctl_dev_t *pbpctl_dev_c = NULL; + +#ifdef BP_SYNC_FLAG + unsigned long flags; + spin_lock_irqsave(&pbpctl_dev->bypass_wr_lock, flags); +#else + atomic_set(&pbpctl_dev->wdt_busy, 1); +#endif + if (pbpctl_dev->bp_10g9) { + if (!(pbpctl_dev_c = get_status_port_fn(pbpctl_dev))) + return -1; + } + + if (pbpctl_dev->bp_10g9) { + ctrl_ext = BP10G_READ_REG(pbpctl_dev, I2CCTL); + ctrl = BP10G_READ_REG(pbpctl_dev_c, ESDP); + + /* BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext&~(BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9))); */ + /* DATA 0 CLK 0 */ + BP10G_WRITE_REG(pbpctl_dev, I2CCTL, + (ctrl_ext & ~BP10G_MDIO_DATA_OUT9)); + BP10G_WRITE_REG(pbpctl_dev_c, ESDP, + ((ctrl | BP10G_MCLK_DIR_OUT9) & + ~(BP10G_MCLK_DATA_OUT9))); + + } else if (pbpctl_dev->bp_fiber5) { + ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL); + + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext | + BPCTLI_CTRL_EXT_MCLK_DIR5 + | + BPCTLI_CTRL_EXT_MDIO_DIR5) + & + ~ + (BPCTLI_CTRL_EXT_MDIO_DATA5 + | + BPCTLI_CTRL_EXT_MCLK_DATA5))); + } else if (pbpctl_dev->bp_i80) { + ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL); + ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); + + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext | + BPCTLI_CTRL_EXT_MDIO_DIR80) + & + ~BPCTLI_CTRL_EXT_MDIO_DATA80)); + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, + ((ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80) & + ~BPCTLI_CTRL_EXT_MCLK_DATA80)); + } else if (pbpctl_dev->bp_540) { + ctrl_ext = BP10G_READ_REG(pbpctl_dev, ESDP); + ctrl = BP10G_READ_REG(pbpctl_dev, ESDP); + + BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl | BP540_MCLK_DIR | + BP540_MDIO_DIR) & + ~(BP540_MDIO_DATA | + BP540_MCLK_DATA))); + } else if (pbpctl_dev->bp_10gb) { + ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO); + + BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, + (ctrl_ext | BP10GB_MDIO_CLR | BP10GB_MCLK_CLR) + & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_DIR | + BP10GB_MDIO_SET | BP10GB_MCLK_SET)); +#if 0 + + /*BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, (ctrl_ext | BP10GB_MCLK_DIR | BP10GB_MDIO_DIR| + BP10GB_MCLK_CLR|BP10GB_MDIO_CLR)); + ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO); + printk("1reg=%x\n", ctrl_ext); */ + + BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, ((ctrl_ext | + BP10GB_MCLK_SET | + BP10GB_MDIO_CLR)) + & ~(BP10GB_MCLK_CLR | BP10GB_MDIO_SET | + BP10GB_MCLK_DIR | BP10GB_MDIO_DIR)); + + /* bnx2x_set_spio(pbpctl_dev, 5, MISC_REGISTERS_SPIO_OUTPUT_LOW); + bnx2x_set_spio(pbpctl_dev, 4, MISC_REGISTERS_SPIO_OUTPUT_LOW); + bnx2x_set_spio(pbpctl_dev, 4, MISC_REGISTERS_SPIO_INPUT_HI_Z); */ + + ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO); + + //printk("2reg=%x\n", ctrl_ext); + +#ifdef BP_SYNC_FLAG + spin_unlock_irqrestore(&pbpctl_dev->bypass_wr_lock, flags); +#else + atomic_set(&pbpctl_dev->wdt_busy, 0); +#endif + + return 0; + +#endif + + } else if (!pbpctl_dev->bp_10g) { + + ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); + + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | + BPCTLI_CTRL_EXT_MCLK_DIR + | + BPCTLI_CTRL_EXT_MDIO_DIR) + & + ~ + (BPCTLI_CTRL_EXT_MDIO_DATA + | + BPCTLI_CTRL_EXT_MCLK_DATA))); + } else { + + // writel((0x0), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ; + ctrl = BP10G_READ_REG(pbpctl_dev, ESDP); + ctrl_ext = BP10G_READ_REG(pbpctl_dev, EODSDP); + BP10G_WRITE_REG(pbpctl_dev, EODSDP, + (ctrl_ext & + ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT))); + //BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA)); + + } + + usec_delay(CMND_INTERVAL); + + /*send sync cmd */ + write_pulse(pbpctl_dev, ctrl_ext, SYNC_CMD_VAL, SYNC_CMD_LEN); + /*send rd cmd */ + write_pulse(pbpctl_dev, ctrl_ext, RD_CMD_VAL, RD_CMD_LEN); + /*send addr */ + write_pulse(pbpctl_dev, ctrl_ext, addr, ADDR_CMD_LEN); + /*read data */ + /* zero */ + if (pbpctl_dev->bp_10g9) { + /* DATA 0 CLK 1 */ + /*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext|BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9)); */ + BP10G_WRITE_REG(pbpctl_dev, I2CCTL, + (ctrl_ext | BP10G_MDIO_DATA_OUT9)); + BP10G_WRITE_REG(pbpctl_dev_c, ESDP, + (ctrl | BP10G_MCLK_DATA_OUT9 | + BP10G_MCLK_DIR_OUT9)); + + } else if (pbpctl_dev->bp_fiber5) { + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext | + BPCTLI_CTRL_EXT_MCLK_DIR5 + | + BPCTLI_CTRL_EXT_MCLK_DATA5) + & + ~ + (BPCTLI_CTRL_EXT_MDIO_DIR5 + | + BPCTLI_CTRL_EXT_MDIO_DATA5))); + + } else if (pbpctl_dev->bp_i80) { + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, + (ctrl_ext & + ~(BPCTLI_CTRL_EXT_MDIO_DATA80 | + BPCTLI_CTRL_EXT_MDIO_DIR80))); + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, + (ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80 | + BPCTLI_CTRL_EXT_MCLK_DATA80)); + + } else if (pbpctl_dev->bp_540) { + BP10G_WRITE_REG(pbpctl_dev, ESDP, + (((ctrl | BP540_MDIO_DIR | BP540_MCLK_DIR | + BP540_MCLK_DATA) & ~BP540_MDIO_DATA))); + + } else if (pbpctl_dev->bp_10gb) { + + BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, + (ctrl_ext | BP10GB_MDIO_DIR | BP10GB_MCLK_SET) + & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_SET | + BP10GB_MDIO_CLR | BP10GB_MCLK_CLR)); + + } else if (!pbpctl_dev->bp_10g) + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | + BPCTLI_CTRL_EXT_MCLK_DIR + | + BPCTLI_CTRL_EXT_MCLK_DATA) + & + ~ + (BPCTLI_CTRL_EXT_MDIO_DIR + | + BPCTLI_CTRL_EXT_MDIO_DATA))); + else { + + // writel((0x8), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ; + BP10G_WRITE_REG(pbpctl_dev, EODSDP, + (ctrl_ext | BP10G_MCLK_DATA_OUT | + BP10G_MDIO_DATA_OUT)); + + // BP10G_WRITE_REG(pbpctl_dev, ESDP, (ctrl &~(BP10G_MDIO_DATA|BP10G_MDIO_DIR))); + + } + usec_delay(PULSE_TIME); + + ctrl_value = read_pulse(pbpctl_dev, ctrl_ext, RD_DATA_LEN); + + if (pbpctl_dev->bp_10g9) { + ctrl_ext = BP10G_READ_REG(pbpctl_dev, I2CCTL); + ctrl = BP10G_READ_REG(pbpctl_dev_c, ESDP); + + /* BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext&~(BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9))); */ + /* DATA 0 CLK 0 */ + BP10G_WRITE_REG(pbpctl_dev, I2CCTL, + (ctrl_ext & ~BP10G_MDIO_DATA_OUT9)); + BP10G_WRITE_REG(pbpctl_dev_c, ESDP, + ((ctrl | BP10G_MCLK_DIR_OUT9) & + ~(BP10G_MCLK_DATA_OUT9))); + + } else if (pbpctl_dev->bp_fiber5) { + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext | + BPCTLI_CTRL_EXT_MCLK_DIR5 + | + BPCTLI_CTRL_EXT_MDIO_DIR5) + & + ~ + (BPCTLI_CTRL_EXT_MDIO_DATA5 + | + BPCTLI_CTRL_EXT_MCLK_DATA5))); + } else if (pbpctl_dev->bp_i80) { + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext | + BPCTLI_CTRL_EXT_MDIO_DIR80) + & + ~BPCTLI_CTRL_EXT_MDIO_DATA80)); + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, + ((ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80) & + ~BPCTLI_CTRL_EXT_MCLK_DATA80)); + + } else if (pbpctl_dev->bp_540) { + ctrl = BP10G_READ_REG(pbpctl_dev, ESDP); + BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl | BP540_MCLK_DIR | + BP540_MDIO_DIR) & + ~(BP540_MDIO_DATA | + BP540_MCLK_DATA))); + + } else if (pbpctl_dev->bp_10gb) { + ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO); + BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, + (ctrl_ext | BP10GB_MDIO_CLR | BP10GB_MCLK_CLR) + & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_DIR | + BP10GB_MDIO_SET | BP10GB_MCLK_SET)); + + } else if (!pbpctl_dev->bp_10g) { + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | + BPCTLI_CTRL_EXT_MCLK_DIR + | + BPCTLI_CTRL_EXT_MDIO_DIR) + & + ~ + (BPCTLI_CTRL_EXT_MDIO_DATA + | + BPCTLI_CTRL_EXT_MCLK_DATA))); + } else { + + //writel((0x0), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ; + ctrl = BP10G_READ_REG(pbpctl_dev, ESDP); + ctrl_ext = BP10G_READ_REG(pbpctl_dev, EODSDP); + BP10G_WRITE_REG(pbpctl_dev, EODSDP, + (ctrl_ext & + ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT))); + //BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA)); + + } + + usec_delay(CMND_INTERVAL * 4); +#ifdef BP_SYNC_FLAG + spin_unlock_irqrestore(&pbpctl_dev->bypass_wr_lock, flags); +#else + atomic_set(&pbpctl_dev->wdt_busy, 0); +#endif + + return ctrl_value; +} + +static int wdt_pulse(bpctl_dev_t * pbpctl_dev) +{ + uint32_t ctrl_ext = 0, ctrl = 0; + bpctl_dev_t *pbpctl_dev_c = NULL; + +#ifdef BP_SYNC_FLAG + unsigned long flags; + + spin_lock_irqsave(&pbpctl_dev->bypass_wr_lock, flags); +#else + + if ((atomic_read(&pbpctl_dev->wdt_busy)) == 1) + return -1; +#endif + if (pbpctl_dev->bp_10g9) { + if (!(pbpctl_dev_c = get_status_port_fn(pbpctl_dev))) + return -1; + } + + if (pbpctl_dev->bp_10g9) { + ctrl_ext = BP10G_READ_REG(pbpctl_dev, I2CCTL); + ctrl = BP10G_READ_REG(pbpctl_dev_c, ESDP); + + /* BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext&~(BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9))); */ + /* DATA 0 CLK 0 */ + BP10G_WRITE_REG(pbpctl_dev, I2CCTL, + (ctrl_ext & ~BP10G_MDIO_DATA_OUT9)); + BP10G_WRITE_REG(pbpctl_dev_c, ESDP, + ((ctrl | BP10G_MCLK_DIR_OUT9) & + ~(BP10G_MCLK_DATA_OUT9))); + + } else if (pbpctl_dev->bp_fiber5) { + ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL); + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext | + BPCTLI_CTRL_EXT_MCLK_DIR5 + | + BPCTLI_CTRL_EXT_MDIO_DIR5) + & + ~ + (BPCTLI_CTRL_EXT_MDIO_DATA5 + | + BPCTLI_CTRL_EXT_MCLK_DATA5))); + } else if (pbpctl_dev->bp_i80) { + ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL); + ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext | + BPCTLI_CTRL_EXT_MDIO_DIR80) + & + ~BPCTLI_CTRL_EXT_MDIO_DATA80)); + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, + ((ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80) & + ~BPCTLI_CTRL_EXT_MCLK_DATA80)); + } else if (pbpctl_dev->bp_540) { + ctrl_ext = ctrl = BP10G_READ_REG(pbpctl_dev, ESDP); + BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl | BP540_MCLK_DIR | + BP540_MDIO_DIR) & + ~(BP540_MDIO_DATA | + BP540_MCLK_DATA))); + } else if (pbpctl_dev->bp_10gb) { + ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO); + BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, + (ctrl_ext | BP10GB_MDIO_CLR | BP10GB_MCLK_CLR) + & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_DIR | + BP10GB_MDIO_SET | BP10GB_MCLK_SET)); + + } else if (!pbpctl_dev->bp_10g) { + + ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | + BPCTLI_CTRL_EXT_MCLK_DIR + | + BPCTLI_CTRL_EXT_MDIO_DIR) + & + ~ + (BPCTLI_CTRL_EXT_MDIO_DATA + | + BPCTLI_CTRL_EXT_MCLK_DATA))); + } else { + + // writel((0x0), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ; + ctrl = BP10G_READ_REG(pbpctl_dev, ESDP); + ctrl_ext = BP10G_READ_REG(pbpctl_dev, EODSDP); + BP10G_WRITE_REG(pbpctl_dev, EODSDP, + (ctrl_ext & + ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT))); + //BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA)); + + } + if (pbpctl_dev->bp_10g9) { + /* BP10G_WRITE_REG(pbpctl_dev, I2CCTL, ((ctrl_ext|BP10G_MCLK_DATA_OUT9)&~BP10G_MDIO_DATA_OUT9)); */ + /* DATA 0 CLK 1 */ + BP10G_WRITE_REG(pbpctl_dev, I2CCTL, + (ctrl_ext & ~BP10G_MDIO_DATA_OUT9)); + BP10G_WRITE_REG(pbpctl_dev_c, ESDP, + (ctrl | BP10G_MCLK_DATA_OUT9 | + BP10G_MCLK_DIR_OUT9)); + + } else if (pbpctl_dev->bp_fiber5) { + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext | + BPCTLI_CTRL_EXT_MCLK_DIR5 + | + BPCTLI_CTRL_EXT_MDIO_DIR5 + | + BPCTLI_CTRL_EXT_MCLK_DATA5) + & + ~ + (BPCTLI_CTRL_EXT_MDIO_DATA5))); + } else if (pbpctl_dev->bp_i80) { + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext | + BPCTLI_CTRL_EXT_MDIO_DIR80) + & + ~BPCTLI_CTRL_EXT_MDIO_DATA80)); + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, + (ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80 | + BPCTLI_CTRL_EXT_MCLK_DATA80)); + + } else if (pbpctl_dev->bp_540) { + BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl | + BP540_MDIO_DIR | + BP540_MCLK_DIR | + BP540_MCLK_DATA) & + ~BP540_MDIO_DATA)); + + } else if (pbpctl_dev->bp_10gb) { + ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO); + + BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, + (ctrl_ext | BP10GB_MDIO_CLR | BP10GB_MCLK_SET) + & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_DIR | + BP10GB_MDIO_SET | BP10GB_MCLK_CLR)); + + } else if (!pbpctl_dev->bp_10g) + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | + BPCTLI_CTRL_EXT_MCLK_DIR + | + BPCTLI_CTRL_EXT_MDIO_DIR + | + BPCTLI_CTRL_EXT_MCLK_DATA) + & + ~ + (BPCTLI_CTRL_EXT_MDIO_DATA))); + else { + + //writel((0x8), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ; + BP10G_WRITE_REG(pbpctl_dev, EODSDP, + ((ctrl_ext | BP10G_MCLK_DATA_OUT) & + ~BP10G_MDIO_DATA_OUT)); + //BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA)); + + } + + usec_delay(WDT_INTERVAL); + if (pbpctl_dev->bp_10g9) { + /* BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext&~(BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9))); */ + /* DATA 0 CLK 0 */ + BP10G_WRITE_REG(pbpctl_dev, I2CCTL, + (ctrl_ext & ~BP10G_MDIO_DATA_OUT9)); + BP10G_WRITE_REG(pbpctl_dev_c, ESDP, + ((ctrl | BP10G_MCLK_DIR_OUT9) & + ~(BP10G_MCLK_DATA_OUT9))); + + } else if (pbpctl_dev->bp_fiber5) { + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext | + BPCTLI_CTRL_EXT_MCLK_DIR5 + | + BPCTLI_CTRL_EXT_MDIO_DIR5) + & + ~ + (BPCTLI_CTRL_EXT_MCLK_DATA5 + | + BPCTLI_CTRL_EXT_MDIO_DATA5))); + } else if (pbpctl_dev->bp_i80) { + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext | + BPCTLI_CTRL_EXT_MDIO_DIR80) + & + ~BPCTLI_CTRL_EXT_MDIO_DATA80)); + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, + ((ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80) & + ~BPCTLI_CTRL_EXT_MCLK_DATA80)); + + } else if (pbpctl_dev->bp_540) { + BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl | BP540_MCLK_DIR | + BP540_MDIO_DIR) & + ~(BP540_MDIO_DATA | + BP540_MCLK_DATA))); + + } else if (pbpctl_dev->bp_10gb) { + ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO); + BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, + (ctrl_ext | BP10GB_MDIO_CLR | BP10GB_MCLK_CLR) + & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_DIR | + BP10GB_MDIO_SET | BP10GB_MCLK_SET)); + + } else if (!pbpctl_dev->bp_10g) + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | + BPCTLI_CTRL_EXT_MCLK_DIR + | + BPCTLI_CTRL_EXT_MDIO_DIR) + & + ~ + (BPCTLI_CTRL_EXT_MCLK_DATA + | + BPCTLI_CTRL_EXT_MDIO_DATA))); + else { + + //writel((0x0), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ; + BP10G_WRITE_REG(pbpctl_dev, EODSDP, + (ctrl_ext & + ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT))); + //BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA)); + } + if ((pbpctl_dev->wdt_status == WDT_STATUS_EN) /*&& + (pbpctl_dev->bp_ext_verbypass_wdt_on_time = jiffies; +#ifdef BP_SYNC_FLAG + spin_unlock_irqrestore(&pbpctl_dev->bypass_wr_lock, flags); +#endif + usec_delay(CMND_INTERVAL * 4); + return 0; +} + +static void data_pulse(bpctl_dev_t * pbpctl_dev, unsigned char value) +{ + + uint32_t ctrl_ext = 0; +#ifdef BP_SYNC_FLAG + unsigned long flags; +#endif + wdt_time_left(pbpctl_dev); +#ifdef BP_SYNC_FLAG + spin_lock_irqsave(&pbpctl_dev->bypass_wr_lock, flags); +#else + atomic_set(&pbpctl_dev->wdt_busy, 1); +#endif + + ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | + BPCTLI_CTRL_EXT_SDP6_DIR | + BPCTLI_CTRL_EXT_SDP7_DIR) & + ~(BPCTLI_CTRL_EXT_SDP6_DATA | + BPCTLI_CTRL_EXT_SDP7_DATA))); + + usec_delay(INIT_CMND_INTERVAL); + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | + BPCTLI_CTRL_EXT_SDP6_DIR | + BPCTLI_CTRL_EXT_SDP7_DIR | + BPCTLI_CTRL_EXT_SDP6_DATA) & + ~ + (BPCTLI_CTRL_EXT_SDP7_DATA))); + usec_delay(INIT_CMND_INTERVAL); + + while (value) { + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ctrl_ext | + BPCTLI_CTRL_EXT_SDP6_DIR | + BPCTLI_CTRL_EXT_SDP7_DIR | + BPCTLI_CTRL_EXT_SDP6_DATA | + BPCTLI_CTRL_EXT_SDP7_DATA); + usec_delay(PULSE_INTERVAL); + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | + BPCTLI_CTRL_EXT_SDP6_DIR + | + BPCTLI_CTRL_EXT_SDP7_DIR + | + BPCTLI_CTRL_EXT_SDP6_DATA) + & + ~BPCTLI_CTRL_EXT_SDP7_DATA)); + usec_delay(PULSE_INTERVAL); + value--; + + } + usec_delay(INIT_CMND_INTERVAL - PULSE_INTERVAL); + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | + BPCTLI_CTRL_EXT_SDP6_DIR | + BPCTLI_CTRL_EXT_SDP7_DIR) & + ~(BPCTLI_CTRL_EXT_SDP6_DATA | + BPCTLI_CTRL_EXT_SDP7_DATA))); + usec_delay(WDT_TIME_CNT); + if (pbpctl_dev->wdt_status == WDT_STATUS_EN) + pbpctl_dev->bypass_wdt_on_time = jiffies; +#ifdef BP_SYNC_FLAG + spin_unlock_irqrestore(&pbpctl_dev->bypass_wr_lock, flags); +#else + atomic_set(&pbpctl_dev->wdt_busy, 0); +#endif + +} + +static int send_wdt_pulse(bpctl_dev_t * pbpctl_dev) +{ + uint32_t ctrl_ext = 0; + +#ifdef BP_SYNC_FLAG + unsigned long flags; + + spin_lock_irqsave(&pbpctl_dev->bypass_wr_lock, flags); +#else + + if ((atomic_read(&pbpctl_dev->wdt_busy)) == 1) + return -1; +#endif + wdt_time_left(pbpctl_dev); + ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); + + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ctrl_ext | /* 1 */ + BPCTLI_CTRL_EXT_SDP7_DIR | + BPCTLI_CTRL_EXT_SDP7_DATA); + usec_delay(PULSE_INTERVAL); + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | /* 0 */ + BPCTLI_CTRL_EXT_SDP7_DIR) & + ~BPCTLI_CTRL_EXT_SDP7_DATA)); + + usec_delay(PULSE_INTERVAL); + if (pbpctl_dev->wdt_status == WDT_STATUS_EN) + pbpctl_dev->bypass_wdt_on_time = jiffies; +#ifdef BP_SYNC_FLAG + spin_unlock_irqrestore(&pbpctl_dev->bypass_wr_lock, flags); +#endif + + return 0; +} + +void send_bypass_clear_pulse(bpctl_dev_t * pbpctl_dev, unsigned int value) +{ + uint32_t ctrl_ext = 0; + + ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | /* 0 */ + BPCTLI_CTRL_EXT_SDP6_DIR) & + ~BPCTLI_CTRL_EXT_SDP6_DATA)); + + usec_delay(PULSE_INTERVAL); + while (value) { + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ctrl_ext | /* 1 */ + BPCTLI_CTRL_EXT_SDP6_DIR | + BPCTLI_CTRL_EXT_SDP6_DATA); + usec_delay(PULSE_INTERVAL); + value--; + } + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | /* 0 */ + BPCTLI_CTRL_EXT_SDP6_DIR) & + ~BPCTLI_CTRL_EXT_SDP6_DATA)); + usec_delay(PULSE_INTERVAL); +} + +/* #endif OLD_FW */ +#ifdef BYPASS_DEBUG + +int pulse_set_fn(bpctl_dev_t * pbpctl_dev, unsigned int counter) +{ + uint32_t ctrl_ext = 0; + + if (!pbpctl_dev) + return -1; + + ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); + write_pulse_1(pbpctl_dev, ctrl_ext, counter, counter); + + pbpctl_dev->bypass_wdt_status = 0; + if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { + write_pulse_1(pbpctl_dev, ctrl_ext, counter, counter); + } else { + wdt_time_left(pbpctl_dev); + if (pbpctl_dev->wdt_status == WDT_STATUS_EN) { + pbpctl_dev->wdt_status = 0; + data_pulse(pbpctl_dev, counter); + pbpctl_dev->wdt_status = WDT_STATUS_EN; + pbpctl_dev->bypass_wdt_on_time = jiffies; + + } else + data_pulse(pbpctl_dev, counter); + } + + return 0; +} + +int zero_set_fn(bpctl_dev_t * pbpctl_dev) +{ + uint32_t ctrl_ext = 0, ctrl_value = 0; + if (!pbpctl_dev) + return -1; + + if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { + printk("zero_set"); + + ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); + + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | + BPCTLI_CTRL_EXT_MCLK_DIR) + & + ~ + (BPCTLI_CTRL_EXT_MCLK_DATA + | + BPCTLI_CTRL_EXT_MDIO_DIR + | + BPCTLI_CTRL_EXT_MDIO_DATA))); + + } + return ctrl_value; +} + +int pulse_get2_fn(bpctl_dev_t * pbpctl_dev) +{ + uint32_t ctrl_ext = 0, ctrl_value = 0; + if (!pbpctl_dev) + return -1; + + if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { + printk("pulse_get_fn\n"); + ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); + ctrl_value = read_pulse_2(pbpctl_dev, ctrl_ext); + printk("read:%d\n", ctrl_value); + } + return ctrl_value; +} + +int pulse_get1_fn(bpctl_dev_t * pbpctl_dev) +{ + uint32_t ctrl_ext = 0, ctrl_value = 0; + if (!pbpctl_dev) + return -1; + + if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { + + printk("pulse_get_fn\n"); + + ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); + ctrl_value = read_pulse_1(pbpctl_dev, ctrl_ext); + printk("read:%d\n", ctrl_value); + } + return ctrl_value; +} + +int gpio6_set_fn(bpctl_dev_t * pbpctl_dev) +{ + uint32_t ctrl_ext = 0; + + ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ctrl_ext | + BPCTLI_CTRL_EXT_SDP6_DIR | + BPCTLI_CTRL_EXT_SDP6_DATA); + return 0; +} + +int gpio7_set_fn(bpctl_dev_t * pbpctl_dev) +{ + uint32_t ctrl_ext = 0; + + ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ctrl_ext | + BPCTLI_CTRL_EXT_SDP7_DIR | + BPCTLI_CTRL_EXT_SDP7_DATA); + return 0; +} + +int gpio7_clear_fn(bpctl_dev_t * pbpctl_dev) +{ + uint32_t ctrl_ext = 0; + + ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | + BPCTLI_CTRL_EXT_SDP7_DIR) & + ~BPCTLI_CTRL_EXT_SDP7_DATA)); + return 0; +} + +int gpio6_clear_fn(bpctl_dev_t * pbpctl_dev) +{ + uint32_t ctrl_ext = 0; + + ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | + BPCTLI_CTRL_EXT_SDP6_DIR) & + ~BPCTLI_CTRL_EXT_SDP6_DATA)); + return 0; +} +#endif /*BYPASS_DEBUG */ + +static bpctl_dev_t *get_status_port_fn(bpctl_dev_t * pbpctl_dev) +{ + int idx_dev = 0; + + if (pbpctl_dev == NULL) + return NULL; + + if ((pbpctl_dev->func == 0) || (pbpctl_dev->func == 2)) { + for (idx_dev = 0; + ((bpctl_dev_arr[idx_dev].pdev != NULL) + && (idx_dev < device_num)); idx_dev++) { + if ((bpctl_dev_arr[idx_dev].bus == pbpctl_dev->bus) + && (bpctl_dev_arr[idx_dev].slot == pbpctl_dev->slot) + && ((bpctl_dev_arr[idx_dev].func == 1) + && (pbpctl_dev->func == 0))) { + + return (&(bpctl_dev_arr[idx_dev])); + } + if ((bpctl_dev_arr[idx_dev].bus == pbpctl_dev->bus) && + (bpctl_dev_arr[idx_dev].slot == pbpctl_dev->slot) && + ((bpctl_dev_arr[idx_dev].func == 3) + && (pbpctl_dev->func == 2))) { + + return (&(bpctl_dev_arr[idx_dev])); + } + } + } + return NULL; +} + +static bpctl_dev_t *get_master_port_fn(bpctl_dev_t * pbpctl_dev) +{ + int idx_dev = 0; + + if (pbpctl_dev == NULL) + return NULL; + + if ((pbpctl_dev->func == 1) || (pbpctl_dev->func == 3)) { + for (idx_dev = 0; + ((bpctl_dev_arr[idx_dev].pdev != NULL) + && (idx_dev < device_num)); idx_dev++) { + if ((bpctl_dev_arr[idx_dev].bus == pbpctl_dev->bus) + && (bpctl_dev_arr[idx_dev].slot == pbpctl_dev->slot) + && ((bpctl_dev_arr[idx_dev].func == 0) + && (pbpctl_dev->func == 1))) { + + return (&(bpctl_dev_arr[idx_dev])); + } + if ((bpctl_dev_arr[idx_dev].bus == pbpctl_dev->bus) && + (bpctl_dev_arr[idx_dev].slot == pbpctl_dev->slot) && + ((bpctl_dev_arr[idx_dev].func == 2) + && (pbpctl_dev->func == 3))) { + + return (&(bpctl_dev_arr[idx_dev])); + } + } + } + return NULL; +} + +/**************************************/ +/**************INTEL API***************/ +/**************************************/ + +static void write_data_port_int(bpctl_dev_t * pbpctl_dev, + unsigned char ctrl_value) +{ + uint32_t value; + + value = BPCTL_READ_REG(pbpctl_dev, CTRL); +/* Make SDP0 Pin Directonality to Output */ + value |= BPCTLI_CTRL_SDP0_DIR; + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, value); + + value &= ~BPCTLI_CTRL_SDP0_DATA; + value |= ((ctrl_value & 0x1) << BPCTLI_CTRL_SDP0_SHIFT); + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, value); + + value = (BPCTL_READ_REG(pbpctl_dev, CTRL_EXT)); +/* Make SDP2 Pin Directonality to Output */ + value |= BPCTLI_CTRL_EXT_SDP6_DIR; + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, value); + + value &= ~BPCTLI_CTRL_EXT_SDP6_DATA; + value |= (((ctrl_value & 0x2) >> 1) << BPCTLI_CTRL_EXT_SDP6_SHIFT); + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, value); + +} + +static int write_data_int(bpctl_dev_t * pbpctl_dev, unsigned char value) +{ + bpctl_dev_t *pbpctl_dev_b = NULL; + + if (!(pbpctl_dev_b = get_status_port_fn(pbpctl_dev))) + return -1; + atomic_set(&pbpctl_dev->wdt_busy, 1); + write_data_port_int(pbpctl_dev, value & 0x3); + write_data_port_int(pbpctl_dev_b, ((value & 0xc) >> 2)); + atomic_set(&pbpctl_dev->wdt_busy, 0); + + return 0; +} + +static int wdt_pulse_int(bpctl_dev_t * pbpctl_dev) +{ + + if ((atomic_read(&pbpctl_dev->wdt_busy)) == 1) + return -1; + + if ((write_data_int(pbpctl_dev, RESET_WDT_INT)) < 0) + return -1; + msec_delay_bp(CMND_INTERVAL_INT); + if ((write_data_int(pbpctl_dev, CMND_OFF_INT)) < 0) + return -1; + msec_delay_bp(CMND_INTERVAL_INT); + + if (pbpctl_dev->wdt_status == WDT_STATUS_EN) + pbpctl_dev->bypass_wdt_on_time = jiffies; + + return 0; +} + +/*************************************/ +/************* COMMANDS **************/ +/*************************************/ + +/* CMND_ON 0x4 (100)*/ +int cmnd_on(bpctl_dev_t * pbpctl_dev) +{ + int ret = BP_NOT_CAP; + + if (pbpctl_dev->bp_caps & SW_CTL_CAP) { + if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) + return 0; + if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) + write_data(pbpctl_dev, CMND_ON); + else + data_pulse(pbpctl_dev, CMND_ON); + ret = 0; + } + return ret; +} + +/* CMND_OFF 0x2 (10)*/ +int cmnd_off(bpctl_dev_t * pbpctl_dev) +{ + int ret = BP_NOT_CAP; + + if (pbpctl_dev->bp_caps & SW_CTL_CAP) { + if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) { + write_data_int(pbpctl_dev, CMND_OFF_INT); + msec_delay_bp(CMND_INTERVAL_INT); + } else if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) + write_data(pbpctl_dev, CMND_OFF); + else + data_pulse(pbpctl_dev, CMND_OFF); + ret = 0; + }; + return ret; +} + +/* BYPASS_ON (0xa)*/ +int bypass_on(bpctl_dev_t * pbpctl_dev) +{ + int ret = BP_NOT_CAP; + + if (pbpctl_dev->bp_caps & BP_CAP) { + if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) { + write_data_int(pbpctl_dev, BYPASS_ON_INT); + msec_delay_bp(BYPASS_DELAY_INT); + pbpctl_dev->bp_status_un = 0; + } else if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { + write_data(pbpctl_dev, BYPASS_ON); + if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) + msec_delay_bp(LATCH_DELAY); + } else + data_pulse(pbpctl_dev, BYPASS_ON); + ret = 0; + }; + return ret; +} + +/* BYPASS_OFF (0x8 111)*/ +int bypass_off(bpctl_dev_t * pbpctl_dev) +{ + int ret = BP_NOT_CAP; + + if (pbpctl_dev->bp_caps & BP_CAP) { + if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) { + write_data_int(pbpctl_dev, DIS_BYPASS_CAP_INT); + msec_delay_bp(BYPASS_DELAY_INT); + write_data_int(pbpctl_dev, PWROFF_BYPASS_ON_INT); + msec_delay_bp(BYPASS_DELAY_INT); + pbpctl_dev->bp_status_un = 0; + } else if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { + write_data(pbpctl_dev, BYPASS_OFF); + if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) + msec_delay_bp(LATCH_DELAY); + } else + data_pulse(pbpctl_dev, BYPASS_OFF); + ret = 0; + } + return ret; +} + +/* TAP_OFF (0x9)*/ +int tap_off(bpctl_dev_t * pbpctl_dev) +{ + int ret = BP_NOT_CAP; + if ((pbpctl_dev->bp_caps & TAP_CAP) + && (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER)) { + write_data(pbpctl_dev, TAP_OFF); + msec_delay_bp(LATCH_DELAY); + ret = 0; + }; + return ret; +} + +/* TAP_ON (0xb)*/ +int tap_on(bpctl_dev_t * pbpctl_dev) +{ + int ret = BP_NOT_CAP; + if ((pbpctl_dev->bp_caps & TAP_CAP) + && (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER)) { + write_data(pbpctl_dev, TAP_ON); + msec_delay_bp(LATCH_DELAY); + ret = 0; + }; + return ret; +} + +/* DISC_OFF (0x9)*/ +int disc_off(bpctl_dev_t * pbpctl_dev) +{ + int ret = 0; + if ((pbpctl_dev->bp_caps & DISC_CAP) && (pbpctl_dev->bp_ext_ver >= 0x8)) { + write_data(pbpctl_dev, DISC_OFF); + msec_delay_bp(LATCH_DELAY); + } else + ret = BP_NOT_CAP; + return ret; +} + +/* DISC_ON (0xb)*/ +int disc_on(bpctl_dev_t * pbpctl_dev) +{ + int ret = 0; + if ((pbpctl_dev->bp_caps & DISC_CAP) && (pbpctl_dev->bp_ext_ver >= 0x8)) { + write_data(pbpctl_dev, /*DISC_ON */ 0x85); + msec_delay_bp(LATCH_DELAY); + } else + ret = BP_NOT_CAP; + return ret; +} + +/* DISC_PORT_ON */ +int disc_port_on(bpctl_dev_t * pbpctl_dev) +{ + int ret = 0; + bpctl_dev_t *pbpctl_dev_m; + + if ((is_bypass_fn(pbpctl_dev)) == 1) + pbpctl_dev_m = pbpctl_dev; + else + pbpctl_dev_m = get_master_port_fn(pbpctl_dev); + if (pbpctl_dev_m == NULL) + return BP_NOT_CAP; + + if (pbpctl_dev_m->bp_caps_ex & DISC_PORT_CAP_EX) { + if (is_bypass_fn(pbpctl_dev) == 1) { + + write_data(pbpctl_dev_m, TX_DISA); + } else { + + write_data(pbpctl_dev_m, TX_DISB); + } + + msec_delay_bp(LATCH_DELAY); + + } + return ret; +} + +/* DISC_PORT_OFF */ +int disc_port_off(bpctl_dev_t * pbpctl_dev) +{ + int ret = 0; + bpctl_dev_t *pbpctl_dev_m; + + if ((is_bypass_fn(pbpctl_dev)) == 1) + pbpctl_dev_m = pbpctl_dev; + else + pbpctl_dev_m = get_master_port_fn(pbpctl_dev); + if (pbpctl_dev_m == NULL) + return BP_NOT_CAP; + + if (pbpctl_dev_m->bp_caps_ex & DISC_PORT_CAP_EX) { + if (is_bypass_fn(pbpctl_dev) == 1) + write_data(pbpctl_dev_m, TX_ENA); + else + write_data(pbpctl_dev_m, TX_ENB); + + msec_delay_bp(LATCH_DELAY); + + } + return ret; +} + +/*TWO_PORT_LINK_HW_EN (0xe)*/ +int tpl_hw_on(bpctl_dev_t * pbpctl_dev) +{ + int ret = 0, ctrl = 0; + bpctl_dev_t *pbpctl_dev_b = NULL; + + if (!(pbpctl_dev_b = get_status_port_fn(pbpctl_dev))) + return BP_NOT_CAP; + + if (pbpctl_dev->bp_caps_ex & TPL2_CAP_EX) { + cmnd_on(pbpctl_dev); + write_data(pbpctl_dev, TPL2_ON); + msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY); + cmnd_off(pbpctl_dev); + return ret; + } + + if (TPL_IF_SERIES(pbpctl_dev->subdevice)) { + ctrl = BPCTL_READ_REG(pbpctl_dev_b, CTRL); + BPCTL_BP_WRITE_REG(pbpctl_dev_b, CTRL, + ((ctrl | BPCTLI_CTRL_SWDPIO0) & + ~BPCTLI_CTRL_SWDPIN0)); + } else + ret = BP_NOT_CAP; + return ret; +} + +/*TWO_PORT_LINK_HW_DIS (0xc)*/ +int tpl_hw_off(bpctl_dev_t * pbpctl_dev) +{ + int ret = 0, ctrl = 0; + bpctl_dev_t *pbpctl_dev_b = NULL; + + if (!(pbpctl_dev_b = get_status_port_fn(pbpctl_dev))) + return BP_NOT_CAP; + if (pbpctl_dev->bp_caps_ex & TPL2_CAP_EX) { + cmnd_on(pbpctl_dev); + write_data(pbpctl_dev, TPL2_OFF); + msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY); + cmnd_off(pbpctl_dev); + return ret; + } + if (TPL_IF_SERIES(pbpctl_dev->subdevice)) { + ctrl = BPCTL_READ_REG(pbpctl_dev_b, CTRL); + BPCTL_BP_WRITE_REG(pbpctl_dev_b, CTRL, + (ctrl | BPCTLI_CTRL_SWDPIO0 | + BPCTLI_CTRL_SWDPIN0)); + } else + ret = BP_NOT_CAP; + return ret; +} + +/* WDT_OFF (0x6 110)*/ +int wdt_off(bpctl_dev_t * pbpctl_dev) +{ + int ret = BP_NOT_CAP; + + if (pbpctl_dev->bp_caps & WD_CTL_CAP) { + if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) { + bypass_off(pbpctl_dev); + } else if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) + write_data(pbpctl_dev, WDT_OFF); + else + data_pulse(pbpctl_dev, WDT_OFF); + pbpctl_dev->wdt_status = WDT_STATUS_DIS; + ret = 0; + }; + return ret; +} + +/* WDT_ON (0x10)*/ + +/***Global***/ +static unsigned int + wdt_val_array[] = { 1000, 1500, 2000, 3000, 4000, 8000, 16000, 32000, 0 }; + +int wdt_on(bpctl_dev_t * pbpctl_dev, unsigned int timeout) +{ + + if (pbpctl_dev->bp_caps & WD_CTL_CAP) { + unsigned int pulse = 0, temp_value = 0, temp_cnt = 0; + pbpctl_dev->wdt_status = 0; + + if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) { + for (; wdt_val_array[temp_cnt]; temp_cnt++) + if (timeout <= wdt_val_array[temp_cnt]) + break; + + if (!wdt_val_array[temp_cnt]) + temp_cnt--; + + timeout = wdt_val_array[temp_cnt]; + temp_cnt += 0x7; + + write_data_int(pbpctl_dev, DIS_BYPASS_CAP_INT); + msec_delay_bp(BYPASS_DELAY_INT); + pbpctl_dev->bp_status_un = 0; + write_data_int(pbpctl_dev, temp_cnt); + pbpctl_dev->bypass_wdt_on_time = jiffies; + msec_delay_bp(CMND_INTERVAL_INT); + pbpctl_dev->bypass_timer_interval = timeout; + } else { + timeout = + (timeout < + TIMEOUT_UNIT ? TIMEOUT_UNIT : (timeout > + WDT_TIMEOUT_MAX ? + WDT_TIMEOUT_MAX : + timeout)); + temp_value = timeout / 100; + while ((temp_value >>= 1)) + temp_cnt++; + if (timeout > ((1 << temp_cnt) * 100)) + temp_cnt++; + pbpctl_dev->bypass_wdt_on_time = jiffies; + pulse = (WDT_ON | temp_cnt); + if (pbpctl_dev->bp_ext_ver == OLD_IF_VER) + data_pulse(pbpctl_dev, pulse); + else + write_data(pbpctl_dev, pulse); + pbpctl_dev->bypass_timer_interval = + (1 << temp_cnt) * 100; + } + pbpctl_dev->wdt_status = WDT_STATUS_EN; + return 0; + } + return BP_NOT_CAP; +} + +void bp75_put_hw_semaphore_generic(bpctl_dev_t * pbpctl_dev) +{ + u32 swsm; + + swsm = BPCTL_READ_REG(pbpctl_dev, SWSM); + + swsm &= ~(BPCTLI_SWSM_SMBI | BPCTLI_SWSM_SWESMBI); + + BPCTL_WRITE_REG(pbpctl_dev, SWSM, swsm); +} + +s32 bp75_get_hw_semaphore_generic(bpctl_dev_t * pbpctl_dev) +{ + u32 swsm; + s32 ret_val = 0; + s32 timeout = 8192 + 1; + s32 i = 0; + + /* Get the SW semaphore */ + while (i < timeout) { + swsm = BPCTL_READ_REG(pbpctl_dev, SWSM); + if (!(swsm & BPCTLI_SWSM_SMBI)) + break; + + usec_delay(50); + i++; + } + + if (i == timeout) { + printk + ("bpctl_mod: Driver can't access device - SMBI bit is set.\n"); + ret_val = -1; + goto out; + } + + /* Get the FW semaphore. */ + for (i = 0; i < timeout; i++) { + swsm = BPCTL_READ_REG(pbpctl_dev, SWSM); + BPCTL_WRITE_REG(pbpctl_dev, SWSM, swsm | BPCTLI_SWSM_SWESMBI); + + /* Semaphore acquired if bit latched */ + if (BPCTL_READ_REG(pbpctl_dev, SWSM) & BPCTLI_SWSM_SWESMBI) + break; + + usec_delay(50); + } + + if (i == timeout) { + /* Release semaphores */ + bp75_put_hw_semaphore_generic(pbpctl_dev); + printk("bpctl_mod: Driver can't access the NVM\n"); + ret_val = -1; + goto out; + } + + out: + return ret_val; +} + +static void bp75_release_phy(bpctl_dev_t * pbpctl_dev) +{ + u16 mask = BPCTLI_SWFW_PHY0_SM; + u32 swfw_sync; + + if ((pbpctl_dev->func == 1) || (pbpctl_dev->func == 3)) + mask = BPCTLI_SWFW_PHY1_SM; + + while (bp75_get_hw_semaphore_generic(pbpctl_dev) != 0) ; + /* Empty */ + + swfw_sync = BPCTL_READ_REG(pbpctl_dev, SW_FW_SYNC); + swfw_sync &= ~mask; + BPCTL_WRITE_REG(pbpctl_dev, SW_FW_SYNC, swfw_sync); + + bp75_put_hw_semaphore_generic(pbpctl_dev); +} + +static s32 bp75_acquire_phy(bpctl_dev_t * pbpctl_dev) +{ + u16 mask = BPCTLI_SWFW_PHY0_SM; + u32 swfw_sync; + u32 swmask; + u32 fwmask; + s32 ret_val = 0; + s32 i = 0, timeout = 200; + + if ((pbpctl_dev->func == 1) || (pbpctl_dev->func == 3)) + mask = BPCTLI_SWFW_PHY1_SM; + + swmask = mask; + fwmask = mask << 16; + + while (i < timeout) { + if (bp75_get_hw_semaphore_generic(pbpctl_dev)) { + ret_val = -1; + goto out; + } + + swfw_sync = BPCTL_READ_REG(pbpctl_dev, SW_FW_SYNC); + if (!(swfw_sync & (fwmask | swmask))) + break; + + bp75_put_hw_semaphore_generic(pbpctl_dev); + mdelay(5); + i++; + } + + if (i == timeout) { + printk + ("bpctl_mod: Driver can't access resource, SW_FW_SYNC timeout.\n"); + ret_val = -1; + goto out; + } + + swfw_sync |= swmask; + BPCTL_WRITE_REG(pbpctl_dev, SW_FW_SYNC, swfw_sync); + + bp75_put_hw_semaphore_generic(pbpctl_dev); + + out: + return ret_val; +} + +s32 bp75_read_phy_reg_mdic(bpctl_dev_t * pbpctl_dev, u32 offset, u16 * data) +{ + u32 i, mdic = 0; + s32 ret_val = 0; + u32 phy_addr = 1; + + mdic = ((offset << BPCTLI_MDIC_REG_SHIFT) | + (phy_addr << BPCTLI_MDIC_PHY_SHIFT) | (BPCTLI_MDIC_OP_READ)); + + BPCTL_WRITE_REG(pbpctl_dev, MDIC, mdic); + + for (i = 0; i < (BPCTLI_GEN_POLL_TIMEOUT * 3); i++) { + usec_delay(50); + mdic = BPCTL_READ_REG(pbpctl_dev, MDIC); + if (mdic & BPCTLI_MDIC_READY) + break; + } + if (!(mdic & BPCTLI_MDIC_READY)) { + printk("bpctl_mod: MDI Read did not complete\n"); + ret_val = -1; + goto out; + } + if (mdic & BPCTLI_MDIC_ERROR) { + printk("bpctl_mod: MDI Error\n"); + ret_val = -1; + goto out; + } + *data = (u16) mdic; + + out: + return ret_val; +} + +s32 bp75_write_phy_reg_mdic(bpctl_dev_t * pbpctl_dev, u32 offset, u16 data) +{ + u32 i, mdic = 0; + s32 ret_val = 0; + u32 phy_addr = 1; + + mdic = (((u32) data) | + (offset << BPCTLI_MDIC_REG_SHIFT) | + (phy_addr << BPCTLI_MDIC_PHY_SHIFT) | (BPCTLI_MDIC_OP_WRITE)); + + BPCTL_WRITE_REG(pbpctl_dev, MDIC, mdic); + + for (i = 0; i < (BPCTLI_GEN_POLL_TIMEOUT * 3); i++) { + usec_delay(50); + mdic = BPCTL_READ_REG(pbpctl_dev, MDIC); + if (mdic & BPCTLI_MDIC_READY) + break; + } + if (!(mdic & BPCTLI_MDIC_READY)) { + printk("bpctl_mod: MDI Write did not complete\n"); + ret_val = -1; + goto out; + } + if (mdic & BPCTLI_MDIC_ERROR) { + printk("bpctl_mod: MDI Error\n"); + ret_val = -1; + goto out; + } + + out: + return ret_val; +} + +static s32 bp75_read_phy_reg(bpctl_dev_t * pbpctl_dev, u32 offset, u16 * data) +{ + s32 ret_val = 0; + + ret_val = bp75_acquire_phy(pbpctl_dev); + if (ret_val) + goto out; + + if (offset > BPCTLI_MAX_PHY_MULTI_PAGE_REG) { + ret_val = bp75_write_phy_reg_mdic(pbpctl_dev, + BPCTLI_IGP01E1000_PHY_PAGE_SELECT, + (u16) offset); + if (ret_val) + goto release; + } + + ret_val = + bp75_read_phy_reg_mdic(pbpctl_dev, + BPCTLI_MAX_PHY_REG_ADDRESS & offset, data); + + release: + bp75_release_phy(pbpctl_dev); + out: + return ret_val; +} + +static s32 bp75_write_phy_reg(bpctl_dev_t * pbpctl_dev, u32 offset, u16 data) +{ + s32 ret_val = 0; + + ret_val = bp75_acquire_phy(pbpctl_dev); + if (ret_val) + goto out; + + if (offset > BPCTLI_MAX_PHY_MULTI_PAGE_REG) { + ret_val = bp75_write_phy_reg_mdic(pbpctl_dev, + BPCTLI_IGP01E1000_PHY_PAGE_SELECT, + (u16) offset); + if (ret_val) + goto release; + } + + ret_val = + bp75_write_phy_reg_mdic(pbpctl_dev, + BPCTLI_MAX_PHY_REG_ADDRESS & offset, data); + + release: + bp75_release_phy(pbpctl_dev); + + out: + return ret_val; +} + +/* SET_TX (non-Bypass command :)) */ +static int set_tx(bpctl_dev_t * pbpctl_dev, int tx_state) +{ + int ret = 0, ctrl = 0; + bpctl_dev_t *pbpctl_dev_m; + if ((is_bypass_fn(pbpctl_dev)) == 1) + pbpctl_dev_m = pbpctl_dev; + else + pbpctl_dev_m = get_master_port_fn(pbpctl_dev); + if (pbpctl_dev_m == NULL) + return BP_NOT_CAP; + if (pbpctl_dev_m->bp_caps_ex & DISC_PORT_CAP_EX) { + ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL); + if (!tx_state) { + if (pbpctl_dev->bp_540) { + ctrl = BP10G_READ_REG(pbpctl_dev, ESDP); + BP10G_WRITE_REG(pbpctl_dev, ESDP, + (ctrl | BP10G_SDP1_DIR | + BP10G_SDP1_DATA)); + + } else { + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, + (ctrl | BPCTLI_CTRL_SDP1_DIR + | BPCTLI_CTRL_SWDPIN1)); + } + } else { + if (pbpctl_dev->bp_540) { + ctrl = BP10G_READ_REG(pbpctl_dev, ESDP); + BP10G_WRITE_REG(pbpctl_dev, ESDP, + ((ctrl | BP10G_SDP1_DIR) & + ~BP10G_SDP1_DATA)); + } else { + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, + ((ctrl | + BPCTLI_CTRL_SDP1_DIR) & + ~BPCTLI_CTRL_SWDPIN1)); + } + return ret; + + } + } else if (pbpctl_dev->bp_caps & TX_CTL_CAP) { + if (PEG5_IF_SERIES(pbpctl_dev->subdevice)) { + if (tx_state) { + uint16_t mii_reg; + if (! + (ret = + bp75_read_phy_reg(pbpctl_dev, + BPCTLI_PHY_CONTROL, + &mii_reg))) { + if (mii_reg & BPCTLI_MII_CR_POWER_DOWN) { + ret = + bp75_write_phy_reg + (pbpctl_dev, + BPCTLI_PHY_CONTROL, + mii_reg & + ~BPCTLI_MII_CR_POWER_DOWN); + } + } + } else { + uint16_t mii_reg; + if (! + (ret = + bp75_read_phy_reg(pbpctl_dev, + BPCTLI_PHY_CONTROL, + &mii_reg))) { + + mii_reg |= BPCTLI_MII_CR_POWER_DOWN; + ret = + bp75_write_phy_reg(pbpctl_dev, + BPCTLI_PHY_CONTROL, + mii_reg); + } + } + + } + if (pbpctl_dev->bp_fiber5) { + ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); + + } else if (pbpctl_dev->bp_10gb) + ctrl = BP10GB_READ_REG(pbpctl_dev, MISC_REG_GPIO); + + else if (!pbpctl_dev->bp_10g) + ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL); + else + //ctrl =readl((void *)((pbpctl_dev)->mem_map) + 0x20); + ctrl = BP10G_READ_REG(pbpctl_dev, ESDP); + + if (!tx_state) + if (pbpctl_dev->bp_10g9) { + BP10G_WRITE_REG(pbpctl_dev, ESDP, + (ctrl | BP10G_SDP3_DATA | + BP10G_SDP3_DIR)); + + } else if (pbpctl_dev->bp_fiber5) { + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, + (ctrl | + BPCTLI_CTRL_EXT_SDP6_DIR | + BPCTLI_CTRL_EXT_SDP6_DATA)); + + } else if (pbpctl_dev->bp_10gb) { + if ((pbpctl_dev->func == 1) + || (pbpctl_dev->func == 3)) + BP10GB_WRITE_REG(pbpctl_dev, + MISC_REG_GPIO, + (ctrl | + BP10GB_GPIO0_SET_P1) & + ~(BP10GB_GPIO0_CLR_P1 | + BP10GB_GPIO0_OE_P1)); + else + BP10GB_WRITE_REG(pbpctl_dev, + MISC_REG_GPIO, + (ctrl | + BP10GB_GPIO0_OE_P0 | + BP10GB_GPIO0_SET_P0)); + + } else if (pbpctl_dev->bp_i80) { + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, + (ctrl | BPCTLI_CTRL_SDP1_DIR + | BPCTLI_CTRL_SWDPIN1)); + + } else if (pbpctl_dev->bp_540) { + ctrl = BP10G_READ_REG(pbpctl_dev, ESDP); + BP10G_WRITE_REG(pbpctl_dev, ESDP, + (ctrl | BP10G_SDP1_DIR | + BP10G_SDP1_DATA)); + + } + + else if (!pbpctl_dev->bp_10g) + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, + (ctrl | BPCTLI_CTRL_SWDPIO0 | + BPCTLI_CTRL_SWDPIN0)); + + else + //writel((ctrl|(0x1|0x100)), (void *)(((pbpctl_dev)->mem_map) + 0x20)) ; + BP10G_WRITE_REG(pbpctl_dev, ESDP, + (ctrl | BP10G_SDP0_DATA | + BP10G_SDP0_DIR)); + + else { + if (pbpctl_dev->bp_10g9) { + BP10G_WRITE_REG(pbpctl_dev, ESDP, + ((ctrl | BP10G_SDP3_DIR) & + ~BP10G_SDP3_DATA)); + + } else if (pbpctl_dev->bp_fiber5) { + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, + ((ctrl | + BPCTLI_CTRL_EXT_SDP6_DIR) & + ~BPCTLI_CTRL_EXT_SDP6_DATA)); + + } else if (pbpctl_dev->bp_10gb) { + if ((bpctl_dev_arr->func == 1) + || (bpctl_dev_arr->func == 3)) + BP10GB_WRITE_REG(pbpctl_dev, + MISC_REG_GPIO, + (ctrl | + BP10GB_GPIO0_CLR_P1) & + ~(BP10GB_GPIO0_SET_P1 | + BP10GB_GPIO0_OE_P1)); + else + BP10GB_WRITE_REG(pbpctl_dev, + MISC_REG_GPIO, + (ctrl | + BP10GB_GPIO0_OE_P0 | + BP10GB_GPIO0_CLR_P0)); + + } else if (pbpctl_dev->bp_i80) { + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, + ((ctrl | + BPCTLI_CTRL_SDP1_DIR) & + ~BPCTLI_CTRL_SWDPIN1)); + } else if (pbpctl_dev->bp_540) { + ctrl = BP10G_READ_REG(pbpctl_dev, ESDP); + BP10G_WRITE_REG(pbpctl_dev, ESDP, + ((ctrl | BP10G_SDP1_DIR) & + ~BP10G_SDP1_DATA)); + } + + else if (!pbpctl_dev->bp_10g) { + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, + ((ctrl | BPCTLI_CTRL_SWDPIO0) + & ~BPCTLI_CTRL_SWDPIN0)); + if (!PEGF_IF_SERIES(pbpctl_dev->subdevice)) { + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, + (ctrl & + ~ + (BPCTLI_CTRL_SDP0_DATA + | + BPCTLI_CTRL_SDP0_DIR))); + } + } else + //writel(((ctrl|0x100)&~0x1), (void *)(((pbpctl_dev)->mem_map) + 0x20)) ; + BP10G_WRITE_REG(pbpctl_dev, ESDP, + ((ctrl | BP10G_SDP0_DIR) & + ~BP10G_SDP0_DATA)); + + } + + } else + ret = BP_NOT_CAP; + return ret; + +} + +/* SET_FORCE_LINK (non-Bypass command :)) */ +static int set_bp_force_link(bpctl_dev_t * pbpctl_dev, int tx_state) +{ + int ret = 0, ctrl = 0; + + if (DBI_IF_SERIES(pbpctl_dev->subdevice)) { + + if ((pbpctl_dev->bp_10g) || (pbpctl_dev->bp_10g9)) { + + ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL); + if (!tx_state) + BP10G_WRITE_REG(pbpctl_dev, ESDP, + ctrl & ~BP10G_SDP1_DIR); + else + BP10G_WRITE_REG(pbpctl_dev, ESDP, + ((ctrl | BP10G_SDP1_DIR) & + ~BP10G_SDP1_DATA)); + return ret; + } + + } + return BP_NOT_CAP; +} + +/*RESET_CONT 0x20 */ +int reset_cont(bpctl_dev_t * pbpctl_dev) +{ + int ret = BP_NOT_CAP; + + if (pbpctl_dev->bp_caps & SW_CTL_CAP) { + if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) + return BP_NOT_CAP; + if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) + write_data(pbpctl_dev, RESET_CONT); + else + data_pulse(pbpctl_dev, RESET_CONT); + ret = 0; + }; + return ret; +} + +/*DIS_BYPASS_CAP 0x22 */ +int dis_bypass_cap(bpctl_dev_t * pbpctl_dev) +{ + + if (pbpctl_dev->bp_caps & BP_DIS_CAP) { + if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) { + write_data_int(pbpctl_dev, DIS_BYPASS_CAP_INT); + msec_delay_bp(BYPASS_DELAY_INT); + } else { + write_data(pbpctl_dev, BYPASS_OFF); + msec_delay_bp(LATCH_DELAY); + write_data(pbpctl_dev, DIS_BYPASS_CAP); + msec_delay_bp(BYPASS_CAP_DELAY); + } + return 0; + } + return BP_NOT_CAP; +} + +/*EN_BYPASS_CAP 0x24 */ +int en_bypass_cap(bpctl_dev_t * pbpctl_dev) +{ + if (pbpctl_dev->bp_caps & BP_DIS_CAP) { + if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) { + write_data_int(pbpctl_dev, PWROFF_BYPASS_ON_INT); + msec_delay_bp(BYPASS_DELAY_INT); + } else { + write_data(pbpctl_dev, EN_BYPASS_CAP); + msec_delay_bp(BYPASS_CAP_DELAY); + } + return 0; + } + return BP_NOT_CAP; +} + +/* BYPASS_STATE_PWRON 0x26*/ +int bypass_state_pwron(bpctl_dev_t * pbpctl_dev) +{ + if (pbpctl_dev->bp_caps & BP_PWUP_CTL_CAP) { + write_data(pbpctl_dev, BYPASS_STATE_PWRON); + if (pbpctl_dev->bp_ext_ver == PXG2BPI_VER) + msec_delay_bp(DFLT_PWRON_DELAY); + else + msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY); + return 0; + } + return BP_NOT_CAP; +} + +/* NORMAL_STATE_PWRON 0x28*/ +int normal_state_pwron(bpctl_dev_t * pbpctl_dev) +{ + if ((pbpctl_dev->bp_caps & BP_PWUP_CTL_CAP) + || (pbpctl_dev->bp_caps & TAP_PWUP_CTL_CAP)) { + write_data(pbpctl_dev, NORMAL_STATE_PWRON); + if (pbpctl_dev->bp_ext_ver == PXG2BPI_VER) + msec_delay_bp(DFLT_PWRON_DELAY); + else + msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY); + return 0; + } + return BP_NOT_CAP; +} + +/* BYPASS_STATE_PWROFF 0x27*/ +int bypass_state_pwroff(bpctl_dev_t * pbpctl_dev) +{ + if (pbpctl_dev->bp_caps & BP_PWOFF_CTL_CAP) { + write_data(pbpctl_dev, BYPASS_STATE_PWROFF); + msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY); + return 0; + } + return BP_NOT_CAP; +} + +/* NORMAL_STATE_PWROFF 0x29*/ +int normal_state_pwroff(bpctl_dev_t * pbpctl_dev) +{ + if ((pbpctl_dev->bp_caps & BP_PWOFF_CTL_CAP)) { + write_data(pbpctl_dev, NORMAL_STATE_PWROFF); + msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY); + return 0; + } + return BP_NOT_CAP; +} + +/*TAP_STATE_PWRON 0x2a*/ +int tap_state_pwron(bpctl_dev_t * pbpctl_dev) +{ + if (pbpctl_dev->bp_caps & TAP_PWUP_CTL_CAP) { + write_data(pbpctl_dev, TAP_STATE_PWRON); + msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY); + return 0; + } + return BP_NOT_CAP; +} + +/*DIS_TAP_CAP 0x2c*/ +int dis_tap_cap(bpctl_dev_t * pbpctl_dev) +{ + if (pbpctl_dev->bp_caps & TAP_DIS_CAP) { + write_data(pbpctl_dev, DIS_TAP_CAP); + msec_delay_bp(BYPASS_CAP_DELAY); + return 0; + } + return BP_NOT_CAP; +} + +/*EN_TAP_CAP 0x2e*/ +int en_tap_cap(bpctl_dev_t * pbpctl_dev) +{ + if (pbpctl_dev->bp_caps & TAP_DIS_CAP) { + write_data(pbpctl_dev, EN_TAP_CAP); + msec_delay_bp(BYPASS_CAP_DELAY); + return 0; + } + return BP_NOT_CAP; +} + +/*DISC_STATE_PWRON 0x2a*/ +int disc_state_pwron(bpctl_dev_t * pbpctl_dev) +{ + if (pbpctl_dev->bp_caps & DISC_PWUP_CTL_CAP) { + if (pbpctl_dev->bp_ext_ver >= 0x8) { + write_data(pbpctl_dev, DISC_STATE_PWRON); + msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY); + return BP_OK; + } + } + return BP_NOT_CAP; +} + +/*DIS_DISC_CAP 0x2c*/ +int dis_disc_cap(bpctl_dev_t * pbpctl_dev) +{ + if (pbpctl_dev->bp_caps & DISC_DIS_CAP) { + if (pbpctl_dev->bp_ext_ver >= 0x8) { + write_data(pbpctl_dev, DIS_DISC_CAP); + msec_delay_bp(BYPASS_CAP_DELAY); + return BP_OK; + } + } + return BP_NOT_CAP; +} + +/*DISC_STATE_PWRON 0x2a*/ +int disc_port_state_pwron(bpctl_dev_t * pbpctl_dev) +{ + int ret = 0; + bpctl_dev_t *pbpctl_dev_m; + + return BP_NOT_CAP; + + if ((is_bypass_fn(pbpctl_dev)) == 1) + pbpctl_dev_m = pbpctl_dev; + else + pbpctl_dev_m = get_master_port_fn(pbpctl_dev); + if (pbpctl_dev_m == NULL) + return BP_NOT_CAP; + + if (pbpctl_dev_m->bp_caps_ex & DISC_PORT_CAP_EX) { + if (is_bypass_fn(pbpctl_dev) == 1) + write_data(pbpctl_dev_m, TX_DISA_PWRUP); + else + write_data(pbpctl_dev_m, TX_DISB_PWRUP); + + msec_delay_bp(LATCH_DELAY); + + } + return ret; +} + +int normal_port_state_pwron(bpctl_dev_t * pbpctl_dev) +{ + int ret = 0; + bpctl_dev_t *pbpctl_dev_m; + return BP_NOT_CAP; + + if ((is_bypass_fn(pbpctl_dev)) == 1) + pbpctl_dev_m = pbpctl_dev; + else + pbpctl_dev_m = get_master_port_fn(pbpctl_dev); + if (pbpctl_dev_m == NULL) + return BP_NOT_CAP; + + if (pbpctl_dev_m->bp_caps_ex & DISC_PORT_CAP_EX) { + if (is_bypass_fn(pbpctl_dev) == 1) + write_data(pbpctl_dev_m, TX_ENA_PWRUP); + else + write_data(pbpctl_dev_m, TX_ENB_PWRUP); + + msec_delay_bp(LATCH_DELAY); + + } + return ret; +} + +/*EN_TAP_CAP 0x2e*/ +int en_disc_cap(bpctl_dev_t * pbpctl_dev) +{ + if (pbpctl_dev->bp_caps & DISC_DIS_CAP) { + if (pbpctl_dev->bp_ext_ver >= 0x8) { + write_data(pbpctl_dev, EN_DISC_CAP); + msec_delay_bp(BYPASS_CAP_DELAY); + return BP_OK; + } + } + return BP_NOT_CAP; +} + +int std_nic_on(bpctl_dev_t * pbpctl_dev) +{ + + if (pbpctl_dev->bp_caps & STD_NIC_CAP) { + + if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) { + write_data_int(pbpctl_dev, DIS_BYPASS_CAP_INT); + msec_delay_bp(BYPASS_DELAY_INT); + pbpctl_dev->bp_status_un = 0; + return BP_OK; + } + + if (pbpctl_dev->bp_ext_ver >= 0x8) { + write_data(pbpctl_dev, STD_NIC_ON); + msec_delay_bp(BYPASS_CAP_DELAY); + return BP_OK; + + } + + if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { + wdt_off(pbpctl_dev); + + if (pbpctl_dev->bp_caps & BP_CAP) { + write_data(pbpctl_dev, BYPASS_OFF); + msec_delay_bp(LATCH_DELAY); + } + + if (pbpctl_dev->bp_caps & TAP_CAP) { + write_data(pbpctl_dev, TAP_OFF); + msec_delay_bp(LATCH_DELAY); + } + + write_data(pbpctl_dev, NORMAL_STATE_PWRON); + if (pbpctl_dev->bp_ext_ver == PXG2BPI_VER) + msec_delay_bp(DFLT_PWRON_DELAY); + else + msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY); + + if (pbpctl_dev->bp_caps & BP_DIS_CAP) { + write_data(pbpctl_dev, DIS_BYPASS_CAP); + msec_delay_bp(BYPASS_CAP_DELAY); + } + + if (pbpctl_dev->bp_caps & TAP_DIS_CAP) { + write_data(pbpctl_dev, DIS_TAP_CAP); + msec_delay_bp(BYPASS_CAP_DELAY); + + } + return 0; + } + } + return BP_NOT_CAP; +} + +int std_nic_off(bpctl_dev_t * pbpctl_dev) +{ + + if (pbpctl_dev->bp_caps & STD_NIC_CAP) { + if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) { + write_data_int(pbpctl_dev, PWROFF_BYPASS_ON_INT); + msec_delay_bp(BYPASS_DELAY_INT); + return BP_OK; + } + if (pbpctl_dev->bp_ext_ver >= 0x8) { + write_data(pbpctl_dev, STD_NIC_OFF); + msec_delay_bp(BYPASS_CAP_DELAY); + return BP_OK; + + } + + if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { + + if (pbpctl_dev->bp_caps & TAP_PWUP_CTL_CAP) { + write_data(pbpctl_dev, TAP_STATE_PWRON); + msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY); + } + + if (pbpctl_dev->bp_caps & BP_PWUP_CTL_CAP) { + write_data(pbpctl_dev, BYPASS_STATE_PWRON); + if (pbpctl_dev->bp_ext_ver > PXG2BPI_VER) + msec_delay_bp(LATCH_DELAY + + EEPROM_WR_DELAY); + else + msec_delay_bp(DFLT_PWRON_DELAY); + } + + if (pbpctl_dev->bp_caps & TAP_DIS_CAP) { + write_data(pbpctl_dev, EN_TAP_CAP); + msec_delay_bp(BYPASS_CAP_DELAY); + } + if (pbpctl_dev->bp_caps & DISC_DIS_CAP) { + write_data(pbpctl_dev, EN_DISC_CAP); + msec_delay_bp(BYPASS_CAP_DELAY); + } + + if (pbpctl_dev->bp_caps & BP_DIS_CAP) { + write_data(pbpctl_dev, EN_BYPASS_CAP); + msec_delay_bp(BYPASS_CAP_DELAY); + } + + return 0; + } + } + return BP_NOT_CAP; +} + +int wdt_time_left(bpctl_dev_t * pbpctl_dev) +{ + + //unsigned long curr_time=((long long)(jiffies*1000))/HZ, delta_time=0,wdt_on_time=((long long)(pbpctl_dev->bypass_wdt_on_time*1000))/HZ; + unsigned long curr_time = jiffies, delta_time = 0, wdt_on_time = + pbpctl_dev->bypass_wdt_on_time, delta_time_msec = 0; + int time_left = 0; + + switch (pbpctl_dev->wdt_status) { + case WDT_STATUS_DIS: + time_left = 0; + break; + case WDT_STATUS_EN: + delta_time = + (curr_time >= + wdt_on_time) ? (curr_time - wdt_on_time) : (~wdt_on_time + + curr_time); + delta_time_msec = jiffies_to_msecs(delta_time); + time_left = pbpctl_dev->bypass_timer_interval - delta_time_msec; + if (time_left < 0) { + time_left = -1; + pbpctl_dev->wdt_status = WDT_STATUS_EXP; + } + break; + case WDT_STATUS_EXP: + time_left = -1; + break; + } + + return time_left; +} + +static int wdt_timer(bpctl_dev_t * pbpctl_dev, int *time_left) +{ + int ret = 0; + if (pbpctl_dev->bp_caps & WD_CTL_CAP) { + { + if (pbpctl_dev->wdt_status == WDT_STATUS_UNKNOWN) + ret = BP_NOT_CAP; + else + *time_left = wdt_time_left(pbpctl_dev); + } + + } else + ret = BP_NOT_CAP; + return ret; +} + +static int wdt_timer_reload(bpctl_dev_t * pbpctl_dev) +{ + + int ret = 0; + + if ((pbpctl_dev->bp_caps & WD_CTL_CAP) && + (pbpctl_dev->wdt_status != WDT_STATUS_UNKNOWN)) { + if (pbpctl_dev->wdt_status == WDT_STATUS_DIS) + return 0; + if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) + ret = wdt_pulse(pbpctl_dev); + else if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) + ret = wdt_pulse_int(pbpctl_dev); + else + ret = send_wdt_pulse(pbpctl_dev); + //if (ret==-1) + // mod_timer(&pbpctl_dev->bp_timer, jiffies+1); + return 1; + } + return BP_NOT_CAP; +} + +static void wd_reset_timer(unsigned long param) +{ + bpctl_dev_t *pbpctl_dev = (bpctl_dev_t *) param; +#ifdef BP_SELF_TEST + struct sk_buff *skb_tmp; +#endif + + if ((pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) && + ((atomic_read(&pbpctl_dev->wdt_busy)) == 1)) { + mod_timer(&pbpctl_dev->bp_timer, jiffies + 1); + return; + } +#ifdef BP_SELF_TEST + + if (pbpctl_dev->bp_self_test_flag == 1) { + skb_tmp = dev_alloc_skb(BPTEST_DATA_LEN + 2); + if ((skb_tmp) && (pbpctl_dev->ndev) && (pbpctl_dev->bp_tx_data)) { + memcpy(skb_put(skb_tmp, BPTEST_DATA_LEN), + pbpctl_dev->bp_tx_data, BPTEST_DATA_LEN); + skb_tmp->dev = pbpctl_dev->ndev; + skb_tmp->protocol = + eth_type_trans(skb_tmp, pbpctl_dev->ndev); + skb_tmp->ip_summed = CHECKSUM_UNNECESSARY; + netif_receive_skb(skb_tmp); + goto bp_timer_reload; + return; + } + } +#endif + + wdt_timer_reload(pbpctl_dev); +#ifdef BP_SELF_TEST + bp_timer_reload: +#endif + if (pbpctl_dev->reset_time) { + mod_timer(&pbpctl_dev->bp_timer, + jiffies + (HZ * pbpctl_dev->reset_time) / 1000); + } +} + +//#ifdef PMC_FIX_FLAG +/*WAIT_AT_PWRUP 0x80 */ +int bp_wait_at_pwup_en(bpctl_dev_t * pbpctl_dev) +{ + + if (pbpctl_dev->bp_caps & SW_CTL_CAP) { + if (pbpctl_dev->bp_ext_ver >= BP_FW_EXT_VER8) { + write_data(pbpctl_dev, BP_WAIT_AT_PWUP_EN); + msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY); + + return BP_OK; + } + } + return BP_NOT_CAP; +} + +/*DIS_WAIT_AT_PWRUP 0x81 */ +int bp_wait_at_pwup_dis(bpctl_dev_t * pbpctl_dev) +{ + + if (pbpctl_dev->bp_caps & SW_CTL_CAP) { + + if (pbpctl_dev->bp_ext_ver >= BP_FW_EXT_VER8) { + write_data(pbpctl_dev, BP_WAIT_AT_PWUP_DIS); + msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY); + + return BP_OK; + } + } + return BP_NOT_CAP; +} + +/*EN_HW_RESET 0x82 */ + +int bp_hw_reset_en(bpctl_dev_t * pbpctl_dev) +{ + + if (pbpctl_dev->bp_caps & SW_CTL_CAP) { + if (pbpctl_dev->bp_ext_ver >= BP_FW_EXT_VER8) { + write_data(pbpctl_dev, BP_HW_RESET_EN); + msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY); + + return BP_OK; + } + } + return BP_NOT_CAP; +} + +/*DIS_HW_RESET 0x83 */ + +int bp_hw_reset_dis(bpctl_dev_t * pbpctl_dev) +{ + + if (pbpctl_dev->bp_caps & SW_CTL_CAP) { + if (pbpctl_dev->bp_ext_ver >= BP_FW_EXT_VER8) { + write_data(pbpctl_dev, BP_HW_RESET_DIS); + msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY); + + return BP_OK; + } + } + return BP_NOT_CAP; +} + +//#endif /*PMC_FIX_FLAG*/ + +int wdt_exp_mode(bpctl_dev_t * pbpctl_dev, int mode) +{ + uint32_t status_reg = 0, status_reg1 = 0; + + if ((pbpctl_dev->bp_caps & (TAP_STATUS_CAP | DISC_CAP)) && + (pbpctl_dev->bp_caps & BP_CAP)) { + if (pbpctl_dev->bp_ext_ver >= PXE2TBPI_VER) { + + if ((pbpctl_dev->bp_ext_ver >= 0x8) && + (mode == 2) && (pbpctl_dev->bp_caps & DISC_CAP)) { + status_reg1 = + read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR); + if (!(status_reg1 & WDTE_DISC_BPN_MASK)) + write_reg(pbpctl_dev, + status_reg1 | + WDTE_DISC_BPN_MASK, + STATUS_DISC_REG_ADDR); + return BP_OK; + } + } + status_reg = read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR); + + if ((mode == 0) && (pbpctl_dev->bp_caps & BP_CAP)) { + if (pbpctl_dev->bp_ext_ver >= 0x8) { + status_reg1 = + read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR); + if (status_reg1 & WDTE_DISC_BPN_MASK) + write_reg(pbpctl_dev, + status_reg1 & + ~WDTE_DISC_BPN_MASK, + STATUS_DISC_REG_ADDR); + } + if (status_reg & WDTE_TAP_BPN_MASK) + write_reg(pbpctl_dev, + status_reg & ~WDTE_TAP_BPN_MASK, + STATUS_TAP_REG_ADDR); + return BP_OK; + + } else if ((mode == 1) && (pbpctl_dev->bp_caps & TAP_CAP)) { + if (!(status_reg & WDTE_TAP_BPN_MASK)) + write_reg(pbpctl_dev, + status_reg | WDTE_TAP_BPN_MASK, + STATUS_TAP_REG_ADDR); + /*else return BP_NOT_CAP; */ + return BP_OK; + } + + } + return BP_NOT_CAP; +} + +int bypass_fw_ver(bpctl_dev_t * pbpctl_dev) +{ + if (is_bypass_fn(pbpctl_dev)) + return ((read_reg(pbpctl_dev, VER_REG_ADDR))); + else + return BP_NOT_CAP; +} + +int bypass_sign_check(bpctl_dev_t * pbpctl_dev) +{ + + if (is_bypass_fn(pbpctl_dev)) + return (((read_reg(pbpctl_dev, PIC_SIGN_REG_ADDR)) == + PIC_SIGN_VALUE) ? 1 : 0); + else + return BP_NOT_CAP; +} + +static int tx_status(bpctl_dev_t * pbpctl_dev) +{ + uint32_t ctrl = 0; + bpctl_dev_t *pbpctl_dev_m; + if ((is_bypass_fn(pbpctl_dev)) == 1) + pbpctl_dev_m = pbpctl_dev; + else + pbpctl_dev_m = get_master_port_fn(pbpctl_dev); + if (pbpctl_dev_m == NULL) + return BP_NOT_CAP; + if (pbpctl_dev_m->bp_caps_ex & DISC_PORT_CAP_EX) { + + ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL); + if (pbpctl_dev->bp_i80) + return ((ctrl & BPCTLI_CTRL_SWDPIN1) != 0 ? 0 : 1); + if (pbpctl_dev->bp_540) { + ctrl = BP10G_READ_REG(pbpctl_dev, ESDP); + + return ((ctrl & BP10G_SDP1_DATA) != 0 ? 0 : 1); + } + + } + + if (pbpctl_dev->bp_caps & TX_CTL_CAP) { + if (PEG5_IF_SERIES(pbpctl_dev->subdevice)) { + uint16_t mii_reg; + if (! + (bp75_read_phy_reg + (pbpctl_dev, BPCTLI_PHY_CONTROL, &mii_reg))) { + if (mii_reg & BPCTLI_MII_CR_POWER_DOWN) + return 0; + + else + return 1; + } + return -1; + } + + if (pbpctl_dev->bp_10g9) { + return ((BP10G_READ_REG(pbpctl_dev, ESDP) & + BP10G_SDP3_DATA) != 0 ? 0 : 1); + + } else if (pbpctl_dev->bp_fiber5) { + ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); + if (ctrl & BPCTLI_CTRL_EXT_SDP6_DATA) + return 0; + return 1; + } else if (pbpctl_dev->bp_10gb) { + ctrl = BP10GB_READ_REG(pbpctl_dev, MISC_REG_GPIO); + BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_GPIO, + (ctrl | BP10GB_GPIO0_OE_P1) & + ~(BP10GB_GPIO0_SET_P1 | + BP10GB_GPIO0_CLR_P1)); + + if ((pbpctl_dev->func == 1) || (pbpctl_dev->func == 3)) + return (((BP10GB_READ_REG + (pbpctl_dev, + MISC_REG_GPIO)) & BP10GB_GPIO0_P1) != + 0 ? 0 : 1); + else + return (((BP10GB_READ_REG + (pbpctl_dev, + MISC_REG_GPIO)) & BP10GB_GPIO0_P0) != + 0 ? 0 : 1); + } + + if (!pbpctl_dev->bp_10g) { + + ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL); + if (pbpctl_dev->bp_i80) + return ((ctrl & BPCTLI_CTRL_SWDPIN1) != + 0 ? 0 : 1); + if (pbpctl_dev->bp_540) { + ctrl = BP10G_READ_REG(pbpctl_dev, ESDP); + + return ((ctrl & BP10G_SDP1_DATA) != 0 ? 0 : 1); + } + + return ((ctrl & BPCTLI_CTRL_SWDPIN0) != 0 ? 0 : 1); + } else + return ((BP10G_READ_REG(pbpctl_dev, ESDP) & + BP10G_SDP0_DATA) != 0 ? 0 : 1); + + } + return BP_NOT_CAP; +} + +static int bp_force_link_status(bpctl_dev_t * pbpctl_dev) +{ + + if (DBI_IF_SERIES(pbpctl_dev->subdevice)) { + + if ((pbpctl_dev->bp_10g) || (pbpctl_dev->bp_10g9)) { + return ((BP10G_READ_REG(pbpctl_dev, ESDP) & + BP10G_SDP1_DIR) != 0 ? 1 : 0); + + } + } + return BP_NOT_CAP; +} + +int bypass_from_last_read(bpctl_dev_t * pbpctl_dev) +{ + uint32_t ctrl_ext = 0; + bpctl_dev_t *pbpctl_dev_b = NULL; + + if ((pbpctl_dev->bp_caps & SW_CTL_CAP) + && (pbpctl_dev_b = get_status_port_fn(pbpctl_dev))) { + ctrl_ext = BPCTL_READ_REG(pbpctl_dev_b, CTRL_EXT); + BPCTL_BP_WRITE_REG(pbpctl_dev_b, CTRL_EXT, + (ctrl_ext & ~BPCTLI_CTRL_EXT_SDP7_DIR)); + ctrl_ext = BPCTL_READ_REG(pbpctl_dev_b, CTRL_EXT); + if (ctrl_ext & BPCTLI_CTRL_EXT_SDP7_DATA) + return 0; + return 1; + } else + return BP_NOT_CAP; +} + +int bypass_status_clear(bpctl_dev_t * pbpctl_dev) +{ + bpctl_dev_t *pbpctl_dev_b = NULL; + + if ((pbpctl_dev->bp_caps & SW_CTL_CAP) + && (pbpctl_dev_b = get_status_port_fn(pbpctl_dev))) { + + send_bypass_clear_pulse(pbpctl_dev_b, 1); + return 0; + } else + return BP_NOT_CAP; +} + +int bypass_flag_status(bpctl_dev_t * pbpctl_dev) +{ + + if ((pbpctl_dev->bp_caps & BP_CAP)) { + if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { + return ((((read_reg(pbpctl_dev, STATUS_REG_ADDR)) & + BYPASS_FLAG_MASK) == + BYPASS_FLAG_MASK) ? 1 : 0); + } + } + return BP_NOT_CAP; +} + +int bypass_flag_status_clear(bpctl_dev_t * pbpctl_dev) +{ + + if (pbpctl_dev->bp_caps & BP_CAP) { + if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { + uint32_t status_reg = 0; + status_reg = read_reg(pbpctl_dev, STATUS_REG_ADDR); + write_reg(pbpctl_dev, status_reg & ~BYPASS_FLAG_MASK, + STATUS_REG_ADDR); + return 0; + } + } + return BP_NOT_CAP; +} + +int bypass_change_status(bpctl_dev_t * pbpctl_dev) +{ + int ret = BP_NOT_CAP; + + if (pbpctl_dev->bp_caps & BP_STATUS_CHANGE_CAP) { + if (pbpctl_dev->bp_ext_ver >= 0x8) { + ret = bypass_flag_status(pbpctl_dev); + bypass_flag_status_clear(pbpctl_dev); + } else if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { + ret = bypass_flag_status(pbpctl_dev); + bypass_flag_status_clear(pbpctl_dev); + } else { + ret = bypass_from_last_read(pbpctl_dev); + bypass_status_clear(pbpctl_dev); + } + } + return ret; +} + +int bypass_off_status(bpctl_dev_t * pbpctl_dev) +{ + + if (pbpctl_dev->bp_caps & BP_CAP) { + if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { + return ((((read_reg(pbpctl_dev, STATUS_REG_ADDR)) & + BYPASS_OFF_MASK) == BYPASS_OFF_MASK) ? 1 : 0); + } + } + return BP_NOT_CAP; +} + +static int bypass_status(bpctl_dev_t * pbpctl_dev) +{ + u32 ctrl_ext = 0; + if (pbpctl_dev->bp_caps & BP_CAP) { + + bpctl_dev_t *pbpctl_dev_b = NULL; + + if (!(pbpctl_dev_b = get_status_port_fn(pbpctl_dev))) + return BP_NOT_CAP; + + if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) { + + if (!pbpctl_dev->bp_status_un) + return (((BPCTL_READ_REG + (pbpctl_dev_b, + CTRL_EXT)) & + BPCTLI_CTRL_EXT_SDP7_DATA) != + 0 ? 1 : 0); + else + return BP_NOT_CAP; + } + if (pbpctl_dev->bp_ext_ver >= 0x8) { + + //BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, (BPCTL_READ_REG(pbpctl_dev_b, CTRL_EXT))&~BPCTLI_CTRL_EXT_SDP7_DIR); + if (pbpctl_dev->bp_10g9) { + ctrl_ext = BP10G_READ_REG(pbpctl_dev_b, I2CCTL); + BP10G_WRITE_REG(pbpctl_dev_b, I2CCTL, + (ctrl_ext | BP10G_I2C_CLK_OUT)); + //return(((readl((void *)((pbpctl_dev)->mem_map) + 0x28))&0x4)!=0?0:1); + return ((BP10G_READ_REG(pbpctl_dev_b, I2CCTL) & + BP10G_I2C_CLK_IN) != 0 ? 0 : 1); + + } else if (pbpctl_dev->bp_540) { + return (((BP10G_READ_REG(pbpctl_dev_b, ESDP)) & + BP10G_SDP0_DATA) != 0 ? 0 : 1); + } + + else if ((pbpctl_dev->bp_fiber5) + || (pbpctl_dev->bp_i80)) { + return (((BPCTL_READ_REG(pbpctl_dev_b, CTRL)) & + BPCTLI_CTRL_SWDPIN0) != 0 ? 0 : 1); + } else if (pbpctl_dev->bp_10gb) { + ctrl_ext = + BP10GB_READ_REG(pbpctl_dev, MISC_REG_GPIO); + BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_GPIO, + (ctrl_ext | BP10GB_GPIO3_OE_P0) + & ~(BP10GB_GPIO3_SET_P0 | + BP10GB_GPIO3_CLR_P0)); + + return (((BP10GB_READ_REG + (pbpctl_dev, + MISC_REG_GPIO)) & BP10GB_GPIO3_P0) != + 0 ? 0 : 1); + } + + else if (!pbpctl_dev->bp_10g) + return (((BPCTL_READ_REG + (pbpctl_dev_b, + CTRL_EXT)) & + BPCTLI_CTRL_EXT_SDP7_DATA) != + 0 ? 0 : 1); + + else { + ctrl_ext = BP10G_READ_REG(pbpctl_dev_b, EODSDP); + BP10G_WRITE_REG(pbpctl_dev_b, EODSDP, + (ctrl_ext | + BP10G_SDP7_DATA_OUT)); + //return(((readl((void *)((pbpctl_dev)->mem_map) + 0x28))&0x4)!=0?0:1); + return ((BP10G_READ_REG(pbpctl_dev_b, EODSDP) & + BP10G_SDP7_DATA_IN) != 0 ? 0 : 1); + } + + } else if (pbpctl_dev->media_type == bp_copper) { + + return (((BPCTL_READ_REG(pbpctl_dev_b, CTRL)) & + BPCTLI_CTRL_SWDPIN1) != 0 ? 1 : 0); + } else { + if ((bypass_status_clear(pbpctl_dev)) >= 0) + return (bypass_from_last_read(pbpctl_dev)); + } + + } + return BP_NOT_CAP; +} + +int default_pwron_status(bpctl_dev_t * pbpctl_dev) +{ + + if (pbpctl_dev->bp_caps & SW_CTL_CAP) { + if (pbpctl_dev->bp_caps & BP_PWUP_CTL_CAP) { + if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { + return ((((read_reg + (pbpctl_dev, + STATUS_REG_ADDR)) & DFLT_PWRON_MASK) + == DFLT_PWRON_MASK) ? 0 : 1); + } + } /*else if ((!pbpctl_dev->bp_caps&BP_DIS_CAP)&& + (pbpctl_dev->bp_caps&BP_PWUP_ON_CAP)) + return 1; */ + } + return BP_NOT_CAP; +} + +static int default_pwroff_status(bpctl_dev_t * pbpctl_dev) +{ + + /*if ((!pbpctl_dev->bp_caps&BP_DIS_CAP)&& + (pbpctl_dev->bp_caps&BP_PWOFF_ON_CAP)) + return 1; */ + if ((pbpctl_dev->bp_caps & SW_CTL_CAP) + && (pbpctl_dev->bp_caps & BP_PWOFF_CTL_CAP)) { + return ((((read_reg(pbpctl_dev, STATUS_REG_ADDR)) & + DFLT_PWROFF_MASK) == DFLT_PWROFF_MASK) ? 0 : 1); + } + return BP_NOT_CAP; +} + +int dis_bypass_cap_status(bpctl_dev_t * pbpctl_dev) +{ + + if (pbpctl_dev->bp_caps & BP_DIS_CAP) { + if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { + return ((((read_reg(pbpctl_dev, STATUS_REG_ADDR)) & + DIS_BYPASS_CAP_MASK) == + DIS_BYPASS_CAP_MASK) ? 1 : 0); + } + } + return BP_NOT_CAP; +} + +int cmd_en_status(bpctl_dev_t * pbpctl_dev) +{ + + if (pbpctl_dev->bp_caps & SW_CTL_CAP) { + if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { + return ((((read_reg(pbpctl_dev, STATUS_REG_ADDR)) & + CMND_EN_MASK) == CMND_EN_MASK) ? 1 : 0); + } + } + return BP_NOT_CAP; +} + +int wdt_en_status(bpctl_dev_t * pbpctl_dev) +{ + + if (pbpctl_dev->bp_caps & WD_CTL_CAP) { + if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { + return ((((read_reg(pbpctl_dev, STATUS_REG_ADDR)) & + WDT_EN_MASK) == WDT_EN_MASK) ? 1 : 0); + } + } + return BP_NOT_CAP; +} + +int wdt_programmed(bpctl_dev_t * pbpctl_dev, int *timeout) +{ + int ret = 0; + if (pbpctl_dev->bp_caps & WD_CTL_CAP) { + if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { + if ((read_reg(pbpctl_dev, STATUS_REG_ADDR)) & + WDT_EN_MASK) { + u8 wdt_val; + wdt_val = read_reg(pbpctl_dev, WDT_REG_ADDR); + *timeout = (1 << wdt_val) * 100; + } else + *timeout = 0; + } else { + int curr_wdt_status = pbpctl_dev->wdt_status; + if (curr_wdt_status == WDT_STATUS_UNKNOWN) + *timeout = -1; + else + *timeout = + curr_wdt_status == + 0 ? 0 : pbpctl_dev->bypass_timer_interval; + }; + } else + ret = BP_NOT_CAP; + return ret; +} + +int bypass_support(bpctl_dev_t * pbpctl_dev) +{ + int ret = 0; + + if (pbpctl_dev->bp_caps & SW_CTL_CAP) { + if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) { + ret = + ((((read_reg(pbpctl_dev, PRODUCT_CAP_REG_ADDR)) & + BYPASS_SUPPORT_MASK) == + BYPASS_SUPPORT_MASK) ? 1 : 0); + } else if (pbpctl_dev->bp_ext_ver == PXG2BPI_VER) + ret = 1; + } else + ret = BP_NOT_CAP; + return ret; +} + +int tap_support(bpctl_dev_t * pbpctl_dev) +{ + int ret = 0; + + if (pbpctl_dev->bp_caps & SW_CTL_CAP) { + if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) { + ret = + ((((read_reg(pbpctl_dev, PRODUCT_CAP_REG_ADDR)) & + TAP_SUPPORT_MASK) == TAP_SUPPORT_MASK) ? 1 : 0); + } else if (pbpctl_dev->bp_ext_ver == PXG2BPI_VER) + ret = 0; + } else + ret = BP_NOT_CAP; + return ret; +} + +int normal_support(bpctl_dev_t * pbpctl_dev) +{ + int ret = BP_NOT_CAP; + + if (pbpctl_dev->bp_caps & SW_CTL_CAP) { + if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) { + ret = + ((((read_reg(pbpctl_dev, PRODUCT_CAP_REG_ADDR)) & + NORMAL_UNSUPPORT_MASK) == + NORMAL_UNSUPPORT_MASK) ? 0 : 1); + } else + ret = 1; + }; + return ret; +} + +int get_bp_prod_caps(bpctl_dev_t * pbpctl_dev) +{ + if ((pbpctl_dev->bp_caps & SW_CTL_CAP) && + (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER)) + return (read_reg(pbpctl_dev, PRODUCT_CAP_REG_ADDR)); + return BP_NOT_CAP; + +} + +int tap_flag_status(bpctl_dev_t * pbpctl_dev) +{ + + if (pbpctl_dev->bp_caps & TAP_STATUS_CAP) { + if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) + return ((((read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR)) & + TAP_FLAG_MASK) == TAP_FLAG_MASK) ? 1 : 0); + + } + return BP_NOT_CAP; +} + +int tap_flag_status_clear(bpctl_dev_t * pbpctl_dev) +{ + uint32_t status_reg = 0; + if (pbpctl_dev->bp_caps & TAP_STATUS_CAP) { + if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) { + status_reg = read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR); + write_reg(pbpctl_dev, status_reg & ~TAP_FLAG_MASK, + STATUS_TAP_REG_ADDR); + return 0; + } + } + return BP_NOT_CAP; +} + +int tap_change_status(bpctl_dev_t * pbpctl_dev) +{ + int ret = BP_NOT_CAP; + if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) { + if (pbpctl_dev->bp_caps & TAP_CAP) { + if (pbpctl_dev->bp_caps & BP_CAP) { + ret = tap_flag_status(pbpctl_dev); + tap_flag_status_clear(pbpctl_dev); + } else { + ret = bypass_from_last_read(pbpctl_dev); + bypass_status_clear(pbpctl_dev); + } + } + } + return ret; +} + +int tap_off_status(bpctl_dev_t * pbpctl_dev) +{ + if (pbpctl_dev->bp_caps & TAP_CAP) { + if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) + return ((((read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR)) & + TAP_OFF_MASK) == TAP_OFF_MASK) ? 1 : 0); + } + return BP_NOT_CAP; +} + +int tap_status(bpctl_dev_t * pbpctl_dev) +{ + u32 ctrl_ext = 0; + + if (pbpctl_dev->bp_caps & TAP_CAP) { + bpctl_dev_t *pbpctl_dev_b = NULL; + + if (!(pbpctl_dev_b = get_status_port_fn(pbpctl_dev))) + return BP_NOT_CAP; + + if (pbpctl_dev->bp_ext_ver >= 0x8) { + if (!pbpctl_dev->bp_10g) + return (((BPCTL_READ_REG + (pbpctl_dev_b, + CTRL_EXT)) & + BPCTLI_CTRL_EXT_SDP6_DATA) != + 0 ? 0 : 1); + else { + ctrl_ext = BP10G_READ_REG(pbpctl_dev_b, EODSDP); + BP10G_WRITE_REG(pbpctl_dev_b, EODSDP, + (ctrl_ext | + BP10G_SDP6_DATA_OUT)); + // return(((readl((void *)((pbpctl_dev)->mem_map) + 0x28))&0x1)!=0?0:1); + return ((BP10G_READ_REG(pbpctl_dev_b, EODSDP) & + BP10G_SDP6_DATA_IN) != 0 ? 0 : 1); + } + + } else if (pbpctl_dev->media_type == bp_copper) + return (((BPCTL_READ_REG(pbpctl_dev, CTRL)) & + BPCTLI_CTRL_SWDPIN0) != 0 ? 1 : 0); + else { + if ((bypass_status_clear(pbpctl_dev)) >= 0) + return (bypass_from_last_read(pbpctl_dev)); + } + + } + return BP_NOT_CAP; +} + +int default_pwron_tap_status(bpctl_dev_t * pbpctl_dev) +{ + if (pbpctl_dev->bp_caps & TAP_PWUP_CTL_CAP) { + if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) + return ((((read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR)) & + DFLT_PWRON_TAP_MASK) == + DFLT_PWRON_TAP_MASK) ? 1 : 0); + } + return BP_NOT_CAP; +} + +int dis_tap_cap_status(bpctl_dev_t * pbpctl_dev) +{ + if (pbpctl_dev->bp_caps & TAP_PWUP_CTL_CAP) { + if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) + return ((((read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR)) & + DIS_TAP_CAP_MASK) == + DIS_TAP_CAP_MASK) ? 1 : 0); + } + return BP_NOT_CAP; +} + +int disc_flag_status(bpctl_dev_t * pbpctl_dev) +{ + + if (pbpctl_dev->bp_caps & DISC_CAP) { + if (pbpctl_dev->bp_ext_ver >= 0x8) + return ((((read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR)) & + DISC_FLAG_MASK) == DISC_FLAG_MASK) ? 1 : 0); + + } + return BP_NOT_CAP; +} + +int disc_flag_status_clear(bpctl_dev_t * pbpctl_dev) +{ + uint32_t status_reg = 0; + if (pbpctl_dev->bp_caps & DISC_CAP) { + if (pbpctl_dev->bp_ext_ver >= 0x8) { + status_reg = read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR); + write_reg(pbpctl_dev, status_reg & ~DISC_FLAG_MASK, + STATUS_DISC_REG_ADDR); + return BP_OK; + } + } + return BP_NOT_CAP; +} + +int disc_change_status(bpctl_dev_t * pbpctl_dev) +{ + int ret = BP_NOT_CAP; + if (pbpctl_dev->bp_caps & DISC_CAP) { + ret = disc_flag_status(pbpctl_dev); + disc_flag_status_clear(pbpctl_dev); + return ret; + } + return BP_NOT_CAP; +} + +int disc_off_status(bpctl_dev_t * pbpctl_dev) +{ + bpctl_dev_t *pbpctl_dev_b = NULL; + u32 ctrl_ext = 0; + + if (pbpctl_dev->bp_caps & DISC_CAP) { + if (!(pbpctl_dev_b = get_status_port_fn(pbpctl_dev))) + return BP_NOT_CAP; + if (DISCF_IF_SERIES(pbpctl_dev->subdevice)) + return ((((read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR)) & + DISC_OFF_MASK) == DISC_OFF_MASK) ? 1 : 0); + + if (pbpctl_dev->bp_i80) { + // return((((read_reg(pbpctl_dev,STATUS_DISC_REG_ADDR)) & DISC_OFF_MASK)==DISC_OFF_MASK)?1:0); + return (((BPCTL_READ_REG(pbpctl_dev_b, CTRL_EXT)) & + BPCTLI_CTRL_EXT_SDP6_DATA) != 0 ? 1 : 0); + + } + if (pbpctl_dev->bp_540) { + ctrl_ext = BP10G_READ_REG(pbpctl_dev_b, ESDP); + //return(((readl((void *)((pbpctl_dev)->mem_map) + 0x28))&0x4)!=0?0:1); + return ((BP10G_READ_REG(pbpctl_dev_b, ESDP) & + BP10G_SDP2_DATA) != 0 ? 1 : 0); + + } + //if (pbpctl_dev->device==SILICOM_PXG2TBI_SSID) { + if (pbpctl_dev->media_type == bp_copper) { + +#if 0 + return ((((read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR)) & + DISC_OFF_MASK) == DISC_OFF_MASK) ? 1 : 0); +#endif + if (!pbpctl_dev->bp_10g) + return (((BPCTL_READ_REG(pbpctl_dev_b, CTRL)) & + BPCTLI_CTRL_SWDPIN1) != 0 ? 1 : 0); + else + // return(((readl((void *)((pbpctl_dev)->mem_map) + 0x20)) & 0x2)!=0?1:0); + return ((BP10G_READ_REG(pbpctl_dev_b, ESDP) & + BP10G_SDP1_DATA) != 0 ? 1 : 0); + + } else { + + if (pbpctl_dev->bp_10g9) { + ctrl_ext = BP10G_READ_REG(pbpctl_dev_b, I2CCTL); + BP10G_WRITE_REG(pbpctl_dev_b, I2CCTL, + (ctrl_ext | + BP10G_I2C_DATA_OUT)); + //return(((readl((void *)((pbpctl_dev)->mem_map) + 0x28))&0x4)!=0?0:1); + return ((BP10G_READ_REG(pbpctl_dev_b, I2CCTL) & + BP10G_I2C_DATA_IN) != 0 ? 1 : 0); + + } else if (pbpctl_dev->bp_fiber5) { + return (((BPCTL_READ_REG(pbpctl_dev_b, CTRL)) & + BPCTLI_CTRL_SWDPIN1) != 0 ? 1 : 0); + } else if (pbpctl_dev->bp_10gb) { + ctrl_ext = + BP10GB_READ_REG(pbpctl_dev, MISC_REG_GPIO); + BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_GPIO, + (ctrl_ext | BP10GB_GPIO3_OE_P1) + & ~(BP10GB_GPIO3_SET_P1 | + BP10GB_GPIO3_CLR_P1)); + + return (((BP10GB_READ_REG + (pbpctl_dev, + MISC_REG_GPIO)) & BP10GB_GPIO3_P1) != + 0 ? 1 : 0); + } + if (!pbpctl_dev->bp_10g) { + + return (((BPCTL_READ_REG + (pbpctl_dev_b, + CTRL_EXT)) & + BPCTLI_CTRL_EXT_SDP6_DATA) != + 0 ? 1 : 0); + } else { + ctrl_ext = BP10G_READ_REG(pbpctl_dev_b, EODSDP); + BP10G_WRITE_REG(pbpctl_dev_b, EODSDP, + (ctrl_ext | + BP10G_SDP6_DATA_OUT)); + // temp= (((BP10G_READ_REG(pbpctl_dev_b,EODSDP))&BP10G_SDP6_DATA_IN)!=0?1:0); + //return(((readl((void *)((pbpctl_dev)->mem_map) + 0x28)) & 0x1)!=0?1:0); + return (((BP10G_READ_REG(pbpctl_dev_b, EODSDP)) + & BP10G_SDP6_DATA_IN) != 0 ? 1 : 0); + } + + } + } + return BP_NOT_CAP; +} + +static int disc_status(bpctl_dev_t * pbpctl_dev) +{ + int ctrl = 0; + if (pbpctl_dev->bp_caps & DISC_CAP) { + + if ((ctrl = disc_off_status(pbpctl_dev)) < 0) + return ctrl; + return ((ctrl == 0) ? 1 : 0); + + } + return BP_NOT_CAP; +} + +int default_pwron_disc_status(bpctl_dev_t * pbpctl_dev) +{ + if (pbpctl_dev->bp_caps & DISC_PWUP_CTL_CAP) { + if (pbpctl_dev->bp_ext_ver >= 0x8) + return ((((read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR)) & + DFLT_PWRON_DISC_MASK) == + DFLT_PWRON_DISC_MASK) ? 1 : 0); + } + return BP_NOT_CAP; +} + +int dis_disc_cap_status(bpctl_dev_t * pbpctl_dev) +{ + if (pbpctl_dev->bp_caps & DIS_DISC_CAP) { + if (pbpctl_dev->bp_ext_ver >= 0x8) + return ((((read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR)) & + DIS_DISC_CAP_MASK) == + DIS_DISC_CAP_MASK) ? 1 : 0); + } + return BP_NOT_CAP; +} + +int disc_port_status(bpctl_dev_t * pbpctl_dev) +{ + int ret = BP_NOT_CAP; + bpctl_dev_t *pbpctl_dev_m; + + if ((is_bypass_fn(pbpctl_dev)) == 1) + pbpctl_dev_m = pbpctl_dev; + else + pbpctl_dev_m = get_master_port_fn(pbpctl_dev); + if (pbpctl_dev_m == NULL) + return BP_NOT_CAP; + + if (pbpctl_dev_m->bp_caps_ex & DISC_PORT_CAP_EX) { + if (is_bypass_fn(pbpctl_dev) == 1) { + return ((((read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR)) & + TX_DISA_MASK) == TX_DISA_MASK) ? 1 : 0); + } else + return ((((read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR)) & + TX_DISB_MASK) == TX_DISB_MASK) ? 1 : 0); + + } + return ret; +} + +int default_pwron_disc_port_status(bpctl_dev_t * pbpctl_dev) +{ + int ret = BP_NOT_CAP; + bpctl_dev_t *pbpctl_dev_m; + + if ((is_bypass_fn(pbpctl_dev)) == 1) + pbpctl_dev_m = pbpctl_dev; + else + pbpctl_dev_m = get_master_port_fn(pbpctl_dev); + if (pbpctl_dev_m == NULL) + return BP_NOT_CAP; + + if (pbpctl_dev_m->bp_caps_ex & DISC_PORT_CAP_EX) { + if (is_bypass_fn(pbpctl_dev) == 1) + return ret; + // return((((read_reg(pbpctl_dev,STATUS_TAP_REG_ADDR)) & TX_DISA_MASK)==TX_DISA_MASK)?1:0); + else + return ret; + // return((((read_reg(pbpctl_dev,STATUS_TAP_REG_ADDR)) & TX_DISA_MASK)==TX_DISA_MASK)?1:0); + + } + return ret; +} + +int wdt_exp_mode_status(bpctl_dev_t * pbpctl_dev) +{ + if (pbpctl_dev->bp_caps & WD_CTL_CAP) { + if (pbpctl_dev->bp_ext_ver <= PXG2BPI_VER) + return 0; /* bypass mode */ + else if (pbpctl_dev->bp_ext_ver == PXG2TBPI_VER) + return 1; /* tap mode */ + else if (pbpctl_dev->bp_ext_ver >= PXE2TBPI_VER) { + if (pbpctl_dev->bp_ext_ver >= 0x8) { + if (((read_reg + (pbpctl_dev, + STATUS_DISC_REG_ADDR)) & + WDTE_DISC_BPN_MASK) == WDTE_DISC_BPN_MASK) + return 2; + } + return ((((read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR)) & + WDTE_TAP_BPN_MASK) == + WDTE_TAP_BPN_MASK) ? 1 : 0); + } + } + return BP_NOT_CAP; +} + +int tpl2_flag_status(bpctl_dev_t * pbpctl_dev) +{ + + if (pbpctl_dev->bp_caps_ex & TPL2_CAP_EX) { + return ((((read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR)) & + TPL2_FLAG_MASK) == TPL2_FLAG_MASK) ? 1 : 0); + + } + return BP_NOT_CAP; +} + +int tpl_hw_status(bpctl_dev_t * pbpctl_dev) +{ + bpctl_dev_t *pbpctl_dev_b = NULL; + + if (!(pbpctl_dev_b = get_status_port_fn(pbpctl_dev))) + return BP_NOT_CAP; + + if (TPL_IF_SERIES(pbpctl_dev->subdevice)) + return (((BPCTL_READ_REG(pbpctl_dev, CTRL)) & + BPCTLI_CTRL_SWDPIN0) != 0 ? 1 : 0); + return BP_NOT_CAP; +} + +//#ifdef PMC_FIX_FLAG + +int bp_wait_at_pwup_status(bpctl_dev_t * pbpctl_dev) +{ + if (pbpctl_dev->bp_caps & SW_CTL_CAP) { + if (pbpctl_dev->bp_ext_ver >= 0x8) + return ((((read_reg(pbpctl_dev, CONT_CONFIG_REG_ADDR)) & + WAIT_AT_PWUP_MASK) == + WAIT_AT_PWUP_MASK) ? 1 : 0); + } + return BP_NOT_CAP; +} + +int bp_hw_reset_status(bpctl_dev_t * pbpctl_dev) +{ + + if (pbpctl_dev->bp_caps & SW_CTL_CAP) { + + if (pbpctl_dev->bp_ext_ver >= 0x8) + return ((((read_reg(pbpctl_dev, CONT_CONFIG_REG_ADDR)) & + EN_HW_RESET_MASK) == + EN_HW_RESET_MASK) ? 1 : 0); + } + return BP_NOT_CAP; +} + +//#endif /*PMC_FIX_FLAG*/ + +int std_nic_status(bpctl_dev_t * pbpctl_dev) +{ + int status_val = 0; + + if (pbpctl_dev->bp_caps & STD_NIC_CAP) { + if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) + return BP_NOT_CAP; + if (pbpctl_dev->bp_ext_ver >= BP_FW_EXT_VER8) { + return ((((read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR)) & + STD_NIC_ON_MASK) == STD_NIC_ON_MASK) ? 1 : 0); + } + + if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { + if (pbpctl_dev->bp_caps & BP_CAP) { + status_val = + read_reg(pbpctl_dev, STATUS_REG_ADDR); + if (((!(status_val & WDT_EN_MASK)) + && ((status_val & STD_NIC_MASK) == + STD_NIC_MASK))) + status_val = 1; + else + return 0; + } + if (pbpctl_dev->bp_caps & TAP_CAP) { + status_val = + read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR); + if ((status_val & STD_NIC_TAP_MASK) == + STD_NIC_TAP_MASK) + status_val = 1; + else + return 0; + } + if (pbpctl_dev->bp_caps & TAP_CAP) { + if ((disc_off_status(pbpctl_dev))) + status_val = 1; + else + return 0; + } + + return status_val; + } + } + return BP_NOT_CAP; +} + +/******************************************************/ +/**************SW_INIT*********************************/ +/******************************************************/ +void bypass_caps_init(bpctl_dev_t * pbpctl_dev) +{ + u_int32_t ctrl_ext = 0; + bpctl_dev_t *pbpctl_dev_m = NULL; + +#ifdef BYPASS_DEBUG + int ret = 0; + if (!(INTEL_IF_SERIES(adapter->bp_device_block.subdevice))) { + ret = read_reg(pbpctl_dev, VER_REG_ADDR); + printk("VER_REG reg1=%x\n", ret); + ret = read_reg(pbpctl_dev, PRODUCT_CAP_REG_ADDR); + printk("PRODUCT_CAP reg=%x\n", ret); + ret = read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR); + printk("STATUS_TAP reg1=%x\n", ret); + ret = read_reg(pbpctl_dev, 0x7); + printk("SIG_REG reg1=%x\n", ret); + ret = read_reg(pbpctl_dev, STATUS_REG_ADDR); + printk("STATUS_REG_ADDR=%x\n", ret); + ret = read_reg(pbpctl_dev, WDT_REG_ADDR); + printk("WDT_REG_ADDR=%x\n", ret); + ret = read_reg(pbpctl_dev, TMRL_REG_ADDR); + printk("TMRL_REG_ADDR=%x\n", ret); + ret = read_reg(pbpctl_dev, TMRH_REG_ADDR); + printk("TMRH_REG_ADDR=%x\n", ret); + } +#endif + if ((pbpctl_dev->bp_fiber5) || (pbpctl_dev->bp_10g9)) { + pbpctl_dev->media_type = bp_fiber; + } else if (pbpctl_dev->bp_10gb) { + if (BP10GB_CX4_SERIES(pbpctl_dev->subdevice)) + pbpctl_dev->media_type = bp_cx4; + else + pbpctl_dev->media_type = bp_fiber; + + } + + else if (pbpctl_dev->bp_540) + pbpctl_dev->media_type = bp_none; + else if (!pbpctl_dev->bp_10g) { + + ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); + if ((ctrl_ext & BPCTLI_CTRL_EXT_LINK_MODE_MASK) == 0x0) + pbpctl_dev->media_type = bp_copper; + else + pbpctl_dev->media_type = bp_fiber; + + } + //if (!pbpctl_dev->bp_10g) + // pbpctl_dev->media_type=((BPCTL_READ_REG(pbpctl_dev, STATUS))&BPCTLI_STATUS_TBIMODE)?bp_fiber:bp_copper; + else { + if (BP10G_CX4_SERIES(pbpctl_dev->subdevice)) + pbpctl_dev->media_type = bp_cx4; + else + pbpctl_dev->media_type = bp_fiber; + } + + //pbpctl_dev->bp_fw_ver=0xa8; + if (is_bypass_fn(pbpctl_dev)) { + + pbpctl_dev->bp_caps |= BP_PWOFF_ON_CAP; + if (pbpctl_dev->media_type == bp_fiber) + pbpctl_dev->bp_caps |= + (TX_CTL_CAP | TX_STATUS_CAP | TPL_CAP); + + if (TPL_IF_SERIES(pbpctl_dev->subdevice)) { + pbpctl_dev->bp_caps |= TPL_CAP; + } + + if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) { + pbpctl_dev->bp_caps |= + (BP_CAP | BP_STATUS_CAP | SW_CTL_CAP | + BP_PWUP_ON_CAP | BP_PWUP_OFF_CAP | BP_PWOFF_OFF_CAP + | WD_CTL_CAP | WD_STATUS_CAP | STD_NIC_CAP | + WD_TIMEOUT_CAP); + + pbpctl_dev->bp_ext_ver = OLD_IF_VER; + return; + } + + if ((pbpctl_dev->bp_fw_ver == 0xff) && + OLD_IF_SERIES(pbpctl_dev->subdevice)) { + + pbpctl_dev->bp_caps |= + (BP_CAP | BP_STATUS_CAP | BP_STATUS_CHANGE_CAP | + SW_CTL_CAP | BP_PWUP_ON_CAP | WD_CTL_CAP | + WD_STATUS_CAP | WD_TIMEOUT_CAP); + + pbpctl_dev->bp_ext_ver = OLD_IF_VER; + return; + } + + else { + switch (pbpctl_dev->bp_fw_ver) { + case BP_FW_VER_A0: + case BP_FW_VER_A1:{ + pbpctl_dev->bp_ext_ver = + (pbpctl_dev-> + bp_fw_ver & EXT_VER_MASK); + break; + } + default:{ + if ((bypass_sign_check(pbpctl_dev)) != + 1) { + pbpctl_dev->bp_caps = 0; + return; + } + pbpctl_dev->bp_ext_ver = + (pbpctl_dev-> + bp_fw_ver & EXT_VER_MASK); + } + } + } + + if (pbpctl_dev->bp_ext_ver == PXG2BPI_VER) + pbpctl_dev->bp_caps |= + (BP_CAP | BP_STATUS_CAP | BP_STATUS_CHANGE_CAP | + SW_CTL_CAP | BP_DIS_CAP | BP_DIS_STATUS_CAP | + BP_PWUP_ON_CAP | BP_PWUP_OFF_CAP | BP_PWUP_CTL_CAP + | WD_CTL_CAP | STD_NIC_CAP | WD_STATUS_CAP | + WD_TIMEOUT_CAP); + else if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) { + int cap_reg; + + pbpctl_dev->bp_caps |= + (SW_CTL_CAP | WD_CTL_CAP | WD_STATUS_CAP | + WD_TIMEOUT_CAP); + cap_reg = get_bp_prod_caps(pbpctl_dev); + + if ((cap_reg & NORMAL_UNSUPPORT_MASK) == + NORMAL_UNSUPPORT_MASK) + pbpctl_dev->bp_caps |= NIC_CAP_NEG; + else + pbpctl_dev->bp_caps |= STD_NIC_CAP; + + if ((normal_support(pbpctl_dev)) == 1) + + pbpctl_dev->bp_caps |= STD_NIC_CAP; + + else + pbpctl_dev->bp_caps |= NIC_CAP_NEG; + if ((cap_reg & BYPASS_SUPPORT_MASK) == + BYPASS_SUPPORT_MASK) { + pbpctl_dev->bp_caps |= + (BP_CAP | BP_STATUS_CAP | + BP_STATUS_CHANGE_CAP | BP_DIS_CAP | + BP_DIS_STATUS_CAP | BP_PWUP_ON_CAP | + BP_PWUP_OFF_CAP | BP_PWUP_CTL_CAP); + if (pbpctl_dev->bp_ext_ver >= BP_FW_EXT_VER7) + pbpctl_dev->bp_caps |= + BP_PWOFF_ON_CAP | BP_PWOFF_OFF_CAP | + BP_PWOFF_CTL_CAP; + } + if ((cap_reg & TAP_SUPPORT_MASK) == TAP_SUPPORT_MASK) { + pbpctl_dev->bp_caps |= + (TAP_CAP | TAP_STATUS_CAP | + TAP_STATUS_CHANGE_CAP | TAP_DIS_CAP | + TAP_DIS_STATUS_CAP | TAP_PWUP_ON_CAP | + TAP_PWUP_OFF_CAP | TAP_PWUP_CTL_CAP); + } + if (pbpctl_dev->bp_ext_ver >= BP_FW_EXT_VER8) { + if ((cap_reg & DISC_SUPPORT_MASK) == + DISC_SUPPORT_MASK) + pbpctl_dev->bp_caps |= + (DISC_CAP | DISC_DIS_CAP | + DISC_PWUP_CTL_CAP); + if ((cap_reg & TPL2_SUPPORT_MASK) == + TPL2_SUPPORT_MASK) { + pbpctl_dev->bp_caps_ex |= TPL2_CAP_EX; + pbpctl_dev->bp_caps |= TPL_CAP; + pbpctl_dev->bp_tpl_flag = + tpl2_flag_status(pbpctl_dev); + } + + } + + if (pbpctl_dev->bp_ext_ver >= BP_FW_EXT_VER9) { + if ((cap_reg & DISC_PORT_SUPPORT_MASK) == + DISC_PORT_SUPPORT_MASK) { + pbpctl_dev->bp_caps_ex |= + DISC_PORT_CAP_EX; + pbpctl_dev->bp_caps |= + (TX_CTL_CAP | TX_STATUS_CAP); + } + + } + + } + if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { + if ((read_reg(pbpctl_dev, STATUS_REG_ADDR)) & + WDT_EN_MASK) + pbpctl_dev->wdt_status = WDT_STATUS_EN; + else + pbpctl_dev->wdt_status = WDT_STATUS_DIS; + } + + } else if ((P2BPFI_IF_SERIES(pbpctl_dev->subdevice)) || + (PEGF5_IF_SERIES(pbpctl_dev->subdevice)) || + (PEGF80_IF_SERIES(pbpctl_dev->subdevice)) || + (BP10G9_IF_SERIES(pbpctl_dev->subdevice))) { + pbpctl_dev->bp_caps |= (TX_CTL_CAP | TX_STATUS_CAP); + } + if ((pbpctl_dev->subdevice & 0xa00) == 0xa00) + pbpctl_dev->bp_caps |= (TX_CTL_CAP | TX_STATUS_CAP); + if (PEG5_IF_SERIES(pbpctl_dev->subdevice)) + pbpctl_dev->bp_caps |= (TX_CTL_CAP | TX_STATUS_CAP); + + if (BP10GB_IF_SERIES(pbpctl_dev->subdevice)) { + pbpctl_dev->bp_caps &= ~(TX_CTL_CAP | TX_STATUS_CAP); + } + pbpctl_dev_m = get_master_port_fn(pbpctl_dev); + if (pbpctl_dev_m != NULL) { + int cap_reg = 0; + if (pbpctl_dev_m->bp_ext_ver >= 0x9) { + cap_reg = get_bp_prod_caps(pbpctl_dev_m); + if ((cap_reg & DISC_PORT_SUPPORT_MASK) == + DISC_PORT_SUPPORT_MASK) + pbpctl_dev->bp_caps |= + (TX_CTL_CAP | TX_STATUS_CAP); + pbpctl_dev->bp_caps_ex |= DISC_PORT_CAP_EX; + } + } +} + +int bypass_off_init(bpctl_dev_t * pbpctl_dev) +{ + int ret = 0; + + if ((ret = cmnd_on(pbpctl_dev)) < 0) + return ret; + if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) + return (dis_bypass_cap(pbpctl_dev)); + wdt_off(pbpctl_dev); + if (pbpctl_dev->bp_caps & BP_CAP) + bypass_off(pbpctl_dev); + if (pbpctl_dev->bp_caps & TAP_CAP) + tap_off(pbpctl_dev); + cmnd_off(pbpctl_dev); + return 0; +} + +void remove_bypass_wd_auto(bpctl_dev_t * pbpctl_dev) +{ +#ifdef BP_SELF_TEST + bpctl_dev_t *pbpctl_dev_sl = NULL; +#endif + + if (pbpctl_dev->bp_caps & WD_CTL_CAP) { + + del_timer_sync(&pbpctl_dev->bp_timer); +#ifdef BP_SELF_TEST + pbpctl_dev_sl = get_status_port_fn(pbpctl_dev); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)) + if (pbpctl_dev_sl && (pbpctl_dev_sl->ndev) + && (pbpctl_dev_sl->ndev->hard_start_xmit) + && (pbpctl_dev_sl->hard_start_xmit_save)) { + rtnl_lock(); + pbpctl_dev_sl->ndev->hard_start_xmit = + pbpctl_dev_sl->hard_start_xmit_save; + rtnl_unlock(); + } +#else + if (pbpctl_dev_sl && (pbpctl_dev_sl->ndev)) { + if ((pbpctl_dev_sl->ndev->netdev_ops) + && (pbpctl_dev_sl->old_ops)) { + rtnl_lock(); + pbpctl_dev_sl->ndev->netdev_ops = + pbpctl_dev_sl->old_ops; + pbpctl_dev_sl->old_ops = NULL; + + rtnl_unlock(); + + } + + } + +#endif +#endif + } + +} + +int init_bypass_wd_auto(bpctl_dev_t * pbpctl_dev) +{ + if (pbpctl_dev->bp_caps & WD_CTL_CAP) { + init_timer(&pbpctl_dev->bp_timer); + pbpctl_dev->bp_timer.function = &wd_reset_timer; + pbpctl_dev->bp_timer.data = (unsigned long)pbpctl_dev; + return 1; + } + return BP_NOT_CAP; +} + +#ifdef BP_SELF_TEST +int bp_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + bpctl_dev_t *pbpctl_dev = NULL, *pbpctl_dev_m = NULL; + int idx_dev = 0; + struct ethhdr *eth = (struct ethhdr *)skb->data; + + for (idx_dev = 0; + ((bpctl_dev_arr[idx_dev].ndev != NULL) && (idx_dev < device_num)); + idx_dev++) { + if (bpctl_dev_arr[idx_dev].ndev == dev) { + pbpctl_dev = &bpctl_dev_arr[idx_dev]; + break; + } + } + if (!pbpctl_dev) + return 1; + if ((htons(ETH_P_BPTEST) == eth->h_proto)) { + + pbpctl_dev_m = get_master_port_fn(pbpctl_dev); + if (pbpctl_dev_m) { + + if (bypass_status(pbpctl_dev_m)) { + cmnd_on(pbpctl_dev_m); + bypass_off(pbpctl_dev_m); + cmnd_off(pbpctl_dev_m); + } + wdt_timer_reload(pbpctl_dev_m); + } + dev_kfree_skb_irq(skb); + return 0; + } + return (pbpctl_dev->hard_start_xmit_save(skb, dev)); +} +#endif + +int set_bypass_wd_auto(bpctl_dev_t * pbpctl_dev, unsigned int param) +{ + if (pbpctl_dev->bp_caps & WD_CTL_CAP) { + if (pbpctl_dev->reset_time != param) { + if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) + pbpctl_dev->reset_time = + (param < + WDT_AUTO_MIN_INT) ? WDT_AUTO_MIN_INT : + param; + else + pbpctl_dev->reset_time = param; + if (param) + mod_timer(&pbpctl_dev->bp_timer, jiffies); + } + return 0; + } + return BP_NOT_CAP; +} + +int get_bypass_wd_auto(bpctl_dev_t * pbpctl_dev) +{ + + if (pbpctl_dev->bp_caps & WD_CTL_CAP) { + return pbpctl_dev->reset_time; + } + return BP_NOT_CAP; +} + +#ifdef BP_SELF_TEST + +int set_bp_self_test(bpctl_dev_t * pbpctl_dev, unsigned int param) +{ + bpctl_dev_t *pbpctl_dev_sl = NULL; + + if (pbpctl_dev->bp_caps & WD_CTL_CAP) { + pbpctl_dev->bp_self_test_flag = param == 0 ? 0 : 1; + pbpctl_dev_sl = get_status_port_fn(pbpctl_dev); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)) + if ((pbpctl_dev_sl->ndev) && + (pbpctl_dev_sl->ndev->hard_start_xmit)) { + rtnl_lock(); + if (pbpctl_dev->bp_self_test_flag == 1) { + + pbpctl_dev_sl->hard_start_xmit_save = + pbpctl_dev_sl->ndev->hard_start_xmit; + pbpctl_dev_sl->ndev->hard_start_xmit = + bp_hard_start_xmit; + } else if (pbpctl_dev_sl->hard_start_xmit_save) { + pbpctl_dev_sl->ndev->hard_start_xmit = + pbpctl_dev_sl->hard_start_xmit_save; + } + rtnl_unlock(); + } +#else + if ((pbpctl_dev_sl->ndev) && (pbpctl_dev_sl->ndev->netdev_ops)) { + rtnl_lock(); + if (pbpctl_dev->bp_self_test_flag == 1) { + + pbpctl_dev_sl->old_ops = + pbpctl_dev_sl->ndev->netdev_ops; + pbpctl_dev_sl->new_ops = + *pbpctl_dev_sl->old_ops; + pbpctl_dev_sl->new_ops.ndo_start_xmit = + bp_hard_start_xmit; + pbpctl_dev_sl->ndev->netdev_ops = + &pbpctl_dev_sl->new_ops; + + } else if (pbpctl_dev_sl->old_ops) { + pbpctl_dev_sl->ndev->netdev_ops = + pbpctl_dev_sl->old_ops; + pbpctl_dev_sl->old_ops = NULL; + } + rtnl_unlock(); + } +#endif + + set_bypass_wd_auto(pbpctl_dev, param); + return 0; + } + return BP_NOT_CAP; +} + +int get_bp_self_test(bpctl_dev_t * pbpctl_dev) +{ + + if (pbpctl_dev->bp_caps & WD_CTL_CAP) { + if (pbpctl_dev->bp_self_test_flag == 1) + return pbpctl_dev->reset_time; + else + return 0; + } + return BP_NOT_CAP; +} + +#endif + +/**************************************************************/ +/************************* API ********************************/ +/**************************************************************/ + +int is_bypass_fn(bpctl_dev_t * pbpctl_dev) +{ + if (!pbpctl_dev) + return -1; + + return (((pbpctl_dev->func == 0) || (pbpctl_dev->func == 2)) ? 1 : 0); +} + +int set_bypass_fn(bpctl_dev_t * pbpctl_dev, int bypass_mode) +{ + int ret = 0; + + if (!(pbpctl_dev->bp_caps & BP_CAP)) + return BP_NOT_CAP; + if ((ret = cmnd_on(pbpctl_dev)) < 0) + return ret; + if (!bypass_mode) + ret = bypass_off(pbpctl_dev); + else + ret = bypass_on(pbpctl_dev); + cmnd_off(pbpctl_dev); + + return ret; +} + +int get_bypass_fn(bpctl_dev_t * pbpctl_dev) +{ + return (bypass_status(pbpctl_dev)); +} + +int get_bypass_change_fn(bpctl_dev_t * pbpctl_dev) +{ + if (!pbpctl_dev) + return -1; + + return (bypass_change_status(pbpctl_dev)); +} + +int set_dis_bypass_fn(bpctl_dev_t * pbpctl_dev, int dis_param) +{ + int ret = 0; + if (!pbpctl_dev) + return -1; + + if (!(pbpctl_dev->bp_caps & BP_DIS_CAP)) + return BP_NOT_CAP; + if ((ret = cmnd_on(pbpctl_dev)) < 0) + return ret; + if (dis_param) + ret = dis_bypass_cap(pbpctl_dev); + else + ret = en_bypass_cap(pbpctl_dev); + cmnd_off(pbpctl_dev); + return ret; +} + +int get_dis_bypass_fn(bpctl_dev_t * pbpctl_dev) +{ + if (!pbpctl_dev) + return -1; + + return (dis_bypass_cap_status(pbpctl_dev)); +} + +int set_bypass_pwoff_fn(bpctl_dev_t * pbpctl_dev, int bypass_mode) +{ + int ret = 0; + if (!pbpctl_dev) + return -1; + + if (!(pbpctl_dev->bp_caps & BP_PWOFF_CTL_CAP)) + return BP_NOT_CAP; + if ((ret = cmnd_on(pbpctl_dev)) < 0) + return ret; + if (bypass_mode) + ret = bypass_state_pwroff(pbpctl_dev); + else + ret = normal_state_pwroff(pbpctl_dev); + cmnd_off(pbpctl_dev); + return ret; +} + +int get_bypass_pwoff_fn(bpctl_dev_t * pbpctl_dev) +{ + if (!pbpctl_dev) + return -1; + + return (default_pwroff_status(pbpctl_dev)); +} + +int set_bypass_pwup_fn(bpctl_dev_t * pbpctl_dev, int bypass_mode) +{ + int ret = 0; + if (!pbpctl_dev) + return -1; + + if (!(pbpctl_dev->bp_caps & BP_PWUP_CTL_CAP)) + return BP_NOT_CAP; + if ((ret = cmnd_on(pbpctl_dev)) < 0) + return ret; + if (bypass_mode) + ret = bypass_state_pwron(pbpctl_dev); + else + ret = normal_state_pwron(pbpctl_dev); + cmnd_off(pbpctl_dev); + return ret; +} + +int get_bypass_pwup_fn(bpctl_dev_t * pbpctl_dev) +{ + if (!pbpctl_dev) + return -1; + + return (default_pwron_status(pbpctl_dev)); +} + +int set_bypass_wd_fn(bpctl_dev_t * pbpctl_dev, int timeout) +{ + int ret = 0; + if (!pbpctl_dev) + return -1; + + if (!(pbpctl_dev->bp_caps & WD_CTL_CAP)) + return BP_NOT_CAP; + + if ((ret = cmnd_on(pbpctl_dev)) < 0) + return ret; + if (!timeout) + ret = wdt_off(pbpctl_dev); + else { + wdt_on(pbpctl_dev, timeout); + ret = pbpctl_dev->bypass_timer_interval; + } + cmnd_off(pbpctl_dev); + return ret; +} + +int get_bypass_wd_fn(bpctl_dev_t * pbpctl_dev, int *timeout) +{ + if (!pbpctl_dev) + return -1; + + return wdt_programmed(pbpctl_dev, timeout); +} + +int get_wd_expire_time_fn(bpctl_dev_t * pbpctl_dev, int *time_left) +{ + if (!pbpctl_dev) + return -1; + + return (wdt_timer(pbpctl_dev, time_left)); +} + +int reset_bypass_wd_timer_fn(bpctl_dev_t * pbpctl_dev) +{ + if (!pbpctl_dev) + return -1; + + return (wdt_timer_reload(pbpctl_dev)); +} + +int get_wd_set_caps_fn(bpctl_dev_t * pbpctl_dev) +{ + int bp_status = 0; + + unsigned int step_value = TIMEOUT_MAX_STEP + 1, bit_cnt = 0; + if (!pbpctl_dev) + return -1; + + if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) + return BP_NOT_CAP; + + while ((step_value >>= 1)) + bit_cnt++; + + if (is_bypass_fn(pbpctl_dev)) { + bp_status = + WD_STEP_COUNT_MASK(bit_cnt) | WDT_STEP_TIME | + WD_MIN_TIME_MASK(TIMEOUT_UNIT / 100); + } else + return -1; + + return bp_status; +} + +int set_std_nic_fn(bpctl_dev_t * pbpctl_dev, int nic_mode) +{ + int ret = 0; + if (!pbpctl_dev) + return -1; + + if (!(pbpctl_dev->bp_caps & STD_NIC_CAP)) + return BP_NOT_CAP; + + if ((ret = cmnd_on(pbpctl_dev)) < 0) + return ret; + if (nic_mode) + ret = std_nic_on(pbpctl_dev); + else + ret = std_nic_off(pbpctl_dev); + cmnd_off(pbpctl_dev); + return ret; +} + +int get_std_nic_fn(bpctl_dev_t * pbpctl_dev) +{ + if (!pbpctl_dev) + return -1; + + return (std_nic_status(pbpctl_dev)); +} + +int set_tap_fn(bpctl_dev_t * pbpctl_dev, int tap_mode) +{ + if (!pbpctl_dev) + return -1; + + if ((pbpctl_dev->bp_caps & TAP_CAP) && ((cmnd_on(pbpctl_dev)) >= 0)) { + if (!tap_mode) + tap_off(pbpctl_dev); + else + tap_on(pbpctl_dev); + cmnd_off(pbpctl_dev); + return 0; + } + return BP_NOT_CAP; +} + +int get_tap_fn(bpctl_dev_t * pbpctl_dev) +{ + if (!pbpctl_dev) + return -1; + + return (tap_status(pbpctl_dev)); +} + +int set_tap_pwup_fn(bpctl_dev_t * pbpctl_dev, int tap_mode) +{ + int ret = 0; + if (!pbpctl_dev) + return -1; + + if ((pbpctl_dev->bp_caps & TAP_PWUP_CTL_CAP) + && ((cmnd_on(pbpctl_dev)) >= 0)) { + if (tap_mode) + ret = tap_state_pwron(pbpctl_dev); + else + ret = normal_state_pwron(pbpctl_dev); + cmnd_off(pbpctl_dev); + } else + ret = BP_NOT_CAP; + return ret; +} + +int get_tap_pwup_fn(bpctl_dev_t * pbpctl_dev) +{ + int ret = 0; + if (!pbpctl_dev) + return -1; + + if ((ret = default_pwron_tap_status(pbpctl_dev)) < 0) + return ret; + return ((ret == 0) ? 1 : 0); +} + +int get_tap_change_fn(bpctl_dev_t * pbpctl_dev) +{ + if (!pbpctl_dev) + return -1; + + return (tap_change_status(pbpctl_dev)); +} + +int set_dis_tap_fn(bpctl_dev_t * pbpctl_dev, int dis_param) +{ + int ret = 0; + if (!pbpctl_dev) + return -1; + + if ((pbpctl_dev->bp_caps & TAP_DIS_CAP) && ((cmnd_on(pbpctl_dev)) >= 0)) { + if (dis_param) + ret = dis_tap_cap(pbpctl_dev); + else + ret = en_tap_cap(pbpctl_dev); + cmnd_off(pbpctl_dev); + return ret; + } else + return BP_NOT_CAP; +} + +int get_dis_tap_fn(bpctl_dev_t * pbpctl_dev) +{ + if (!pbpctl_dev) + return -1; + + return (dis_tap_cap_status(pbpctl_dev)); +} + +int set_disc_fn(bpctl_dev_t * pbpctl_dev, int disc_mode) +{ + if (!pbpctl_dev) + return -1; + + if ((pbpctl_dev->bp_caps & DISC_CAP) && ((cmnd_on(pbpctl_dev)) >= 0)) { + if (!disc_mode) + disc_off(pbpctl_dev); + else + disc_on(pbpctl_dev); + cmnd_off(pbpctl_dev); + + return BP_OK; + } + return BP_NOT_CAP; +} + +int get_disc_fn(bpctl_dev_t * pbpctl_dev) +{ + int ret = 0; + if (!pbpctl_dev) + return -1; + + ret = disc_status(pbpctl_dev); + + return ret; +} + +int set_disc_pwup_fn(bpctl_dev_t * pbpctl_dev, int disc_mode) +{ + int ret = 0; + if (!pbpctl_dev) + return -1; + + if ((pbpctl_dev->bp_caps & DISC_PWUP_CTL_CAP) + && ((cmnd_on(pbpctl_dev)) >= 0)) { + if (disc_mode) + ret = disc_state_pwron(pbpctl_dev); + else + ret = normal_state_pwron(pbpctl_dev); + cmnd_off(pbpctl_dev); + } else + ret = BP_NOT_CAP; + return ret; +} + +int get_disc_pwup_fn(bpctl_dev_t * pbpctl_dev) +{ + int ret = 0; + if (!pbpctl_dev) + return -1; + + ret = default_pwron_disc_status(pbpctl_dev); + return (ret == 0 ? 1 : (ret < 0 ? BP_NOT_CAP : 0)); +} + +int get_disc_change_fn(bpctl_dev_t * pbpctl_dev) +{ + int ret = 0; + if (!pbpctl_dev) + return -1; + + ret = disc_change_status(pbpctl_dev); + return ret; +} + +int set_dis_disc_fn(bpctl_dev_t * pbpctl_dev, int dis_param) +{ + int ret = 0; + if (!pbpctl_dev) + return -1; + + if ((pbpctl_dev->bp_caps & DISC_DIS_CAP) + && ((cmnd_on(pbpctl_dev)) >= 0)) { + if (dis_param) + ret = dis_disc_cap(pbpctl_dev); + else + ret = en_disc_cap(pbpctl_dev); + cmnd_off(pbpctl_dev); + return ret; + } else + return BP_NOT_CAP; +} + +int get_dis_disc_fn(bpctl_dev_t * pbpctl_dev) +{ + int ret = 0; + if (!pbpctl_dev) + return -1; + + ret = dis_disc_cap_status(pbpctl_dev); + + return ret; +} + +int set_disc_port_fn(bpctl_dev_t * pbpctl_dev, int disc_mode) +{ + int ret = BP_NOT_CAP; + if (!pbpctl_dev) + return -1; + + if (!disc_mode) + ret = disc_port_off(pbpctl_dev); + else + ret = disc_port_on(pbpctl_dev); + + return ret; +} + +int get_disc_port_fn(bpctl_dev_t * pbpctl_dev) +{ + if (!pbpctl_dev) + return -1; + + return (disc_port_status(pbpctl_dev)); +} + +int set_disc_port_pwup_fn(bpctl_dev_t * pbpctl_dev, int disc_mode) +{ + int ret = BP_NOT_CAP; + if (!pbpctl_dev) + return -1; + + if (!disc_mode) + ret = normal_port_state_pwron(pbpctl_dev); + else + ret = disc_port_state_pwron(pbpctl_dev); + + return ret; +} + +int get_disc_port_pwup_fn(bpctl_dev_t * pbpctl_dev) +{ + int ret = 0; + if (!pbpctl_dev) + return -1; + + if ((ret = default_pwron_disc_port_status(pbpctl_dev)) < 0) + return ret; + return ((ret == 0) ? 1 : 0); +} + +int get_wd_exp_mode_fn(bpctl_dev_t * pbpctl_dev) +{ + if (!pbpctl_dev) + return -1; + + return (wdt_exp_mode_status(pbpctl_dev)); +} + +int set_wd_exp_mode_fn(bpctl_dev_t * pbpctl_dev, int param) +{ + if (!pbpctl_dev) + return -1; + + return (wdt_exp_mode(pbpctl_dev, param)); +} + +int reset_cont_fn(bpctl_dev_t * pbpctl_dev) +{ + int ret = 0; + if (!pbpctl_dev) + return -1; + + if ((ret = cmnd_on(pbpctl_dev)) < 0) + return ret; + return (reset_cont(pbpctl_dev)); +} + +int set_tx_fn(bpctl_dev_t * pbpctl_dev, int tx_state) +{ + + bpctl_dev_t *pbpctl_dev_b = NULL; + if (!pbpctl_dev) + return -1; + + if ((pbpctl_dev->bp_caps & TPL_CAP) && + (pbpctl_dev->bp_caps & SW_CTL_CAP)) { + if ((pbpctl_dev->bp_tpl_flag)) + return BP_NOT_CAP; + } else if ((pbpctl_dev_b = get_master_port_fn(pbpctl_dev))) { + if ((pbpctl_dev_b->bp_caps & TPL_CAP) && + (pbpctl_dev_b->bp_tpl_flag)) + return BP_NOT_CAP; + } + return (set_tx(pbpctl_dev, tx_state)); +} + +int set_bp_force_link_fn(int dev_num, int tx_state) +{ + static bpctl_dev_t *bpctl_dev_curr; + + if ((dev_num < 0) || (dev_num > device_num) + || (bpctl_dev_arr[dev_num].pdev == NULL)) + return -1; + bpctl_dev_curr = &bpctl_dev_arr[dev_num]; + + return (set_bp_force_link(bpctl_dev_curr, tx_state)); +} + +int set_wd_autoreset_fn(bpctl_dev_t * pbpctl_dev, int param) +{ + if (!pbpctl_dev) + return -1; + + return (set_bypass_wd_auto(pbpctl_dev, param)); +} + +int get_wd_autoreset_fn(bpctl_dev_t * pbpctl_dev) +{ + if (!pbpctl_dev) + return -1; + + return (get_bypass_wd_auto(pbpctl_dev)); +} + +#ifdef BP_SELF_TEST +int set_bp_self_test_fn(bpctl_dev_t * pbpctl_dev, int param) +{ + if (!pbpctl_dev) + return -1; + + return (set_bp_self_test(pbpctl_dev, param)); +} + +int get_bp_self_test_fn(bpctl_dev_t * pbpctl_dev) +{ + if (!pbpctl_dev) + return -1; + + return (get_bp_self_test(pbpctl_dev)); +} + +#endif + +int get_bypass_caps_fn(bpctl_dev_t * pbpctl_dev) +{ + if (!pbpctl_dev) + return -1; + + return (pbpctl_dev->bp_caps); + +} + +int get_bypass_slave_fn(bpctl_dev_t * pbpctl_dev, bpctl_dev_t ** pbpctl_dev_out) +{ + int idx_dev = 0; + if (!pbpctl_dev) + return -1; + + if ((pbpctl_dev->func == 0) || (pbpctl_dev->func == 2)) { + for (idx_dev = 0; + ((bpctl_dev_arr[idx_dev].pdev != NULL) + && (idx_dev < device_num)); idx_dev++) { + if ((bpctl_dev_arr[idx_dev].bus == pbpctl_dev->bus) + && (bpctl_dev_arr[idx_dev].slot == + pbpctl_dev->slot)) { + if ((pbpctl_dev->func == 0) + && (bpctl_dev_arr[idx_dev].func == 1)) { + *pbpctl_dev_out = + &bpctl_dev_arr[idx_dev]; + return 1; + } + if ((pbpctl_dev->func == 2) && + (bpctl_dev_arr[idx_dev].func == 3)) { + *pbpctl_dev_out = + &bpctl_dev_arr[idx_dev]; + return 1; + } + } + } + return -1; + } else + return 0; +} + +int is_bypass(bpctl_dev_t * pbpctl_dev) +{ + if (!pbpctl_dev) + return -1; + + if ((pbpctl_dev->func == 0) || (pbpctl_dev->func == 2)) + return 1; + else + return 0; +} + +int get_tx_fn(bpctl_dev_t * pbpctl_dev) +{ + bpctl_dev_t *pbpctl_dev_b = NULL; + if (!pbpctl_dev) + return -1; + + if ((pbpctl_dev->bp_caps & TPL_CAP) && + (pbpctl_dev->bp_caps & SW_CTL_CAP)) { + if ((pbpctl_dev->bp_tpl_flag)) + return BP_NOT_CAP; + } else if ((pbpctl_dev_b = get_master_port_fn(pbpctl_dev))) { + if ((pbpctl_dev_b->bp_caps & TPL_CAP) && + (pbpctl_dev_b->bp_tpl_flag)) + return BP_NOT_CAP; + } + return (tx_status(pbpctl_dev)); +} + +int get_bp_force_link_fn(int dev_num) +{ + static bpctl_dev_t *bpctl_dev_curr; + + if ((dev_num < 0) || (dev_num > device_num) + || (bpctl_dev_arr[dev_num].pdev == NULL)) + return -1; + bpctl_dev_curr = &bpctl_dev_arr[dev_num]; + + return (bp_force_link_status(bpctl_dev_curr)); +} + +static int get_bypass_link_status(bpctl_dev_t * pbpctl_dev) +{ + if (!pbpctl_dev) + return -1; + + if (pbpctl_dev->media_type == bp_fiber) + return ((BPCTL_READ_REG(pbpctl_dev, CTRL) & + BPCTLI_CTRL_SWDPIN1)); + else + return ((BPCTL_READ_REG(pbpctl_dev, STATUS) & + BPCTLI_STATUS_LU)); + +} + +static void bp_tpl_timer_fn(unsigned long param) +{ + bpctl_dev_t *pbpctl_dev = (bpctl_dev_t *) param; + uint32_t link1, link2; + bpctl_dev_t *pbpctl_dev_b = NULL; + + if (!(pbpctl_dev_b = get_status_port_fn(pbpctl_dev))) + return; + + if (!pbpctl_dev->bp_tpl_flag) { + set_tx(pbpctl_dev_b, 1); + set_tx(pbpctl_dev, 1); + return; + } + link1 = get_bypass_link_status(pbpctl_dev); + + link2 = get_bypass_link_status(pbpctl_dev_b); + if ((link1) && (tx_status(pbpctl_dev))) { + if ((!link2) && (tx_status(pbpctl_dev_b))) { + set_tx(pbpctl_dev, 0); + } else if (!tx_status(pbpctl_dev_b)) { + set_tx(pbpctl_dev_b, 1); + } + } else if ((!link1) && (tx_status(pbpctl_dev))) { + if ((link2) && (tx_status(pbpctl_dev_b))) { + set_tx(pbpctl_dev_b, 0); + } + } else if ((link1) && (!tx_status(pbpctl_dev))) { + if ((link2) && (tx_status(pbpctl_dev_b))) { + set_tx(pbpctl_dev, 1); + } + } else if ((!link1) && (!tx_status(pbpctl_dev))) { + if ((link2) && (tx_status(pbpctl_dev_b))) { + set_tx(pbpctl_dev, 1); + } + } + + mod_timer(&pbpctl_dev->bp_tpl_timer, jiffies + BP_LINK_MON_DELAY * HZ); +} + +void remove_bypass_tpl_auto(bpctl_dev_t * pbpctl_dev) +{ + bpctl_dev_t *pbpctl_dev_b = NULL; + if (!pbpctl_dev) + return; + pbpctl_dev_b = get_status_port_fn(pbpctl_dev); + + if (pbpctl_dev->bp_caps & TPL_CAP) { + del_timer_sync(&pbpctl_dev->bp_tpl_timer); + pbpctl_dev->bp_tpl_flag = 0; + pbpctl_dev_b = get_status_port_fn(pbpctl_dev); + if (pbpctl_dev_b) + set_tx(pbpctl_dev_b, 1); + set_tx(pbpctl_dev, 1); + } + return; +} + +int init_bypass_tpl_auto(bpctl_dev_t * pbpctl_dev) +{ + if (!pbpctl_dev) + return -1; + if (pbpctl_dev->bp_caps & TPL_CAP) { + init_timer(&pbpctl_dev->bp_tpl_timer); + pbpctl_dev->bp_tpl_timer.function = &bp_tpl_timer_fn; + pbpctl_dev->bp_tpl_timer.data = (unsigned long)pbpctl_dev; + return BP_OK; + } + return BP_NOT_CAP; +} + +int set_bypass_tpl_auto(bpctl_dev_t * pbpctl_dev, unsigned int param) +{ + if (!pbpctl_dev) + return -1; + if (pbpctl_dev->bp_caps & TPL_CAP) { + if ((param) && (!pbpctl_dev->bp_tpl_flag)) { + pbpctl_dev->bp_tpl_flag = param; + mod_timer(&pbpctl_dev->bp_tpl_timer, jiffies + 1); + return BP_OK; + }; + if ((!param) && (pbpctl_dev->bp_tpl_flag)) + remove_bypass_tpl_auto(pbpctl_dev); + + return BP_OK; + } + return BP_NOT_CAP; +} + +int get_bypass_tpl_auto(bpctl_dev_t * pbpctl_dev) +{ + if (!pbpctl_dev) + return -1; + if (pbpctl_dev->bp_caps & TPL_CAP) { + return pbpctl_dev->bp_tpl_flag; + } + return BP_NOT_CAP; +} + +int set_tpl_fn(bpctl_dev_t * pbpctl_dev, int tpl_mode) +{ + + bpctl_dev_t *pbpctl_dev_b = NULL; + if (!pbpctl_dev) + return -1; + + pbpctl_dev_b = get_status_port_fn(pbpctl_dev); + + if (pbpctl_dev->bp_caps & TPL_CAP) { + if (tpl_mode) { + if ((pbpctl_dev_b = get_status_port_fn(pbpctl_dev))) + set_tx(pbpctl_dev_b, 1); + set_tx(pbpctl_dev, 1); + } + if ((TPL_IF_SERIES(pbpctl_dev->subdevice)) || + (pbpctl_dev->bp_caps_ex & TPL2_CAP_EX)) { + pbpctl_dev->bp_tpl_flag = tpl_mode; + if (!tpl_mode) + tpl_hw_off(pbpctl_dev); + else + tpl_hw_on(pbpctl_dev); + } else + set_bypass_tpl_auto(pbpctl_dev, tpl_mode); + return 0; + } + return BP_NOT_CAP; +} + +int get_tpl_fn(bpctl_dev_t * pbpctl_dev) +{ + int ret = BP_NOT_CAP; + if (!pbpctl_dev) + return -1; + + if (pbpctl_dev->bp_caps & TPL_CAP) { + if (pbpctl_dev->bp_caps_ex & TPL2_CAP_EX) + return (tpl2_flag_status(pbpctl_dev)); + ret = pbpctl_dev->bp_tpl_flag; + } + return ret; +} + +//#ifdef PMC_FIX_FLAG +int set_bp_wait_at_pwup_fn(bpctl_dev_t * pbpctl_dev, int tap_mode) +{ + if (!pbpctl_dev) + return -1; + + if (pbpctl_dev->bp_caps & SW_CTL_CAP) { + //bp_lock(pbp_device_block); + cmnd_on(pbpctl_dev); + if (!tap_mode) + bp_wait_at_pwup_dis(pbpctl_dev); + else + bp_wait_at_pwup_en(pbpctl_dev); + cmnd_off(pbpctl_dev); + + // bp_unlock(pbp_device_block); + return BP_OK; + } + return BP_NOT_CAP; +} + +int get_bp_wait_at_pwup_fn(bpctl_dev_t * pbpctl_dev) +{ + int ret = 0; + if (!pbpctl_dev) + return -1; + + // bp_lock(pbp_device_block); + ret = bp_wait_at_pwup_status(pbpctl_dev); + // bp_unlock(pbp_device_block); + + return ret; +} + +int set_bp_hw_reset_fn(bpctl_dev_t * pbpctl_dev, int tap_mode) +{ + if (!pbpctl_dev) + return -1; + + if (pbpctl_dev->bp_caps & SW_CTL_CAP) { + // bp_lock(pbp_device_block); + cmnd_on(pbpctl_dev); + + if (!tap_mode) + bp_hw_reset_dis(pbpctl_dev); + else + bp_hw_reset_en(pbpctl_dev); + cmnd_off(pbpctl_dev); + // bp_unlock(pbp_device_block); + return BP_OK; + } + return BP_NOT_CAP; +} + +int get_bp_hw_reset_fn(bpctl_dev_t * pbpctl_dev) +{ + int ret = 0; + if (!pbpctl_dev) + return -1; + + //bp_lock(pbp_device_block); + ret = bp_hw_reset_status(pbpctl_dev); + + //bp_unlock(pbp_device_block); + + return ret; +} + +//#endif /*PMC_FIX_FLAG*/ + +int get_bypass_info_fn(bpctl_dev_t * pbpctl_dev, char *dev_name, + char *add_param) +{ + if (!pbpctl_dev) + return -1; + if (!is_bypass_fn(pbpctl_dev)) + return -1; + strcpy(dev_name, pbpctl_dev->name); + *add_param = pbpctl_dev->bp_fw_ver; + return 0; +} + +int get_dev_idx_bsf(int bus, int slot, int func) +{ + int idx_dev = 0; + //if_scan(); + for (idx_dev = 0; + ((bpctl_dev_arr[idx_dev].pdev != NULL) && (idx_dev < device_num)); + idx_dev++) { + if ((bus == bpctl_dev_arr[idx_dev].bus) + && (slot == bpctl_dev_arr[idx_dev].slot) + && (func == bpctl_dev_arr[idx_dev].func)) + + return idx_dev; + } + return -1; +} + +static void str_low(char *str) +{ + int i; + + for (i = 0; i < strlen(str); i++) + if ((str[i] >= 65) && (str[i] <= 90)) + str[i] += 32; +} + +static unsigned long str_to_hex(char *p) +{ + unsigned long hex = 0; + unsigned long length = strlen(p), shift = 0; + unsigned char dig = 0; + + str_low(p); + length = strlen(p); + + if (length == 0) + return 0; + + do { + dig = p[--length]; + dig = dig < 'a' ? (dig - '0') : (dig - 'a' + 0xa); + hex |= (dig << shift); + shift += 4; + } while (length); + return hex; +} + +static int get_dev_idx(int ifindex) +{ + int idx_dev = 0; + + for (idx_dev = 0; + ((bpctl_dev_arr[idx_dev].pdev != NULL) && (idx_dev < device_num)); + idx_dev++) { + if (ifindex == bpctl_dev_arr[idx_dev].ifindex) + return idx_dev; + } + + return -1; +} + +static bpctl_dev_t *get_dev_idx_p(int ifindex) +{ + int idx_dev = 0; + + for (idx_dev = 0; + ((bpctl_dev_arr[idx_dev].pdev != NULL) && (idx_dev < device_num)); + idx_dev++) { + if (ifindex == bpctl_dev_arr[idx_dev].ifindex) + return &bpctl_dev_arr[idx_dev]; + } + + return NULL; +} + +static void if_scan_init(void) +{ + int idx_dev = 0; + struct net_device *dev; + int ifindex; + //rcu_read_lock(); + //rtnl_lock(); + //rcu_read_lock(); +#if 1 +#if (LINUX_VERSION_CODE >= 0x020618) + for_each_netdev(&init_net, dev) +#elif (LINUX_VERSION_CODE >= 0x20616) + for_each_netdev(dev) +#else + for (dev = dev_base; dev; dev = dev->next) +#endif + { + + struct ethtool_drvinfo drvinfo; + // char *str=NULL; + char cbuf[32]; + char *buf = NULL; + char res[10]; + int i = 0; + int bus = 0, slot = 0, func = 0; + ifindex = dev->ifindex; + + memset(res, 0, 10); + memset(&drvinfo, 0, sizeof(struct ethtool_drvinfo)); + + if (dev->ethtool_ops && dev->ethtool_ops->get_drvinfo) { + memset(&drvinfo, 0, sizeof(drvinfo)); + dev->ethtool_ops->get_drvinfo(dev, &drvinfo); + } else + continue; + if (!drvinfo.bus_info) + continue; + if (!strcmp(drvinfo.bus_info, "N/A")) + continue; + memcpy(&cbuf, drvinfo.bus_info, 32); + buf = &cbuf[0]; + + // while(*buf++){ + + /*if(*buf==':'){ + buf++; + break; + } */ + //} + while (*buf++ != ':') ; + for (i = 0; i < 10; i++, buf++) { + if (*buf == ':') + break; + res[i] = *buf; + + } + buf++; + bus = str_to_hex(res); + memset(res, 0, 10); + + for (i = 0; i < 10; i++, buf++) { + if (*buf == '.') + break; + res[i] = *buf; + + } + buf++; + slot = str_to_hex(res); + func = str_to_hex(buf); + idx_dev = get_dev_idx_bsf(bus, slot, func); + + if (idx_dev != -1) { + + bpctl_dev_arr[idx_dev].ifindex = ifindex; + bpctl_dev_arr[idx_dev].ndev = dev; + + } + + } +#endif + //rtnl_unlock(); + //rcu_read_unlock(); + +} + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)) +static int device_ioctl(struct inode *inode, /* see include/linux/fs.h */ + struct file *file, /* ditto */ + unsigned int ioctl_num, /* number and param for ioctl */ + unsigned long ioctl_param) +#else +static long device_ioctl(struct file *file, /* ditto */ + unsigned int ioctl_num, /* number and param for ioctl */ + unsigned long ioctl_param) +#endif +{ + struct bpctl_cmd bpctl_cmd; + int dev_idx = 0; + bpctl_dev_t *pbpctl_dev_out; + void __user *argp = (void __user *)ioctl_param; + int ret = 0; + unsigned long flags; + + static bpctl_dev_t *pbpctl_dev; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)) + //lock_kernel(); +#endif + lock_bpctl(); + //local_irq_save(flags); + /*if(!spin_trylock_irqsave(&bpvm_lock)){ + local_irq_restore(flags); + //unlock_bpctl(); + //unlock_kernel(); + return -1; + } */ + //spin_lock_irqsave(&bpvm_lock, flags); + +/* +* Switch according to the ioctl called +*/ + if (ioctl_num == IOCTL_TX_MSG(IF_SCAN)) { + if_scan_init(); + ret = SUCCESS; + goto bp_exit; + } + if (copy_from_user(&bpctl_cmd, argp, sizeof(struct bpctl_cmd))) { + + ret = -EFAULT; + goto bp_exit; + } + + if (ioctl_num == IOCTL_TX_MSG(GET_DEV_NUM)) { + bpctl_cmd.out_param[0] = device_num; + if (copy_to_user + (argp, (void *)&bpctl_cmd, sizeof(struct bpctl_cmd))) { + ret = -EFAULT; + goto bp_exit; + } + ret = SUCCESS; + goto bp_exit; + + } + //lock_bpctl(); + //preempt_disable(); + local_irq_save(flags); + if (!spin_trylock(&bpvm_lock)) { + local_irq_restore(flags); + unlock_bpctl(); + //unlock_kernel(); + return -1; + } +// preempt_disable(); + //rcu_read_lock(); +// spin_lock_irqsave(&bpvm_lock, flags); + if ((bpctl_cmd.in_param[5]) || + (bpctl_cmd.in_param[6]) || (bpctl_cmd.in_param[7])) + dev_idx = get_dev_idx_bsf(bpctl_cmd.in_param[5], + bpctl_cmd.in_param[6], + bpctl_cmd.in_param[7]); + else if (bpctl_cmd.in_param[1] == 0) + dev_idx = bpctl_cmd.in_param[0]; + else + dev_idx = get_dev_idx(bpctl_cmd.in_param[1]); + + if (dev_idx < 0 || dev_idx > device_num) { + //unlock_bpctl(); + //preempt_enable(); + ret = -EOPNOTSUPP; + //preempt_enable(); + //rcu_read_unlock(); + spin_unlock_irqrestore(&bpvm_lock, flags); + goto bp_exit; + } + + bpctl_cmd.out_param[0] = bpctl_dev_arr[dev_idx].bus; + bpctl_cmd.out_param[1] = bpctl_dev_arr[dev_idx].slot; + bpctl_cmd.out_param[2] = bpctl_dev_arr[dev_idx].func; + bpctl_cmd.out_param[3] = bpctl_dev_arr[dev_idx].ifindex; + + if ((bpctl_dev_arr[dev_idx].bp_10gb) + && (!(bpctl_dev_arr[dev_idx].ifindex))) { + printk("Please load network driver for %s adapter!\n", + bpctl_dev_arr[dev_idx].name); + bpctl_cmd.status = -1; + ret = SUCCESS; + /*preempt_enable(); */ + //rcu_read_unlock(); + spin_unlock_irqrestore(&bpvm_lock, flags); + goto bp_exit; + + } + if ((bpctl_dev_arr[dev_idx].bp_10gb) && (bpctl_dev_arr[dev_idx].ndev)) { + if (!(bpctl_dev_arr[dev_idx].ndev->flags & IFF_UP)) { + if (!(bpctl_dev_arr[dev_idx].ndev->flags & IFF_UP)) { + printk + ("Please bring up network interfaces for %s adapter!\n", + bpctl_dev_arr[dev_idx].name); + bpctl_cmd.status = -1; + ret = SUCCESS; + /*preempt_enable(); */ + //rcu_read_unlock(); + spin_unlock_irqrestore(&bpvm_lock, flags); + goto bp_exit; + } + + } + } + + if ((dev_idx < 0) || (dev_idx > device_num) + || (bpctl_dev_arr[dev_idx].pdev == NULL)) { + bpctl_cmd.status = -1; + goto bpcmd_exit; + } + + pbpctl_dev = &bpctl_dev_arr[dev_idx]; + + switch (ioctl_num) { + case IOCTL_TX_MSG(SET_BYPASS_PWOFF): + bpctl_cmd.status = + set_bypass_pwoff_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + break; + + case IOCTL_TX_MSG(GET_BYPASS_PWOFF): + bpctl_cmd.status = get_bypass_pwoff_fn(pbpctl_dev); + break; + + case IOCTL_TX_MSG(SET_BYPASS_PWUP): + bpctl_cmd.status = + set_bypass_pwup_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + break; + + case IOCTL_TX_MSG(GET_BYPASS_PWUP): + bpctl_cmd.status = get_bypass_pwup_fn(pbpctl_dev); + break; + + case IOCTL_TX_MSG(SET_BYPASS_WD): + bpctl_cmd.status = + set_bypass_wd_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + break; + + case IOCTL_TX_MSG(GET_BYPASS_WD): + bpctl_cmd.status = + get_bypass_wd_fn(pbpctl_dev, (int *)&(bpctl_cmd.data[0])); + break; + + case IOCTL_TX_MSG(GET_WD_EXPIRE_TIME): + bpctl_cmd.status = + get_wd_expire_time_fn(pbpctl_dev, + (int *)&(bpctl_cmd.data[0])); + break; + + case IOCTL_TX_MSG(RESET_BYPASS_WD_TIMER): + bpctl_cmd.status = reset_bypass_wd_timer_fn(pbpctl_dev); + break; + + case IOCTL_TX_MSG(GET_WD_SET_CAPS): + bpctl_cmd.status = get_wd_set_caps_fn(pbpctl_dev); + break; + + case IOCTL_TX_MSG(SET_STD_NIC): + bpctl_cmd.status = + set_std_nic_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + break; + + case IOCTL_TX_MSG(GET_STD_NIC): + bpctl_cmd.status = get_std_nic_fn(pbpctl_dev); + break; + + case IOCTL_TX_MSG(SET_TAP): + bpctl_cmd.status = + set_tap_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + break; + + case IOCTL_TX_MSG(GET_TAP): + bpctl_cmd.status = get_tap_fn(pbpctl_dev); + break; + + case IOCTL_TX_MSG(GET_TAP_CHANGE): + bpctl_cmd.status = get_tap_change_fn(pbpctl_dev); + break; + + case IOCTL_TX_MSG(SET_DIS_TAP): + bpctl_cmd.status = + set_dis_tap_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + break; + + case IOCTL_TX_MSG(GET_DIS_TAP): + bpctl_cmd.status = get_dis_tap_fn(pbpctl_dev); + break; + + case IOCTL_TX_MSG(SET_TAP_PWUP): + bpctl_cmd.status = + set_tap_pwup_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + break; + + case IOCTL_TX_MSG(GET_TAP_PWUP): + bpctl_cmd.status = get_tap_pwup_fn(pbpctl_dev); + break; + + case IOCTL_TX_MSG(SET_WD_EXP_MODE): + bpctl_cmd.status = + set_wd_exp_mode_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + break; + + case IOCTL_TX_MSG(GET_WD_EXP_MODE): + bpctl_cmd.status = get_wd_exp_mode_fn(pbpctl_dev); + break; + + case IOCTL_TX_MSG(GET_DIS_BYPASS): + bpctl_cmd.status = get_dis_bypass_fn(pbpctl_dev); + break; + + case IOCTL_TX_MSG(SET_DIS_BYPASS): + bpctl_cmd.status = + set_dis_bypass_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + break; + + case IOCTL_TX_MSG(GET_BYPASS_CHANGE): + bpctl_cmd.status = get_bypass_change_fn(pbpctl_dev); + break; + + case IOCTL_TX_MSG(GET_BYPASS): + bpctl_cmd.status = get_bypass_fn(pbpctl_dev); + break; + + case IOCTL_TX_MSG(SET_BYPASS): + bpctl_cmd.status = + set_bypass_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + break; + + case IOCTL_TX_MSG(GET_BYPASS_CAPS): + bpctl_cmd.status = get_bypass_caps_fn(pbpctl_dev); + /*preempt_enable(); */ + //rcu_read_unlock(); + spin_unlock_irqrestore(&bpvm_lock, flags); + if (copy_to_user + (argp, (void *)&bpctl_cmd, sizeof(struct bpctl_cmd))) { + //unlock_bpctl(); + //preempt_enable(); + ret = -EFAULT; + goto bp_exit; + } + goto bp_exit; + + case IOCTL_TX_MSG(GET_BYPASS_SLAVE): + bpctl_cmd.status = + get_bypass_slave_fn(pbpctl_dev, &pbpctl_dev_out); + if (bpctl_cmd.status == 1) { + bpctl_cmd.out_param[4] = pbpctl_dev_out->bus; + bpctl_cmd.out_param[5] = pbpctl_dev_out->slot; + bpctl_cmd.out_param[6] = pbpctl_dev_out->func; + bpctl_cmd.out_param[7] = pbpctl_dev_out->ifindex; + } + break; + + case IOCTL_TX_MSG(IS_BYPASS): + bpctl_cmd.status = is_bypass(pbpctl_dev); + break; + case IOCTL_TX_MSG(SET_TX): + bpctl_cmd.status = set_tx_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + break; + case IOCTL_TX_MSG(GET_TX): + bpctl_cmd.status = get_tx_fn(pbpctl_dev); + break; + case IOCTL_TX_MSG(SET_WD_AUTORESET): + bpctl_cmd.status = + set_wd_autoreset_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + + break; + case IOCTL_TX_MSG(GET_WD_AUTORESET): + + bpctl_cmd.status = get_wd_autoreset_fn(pbpctl_dev); + break; + case IOCTL_TX_MSG(SET_DISC): + bpctl_cmd.status = + set_disc_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + break; + case IOCTL_TX_MSG(GET_DISC): + bpctl_cmd.status = get_disc_fn(pbpctl_dev); + break; + case IOCTL_TX_MSG(GET_DISC_CHANGE): + bpctl_cmd.status = get_disc_change_fn(pbpctl_dev); + break; + case IOCTL_TX_MSG(SET_DIS_DISC): + bpctl_cmd.status = + set_dis_disc_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + break; + case IOCTL_TX_MSG(GET_DIS_DISC): + bpctl_cmd.status = get_dis_disc_fn(pbpctl_dev); + break; + case IOCTL_TX_MSG(SET_DISC_PWUP): + bpctl_cmd.status = + set_disc_pwup_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + break; + case IOCTL_TX_MSG(GET_DISC_PWUP): + bpctl_cmd.status = get_disc_pwup_fn(pbpctl_dev); + break; + + case IOCTL_TX_MSG(GET_BYPASS_INFO): + + bpctl_cmd.status = + get_bypass_info_fn(pbpctl_dev, (char *)&bpctl_cmd.data, + (char *)&bpctl_cmd.out_param[4]); + break; + + case IOCTL_TX_MSG(SET_TPL): + bpctl_cmd.status = + set_tpl_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + break; + + case IOCTL_TX_MSG(GET_TPL): + bpctl_cmd.status = get_tpl_fn(pbpctl_dev); + break; +//#ifdef PMC_FIX_FLAG + case IOCTL_TX_MSG(SET_BP_WAIT_AT_PWUP): + bpctl_cmd.status = + set_bp_wait_at_pwup_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + break; + + case IOCTL_TX_MSG(GET_BP_WAIT_AT_PWUP): + bpctl_cmd.status = get_bp_wait_at_pwup_fn(pbpctl_dev); + break; + case IOCTL_TX_MSG(SET_BP_HW_RESET): + bpctl_cmd.status = + set_bp_hw_reset_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + break; + + case IOCTL_TX_MSG(GET_BP_HW_RESET): + bpctl_cmd.status = get_bp_hw_reset_fn(pbpctl_dev); + break; +//#endif +#ifdef BP_SELF_TEST + case IOCTL_TX_MSG(SET_BP_SELF_TEST): + bpctl_cmd.status = + set_bp_self_test_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + + break; + case IOCTL_TX_MSG(GET_BP_SELF_TEST): + bpctl_cmd.status = get_bp_self_test_fn(pbpctl_dev); + break; + +#endif +#if 0 + case IOCTL_TX_MSG(SET_DISC_PORT): + bpctl_cmd.status = + set_disc_port_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + break; + + case IOCTL_TX_MSG(GET_DISC_PORT): + bpctl_cmd.status = get_disc_port_fn(pbpctl_dev); + break; + + case IOCTL_TX_MSG(SET_DISC_PORT_PWUP): + bpctl_cmd.status = + set_disc_port_pwup_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + break; + + case IOCTL_TX_MSG(GET_DISC_PORT_PWUP): + bpctl_cmd.status = get_disc_port_pwup_fn(pbpctl_dev); + break; +#endif + case IOCTL_TX_MSG(SET_BP_FORCE_LINK): + bpctl_cmd.status = + set_bp_force_link_fn(dev_idx, bpctl_cmd.in_param[2]); + break; + + case IOCTL_TX_MSG(GET_BP_FORCE_LINK): + bpctl_cmd.status = get_bp_force_link_fn(dev_idx); + break; + + default: + // unlock_bpctl(); + + ret = -EOPNOTSUPP; + /*preempt_enable(); */ + //rcu_read_unlock(); + spin_unlock_irqrestore(&bpvm_lock, flags); + goto bp_exit; + } + //unlock_bpctl(); + /*preempt_enable(); */ + bpcmd_exit: + //rcu_read_unlock(); + spin_unlock_irqrestore(&bpvm_lock, flags); + if (copy_to_user(argp, (void *)&bpctl_cmd, sizeof(struct bpctl_cmd))) + ret = -EFAULT; + ret = SUCCESS; + bp_exit: +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)) + //unlock_kernel(); +#endif + //spin_unlock_irqrestore(&bpvm_lock, flags); + unlock_bpctl(); + //unlock_kernel(); + return ret; +} + +struct file_operations Fops = { + .owner = THIS_MODULE, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)) + .ioctl = device_ioctl, +#else + .unlocked_ioctl = device_ioctl, +#endif + + .open = device_open, + .release = device_release, /* a.k.a. close */ +}; + +#ifndef PCI_DEVICE +#define PCI_DEVICE(vend,dev) \ + .vendor = (vend), .device = (dev), \ + .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID +#endif + +#define SILICOM_E1000BP_ETHERNET_DEVICE(device_id) {\ + PCI_DEVICE(SILICOM_VID, device_id)} + +typedef enum { + PXG2BPFI, + PXG2BPFIL, + PXG2BPFILX, + PXG2BPFILLX, + PXGBPI, + PXGBPIG, + PXG2TBFI, + PXG4BPI, + PXG4BPFI, + PEG4BPI, + PEG2BPI, + PEG4BPIN, + PEG2BPFI, + PEG2BPFILX, + PMCXG2BPFI, + PMCXG2BPFIN, + PEG4BPII, + PEG4BPFII, + PXG4BPFILX, + PMCXG2BPIN, + PMCXG4BPIN, + PXG2BISC1, + PEG2TBFI, + PXG2TBI, + PXG4BPFID, + PEG4BPFI, + PEG4BPIPT, + PXG6BPI, + PEG4BPIL, + PMCXG2BPIN2, + PMCXG4BPIN2, + PMCX2BPI, + PEG2BPFID, + PEG2BPFIDLX, + PMCX4BPI, + MEG2BPFILN, + MEG2BPFINX, + PEG4BPFILX, + PE10G2BPISR, + PE10G2BPILR, + MHIO8AD, + PE10G2BPICX4, + PEG2BPI5, + PEG6BPI, + PEG4BPFI5, + PEG4BPFI5LX, + MEG2BPFILXLN, + PEG2BPIX1, + MEG2BPFILXNX, + XE10G2BPIT, + XE10G2BPICX4, + XE10G2BPISR, + XE10G2BPILR, + PEG4BPIIO, + XE10G2BPIXR, + PE10GDBISR, + PE10GDBILR, + PEG2BISC6, + PEG6BPIFC, + PE10G2BPTCX4, + PE10G2BPTSR, + PE10G2BPTLR, + PE10G2BPTT, + PEG4BPI6, + PEG4BPFI6, + PEG4BPFI6LX, + PEG4BPFI6ZX, + PEG2BPI6, + PEG2BPFI6, + PEG2BPFI6LX, + PEG2BPFI6ZX, + PEG2BPFI6FLXM, + PEG4BPI6FC, + PEG4BPFI6FC, + PEG4BPFI6FCLX, + PEG4BPFI6FCZX, + PEG6BPI6, + PEG2BPI6SC6, + MEG2BPI6, + XEG2BPI6, + MEG4BPI6, + PEG2BPFI5, + PEG2BPFI5LX, + PXEG4BPFI, + M1EG2BPI6, + M1EG2BPFI6, + M1EG2BPFI6LX, + M1EG2BPFI6ZX, + M1EG4BPI6, + M1EG4BPFI6, + M1EG4BPFI6LX, + M1EG4BPFI6ZX, + M1EG6BPI6, + M1E2G4BPi80, + M1E2G4BPFi80, + M1E2G4BPFi80LX, + M1E2G4BPFi80ZX, + PE210G2SPI9, + M1E10G2BPI9CX4, + M1E10G2BPI9SR, + M1E10G2BPI9LR, + M1E10G2BPI9T, + PE210G2BPI9CX4, + PE210G2BPI9SR, + PE210G2BPI9LR, + PE210G2BPI9T, + M2EG2BPFI6, + M2EG2BPFI6LX, + M2EG2BPFI6ZX, + M2EG4BPI6, + M2EG4BPFI6, + M2EG4BPFI6LX, + M2EG4BPFI6ZX, + M2EG6BPI6, + PEG2DBI6, + PEG2DBFI6, + PEG2DBFI6LX, + PEG2DBFI6ZX, + PE2G4BPi80, + PE2G4BPFi80, + PE2G4BPFi80LX, + PE2G4BPFi80ZX, + PE2G4BPi80L, + M6E2G8BPi80A, + + PE2G2BPi35, + PAC1200BPi35, + PE2G2BPFi35, + PE2G2BPFi35LX, + PE2G2BPFi35ZX, + PE2G4BPi35, + PE2G4BPi35L, + PE2G4BPFi35, + PE2G4BPFi35LX, + PE2G4BPFi35ZX, + + PE2G6BPi35, + PE2G6BPi35CX, + + PE2G2BPi80, + PE2G2BPFi80, + PE2G2BPFi80LX, + PE2G2BPFi80ZX, + M2E10G2BPI9CX4, + M2E10G2BPI9SR, + M2E10G2BPI9LR, + M2E10G2BPI9T, + M6E2G8BPi80, + PE210G2DBi9SR, + PE210G2DBi9SRRB, + PE210G2DBi9LR, + PE210G2DBi9LRRB, + PE310G4DBi940SR, + PE310G4BPi9T, + PE310G4BPi9SR, + PE310G4BPi9LR, + PE210G2BPi40, +} board_t; + +typedef struct _bpmod_info_t { + unsigned int vendor; + unsigned int device; + unsigned int subvendor; + unsigned int subdevice; + unsigned int index; + char *bp_name; + +} bpmod_info_t; + +typedef struct _dev_desc { + char *name; +} dev_desc_t; + +dev_desc_t dev_desc[] = { + {"Silicom Bypass PXG2BPFI-SD series adapter"}, + {"Silicom Bypass PXG2BPFIL-SD series adapter"}, + {"Silicom Bypass PXG2BPFILX-SD series adapter"}, + {"Silicom Bypass PXG2BPFILLX-SD series adapter"}, + {"Silicom Bypass PXG2BPI-SD series adapter"}, + {"Silicom Bypass PXG2BPIG-SD series adapter"}, + {"Silicom Bypass PXG2TBFI-SD series adapter"}, + {"Silicom Bypass PXG4BPI-SD series adapter"}, + {"Silicom Bypass PXG4BPFI-SD series adapter"}, + {"Silicom Bypass PEG4BPI-SD series adapter"}, + {"Silicom Bypass PEG2BPI-SD series adapter"}, + {"Silicom Bypass PEG4BPIN-SD series adapter"}, + {"Silicom Bypass PEG2BPFI-SD series adapter"}, + {"Silicom Bypass PEG2BPFI-LX-SD series adapter"}, + {"Silicom Bypass PMCX2BPFI-SD series adapter"}, + {"Silicom Bypass PMCX2BPFI-N series adapter"}, + {"Intel Bypass PEG2BPII series adapter"}, + {"Intel Bypass PEG2BPFII series adapter"}, + {"Silicom Bypass PXG4BPFILX-SD series adapter"}, + {"Silicom Bypass PMCX2BPI-N series adapter"}, + {"Silicom Bypass PMCX4BPI-N series adapter"}, + {"Silicom Bypass PXG2BISC1-SD series adapter"}, + {"Silicom Bypass PEG2TBFI-SD series adapter"}, + {"Silicom Bypass PXG2TBI-SD series adapter"}, + {"Silicom Bypass PXG4BPFID-SD series adapter"}, + {"Silicom Bypass PEG4BPFI-SD series adapter"}, + {"Silicom Bypass PEG4BPIPT-SD series adapter"}, + {"Silicom Bypass PXG6BPI-SD series adapter"}, + {"Silicom Bypass PEG4BPIL-SD series adapter"}, + {"Silicom Bypass PMCX2BPI-N2 series adapter"}, + {"Silicom Bypass PMCX4BPI-N2 series adapter"}, + {"Silicom Bypass PMCX2BPI-SD series adapter"}, + {"Silicom Bypass PEG2BPFID-SD series adapter"}, + {"Silicom Bypass PEG2BPFIDLX-SD series adapter"}, + {"Silicom Bypass PMCX4BPI-SD series adapter"}, + {"Silicom Bypass MEG2BPFILN-SD series adapter"}, + {"Silicom Bypass MEG2BPFINX-SD series adapter"}, + {"Silicom Bypass PEG4BPFILX-SD series adapter"}, + {"Silicom Bypass PE10G2BPISR-SD series adapter"}, + {"Silicom Bypass PE10G2BPILR-SD series adapter"}, + {"Silicom Bypass MHIO8AD-SD series adapter"}, + {"Silicom Bypass PE10G2BPICX4-SD series adapter"}, + {"Silicom Bypass PEG2BPI5-SD series adapter"}, + {"Silicom Bypass PEG6BPI5-SD series adapter"}, + {"Silicom Bypass PEG4BPFI5-SD series adapter"}, + {"Silicom Bypass PEG4BPFI5LX-SD series adapter"}, + {"Silicom Bypass MEG2BPFILXLN-SD series adapter"}, + {"Silicom Bypass PEG2BPIX1-SD series adapter"}, + {"Silicom Bypass MEG2BPFILXNX-SD series adapter"}, + {"Silicom Bypass XE10G2BPIT-SD series adapter"}, + {"Silicom Bypass XE10G2BPICX4-SD series adapter"}, + {"Silicom Bypass XE10G2BPISR-SD series adapter"}, + {"Silicom Bypass XE10G2BPILR-SD series adapter"}, + {"Intel Bypass PEG2BPFII0 series adapter"}, + {"Silicom Bypass XE10G2BPIXR series adapter"}, + {"Silicom Bypass PE10G2DBISR series adapter"}, + {"Silicom Bypass PEG2BI5SC6 series adapter"}, + {"Silicom Bypass PEG6BPI5FC series adapter"}, + + {"Silicom Bypass PE10G2BPTCX4 series adapter"}, + {"Silicom Bypass PE10G2BPTSR series adapter"}, + {"Silicom Bypass PE10G2BPTLR series adapter"}, + {"Silicom Bypass PE10G2BPTT series adapter"}, + {"Silicom Bypass PEG4BPI6 series adapter"}, + {"Silicom Bypass PEG4BPFI6 series adapter"}, + {"Silicom Bypass PEG4BPFI6LX series adapter"}, + {"Silicom Bypass PEG4BPFI6ZX series adapter"}, + {"Silicom Bypass PEG2BPI6 series adapter"}, + {"Silicom Bypass PEG2BPFI6 series adapter"}, + {"Silicom Bypass PEG2BPFI6LX series adapter"}, + {"Silicom Bypass PEG2BPFI6ZX series adapter"}, + {"Silicom Bypass PEG2BPFI6FLXM series adapter"}, + {"Silicom Bypass PEG4BPI6FC series adapter"}, + {"Silicom Bypass PEG4BPFI6FC series adapter"}, + {"Silicom Bypass PEG4BPFI6FCLX series adapter"}, + {"Silicom Bypass PEG4BPFI6FCZX series adapter"}, + {"Silicom Bypass PEG6BPI6 series adapter"}, + {"Silicom Bypass PEG2BPI6SC6 series adapter"}, + {"Silicom Bypass MEG2BPI6 series adapter"}, + {"Silicom Bypass XEG2BPI6 series adapter"}, + {"Silicom Bypass MEG4BPI6 series adapter"}, + {"Silicom Bypass PEG2BPFI5-SD series adapter"}, + {"Silicom Bypass PEG2BPFI5LX-SD series adapter"}, + {"Silicom Bypass PXEG4BPFI-SD series adapter"}, + {"Silicom Bypass MxEG2BPI6 series adapter"}, + {"Silicom Bypass MxEG2BPFI6 series adapter"}, + {"Silicom Bypass MxEG2BPFI6LX series adapter"}, + {"Silicom Bypass MxEG2BPFI6ZX series adapter"}, + {"Silicom Bypass MxEG4BPI6 series adapter"}, + {"Silicom Bypass MxEG4BPFI6 series adapter"}, + {"Silicom Bypass MxEG4BPFI6LX series adapter"}, + {"Silicom Bypass MxEG4BPFI6ZX series adapter"}, + {"Silicom Bypass MxEG6BPI6 series adapter"}, + {"Silicom Bypass MxE2G4BPi80 series adapter"}, + {"Silicom Bypass MxE2G4BPFi80 series adapter"}, + {"Silicom Bypass MxE2G4BPFi80LX series adapter"}, + {"Silicom Bypass MxE2G4BPFi80ZX series adapter"}, + + {"Silicom Bypass PE210G2SPI9 series adapter"}, + + {"Silicom Bypass MxE210G2BPI9CX4 series adapter"}, + {"Silicom Bypass MxE210G2BPI9SR series adapter"}, + {"Silicom Bypass MxE210G2BPI9LR series adapter"}, + {"Silicom Bypass MxE210G2BPI9T series adapter"}, + + {"Silicom Bypass PE210G2BPI9CX4 series adapter"}, + {"Silicom Bypass PE210G2BPI9SR series adapter"}, + {"Silicom Bypass PE210G2BPI9LR series adapter"}, + {"Silicom Bypass PE210G2BPI9T series adapter"}, + + {"Silicom Bypass M2EG2BPFI6 series adapter"}, + {"Silicom Bypass M2EG2BPFI6LX series adapter"}, + {"Silicom Bypass M2EG2BPFI6ZX series adapter"}, + {"Silicom Bypass M2EG4BPI6 series adapter"}, + {"Silicom Bypass M2EG4BPFI6 series adapter"}, + {"Silicom Bypass M2EG4BPFI6LX series adapter"}, + {"Silicom Bypass M2EG4BPFI6ZX series adapter"}, + {"Silicom Bypass M2EG6BPI6 series adapter"}, + + {"Silicom Bypass PEG2DBI6 series adapter"}, + {"Silicom Bypass PEG2DBFI6 series adapter"}, + {"Silicom Bypass PEG2DBFI6LX series adapter"}, + {"Silicom Bypass PEG2DBFI6ZX series adapter"}, + + {"Silicom Bypass PE2G4BPi80 series adapter"}, + {"Silicom Bypass PE2G4BPFi80 series adapter"}, + {"Silicom Bypass PE2G4BPFi80LX series adapter"}, + {"Silicom Bypass PE2G4BPFi80ZX series adapter"}, + + {"Silicom Bypass PE2G4BPi80L series adapter"}, + {"Silicom Bypass MxE2G8BPi80A series adapter"}, + + {"Silicom Bypass PE2G2BPi35 series adapter"}, + {"Silicom Bypass PAC1200BPi35 series adapter"}, + {"Silicom Bypass PE2G2BPFi35 series adapter"}, + {"Silicom Bypass PE2G2BPFi35LX series adapter"}, + {"Silicom Bypass PE2G2BPFi35ZX series adapter"}, + + {"Silicom Bypass PE2G4BPi35 series adapter"}, + {"Silicom Bypass PE2G4BPi35L series adapter"}, + {"Silicom Bypass PE2G4BPFi35 series adapter"}, + {"Silicom Bypass PE2G4BPFi35LX series adapter"}, + {"Silicom Bypass PE2G4BPFi35ZX series adapter"}, + + {"Silicom Bypass PE2G6BPi35 series adapter"}, + {"Silicom Bypass PE2G6BPi35CX series adapter"}, + + {"Silicom Bypass PE2G2BPi80 series adapter"}, + {"Silicom Bypass PE2G2BPFi80 series adapter"}, + {"Silicom Bypass PE2G2BPFi80LX series adapter"}, + {"Silicom Bypass PE2G2BPFi80ZX series adapter"}, + + {"Silicom Bypass M2E10G2BPI9CX4 series adapter"}, + {"Silicom Bypass M2E10G2BPI9SR series adapter"}, + {"Silicom Bypass M2E10G2BPI9LR series adapter"}, + {"Silicom Bypass M2E10G2BPI9T series adapter"}, + {"Silicom Bypass MxE2G8BPi80 series adapter"}, + {"Silicom Bypass PE210G2DBi9SR series adapter"}, + {"Silicom Bypass PE210G2DBi9SRRB series adapter"}, + {"Silicom Bypass PE210G2DBi9LR series adapter"}, + {"Silicom Bypass PE210G2DBi9LRRB series adapter"}, + {"Silicom Bypass PE310G4DBi9-SR series adapter"}, + {"Silicom Bypass PE310G4BPi9T series adapter"}, + {"Silicom Bypass PE310G4BPi9SR series adapter"}, + {"Silicom Bypass PE310G4BPi9LR series adapter"}, + {"Silicom Bypass PE210G2BPi40T series adapter"}, + {0}, +}; + +static bpmod_info_t tx_ctl_pci_tbl[] = { + {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG2BPFI_SSID, PXG2BPFI, + "PXG2BPFI-SD"}, + {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG2BPFIL_SSID, PXG2BPFIL, + "PXG2BPFIL-SD"}, + {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG2BPFILX_SSID, PXG2BPFILX, + "PXG2BPFILX-SD"}, + {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG2BPFILLX_SSID, PXG2BPFILLX, + "PXG2BPFILLXSD"}, + {0x8086, 0x1010, SILICOM_SVID, SILICOM_PXGBPI_SSID, PXGBPI, + "PXG2BPI-SD"}, + {0x8086, 0x1079, SILICOM_SVID, SILICOM_PXGBPIG_SSID, PXGBPIG, + "PXG2BPIG-SD"}, + {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG2TBFI_SSID, PXG2TBFI, + "PXG2TBFI-SD"}, + {0x8086, 0x1079, SILICOM_SVID, SILICOM_PXG4BPI_SSID, PXG4BPI, + "PXG4BPI-SD"}, + {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG4BPFI_SSID, PXG4BPFI, + "PXG4BPFI-SD"}, + {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG4BPFILX_SSID, PXG4BPFILX, + "PXG4BPFILX-SD"}, + {0x8086, 0x1079, SILICOM_SVID, SILICOM_PEG4BPI_SSID, PEG4BPI, + "PEXG4BPI-SD"}, + {0x8086, 0x105e, SILICOM_SVID, SILICOM_PEG2BPI_SSID, PEG2BPI, + "PEG2BPI-SD"}, + {0x8086, 0x105e, SILICOM_SVID, SILICOM_PEG4BPIN_SSID, PEG4BPIN, + "PEG4BPI-SD"}, + {0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG2BPFI_SSID, PEG2BPFI, + "PEG2BPFI-SD"}, + {0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG2BPFILX_SSID, PEG2BPFILX, + "PEG2BPFILX-SD"}, + {0x8086, 0x107a, SILICOM_SVID, SILICOM_PMCXG2BPFI_SSID, PMCXG2BPFI, + "PMCX2BPFI-SD"}, + {0x8086, 0x107a, NOKIA_PMCXG2BPFIN_SVID, NOKIA_PMCXG2BPFIN_SSID, + PMCXG2BPFIN, "PMCX2BPFI-N"}, + {0x8086, INTEL_PEG4BPII_PID, 0x8086, INTEL_PEG4BPII_SSID, PEG4BPII, + "PEG4BPII"}, + {0x8086, INTEL_PEG4BPIIO_PID, 0x8086, INTEL_PEG4BPIIO_SSID, PEG4BPIIO, + "PEG4BPII0"}, + {0x8086, INTEL_PEG4BPFII_PID, 0x8086, INTEL_PEG4BPFII_SSID, PEG4BPFII, + "PEG4BPFII"}, + {0x8086, 0x1079, NOKIA_PMCXG2BPFIN_SVID, NOKIA_PMCXG2BPIN_SSID, + PMCXG2BPIN, "PMCX2BPI-N"}, + {0x8086, 0x1079, NOKIA_PMCXG2BPFIN_SVID, NOKIA_PMCXG4BPIN_SSID, + PMCXG4BPIN, "PMCX4BPI-N"}, + {0x8086, 0x1079, SILICOM_SVID, SILICOM_PXG2BISC1_SSID, PXG2BISC1, + "PXG2BISC1-SD"}, + {0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG2TBFI_SSID, PEG2TBFI, + "PEG2TBFI-SD"}, + {0x8086, 0x1079, SILICOM_SVID, SILICOM_PXG2TBI_SSID, PXG2TBI, + "PXG2TBI-SD"}, + {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG4BPFID_SSID, PXG4BPFID, + "PXG4BPFID-SD"}, + {0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG4BPFI_SSID, PEG4BPFI, + "PEG4BPFI-SD"}, + {0x8086, 0x105e, SILICOM_SVID, SILICOM_PEG4BPIPT_SSID, PEG4BPIPT, + "PEG4BPIPT-SD"}, + {0x8086, 0x1079, SILICOM_SVID, SILICOM_PXG6BPI_SSID, PXG6BPI, + "PXG6BPI-SD"}, + {0x8086, 0x10a7, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PEG4BPIL_SSID /*PCI_ANY_ID */ , PEG4BPIL, "PEG4BPIL-SD"}, + {0x8086, 0x1079, NOKIA_PMCXG2BPFIN_SVID, NOKIA_PMCXG2BPIN2_SSID, + PMCXG2BPIN2, "PMCX2BPI-N2"}, + {0x8086, 0x1079, NOKIA_PMCXG2BPFIN_SVID, NOKIA_PMCXG4BPIN2_SSID, + PMCXG4BPIN2, "PMCX4BPI-N2"}, + {0x8086, 0x1079, SILICOM_SVID, SILICOM_PMCX2BPI_SSID, PMCX2BPI, + "PMCX2BPI-SD"}, + {0x8086, 0x1079, SILICOM_SVID, SILICOM_PMCX4BPI_SSID, PMCX4BPI, + "PMCX4BPI-SD"}, + {0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG2BPFID_SSID, PEG2BPFID, + "PEG2BPFID-SD"}, + {0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG2BPFIDLX_SSID, PEG2BPFIDLX, + "PEG2BPFIDLXSD"}, + {0x8086, 0x105f, SILICOM_SVID, SILICOM_MEG2BPFILN_SSID, MEG2BPFILN, + "MEG2BPFILN-SD"}, + {0x8086, 0x105f, SILICOM_SVID, SILICOM_MEG2BPFINX_SSID, MEG2BPFINX, + "MEG2BPFINX-SD"}, + {0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG4BPFILX_SSID, PEG4BPFILX, + "PEG4BPFILX-SD"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID, SILICOM_PE10G2BPISR_SSID, + PE10G2BPISR, "PE10G2BPISR"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID, SILICOM_PE10G2BPILR_SSID, + PE10G2BPILR, "PE10G2BPILR"}, + {0x8086, 0x10a9, SILICOM_SVID, SILICOM_MHIO8AD_SSID, MHIO8AD, + "MHIO8AD-SD"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID, SILICOM_PE10G2BPICX4_SSID, + PE10G2BPISR, "PE10G2BPICX4"}, + {0x8086, 0x10a7, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PEG2BPI5_SSID /*PCI_ANY_ID */ , PEG2BPI5, "PEG2BPI5-SD"}, + {0x8086, 0x10a7, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PEG6BPI_SSID /*PCI_ANY_ID */ , PEG6BPI, "PEG6BPI5"}, + {0x8086, 0x10a9, SILICOM_SVID /*PCI_ANY_ID */ , SILICOM_PEG4BPFI5_SSID, + PEG4BPFI5, "PEG4BPFI5"}, + {0x8086, 0x10a9, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PEG4BPFI5LX_SSID, PEG4BPFI5LX, "PEG4BPFI5LX"}, + {0x8086, 0x105f, SILICOM_SVID, SILICOM_MEG2BPFILXLN_SSID, MEG2BPFILXLN, + "MEG2BPFILXLN"}, + {0x8086, 0x105e, SILICOM_SVID, SILICOM_PEG2BPIX1_SSID, PEG2BPIX1, + "PEG2BPIX1-SD"}, + {0x8086, 0x105f, SILICOM_SVID, SILICOM_MEG2BPFILXNX_SSID, MEG2BPFILXNX, + "MEG2BPFILXNX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID, SILICOM_XE10G2BPIT_SSID, XE10G2BPIT, + "XE10G2BPIT"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID, SILICOM_XE10G2BPICX4_SSID, + XE10G2BPICX4, "XE10G2BPICX4"}, + {0x8086, 0x10C6, SILICOM_SVID, SILICOM_XE10G2BPISR_SSID, XE10G2BPISR, + "XE10G2BPISR"}, + {0x8086, 0x10C6, SILICOM_SVID, SILICOM_XE10G2BPILR_SSID, XE10G2BPILR, + "XE10G2BPILR"}, + {0x8086, 0x10C6, NOKIA_XE10G2BPIXR_SVID, NOKIA_XE10G2BPIXR_SSID, + XE10G2BPIXR, "XE10G2BPIXR"}, + {0x8086, 0x10C6, SILICOM_SVID, SILICOM_PE10GDBISR_SSID, PE10GDBISR, + "PE10G2DBISR"}, + {0x8086, 0x10C6, SILICOM_SVID, SILICOM_PE10GDBILR_SSID, PE10GDBILR, + "PE10G2DBILR"}, + {0x8086, 0x10a7, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PEG2BISC6_SSID /*PCI_ANY_ID */ , PEG2BISC6, "PEG2BI5SC6"}, + {0x8086, 0x10a7, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PEG6BPIFC_SSID /*PCI_ANY_ID */ , PEG6BPIFC, "PEG6BPI5FC"}, + + {BROADCOM_VID, BROADCOM_PE10G2_PID, SILICOM_SVID, + SILICOM_PE10G2BPTCX4_SSID, PE10G2BPTCX4, "PE10G2BPTCX4"}, + {BROADCOM_VID, BROADCOM_PE10G2_PID, SILICOM_SVID, + SILICOM_PE10G2BPTSR_SSID, PE10G2BPTSR, "PE10G2BPTSR"}, + {BROADCOM_VID, BROADCOM_PE10G2_PID, SILICOM_SVID, + SILICOM_PE10G2BPTLR_SSID, PE10G2BPTLR, "PE10G2BPTLR"}, + {BROADCOM_VID, BROADCOM_PE10G2_PID, SILICOM_SVID, + SILICOM_PE10G2BPTT_SSID, PE10G2BPTT, "PE10G2BPTT"}, + + //{BROADCOM_VID, BROADCOM_PE10G2_PID, PCI_ANY_ID, PCI_ANY_ID, PE10G2BPTCX4, "PE10G2BPTCX4"}, + + {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PEG4BPI6_SSID /*PCI_ANY_ID */ , PEG4BPI6, "PEG4BPI6"}, + {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PEG4BPFI6_SSID /*PCI_ANY_ID */ , PEG4BPFI6, "PEG4BPFI6"}, + {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PEG4BPFI6LX_SSID /*PCI_ANY_ID */ , PEG4BPFI6LX, "PEG4BPFI6LX"}, + {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PEG4BPFI6ZX_SSID /*PCI_ANY_ID */ , PEG4BPFI6ZX, "PEG4BPFI6ZX"}, + {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PEG2BPI6_SSID /*PCI_ANY_ID */ , PEG2BPI6, "PEG2BPI6"}, + {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PEG2BPFI6_SSID /*PCI_ANY_ID */ , PEG2BPFI6, "PEG2BPFI6"}, + {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PEG2BPFI6LX_SSID /*PCI_ANY_ID */ , PEG2BPFI6LX, "PEG2BPFI6LX"}, + {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PEG2BPFI6ZX_SSID /*PCI_ANY_ID */ , PEG2BPFI6ZX, "PEG2BPFI6ZX"}, + {0x8086, 0x10e7, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PEG2BPFI6FLXM_SSID /*PCI_ANY_ID */ , PEG2BPFI6FLXM, + "PEG2BPFI6FLXM"}, + {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PEG4BPI6FC_SSID /*PCI_ANY_ID */ , PEG4BPI6FC, "PEG4BPI6FC"}, + {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PEG4BPFI6FC_SSID /*PCI_ANY_ID */ , PEG4BPFI6FC, "PEG4BPFI6FC"}, + {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PEG4BPFI6FCLX_SSID /*PCI_ANY_ID */ , PEG4BPFI6FCLX, + "PEG4BPFI6FCLX"}, + {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PEG4BPFI6FCZX_SSID /*PCI_ANY_ID */ , PEG4BPFI6FCZX, + "PEG4BPFI6FCZX"}, + {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PEG6BPI6_SSID /*PCI_ANY_ID */ , PEG6BPI6, "PEG6BPI6"}, + {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PEG2BPI6SC6_SSID /*PCI_ANY_ID */ , PEG2BPI6SC6, + "PEG6BPI62SC6"}, + {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_MEG2BPI6_SSID /*PCI_ANY_ID */ , MEG2BPI6, "MEG2BPI6"}, + {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_XEG2BPI6_SSID /*PCI_ANY_ID */ , XEG2BPI6, "XEG2BPI6"}, + {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_MEG4BPI6_SSID /*PCI_ANY_ID */ , MEG4BPI6, "MEG4BPI6"}, + + {0x8086, 0x10a9, SILICOM_SVID /*PCI_ANY_ID */ , SILICOM_PEG2BPFI5_SSID, + PEG2BPFI5, "PEG2BPFI5"}, + {0x8086, 0x10a9, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PEG2BPFI5LX_SSID, PEG2BPFI5LX, "PEG2BPFI5LX"}, + + {0x8086, 0x105f, SILICOM_SVID, SILICOM_PXEG4BPFI_SSID, PXEG4BPFI, + "PXEG4BPFI-SD"}, + + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_M1EG2BPI6_SSID /*PCI_ANY_ID */ , M1EG2BPI6, "MxEG2BPI6"}, + + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_M1EG2BPFI6_SSID /*PCI_ANY_ID */ , M1EG2BPFI6, "MxEG2BPFI6"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_M1EG2BPFI6LX_SSID /*PCI_ANY_ID */ , M1EG2BPFI6LX, + "MxEG2BPFI6LX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_M1EG2BPFI6ZX_SSID /*PCI_ANY_ID */ , M1EG2BPFI6ZX, + "MxEG2BPFI6ZX"}, + + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_M1EG4BPI6_SSID /*PCI_ANY_ID */ , M1EG4BPI6, "MxEG4BPI6"}, + + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_M1EG4BPFI6_SSID /*PCI_ANY_ID */ , M1EG4BPFI6, "MxEG4BPFI6"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_M1EG4BPFI6LX_SSID /*PCI_ANY_ID */ , M1EG4BPFI6LX, + "MxEG4BPFI6LX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_M1EG4BPFI6ZX_SSID /*PCI_ANY_ID */ , M1EG4BPFI6ZX, + "MxEG4BPFI6ZX"}, + + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_M1EG6BPI6_SSID /*PCI_ANY_ID */ , M1EG6BPI6, "MxEG6BPI6"}, + + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_M1E2G4BPi80_SSID /*PCI_ANY_ID */ , M1E2G4BPi80, "MxE2G4BPi80"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_M1E2G4BPFi80_SSID /*PCI_ANY_ID */ , M1E2G4BPFi80, + "MxE2G4BPFi80"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_M1E2G4BPFi80LX_SSID /*PCI_ANY_ID */ , M1E2G4BPFi80LX, + "MxE2G4BPFi80LX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_M1E2G4BPFi80ZX_SSID /*PCI_ANY_ID */ , M1E2G4BPFi80ZX, + "MxE2G4BPFi80ZX"}, + + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_M2EG2BPFI6_SSID /*PCI_ANY_ID */ , M2EG2BPFI6, "M2EG2BPFI6"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_M2EG2BPFI6LX_SSID /*PCI_ANY_ID */ , M2EG2BPFI6LX, + "M2EG2BPFI6LX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_M2EG2BPFI6ZX_SSID /*PCI_ANY_ID */ , M2EG2BPFI6ZX, + "M2EG2BPFI6ZX"}, + + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_M2EG4BPI6_SSID /*PCI_ANY_ID */ , M2EG4BPI6, "M2EG4BPI6"}, + + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_M2EG4BPFI6_SSID /*PCI_ANY_ID */ , M2EG4BPFI6, "M2EG4BPFI6"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_M2EG4BPFI6LX_SSID /*PCI_ANY_ID */ , M2EG4BPFI6LX, + "M2EG4BPFI6LX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_M2EG4BPFI6ZX_SSID /*PCI_ANY_ID */ , M2EG4BPFI6ZX, + "M2EG4BPFI6ZX"}, + + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_M2EG6BPI6_SSID /*PCI_ANY_ID */ , M2EG6BPI6, "M2EG6BPI6"}, + + {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PEG2DBI6_SSID /*PCI_ANY_ID */ , PEG2DBI6, "PEG2DBI6"}, + {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PEG2DBFI6_SSID /*PCI_ANY_ID */ , PEG2DBFI6, "PEG2DBFI6"}, + {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PEG2DBFI6LX_SSID /*PCI_ANY_ID */ , PEG2DBFI6LX, "PEG2DBFI6LX"}, + {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PEG2DBFI6ZX_SSID /*PCI_ANY_ID */ , PEG2DBFI6ZX, "PEG2DBFI6ZX"}, + + {0x8086, 0x10F9, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PE210G2DBi9SR_SSID, PE210G2DBi9SR, "PE210G2DBi9SR"}, + //{0x8086, 0x10F9, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_PE210G2DBi9SRRB_SSID , PE210G2DBi9SRRB, "PE210G2DBi9SRRB"}, + {0x8086, 0x10F9, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PE210G2DBi9LR_SSID, PE210G2DBi9LR, "PE210G2DBi9LR"}, + // {0x8086, 0x10F9, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_PE210G2DBi9LRRB_SSID , PE210G2DBi9LRRB, "PE210G2DBi9LRRB"}, + {0x8086, 0x10F9, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PE310G4DBi940SR_SSID, PE310G4DBi940SR, "PE310G4DBi9SR"}, + + {0x8086, 0x10Fb, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PE310G4BPi9T_SSID, PE310G4BPi9T, "PE310G4BPi9T"}, + {0x8086, 0x10Fb, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PE310G4BPi9SR_SSID, PE310G4BPi9SR, "PE310G4BPi9SR"}, + {0x8086, 0x10Fb, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PE310G4BPi9LR_SSID, PE310G4BPi9LR, "PE310G4BPi9LR"}, + + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PE2G4BPi80_SSID /*PCI_ANY_ID */ , PE2G4BPi80, "PE2G4BPi80"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PE2G4BPFi80_SSID /*PCI_ANY_ID */ , PE2G4BPFi80, "PE2G4BPFi80"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PE2G4BPFi80LX_SSID /*PCI_ANY_ID */ , PE2G4BPFi80LX, + "PE2G4BPFi80LX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PE2G4BPFi80ZX_SSID /*PCI_ANY_ID */ , PE2G4BPFi80ZX, + "PE2G4BPFi80ZX"}, + + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PE2G4BPi80L_SSID /*PCI_ANY_ID */ , PE2G4BPi80L, "PE2G4BPi80L"}, + + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_M6E2G8BPi80A_SSID /*PCI_ANY_ID */ , M6E2G8BPi80A, + "MxE2G8BPi80A"}, + + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PE2G2BPi35_SSID /*PCI_ANY_ID */ , PE2G2BPi35, "PE2G2BPi35"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PAC1200BPi35_SSID /*PCI_ANY_ID */ , PAC1200BPi35, + "PAC1200BPi35"}, + + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PE2G2BPFi35_SSID /*PCI_ANY_ID */ , PE2G2BPFi35, "PE2G2BPFi35"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PE2G2BPFi35LX_SSID /*PCI_ANY_ID */ , PE2G2BPFi35LX, + "PE2G2BPFi35LX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PE2G2BPFi35ZX_SSID /*PCI_ANY_ID */ , PE2G2BPFi35ZX, + "PE2G2BPFi35ZX"}, + + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PE2G4BPi35_SSID /*PCI_ANY_ID */ , PE2G4BPi35, "PE2G4BPi35"}, + + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PE2G4BPi35L_SSID /*PCI_ANY_ID */ , PE2G4BPi35L, "PE2G4BPi35L"}, + + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PE2G4BPFi35_SSID /*PCI_ANY_ID */ , PE2G4BPFi35, "PE2G4BPFi35"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PE2G4BPFi35LX_SSID /*PCI_ANY_ID */ , PE2G4BPFi35LX, + "PE2G4BPFi35LX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PE2G4BPFi35ZX_SSID /*PCI_ANY_ID */ , PE2G4BPFi35ZX, + "PE2G4BPFi35ZX"}, + + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PE2G6BPi35_SSID /*PCI_ANY_ID */ , PE2G6BPi35, "PE2G6BPi35"}, + + // {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID*/,0xaa0,PE2G6BPi35CX,"PE2G6BPi35CX"}, + // {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID*/,0xaa1,PE2G6BPi35CX,"PE2G6BPi35CX"}, + // {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID*/,0xaa2,PE2G6BPi35CX,"PE2G6BPi35CX"}, + + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa0, PE2G6BPi35CX, + "PE2G6BPi35CX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa1, PE2G6BPi35CX, + "PE2G6BPi35CX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa2, PE2G6BPi35CX, + "PE2G6BPi35CX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa3, PE2G6BPi35CX, + "PE2G6BPi35CX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa4, PE2G6BPi35CX, + "PE2G6BPi35CX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa5, PE2G6BPi35CX, + "PE2G6BPi35CX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa6, PE2G6BPi35CX, + "PE2G6BPi35CX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa7, PE2G6BPi35CX, + "PE2G6BPi35CX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa8, PE2G6BPi35CX, + "PE2G6BPi35CX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa9, PE2G6BPi35CX, + "PE2G6BPi35CX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaaa, PE2G6BPi35CX, + "PE2G6BPi35CX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaab, PE2G6BPi35CX, + "PE2G6BPi35CX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaac, PE2G6BPi35CX, + "PE2G6BPi35CX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaad, PE2G6BPi35CX, + "PE2G6BPi35CX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaae, PE2G6BPi35CX, + "PE2G6BPi35CX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaaf, PE2G6BPi35CX, + "PE2G6BPi35CX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab0, PE2G6BPi35CX, + "PE2G6BPi35CX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab1, PE2G6BPi35CX, + "PE2G6BPi35CX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab2, PE2G6BPi35CX, + "PE2G6BPi35CX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab3, PE2G6BPi35CX, + "PE2G6BPi35CX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab4, PE2G6BPi35CX, + "PE2G6BPi35CX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab5, PE2G6BPi35CX, + "PE2G6BPi35CX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab6, PE2G6BPi35CX, + "PE2G6BPi35CX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab7, PE2G6BPi35CX, + "PE2G6BPi35CX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab8, PE2G6BPi35CX, + "PE2G6BPi35CX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab9, PE2G6BPi35CX, + "PE2G6BPi35CX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaba, PE2G6BPi35CX, + "PE2G6BPi35CX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xabb, PE2G6BPi35CX, + "PE2G6BPi35CX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xabc, PE2G6BPi35CX, + "PE2G6BPi35CX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xabd, PE2G6BPi35CX, + "PE2G6BPi35CX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xabe, PE2G6BPi35CX, + "PE2G6BPi35CX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xabf, PE2G6BPi35CX, + "PE2G6BPi35CX"}, + + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PE2G2BPi80_SSID /*PCI_ANY_ID */ , PE2G2BPi80, "PE2G2BPi80"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PE2G2BPFi80_SSID /*PCI_ANY_ID */ , PE2G2BPFi80, "PE2G2BPFi80"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PE2G2BPFi80LX_SSID /*PCI_ANY_ID */ , PE2G2BPFi80LX, + "PE2G2BPFi80LX"}, + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PE2G2BPFi80ZX_SSID /*PCI_ANY_ID */ , PE2G2BPFi80ZX, + "PE2G2BPFi80ZX"}, + + {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_MEG2BPI6_SSID /*PCI_ANY_ID */ , MEG2BPI6, "MEG2BPI6"}, + {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_XEG2BPI6_SSID /*PCI_ANY_ID */ , XEG2BPI6, "XEG2BPI6"}, + +#if 0 + {0x8086, 0x10fb, 0x8086, INTEL_PE210G2SPI9_SSID, PE210G2SPI9, + "PE210G2SPI9"}, +#endif + {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_M1E10G2BPI9CX4_SSID /*PCI_ANY_ID */ , M1E10G2BPI9CX4, + "MxE210G2BPI9CX4"}, + {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_M1E10G2BPI9SR_SSID /*PCI_ANY_ID */ , M1E10G2BPI9SR, + "MxE210G2BPI9SR"}, + {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_M1E10G2BPI9LR_SSID /*PCI_ANY_ID */ , M1E10G2BPI9LR, + "MxE210G2BPI9LR"}, + {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_M1E10G2BPI9T_SSID /*PCI_ANY_ID */ , M1E10G2BPI9T, + "MxE210G2BPI9T"}, + + {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_M2E10G2BPI9CX4_SSID /*PCI_ANY_ID */ , M2E10G2BPI9CX4, + "M2E10G2BPI9CX4"}, + {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_M2E10G2BPI9SR_SSID /*PCI_ANY_ID */ , M2E10G2BPI9SR, + "M2E10G2BPI9SR"}, + {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_M2E10G2BPI9LR_SSID /*PCI_ANY_ID */ , M2E10G2BPI9LR, + "M2E10G2BPI9LR"}, + {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_M2E10G2BPI9T_SSID /*PCI_ANY_ID */ , M2E10G2BPI9T, + "M2E10G2BPI9T"}, + + {0x8086, 0x10fb, SILICOM_SVID, SILICOM_PE210G2BPI9CX4_SSID, + PE210G2BPI9CX4, "PE210G2BPI9CX4"}, + {0x8086, 0x10fb, SILICOM_SVID, SILICOM_PE210G2BPI9SR_SSID, + PE210G2BPI9SR, "PE210G2BPI9SR"}, + {0x8086, 0x10fb, SILICOM_SVID, SILICOM_PE210G2BPI9LR_SSID, + PE210G2BPI9LR, "PE210G2BPI9LR"}, + {0x8086, 0x10fb, SILICOM_SVID, SILICOM_PE210G2BPI9T_SSID, PE210G2BPI9T, + "PE210G2BPI9T"}, + +#if 0 + {0x1374, 0x2c, SILICOM_SVID, SILICOM_PXG4BPI_SSID, PXG4BPI, + "PXG4BPI-SD"}, + + {0x1374, 0x2d, SILICOM_SVID, SILICOM_PXG4BPFI_SSID, PXG4BPFI, + "PXG4BPFI-SD"}, + + {0x1374, 0x3f, SILICOM_SVID, SILICOM_PXG2TBI_SSID, PXG2TBI, + "PXG2TBI-SD"}, + + {0x1374, 0x3d, SILICOM_SVID, SILICOM_PXG2BISC1_SSID, PXG2BISC1, + "PXG2BISC1-SD"}, + + {0x1374, 0x40, SILICOM_SVID, SILICOM_PEG4BPFI_SSID, PEG4BPFI, + "PEG4BPFI-SD"}, + +#ifdef BP_SELF_TEST + {0x1374, 0x28, SILICOM_SVID, 0x28, PXGBPI, "PXG2BPI-SD"}, +#endif +#endif + {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_M6E2G8BPi80_SSID /*PCI_ANY_ID */ , M6E2G8BPi80, "MxE2G8BPi80"}, + {0x8086, 0x1528, SILICOM_SVID /*PCI_ANY_ID */ , + SILICOM_PE210G2BPi40_SSID /*PCI_ANY_ID */ , PE210G2BPi40, + "PE210G2BPi40T"}, + + /* required last entry */ + {0,} +}; + +/* +* Initialize the module - Register the character device +*/ + +static int __init bypass_init_module(void) +{ + int ret_val, idx, idx_dev = 0; + struct pci_dev *pdev1 = NULL; + unsigned long mmio_start, mmio_len; + + printk(BP_MOD_DESCR " v" BP_MOD_VER "\n"); + ret_val = register_chrdev(major_num, DEVICE_NAME, &Fops); + if (ret_val < 0) { + printk("%s failed with %d\n", DEVICE_NAME, ret_val); + return ret_val; + } + major_num = ret_val; /* dynamic */ + for (idx = 0; tx_ctl_pci_tbl[idx].vendor; idx++) { + while ((pdev1 = pci_get_subsys(tx_ctl_pci_tbl[idx].vendor, + tx_ctl_pci_tbl[idx].device, + tx_ctl_pci_tbl[idx].subvendor, + tx_ctl_pci_tbl[idx].subdevice, + pdev1))) { + + device_num++; + } + } + if (!device_num) { + printk("No such device\n"); + unregister_chrdev(major_num, DEVICE_NAME); + return -1; + } + + bpctl_dev_arr = kmalloc((device_num) * sizeof(bpctl_dev_t), GFP_KERNEL); + + if (!bpctl_dev_arr) { + printk("Allocation error\n"); + unregister_chrdev(major_num, DEVICE_NAME); + return -1; + } + memset(bpctl_dev_arr, 0, ((device_num) * sizeof(bpctl_dev_t))); + + pdev1 = NULL; + for (idx = 0; tx_ctl_pci_tbl[idx].vendor; idx++) { + while ((pdev1 = pci_get_subsys(tx_ctl_pci_tbl[idx].vendor, + tx_ctl_pci_tbl[idx].device, + tx_ctl_pci_tbl[idx].subvendor, + tx_ctl_pci_tbl[idx].subdevice, + pdev1))) { + bpctl_dev_arr[idx_dev].pdev = pdev1; + + mmio_start = pci_resource_start(pdev1, 0); + mmio_len = pci_resource_len(pdev1, 0); + + bpctl_dev_arr[idx_dev].desc = + dev_desc[tx_ctl_pci_tbl[idx].index].name; + bpctl_dev_arr[idx_dev].name = + tx_ctl_pci_tbl[idx].bp_name; + bpctl_dev_arr[idx_dev].device = + tx_ctl_pci_tbl[idx].device; + bpctl_dev_arr[idx_dev].vendor = + tx_ctl_pci_tbl[idx].vendor; + bpctl_dev_arr[idx_dev].subdevice = + tx_ctl_pci_tbl[idx].subdevice; + bpctl_dev_arr[idx_dev].subvendor = + tx_ctl_pci_tbl[idx].subvendor; + //bpctl_dev_arr[idx_dev].pdev=pdev1; + bpctl_dev_arr[idx_dev].func = PCI_FUNC(pdev1->devfn); + bpctl_dev_arr[idx_dev].slot = PCI_SLOT(pdev1->devfn); + bpctl_dev_arr[idx_dev].bus = pdev1->bus->number; + bpctl_dev_arr[idx_dev].mem_map = + (unsigned long)ioremap(mmio_start, mmio_len); +#ifdef BP_SYNC_FLAG + spin_lock_init(&bpctl_dev_arr[idx_dev].bypass_wr_lock); +#endif + if (BP10G9_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice)) + bpctl_dev_arr[idx_dev].bp_10g9 = 1; + if (BP10G_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice)) + bpctl_dev_arr[idx_dev].bp_10g = 1; + if (PEG540_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice)) { + + bpctl_dev_arr[idx_dev].bp_540 = 1; + } + if (PEGF5_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice)) + bpctl_dev_arr[idx_dev].bp_fiber5 = 1; + if (PEG80_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice)) + bpctl_dev_arr[idx_dev].bp_i80 = 1; + if (PEGF80_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice)) + bpctl_dev_arr[idx_dev].bp_i80 = 1; + if ((bpctl_dev_arr[idx_dev].subdevice & 0xa00) == 0xa00) + bpctl_dev_arr[idx_dev].bp_i80 = 1; + if (BP10GB_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice)) { + if (bpctl_dev_arr[idx_dev].ifindex == 0) { + unregister_chrdev(major_num, + DEVICE_NAME); + printk + ("Please load network driver for %s adapter!\n", + bpctl_dev_arr[idx_dev].name); + return -1; + } + + if (bpctl_dev_arr[idx_dev].ndev) { + if (! + (bpctl_dev_arr[idx_dev].ndev-> + flags & IFF_UP)) { + if (! + (bpctl_dev_arr[idx_dev]. + ndev->flags & IFF_UP)) { + unregister_chrdev + (major_num, + DEVICE_NAME); + printk + ("Please bring up network interfaces for %s adapter!\n", + bpctl_dev_arr + [idx_dev].name); + return -1; + } + + } + } + bpctl_dev_arr[idx_dev].bp_10gb = 1; + } + + if (!bpctl_dev_arr[idx_dev].bp_10g9) { + + if (is_bypass_fn(&bpctl_dev_arr[idx_dev])) { + printk(KERN_INFO "%s found, ", + bpctl_dev_arr[idx_dev].name); + if ((OLD_IF_SERIES + (bpctl_dev_arr[idx_dev].subdevice)) + || + (INTEL_IF_SERIES + (bpctl_dev_arr[idx_dev]. + subdevice))) + bpctl_dev_arr[idx_dev]. + bp_fw_ver = 0xff; + else + bpctl_dev_arr[idx_dev]. + bp_fw_ver = + bypass_fw_ver(&bpctl_dev_arr + [idx_dev]); + if ((bpctl_dev_arr[idx_dev].bp_10gb == + 1) + && (bpctl_dev_arr[idx_dev]. + bp_fw_ver == 0xff)) { + int cnt = 100; + while (cnt--) { + iounmap((void + *) + (bpctl_dev_arr + [idx_dev]. + mem_map)); + mmio_start = + pci_resource_start + (pdev1, 0); + mmio_len = + pci_resource_len + (pdev1, 0); + + bpctl_dev_arr[idx_dev]. + mem_map = + (unsigned long) + ioremap(mmio_start, + mmio_len); + + bpctl_dev_arr[idx_dev]. + bp_fw_ver = + bypass_fw_ver + (&bpctl_dev_arr + [idx_dev]); + if (bpctl_dev_arr + [idx_dev]. + bp_fw_ver == 0xa8) + break; + + } + } + //bpctl_dev_arr[idx_dev].bp_fw_ver=0xa8; + printk("firmware version: 0x%x\n", + bpctl_dev_arr[idx_dev]. + bp_fw_ver); + } + bpctl_dev_arr[idx_dev].wdt_status = + WDT_STATUS_UNKNOWN; + bpctl_dev_arr[idx_dev].reset_time = 0; + atomic_set(&bpctl_dev_arr[idx_dev].wdt_busy, 0); + bpctl_dev_arr[idx_dev].bp_status_un = 1; + + bypass_caps_init(&bpctl_dev_arr[idx_dev]); + + init_bypass_wd_auto(&bpctl_dev_arr[idx_dev]); + init_bypass_tpl_auto(&bpctl_dev_arr[idx_dev]); + if (NOKIA_SERIES + (bpctl_dev_arr[idx_dev].subdevice)) + reset_cont(&bpctl_dev_arr[idx_dev]); + } +#ifdef BP_SELF_TEST + if ((bpctl_dev_arr[idx_dev].bp_tx_data = + kmalloc(BPTEST_DATA_LEN, GFP_KERNEL))) { + + memset(bpctl_dev_arr[idx_dev].bp_tx_data, 0x0, + BPTEST_DATA_LEN); + + memset(bpctl_dev_arr[idx_dev].bp_tx_data, 0xff, + 6); + memset(bpctl_dev_arr[idx_dev].bp_tx_data + 6, + 0x0, 1); + memset(bpctl_dev_arr[idx_dev].bp_tx_data + 7, + 0xaa, 5); + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9)) + bpctl_dev_arr[idx_dev].bp_tx_data[12] = + (ETH_P_BPTEST >> 8) & 0xff; + bpctl_dev_arr[idx_dev].bp_tx_data[13] = + ETH_P_BPTEST & 0xff; +#else + *(__be16 *) (bpctl_dev_arr[idx_dev].bp_tx_data + + 12) = htons(ETH_P_BPTEST); +#endif + + } else + printk("bp_ctl: Memory allocation error!\n"); +#endif + idx_dev++; + + } + } + if_scan_init(); + + sema_init(&bpctl_sema, 1); + spin_lock_init(&bpvm_lock); + { + + bpctl_dev_t *pbpctl_dev_c = NULL; + for (idx_dev = 0; + ((bpctl_dev_arr[idx_dev].pdev != NULL) + && (idx_dev < device_num)); idx_dev++) { + if (bpctl_dev_arr[idx_dev].bp_10g9) { + pbpctl_dev_c = + get_status_port_fn(&bpctl_dev_arr[idx_dev]); + if (is_bypass_fn(&bpctl_dev_arr[idx_dev])) { + printk(KERN_INFO "%s found, ", + bpctl_dev_arr[idx_dev].name); + bpctl_dev_arr[idx_dev].bp_fw_ver = + bypass_fw_ver(&bpctl_dev_arr + [idx_dev]); + printk("firmware version: 0x%x\n", + bpctl_dev_arr[idx_dev]. + bp_fw_ver); + + } + bpctl_dev_arr[idx_dev].wdt_status = + WDT_STATUS_UNKNOWN; + bpctl_dev_arr[idx_dev].reset_time = 0; + atomic_set(&bpctl_dev_arr[idx_dev].wdt_busy, 0); + bpctl_dev_arr[idx_dev].bp_status_un = 1; + + bypass_caps_init(&bpctl_dev_arr[idx_dev]); + + init_bypass_wd_auto(&bpctl_dev_arr[idx_dev]); + init_bypass_tpl_auto(&bpctl_dev_arr[idx_dev]); + + } + + } + } + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) + inter_module_register("is_bypass_sd", THIS_MODULE, &is_bypass_sd); + inter_module_register("get_bypass_slave_sd", THIS_MODULE, + &get_bypass_slave_sd); + inter_module_register("get_bypass_caps_sd", THIS_MODULE, + &get_bypass_caps_sd); + inter_module_register("get_wd_set_caps_sd", THIS_MODULE, + &get_wd_set_caps_sd); + inter_module_register("set_bypass_sd", THIS_MODULE, &set_bypass_sd); + inter_module_register("get_bypass_sd", THIS_MODULE, &get_bypass_sd); + inter_module_register("get_bypass_change_sd", THIS_MODULE, + &get_bypass_change_sd); + inter_module_register("set_dis_bypass_sd", THIS_MODULE, + &set_dis_bypass_sd); + inter_module_register("get_dis_bypass_sd", THIS_MODULE, + &get_dis_bypass_sd); + inter_module_register("set_bypass_pwoff_sd", THIS_MODULE, + &set_bypass_pwoff_sd); + inter_module_register("get_bypass_pwoff_sd", THIS_MODULE, + &get_bypass_pwoff_sd); + inter_module_register("set_bypass_pwup_sd", THIS_MODULE, + &set_bypass_pwup_sd); + inter_module_register("get_bypass_pwup_sd", THIS_MODULE, + &get_bypass_pwup_sd); + inter_module_register("get_bypass_wd_sd", THIS_MODULE, + &get_bypass_wd_sd); + inter_module_register("set_bypass_wd_sd", THIS_MODULE, + &set_bypass_wd_sd); + inter_module_register("get_wd_expire_time_sd", THIS_MODULE, + &get_wd_expire_time_sd); + inter_module_register("reset_bypass_wd_timer_sd", THIS_MODULE, + &reset_bypass_wd_timer_sd); + inter_module_register("set_std_nic_sd", THIS_MODULE, &set_std_nic_sd); + inter_module_register("get_std_nic_sd", THIS_MODULE, &get_std_nic_sd); + inter_module_register("set_tx_sd", THIS_MODULE, &set_tx_sd); + inter_module_register("get_tx_sd", THIS_MODULE, &get_tx_sd); + inter_module_register("set_tpl_sd", THIS_MODULE, &set_tpl_sd); + inter_module_register("get_tpl_sd", THIS_MODULE, &get_tpl_sd); + + inter_module_register("set_bp_hw_reset_sd", THIS_MODULE, + &set_bp_hw_reset_sd); + inter_module_register("get_bp_hw_reset_sd", THIS_MODULE, + &get_bp_hw_reset_sd); + + inter_module_register("set_tap_sd", THIS_MODULE, &set_tap_sd); + inter_module_register("get_tap_sd", THIS_MODULE, &get_tap_sd); + inter_module_register("get_tap_change_sd", THIS_MODULE, + &get_tap_change_sd); + inter_module_register("set_dis_tap_sd", THIS_MODULE, &set_dis_tap_sd); + inter_module_register("get_dis_tap_sd", THIS_MODULE, &get_dis_tap_sd); + inter_module_register("set_tap_pwup_sd", THIS_MODULE, &set_tap_pwup_sd); + inter_module_register("get_tap_pwup_sd", THIS_MODULE, &get_tap_pwup_sd); + inter_module_register("set_bp_disc_sd", THIS_MODULE, &set_bp_disc_sd); + inter_module_register("get_bp_disc_sd", THIS_MODULE, &get_bp_disc_sd); + inter_module_register("get_bp_disc_change_sd", THIS_MODULE, + &get_bp_disc_change_sd); + inter_module_register("set_bp_dis_disc_sd", THIS_MODULE, + &set_bp_dis_disc_sd); + inter_module_register("get_bp_dis_disc_sd", THIS_MODULE, + &get_bp_dis_disc_sd); + inter_module_register("set_bp_disc_pwup_sd", THIS_MODULE, + &set_bp_disc_pwup_sd); + inter_module_register("get_bp_disc_pwup_sd", THIS_MODULE, + &get_bp_disc_pwup_sd); + inter_module_register("set_wd_exp_mode_sd", THIS_MODULE, + &set_wd_exp_mode_sd); + inter_module_register("get_wd_exp_mode_sd", THIS_MODULE, + &get_wd_exp_mode_sd); + inter_module_register("set_wd_autoreset_sd", THIS_MODULE, + &set_wd_autoreset_sd); + inter_module_register("get_wd_autoreset_sd", THIS_MODULE, + &get_wd_autoreset_sd); + inter_module_register("get_bypass_info_sd", THIS_MODULE, + &get_bypass_info_sd); + inter_module_register("bp_if_scan_sd", THIS_MODULE, &bp_if_scan_sd); + +#endif + register_netdevice_notifier(&bp_notifier_block); +#ifdef BP_PROC_SUPPORT + { + int i = 0; + //unsigned long flags; + //rcu_read_lock(); + bp_proc_create(); + for (i = 0; i < device_num; i++) { + if (bpctl_dev_arr[i].ifindex) { + //spin_lock_irqsave(&bpvm_lock, flags); + bypass_proc_remove_dev_sd(&bpctl_dev_arr[i]); + bypass_proc_create_dev_sd(&bpctl_dev_arr[i]); + //spin_unlock_irqrestore(&bpvm_lock, flags); + } + + } + //rcu_read_unlock(); + } +#endif + + //register_netdevice_notifier(&bp_notifier_block); + return 0; +} + +/* +* Cleanup - unregister the appropriate file from /proc +*/ +static void __exit bypass_cleanup_module(void) +{ + int i; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) + int ret; +#endif + unregister_netdevice_notifier(&bp_notifier_block); + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) + inter_module_unregister("is_bypass_sd"); + inter_module_unregister("get_bypass_slave_sd"); + inter_module_unregister("get_bypass_caps_sd"); + inter_module_unregister("get_wd_set_caps_sd"); + inter_module_unregister("set_bypass_sd"); + inter_module_unregister("get_bypass_sd"); + inter_module_unregister("get_bypass_change_sd"); + inter_module_unregister("set_dis_bypass_sd"); + inter_module_unregister("get_dis_bypass_sd"); + inter_module_unregister("set_bypass_pwoff_sd"); + inter_module_unregister("get_bypass_pwoff_sd"); + inter_module_unregister("set_bypass_pwup_sd"); + inter_module_unregister("get_bypass_pwup_sd"); + inter_module_unregister("set_bypass_wd_sd"); + inter_module_unregister("get_bypass_wd_sd"); + inter_module_unregister("get_wd_expire_time_sd"); + inter_module_unregister("reset_bypass_wd_timer_sd"); + inter_module_unregister("set_std_nic_sd"); + inter_module_unregister("get_std_nic_sd"); + inter_module_unregister("set_tx_sd"); + inter_module_unregister("get_tx_sd"); + inter_module_unregister("set_tpl_sd"); + inter_module_unregister("get_tpl_sd"); + inter_module_unregister("set_tap_sd"); + inter_module_unregister("get_tap_sd"); + inter_module_unregister("get_tap_change_sd"); + inter_module_unregister("set_dis_tap_sd"); + inter_module_unregister("get_dis_tap_sd"); + inter_module_unregister("set_tap_pwup_sd"); + inter_module_unregister("get_tap_pwup_sd"); + inter_module_unregister("set_bp_disc_sd"); + inter_module_unregister("get_bp_disc_sd"); + inter_module_unregister("get_bp_disc_change_sd"); + inter_module_unregister("set_bp_dis_disc_sd"); + inter_module_unregister("get_bp_dis_disc_sd"); + inter_module_unregister("set_bp_disc_pwup_sd"); + inter_module_unregister("get_bp_disc_pwup_sd"); + inter_module_unregister("set_wd_exp_mode_sd"); + inter_module_unregister("get_wd_exp_mode_sd"); + inter_module_unregister("set_wd_autoreset_sd"); + inter_module_unregister("get_wd_autoreset_sd"); + inter_module_unregister("get_bypass_info_sd"); + inter_module_unregister("bp_if_scan_sd"); + +#endif + + for (i = 0; i < device_num; i++) { + //unsigned long flags; +#ifdef BP_PROC_SUPPORT +//spin_lock_irqsave(&bpvm_lock, flags); +//rcu_read_lock(); + bypass_proc_remove_dev_sd(&bpctl_dev_arr[i]); +//spin_unlock_irqrestore(&bpvm_lock, flags); +//rcu_read_unlock(); +#endif + remove_bypass_wd_auto(&bpctl_dev_arr[i]); + bpctl_dev_arr[i].reset_time = 0; + + remove_bypass_tpl_auto(&bpctl_dev_arr[i]); + } + + /* unmap all devices */ + for (i = 0; i < device_num; i++) { +#ifdef BP_SELF_TEST + if (bpctl_dev_arr[i].bp_tx_data) + kfree(bpctl_dev_arr[i].bp_tx_data); +#endif + iounmap((void *)(bpctl_dev_arr[i].mem_map)); + } + + /* free all devices space */ + if (bpctl_dev_arr) + kfree(bpctl_dev_arr); + +/* +* Unregister the device +*/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) + ret = unregister_chrdev(major_num, DEVICE_NAME); +/* +* If there's an error, report it +*/ + if (ret < 0) + printk("Error in module_unregister_chrdev: %d\n", ret); +#else + unregister_chrdev(major_num, DEVICE_NAME); + +#endif +} + +module_init(bypass_init_module); +module_exit(bypass_cleanup_module); + +int is_bypass_sd(int ifindex) +{ + return (is_bypass(get_dev_idx_p(ifindex))); +} + +int set_bypass_sd(int ifindex, int bypass_mode) +{ + + return (set_bypass_fn(get_dev_idx_p(ifindex), bypass_mode)); +} + +int get_bypass_sd(int ifindex) +{ + + return (get_bypass_fn(get_dev_idx_p(ifindex))); +} + +int get_bypass_change_sd(int ifindex) +{ + + return (get_bypass_change_fn(get_dev_idx_p(ifindex))); +} + +int set_dis_bypass_sd(int ifindex, int dis_param) +{ + return (set_dis_bypass_fn(get_dev_idx_p(ifindex), dis_param)); +} + +int get_dis_bypass_sd(int ifindex) +{ + + return (get_dis_bypass_fn(get_dev_idx_p(ifindex))); +} + +int set_bypass_pwoff_sd(int ifindex, int bypass_mode) +{ + return (set_bypass_pwoff_fn(get_dev_idx_p(ifindex), bypass_mode)); + +} + +int get_bypass_pwoff_sd(int ifindex) +{ + return (get_bypass_pwoff_fn(get_dev_idx_p(ifindex))); + +} + +int set_bypass_pwup_sd(int ifindex, int bypass_mode) +{ + return (set_bypass_pwup_fn(get_dev_idx_p(ifindex), bypass_mode)); + +} + +int get_bypass_pwup_sd(int ifindex) +{ + return (get_bypass_pwup_fn(get_dev_idx_p(ifindex))); + +} + +int set_bypass_wd_sd(int if_index, int ms_timeout, int *ms_timeout_set) +{ + if ((is_bypass(get_dev_idx_p(if_index))) <= 0) + return BP_NOT_CAP; + *ms_timeout_set = set_bypass_wd_fn(get_dev_idx_p(if_index), ms_timeout); + return 0; +} + +int get_bypass_wd_sd(int ifindex, int *timeout) +{ + return (get_bypass_wd_fn(get_dev_idx_p(ifindex), timeout)); + +} + +int get_wd_expire_time_sd(int ifindex, int *time_left) +{ + return (get_wd_expire_time_fn(get_dev_idx_p(ifindex), time_left)); +} + +int reset_bypass_wd_timer_sd(int ifindex) +{ + return (reset_bypass_wd_timer_fn(get_dev_idx_p(ifindex))); + +} + +int get_wd_set_caps_sd(int ifindex) +{ + return (get_wd_set_caps_fn(get_dev_idx_p(ifindex))); + +} + +int set_std_nic_sd(int ifindex, int nic_mode) +{ + return (set_std_nic_fn(get_dev_idx_p(ifindex), nic_mode)); + +} + +int get_std_nic_sd(int ifindex) +{ + return (get_std_nic_fn(get_dev_idx_p(ifindex))); + +} + +int set_tap_sd(int ifindex, int tap_mode) +{ + return (set_tap_fn(get_dev_idx_p(ifindex), tap_mode)); + +} + +int get_tap_sd(int ifindex) +{ + return (get_tap_fn(get_dev_idx_p(ifindex))); + +} + +int set_tap_pwup_sd(int ifindex, int tap_mode) +{ + return (set_tap_pwup_fn(get_dev_idx_p(ifindex), tap_mode)); + +} + +int get_tap_pwup_sd(int ifindex) +{ + return (get_tap_pwup_fn(get_dev_idx_p(ifindex))); + +} + +int get_tap_change_sd(int ifindex) +{ + return (get_tap_change_fn(get_dev_idx_p(ifindex))); + +} + +int set_dis_tap_sd(int ifindex, int dis_param) +{ + return (set_dis_tap_fn(get_dev_idx_p(ifindex), dis_param)); + +} + +int get_dis_tap_sd(int ifindex) +{ + return (get_dis_tap_fn(get_dev_idx_p(ifindex))); + +} + +int set_bp_disc_sd(int ifindex, int disc_mode) +{ + return (set_disc_fn(get_dev_idx_p(ifindex), disc_mode)); + +} + +int get_bp_disc_sd(int ifindex) +{ + return (get_disc_fn(get_dev_idx_p(ifindex))); + +} + +int set_bp_disc_pwup_sd(int ifindex, int disc_mode) +{ + return (set_disc_pwup_fn(get_dev_idx_p(ifindex), disc_mode)); + +} + +int get_bp_disc_pwup_sd(int ifindex) +{ + return (get_disc_pwup_fn(get_dev_idx_p(ifindex))); + +} + +int get_bp_disc_change_sd(int ifindex) +{ + return (get_disc_change_fn(get_dev_idx_p(ifindex))); + +} + +int set_bp_dis_disc_sd(int ifindex, int dis_param) +{ + return (set_dis_disc_fn(get_dev_idx_p(ifindex), dis_param)); + +} + +int get_bp_dis_disc_sd(int ifindex) +{ + return (get_dis_disc_fn(get_dev_idx_p(ifindex))); + +} + +int get_wd_exp_mode_sd(int ifindex) +{ + return (get_wd_exp_mode_fn(get_dev_idx_p(ifindex))); +} + +int set_wd_exp_mode_sd(int ifindex, int param) +{ + return (set_wd_exp_mode_fn(get_dev_idx_p(ifindex), param)); + +} + +int reset_cont_sd(int ifindex) +{ + return (reset_cont_fn(get_dev_idx_p(ifindex))); + +} + +int set_tx_sd(int ifindex, int tx_state) +{ + return (set_tx_fn(get_dev_idx_p(ifindex), tx_state)); + +} + +int set_tpl_sd(int ifindex, int tpl_state) +{ + return (set_tpl_fn(get_dev_idx_p(ifindex), tpl_state)); + +} + +int set_bp_hw_reset_sd(int ifindex, int status) +{ + return (set_bp_hw_reset_fn(get_dev_idx_p(ifindex), status)); + +} + +int set_wd_autoreset_sd(int ifindex, int param) +{ + return (set_wd_autoreset_fn(get_dev_idx_p(ifindex), param)); + +} + +int get_wd_autoreset_sd(int ifindex) +{ + return (get_wd_autoreset_fn(get_dev_idx_p(ifindex))); + +} + +int get_bypass_caps_sd(int ifindex) +{ + return (get_bypass_caps_fn(get_dev_idx_p(ifindex))); +} + +int get_bypass_slave_sd(int ifindex) +{ + bpctl_dev_t *pbpctl_dev_out; + int ret = get_bypass_slave_fn(get_dev_idx_p(ifindex), &pbpctl_dev_out); + if (ret == 1) + return (pbpctl_dev_out->ifindex); + return -1; + +} + +int get_tx_sd(int ifindex) +{ + return (get_tx_fn(get_dev_idx_p(ifindex))); + +} + +int get_tpl_sd(int ifindex) +{ + return (get_tpl_fn(get_dev_idx_p(ifindex))); + +} + +int get_bp_hw_reset_sd(int ifindex) +{ + return (get_bp_hw_reset_fn(get_dev_idx_p(ifindex))); + +} + +int get_bypass_info_sd(int ifindex, struct bp_info *bp_info) +{ + return (get_bypass_info_fn + (get_dev_idx_p(ifindex), bp_info->prod_name, &bp_info->fw_ver)); +} + +int bp_if_scan_sd(void) +{ + if_scan_init(); + return 0; +} + +EXPORT_SYMBOL_NOVERS(is_bypass_sd); +EXPORT_SYMBOL_NOVERS(get_bypass_slave_sd); +EXPORT_SYMBOL_NOVERS(get_bypass_caps_sd); +EXPORT_SYMBOL_NOVERS(get_wd_set_caps_sd); +EXPORT_SYMBOL_NOVERS(set_bypass_sd); +EXPORT_SYMBOL_NOVERS(get_bypass_sd); +EXPORT_SYMBOL_NOVERS(get_bypass_change_sd); +EXPORT_SYMBOL_NOVERS(set_dis_bypass_sd); +EXPORT_SYMBOL_NOVERS(get_dis_bypass_sd); +EXPORT_SYMBOL_NOVERS(set_bypass_pwoff_sd); +EXPORT_SYMBOL_NOVERS(get_bypass_pwoff_sd); +EXPORT_SYMBOL_NOVERS(set_bypass_pwup_sd); +EXPORT_SYMBOL_NOVERS(get_bypass_pwup_sd); +EXPORT_SYMBOL_NOVERS(set_bypass_wd_sd); +EXPORT_SYMBOL_NOVERS(get_bypass_wd_sd); +EXPORT_SYMBOL_NOVERS(get_wd_expire_time_sd); +EXPORT_SYMBOL_NOVERS(reset_bypass_wd_timer_sd); +EXPORT_SYMBOL_NOVERS(set_std_nic_sd); +EXPORT_SYMBOL_NOVERS(get_std_nic_sd); +EXPORT_SYMBOL_NOVERS(set_tx_sd); +EXPORT_SYMBOL_NOVERS(get_tx_sd); +EXPORT_SYMBOL_NOVERS(set_tpl_sd); +EXPORT_SYMBOL_NOVERS(get_tpl_sd); +EXPORT_SYMBOL_NOVERS(set_bp_hw_reset_sd); +EXPORT_SYMBOL_NOVERS(get_bp_hw_reset_sd); +EXPORT_SYMBOL_NOVERS(set_tap_sd); +EXPORT_SYMBOL_NOVERS(get_tap_sd); +EXPORT_SYMBOL_NOVERS(get_tap_change_sd); +EXPORT_SYMBOL_NOVERS(set_dis_tap_sd); +EXPORT_SYMBOL_NOVERS(get_dis_tap_sd); +EXPORT_SYMBOL_NOVERS(set_tap_pwup_sd); +EXPORT_SYMBOL_NOVERS(get_tap_pwup_sd); +EXPORT_SYMBOL_NOVERS(set_wd_exp_mode_sd); +EXPORT_SYMBOL_NOVERS(get_wd_exp_mode_sd); +EXPORT_SYMBOL_NOVERS(set_wd_autoreset_sd); +EXPORT_SYMBOL_NOVERS(get_wd_autoreset_sd); +EXPORT_SYMBOL_NOVERS(set_bp_disc_sd); +EXPORT_SYMBOL_NOVERS(get_bp_disc_sd); +EXPORT_SYMBOL_NOVERS(get_bp_disc_change_sd); +EXPORT_SYMBOL_NOVERS(set_bp_dis_disc_sd); +EXPORT_SYMBOL_NOVERS(get_bp_dis_disc_sd); +EXPORT_SYMBOL_NOVERS(set_bp_disc_pwup_sd); +EXPORT_SYMBOL_NOVERS(get_bp_disc_pwup_sd); +EXPORT_SYMBOL_NOVERS(get_bypass_info_sd); +EXPORT_SYMBOL_NOVERS(bp_if_scan_sd); + +#define BP_PROC_DIR "bypass" + +#define GPIO6_SET_ENTRY_SD "gpio6_set" +#define GPIO6_CLEAR_ENTRY_SD "gpio6_clear" + +#define GPIO7_SET_ENTRY_SD "gpio7_set" +#define GPIO7_CLEAR_ENTRY_SD "gpio7_clear" + +#define PULSE_SET_ENTRY_SD "pulse_set" +#define ZERO_SET_ENTRY_SD "zero_set" +#define PULSE_GET1_ENTRY_SD "pulse_get1" +#define PULSE_GET2_ENTRY_SD "pulse_get2" + +#define CMND_ON_ENTRY_SD "cmnd_on" +#define CMND_OFF_ENTRY_SD "cmnd_off" +#define RESET_CONT_ENTRY_SD "reset_cont" + + /*COMMANDS*/ +#define BYPASS_INFO_ENTRY_SD "bypass_info" +#define BYPASS_SLAVE_ENTRY_SD "bypass_slave" +#define BYPASS_CAPS_ENTRY_SD "bypass_caps" +#define WD_SET_CAPS_ENTRY_SD "wd_set_caps" +#define BYPASS_ENTRY_SD "bypass" +#define BYPASS_CHANGE_ENTRY_SD "bypass_change" +#define BYPASS_WD_ENTRY_SD "bypass_wd" +#define WD_EXPIRE_TIME_ENTRY_SD "wd_expire_time" +#define RESET_BYPASS_WD_ENTRY_SD "reset_bypass_wd" +#define DIS_BYPASS_ENTRY_SD "dis_bypass" +#define BYPASS_PWUP_ENTRY_SD "bypass_pwup" +#define BYPASS_PWOFF_ENTRY_SD "bypass_pwoff" +#define STD_NIC_ENTRY_SD "std_nic" +#define STD_NIC_ENTRY_SD "std_nic" +#define TAP_ENTRY_SD "tap" +#define TAP_CHANGE_ENTRY_SD "tap_change" +#define DIS_TAP_ENTRY_SD "dis_tap" +#define TAP_PWUP_ENTRY_SD "tap_pwup" +#define TWO_PORT_LINK_ENTRY_SD "two_port_link" +#define WD_EXP_MODE_ENTRY_SD "wd_exp_mode" +#define WD_AUTORESET_ENTRY_SD "wd_autoreset" +#define TPL_ENTRY_SD "tpl" +#define WAIT_AT_PWUP_ENTRY_SD "wait_at_pwup" +#define HW_RESET_ENTRY_SD "hw_reset" +#define DISC_ENTRY_SD "disc" +#define DISC_CHANGE_ENTRY_SD "disc_change" +#define DIS_DISC_ENTRY_SD "dis_disc" +#define DISC_PWUP_ENTRY_SD "disc_pwup" +static struct proc_dir_entry *bp_procfs_dir; + +static struct proc_dir_entry *proc_getdir(char *name, + struct proc_dir_entry *proc_dir) +{ + struct proc_dir_entry *pde = proc_dir; + + for (pde = pde->subdir; pde; pde = pde->next) { + if (pde->namelen && (strcmp(name, pde->name) == 0)) { + /* directory exists */ + break; + } + } + if (pde == (struct proc_dir_entry *)0) { + /* create the directory */ +#if (LINUX_VERSION_CODE > 0x20300) + pde = proc_mkdir(name, proc_dir); +#else + pde = create_proc_entry(name, S_IFDIR, proc_dir); +#endif + if (pde == (struct proc_dir_entry *)0) { + + return (pde); + } + } + + return (pde); +} + +int bp_proc_create(void) +{ + bp_procfs_dir = proc_getdir(BP_PROC_DIR, init_net.proc_net); + if (bp_procfs_dir == (struct proc_dir_entry *)0) { + printk(KERN_DEBUG + "Could not create procfs nicinfo directory %s\n", + BP_PROC_DIR); + return -1; + } + return 0; +} + +int +bypass_proc_create_entry_sd(struct pfs_unit_sd *pfs_unit_curr, + char *proc_name, + write_proc_t * write_proc, + read_proc_t * read_proc, + struct proc_dir_entry *parent_pfs, void *data) +{ + strcpy(pfs_unit_curr->proc_name, proc_name); + pfs_unit_curr->proc_entry = create_proc_entry(pfs_unit_curr->proc_name, + S_IFREG | S_IRUSR | + S_IWUSR | S_IRGRP | + S_IWGRP | S_IROTH | + S_IWOTH, parent_pfs); + if (pfs_unit_curr->proc_entry == 0) { + + return -1; + } + + pfs_unit_curr->proc_entry->read_proc = read_proc; + pfs_unit_curr->proc_entry->write_proc = write_proc; + pfs_unit_curr->proc_entry->data = data; + + return 0; + +} + +int +get_bypass_info_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + int len = 0; + + len += sprintf(page, "Name\t\t\t%s\n", pbp_device_block->name); + len += + sprintf(page + len, "Firmware version\t0x%x\n", + pbp_device_block->bp_fw_ver); + + *eof = 1; + return len; +} + +int +get_bypass_slave_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0; + bpctl_dev_t *pbp_device_block_slave = NULL; + int idx_dev = 0; + struct net_device *net_slave_dev = NULL; + + if ((pbp_device_block->func == 0) || (pbp_device_block->func == 2)) { + for (idx_dev = 0; + ((bpctl_dev_arr[idx_dev].pdev != NULL) + && (idx_dev < device_num)); idx_dev++) { + if ((bpctl_dev_arr[idx_dev].bus == + pbp_device_block->bus) + && (bpctl_dev_arr[idx_dev].slot == + pbp_device_block->slot)) { + if ((pbp_device_block->func == 0) + && (bpctl_dev_arr[idx_dev].func == 1)) { + pbp_device_block_slave = + &bpctl_dev_arr[idx_dev]; + break; + } + if ((pbp_device_block->func == 2) && + (bpctl_dev_arr[idx_dev].func == 3)) { + pbp_device_block_slave = + &bpctl_dev_arr[idx_dev]; + break; + } + } + } + } else + pbp_device_block_slave = pbp_device_block; + if (!pbp_device_block_slave) { + len = sprintf(page, "fail\n"); + *eof = 1; + return len; + } + net_slave_dev = pbp_device_block_slave->ndev; + if (net_slave_dev) { + if (net_slave_dev) + len = sprintf(page, "%s\n", net_slave_dev->name); + else + len = sprintf(page, "fail\n"); + + } + + *eof = 1; + return len; +} + +int +get_bypass_caps_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_bypass_caps_fn(pbp_device_block); + if (ret == BP_NOT_CAP) + len = sprintf(page, "-1\n"); + else + len = sprintf(page, "0x%x\n", ret); + *eof = 1; + return len; + +} + +int +get_wd_set_caps_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_wd_set_caps_fn(pbp_device_block); + if (ret == BP_NOT_CAP) + len = sprintf(page, "-1\n"); + else + len = sprintf(page, "0x%x\n", ret); + *eof = 1; + return len; +} + +int +set_bypass_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int bypass_param = 0, length = 0; + + if (count > (sizeof(kbuf) - 1)) + return -1; + + if (copy_from_user(&kbuf, buffer, count)) { + return -1; + } + + kbuf[count] = '\0'; + length = strlen(kbuf); + if (kbuf[length - 1] == '\n') + kbuf[--length] = '\0'; + + if (strcmp(kbuf, "on") == 0) + bypass_param = 1; + else if (strcmp(kbuf, "off") == 0) + bypass_param = 0; + + set_bypass_fn(pbp_device_block, bypass_param); + + return count; +} + +int +set_tap_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int tap_param = 0, length = 0; + + if (count > (sizeof(kbuf) - 1)) + return -1; + + if (copy_from_user(&kbuf, buffer, count)) { + return -1; + } + + kbuf[count] = '\0'; + length = strlen(kbuf); + if (kbuf[length - 1] == '\n') + kbuf[--length] = '\0'; + + if (strcmp(kbuf, "on") == 0) + tap_param = 1; + else if (strcmp(kbuf, "off") == 0) + tap_param = 0; + + set_tap_fn(pbp_device_block, tap_param); + + return count; +} + +int +set_disc_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int tap_param = 0, length = 0; + + if (count > (sizeof(kbuf) - 1)) + return -1; + + if (copy_from_user(&kbuf, buffer, count)) { + return -1; + } + + kbuf[count] = '\0'; + length = strlen(kbuf); + if (kbuf[length - 1] == '\n') + kbuf[--length] = '\0'; + + if (strcmp(kbuf, "on") == 0) + tap_param = 1; + else if (strcmp(kbuf, "off") == 0) + tap_param = 0; + + set_disc_fn(pbp_device_block, tap_param); + + return count; +} + +int +get_bypass_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_bypass_fn(pbp_device_block); + if (ret == BP_NOT_CAP) + len = sprintf(page, "fail\n"); + else if (ret == 1) + len = sprintf(page, "on\n"); + else if (ret == 0) + len = sprintf(page, "off\n"); + + *eof = 1; + return len; +} + +int +get_tap_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_tap_fn(pbp_device_block); + if (ret == BP_NOT_CAP) + len = sprintf(page, "fail\n"); + else if (ret == 1) + len = sprintf(page, "on\n"); + else if (ret == 0) + len = sprintf(page, "off\n"); + + *eof = 1; + return len; +} + +int +get_disc_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_disc_fn(pbp_device_block); + if (ret == BP_NOT_CAP) + len = sprintf(page, "fail\n"); + else if (ret == 1) + len = sprintf(page, "on\n"); + else if (ret == 0) + len = sprintf(page, "off\n"); + + *eof = 1; + return len; +} + +int +get_bypass_change_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_bypass_change_fn(pbp_device_block); + if (ret == 1) + len = sprintf(page, "on\n"); + else if (ret == 0) + len = sprintf(page, "off\n"); + else + len = sprintf(page, "fail\n"); + + *eof = 1; + return len; +} + +int +get_tap_change_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_tap_change_fn(pbp_device_block); + if (ret == 1) + len = sprintf(page, "on\n"); + else if (ret == 0) + len = sprintf(page, "off\n"); + else + len = sprintf(page, "fail\n"); + + *eof = 1; + return len; +} + +int +get_disc_change_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_disc_change_fn(pbp_device_block); + if (ret == 1) + len = sprintf(page, "on\n"); + else if (ret == 0) + len = sprintf(page, "off\n"); + else + len = sprintf(page, "fail\n"); + + *eof = 1; + return len; +} + +#define isdigit(c) (c >= '0' && c <= '9') +__inline static int atoi(char **s) +{ + int i = 0; + while (isdigit(**s)) + i = i * 10 + *((*s)++) - '0'; + return i; +} + +int +set_bypass_wd_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + unsigned int timeout = 0; + char *timeout_ptr = kbuf; + + if (copy_from_user(&kbuf, buffer, count)) { + return -1; + } + + timeout_ptr = kbuf; + timeout = atoi(&timeout_ptr); + + set_bypass_wd_fn(pbp_device_block, timeout); + + return count; +} + +int +get_bypass_wd_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0, timeout = 0; + + ret = get_bypass_wd_fn(pbp_device_block, &timeout); + if (ret == BP_NOT_CAP) + len = sprintf(page, "fail\n"); + else if (timeout == -1) + len = sprintf(page, "unknown\n"); + else if (timeout == 0) + len = sprintf(page, "disable\n"); + else + len = sprintf(page, "%d\n", timeout); + + *eof = 1; + return len; +} + +int +get_wd_expire_time_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0, timeout = 0; + + ret = get_wd_expire_time_fn(pbp_device_block, &timeout); + if (ret == BP_NOT_CAP) + len = sprintf(page, "fail\n"); + else if (timeout == -1) + len = sprintf(page, "expire\n"); + else if (timeout == 0) + len = sprintf(page, "disable\n"); + + else + len = sprintf(page, "%d\n", timeout); + *eof = 1; + return len; +} + +int +get_tpl_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_tpl_fn(pbp_device_block); + if (ret == BP_NOT_CAP) + len = sprintf(page, "fail\n"); + else if (ret == 1) + len = sprintf(page, "on\n"); + else if (ret == 0) + len = sprintf(page, "off\n"); + + *eof = 1; + return len; +} + +#ifdef PMC_FIX_FLAG +int +get_wait_at_pwup_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_bp_wait_at_pwup_fn(pbp_device_block); + if (ret == BP_NOT_CAP) + len = sprintf(page, "fail\n"); + else if (ret == 1) + len = sprintf(page, "on\n"); + else if (ret == 0) + len = sprintf(page, "off\n"); + + *eof = 1; + return len; +} + +int +get_hw_reset_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_bp_hw_reset_fn(pbp_device_block); + if (ret == BP_NOT_CAP) + len = sprintf(page, "fail\n"); + else if (ret == 1) + len = sprintf(page, "on\n"); + else if (ret == 0) + len = sprintf(page, "off\n"); + + *eof = 1; + return len; +} + +#endif /*PMC_WAIT_FLAG */ + +int +reset_bypass_wd_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = reset_bypass_wd_timer_fn(pbp_device_block); + if (ret == BP_NOT_CAP) + len = sprintf(page, "fail\n"); + else if (ret == 0) + len = sprintf(page, "disable\n"); + else if (ret == 1) + len = sprintf(page, "success\n"); + + *eof = 1; + return len; +} + +int +set_dis_bypass_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int bypass_param = 0, length = 0; + + if (copy_from_user(&kbuf, buffer, count)) { + return -1; + } + + kbuf[count] = '\0'; + length = strlen(kbuf); + if (kbuf[length - 1] == '\n') + kbuf[--length] = '\0'; + + if (strcmp(kbuf, "on") == 0) + bypass_param = 1; + else if (strcmp(kbuf, "off") == 0) + bypass_param = 0; + + set_dis_bypass_fn(pbp_device_block, bypass_param); + + return count; +} + +int +set_dis_tap_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int tap_param = 0, length = 0; + + if (copy_from_user(&kbuf, buffer, count)) { + return -1; + } + + kbuf[count] = '\0'; + length = strlen(kbuf); + if (kbuf[length - 1] == '\n') + kbuf[--length] = '\0'; + + if (strcmp(kbuf, "on") == 0) + tap_param = 1; + else if (strcmp(kbuf, "off") == 0) + tap_param = 0; + + set_dis_tap_fn(pbp_device_block, tap_param); + + return count; +} + +int +set_dis_disc_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int tap_param = 0, length = 0; + + if (copy_from_user(&kbuf, buffer, count)) { + return -1; + } + + kbuf[count] = '\0'; + length = strlen(kbuf); + if (kbuf[length - 1] == '\n') + kbuf[--length] = '\0'; + + if (strcmp(kbuf, "on") == 0) + tap_param = 1; + else if (strcmp(kbuf, "off") == 0) + tap_param = 0; + + set_dis_disc_fn(pbp_device_block, tap_param); + + return count; +} + +int +get_dis_bypass_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_dis_bypass_fn(pbp_device_block); + if (ret == BP_NOT_CAP) + len = sprintf(page, "fail\n"); + else if (ret == 0) + len = sprintf(page, "off\n"); + else + len = sprintf(page, "on\n"); + + *eof = 1; + return len; +} + +int +get_dis_tap_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_dis_tap_fn(pbp_device_block); + if (ret == BP_NOT_CAP) + len = sprintf(page, "fail\n"); + else if (ret == 0) + len = sprintf(page, "off\n"); + else + len = sprintf(page, "on\n"); + + *eof = 1; + return len; +} + +int +get_dis_disc_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_dis_disc_fn(pbp_device_block); + if (ret == BP_NOT_CAP) + len = sprintf(page, "fail\n"); + else if (ret == 0) + len = sprintf(page, "off\n"); + else + len = sprintf(page, "on\n"); + + *eof = 1; + return len; +} + +int +set_bypass_pwup_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int bypass_param = 0, length = 0; + + if (copy_from_user(&kbuf, buffer, count)) { + return -1; + } + + kbuf[count] = '\0'; + length = strlen(kbuf); + if (kbuf[length - 1] == '\n') + kbuf[--length] = '\0'; + + if (strcmp(kbuf, "on") == 0) + bypass_param = 1; + else if (strcmp(kbuf, "off") == 0) + bypass_param = 0; + + set_bypass_pwup_fn(pbp_device_block, bypass_param); + + return count; +} + +int +set_bypass_pwoff_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int bypass_param = 0, length = 0; + + if (copy_from_user(&kbuf, buffer, count)) { + return -1; + } + + kbuf[count] = '\0'; + length = strlen(kbuf); + if (kbuf[length - 1] == '\n') + kbuf[--length] = '\0'; + + if (strcmp(kbuf, "on") == 0) + bypass_param = 1; + else if (strcmp(kbuf, "off") == 0) + bypass_param = 0; + + set_bypass_pwoff_fn(pbp_device_block, bypass_param); + + return count; +} + +int +set_tap_pwup_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int tap_param = 0, length = 0; + + if (copy_from_user(&kbuf, buffer, count)) { + return -1; + } + + kbuf[count] = '\0'; + length = strlen(kbuf); + if (kbuf[length - 1] == '\n') + kbuf[--length] = '\0'; + + if (strcmp(kbuf, "on") == 0) + tap_param = 1; + else if (strcmp(kbuf, "off") == 0) + tap_param = 0; + + set_tap_pwup_fn(pbp_device_block, tap_param); + + return count; +} + +int +set_disc_pwup_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int tap_param = 0, length = 0; + + if (copy_from_user(&kbuf, buffer, count)) { + return -1; + } + + kbuf[count] = '\0'; + length = strlen(kbuf); + if (kbuf[length - 1] == '\n') + kbuf[--length] = '\0'; + + if (strcmp(kbuf, "on") == 0) + tap_param = 1; + else if (strcmp(kbuf, "off") == 0) + tap_param = 0; + + set_disc_pwup_fn(pbp_device_block, tap_param); + + return count; +} + +int +get_bypass_pwup_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_bypass_pwup_fn(pbp_device_block); + if (ret == BP_NOT_CAP) + len = sprintf(page, "fail\n"); + else if (ret == 0) + len = sprintf(page, "off\n"); + else + len = sprintf(page, "on\n"); + + *eof = 1; + return len; +} + +int +get_bypass_pwoff_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_bypass_pwoff_fn(pbp_device_block); + if (ret == BP_NOT_CAP) + len = sprintf(page, "fail\n"); + else if (ret == 0) + len = sprintf(page, "off\n"); + else + len = sprintf(page, "on\n"); + + *eof = 1; + return len; +} + +int +get_tap_pwup_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_tap_pwup_fn(pbp_device_block); + if (ret == BP_NOT_CAP) + len = sprintf(page, "fail\n"); + else if (ret == 0) + len = sprintf(page, "off\n"); + else + len = sprintf(page, "on\n"); + + *eof = 1; + return len; +} + +int +get_disc_pwup_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_disc_pwup_fn(pbp_device_block); + if (ret == BP_NOT_CAP) + len = sprintf(page, "fail\n"); + else if (ret == 0) + len = sprintf(page, "off\n"); + else + len = sprintf(page, "on\n"); + + *eof = 1; + return len; +} + +int +set_std_nic_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int bypass_param = 0, length = 0; + + if (copy_from_user(&kbuf, buffer, count)) { + return -1; + } + + kbuf[count] = '\0'; + length = strlen(kbuf); + if (kbuf[length - 1] == '\n') + kbuf[--length] = '\0'; + + if (strcmp(kbuf, "on") == 0) + bypass_param = 1; + else if (strcmp(kbuf, "off") == 0) + bypass_param = 0; + + set_std_nic_fn(pbp_device_block, bypass_param); + + return count; +} + +int +get_std_nic_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_std_nic_fn(pbp_device_block); + if (ret == BP_NOT_CAP) + len = sprintf(page, "fail\n"); + else if (ret == 0) + len = sprintf(page, "off\n"); + else + len = sprintf(page, "on\n"); + + *eof = 1; + return len; +} + +int +get_wd_exp_mode_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_wd_exp_mode_fn(pbp_device_block); + if (ret == 1) + len = sprintf(page, "tap\n"); + else if (ret == 0) + len = sprintf(page, "bypass\n"); + else if (ret == 2) + len = sprintf(page, "disc\n"); + + else + len = sprintf(page, "fail\n"); + + *eof = 1; + return len; +} + +int +set_wd_exp_mode_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int bypass_param = 0, length = 0; + + if (count > (sizeof(kbuf) - 1)) + return -1; + + if (copy_from_user(&kbuf, buffer, count)) { + return -1; + } + + kbuf[count] = '\0'; + length = strlen(kbuf); + if (kbuf[length - 1] == '\n') + kbuf[--length] = '\0'; + + if (strcmp(kbuf, "tap") == 0) + bypass_param = 1; + else if (strcmp(kbuf, "bypass") == 0) + bypass_param = 0; + else if (strcmp(kbuf, "disc") == 0) + bypass_param = 2; + + set_wd_exp_mode_fn(pbp_device_block, bypass_param); + + return count; +} + +int +get_wd_autoreset_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_wd_autoreset_fn(pbp_device_block); + if (ret >= 0) + len = sprintf(page, "%d\n", ret); + else + len = sprintf(page, "fail\n"); + + *eof = 1; + return len; +} + +int +set_wd_autoreset_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + char kbuf[256]; + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + u32 timeout = 0; + char *timeout_ptr = kbuf; + + if (copy_from_user(&kbuf, buffer, count)) { + return -1; + } + + timeout_ptr = kbuf; + timeout = atoi(&timeout_ptr); + + set_wd_autoreset_fn(pbp_device_block, timeout); + + return count; +} + +int +set_tpl_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int tpl_param = 0, length = 0; + + if (count > (sizeof(kbuf) - 1)) + return -1; + + if (copy_from_user(&kbuf, buffer, count)) { + return -1; + } + + kbuf[count] = '\0'; + length = strlen(kbuf); + if (kbuf[length - 1] == '\n') + kbuf[--length] = '\0'; + + if (strcmp(kbuf, "on") == 0) + tpl_param = 1; + else if (strcmp(kbuf, "off") == 0) + tpl_param = 0; + + set_tpl_fn(pbp_device_block, tpl_param); + + return count; +} + +#ifdef PMC_FIX_FLAG +int +set_wait_at_pwup_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int tpl_param = 0, length = 0; + + if (count > (sizeof(kbuf) - 1)) + return -1; + + if (copy_from_user(&kbuf, buffer, count)) { + return -1; + } + + kbuf[count] = '\0'; + length = strlen(kbuf); + if (kbuf[length - 1] == '\n') + kbuf[--length] = '\0'; + + if (strcmp(kbuf, "on") == 0) + tpl_param = 1; + else if (strcmp(kbuf, "off") == 0) + tpl_param = 0; + + set_bp_wait_at_pwup_fn(pbp_device_block, tpl_param); + + return count; +} + +int +set_hw_reset_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int tpl_param = 0, length = 0; + + if (count > (sizeof(kbuf) - 1)) + return -1; + + if (copy_from_user(&kbuf, buffer, count)) { + return -1; + } + + kbuf[count] = '\0'; + length = strlen(kbuf); + if (kbuf[length - 1] == '\n') + kbuf[--length] = '\0'; + + if (strcmp(kbuf, "on") == 0) + tpl_param = 1; + else if (strcmp(kbuf, "off") == 0) + tpl_param = 0; + + set_bp_hw_reset_fn(pbp_device_block, tpl_param); + + return count; +} + +#endif /*PMC_FIX_FLAG */ + +int bypass_proc_create_dev_sd(bpctl_dev_t * pbp_device_block) +{ + struct bypass_pfs_sd *current_pfs = &(pbp_device_block->bypass_pfs_set); + static struct proc_dir_entry *procfs_dir = NULL; + int ret = 0; + + if (!pbp_device_block->ndev) + return -1; + sprintf(current_pfs->dir_name, "bypass_%s", + pbp_device_block->ndev->name); + + if (!bp_procfs_dir) + return -1; + + /* create device proc dir */ + procfs_dir = proc_getdir(current_pfs->dir_name, bp_procfs_dir); + if (procfs_dir == 0) { + printk(KERN_DEBUG "Could not create procfs directory %s\n", + current_pfs->dir_name); + return -1; + } + current_pfs->bypass_entry = procfs_dir; + + if (bypass_proc_create_entry_sd(&(current_pfs->bypass_info), BYPASS_INFO_ENTRY_SD, NULL, /* write */ + get_bypass_info_pfs, /* read */ + procfs_dir, pbp_device_block)) + ret = -1; + + if (pbp_device_block->bp_caps & SW_CTL_CAP) { + + /* Create set param proc's */ + if (bypass_proc_create_entry_sd(&(current_pfs->bypass_slave), BYPASS_SLAVE_ENTRY_SD, NULL, /* write */ + get_bypass_slave_pfs, /* read */ + procfs_dir, pbp_device_block)) + ret = -1; + + if (bypass_proc_create_entry_sd(&(current_pfs->bypass_caps), BYPASS_CAPS_ENTRY_SD, NULL, /* write */ + get_bypass_caps_pfs, /* read */ + procfs_dir, pbp_device_block)) + ret = -1; + + if (bypass_proc_create_entry_sd(&(current_pfs->wd_set_caps), WD_SET_CAPS_ENTRY_SD, NULL, /* write */ + get_wd_set_caps_pfs, /* read */ + procfs_dir, pbp_device_block)) + ret = -1; + if (bypass_proc_create_entry_sd(&(current_pfs->bypass_wd), BYPASS_WD_ENTRY_SD, set_bypass_wd_pfs, /* write */ + get_bypass_wd_pfs, /* read */ + procfs_dir, pbp_device_block)) + ret = -1; + + if (bypass_proc_create_entry_sd(&(current_pfs->wd_expire_time), WD_EXPIRE_TIME_ENTRY_SD, NULL, /* write */ + get_wd_expire_time_pfs, /* read */ + procfs_dir, pbp_device_block)) + ret = -1; + + if (bypass_proc_create_entry_sd(&(current_pfs->reset_bypass_wd), RESET_BYPASS_WD_ENTRY_SD, NULL, /* write */ + reset_bypass_wd_pfs, /* read */ + procfs_dir, pbp_device_block)) + ret = -1; + + if (bypass_proc_create_entry_sd(&(current_pfs->std_nic), STD_NIC_ENTRY_SD, set_std_nic_pfs, /* write */ + get_std_nic_pfs, /* read */ + procfs_dir, pbp_device_block)) + ret = -1; + + if (pbp_device_block->bp_caps & BP_CAP) { + if (bypass_proc_create_entry_sd(&(current_pfs->bypass), BYPASS_ENTRY_SD, set_bypass_pfs, /* write */ + get_bypass_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret = -1; + + if (bypass_proc_create_entry_sd(&(current_pfs->dis_bypass), DIS_BYPASS_ENTRY_SD, set_dis_bypass_pfs, /* write */ + get_dis_bypass_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret = -1; + + if (bypass_proc_create_entry_sd(&(current_pfs->bypass_pwup), BYPASS_PWUP_ENTRY_SD, set_bypass_pwup_pfs, /* write */ + get_bypass_pwup_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret = -1; + if (bypass_proc_create_entry_sd(&(current_pfs->bypass_pwoff), BYPASS_PWOFF_ENTRY_SD, set_bypass_pwoff_pfs, /* write */ + get_bypass_pwoff_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret = -1; + + if (bypass_proc_create_entry_sd(&(current_pfs->bypass_change), BYPASS_CHANGE_ENTRY_SD, NULL, /* write */ + get_bypass_change_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret = -1; + } + + if (pbp_device_block->bp_caps & TAP_CAP) { + + if (bypass_proc_create_entry_sd(&(current_pfs->tap), TAP_ENTRY_SD, set_tap_pfs, /* write */ + get_tap_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret = -1; + + if (bypass_proc_create_entry_sd(&(current_pfs->dis_tap), DIS_TAP_ENTRY_SD, set_dis_tap_pfs, /* write */ + get_dis_tap_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret = -1; + + if (bypass_proc_create_entry_sd(&(current_pfs->tap_pwup), TAP_PWUP_ENTRY_SD, set_tap_pwup_pfs, /* write */ + get_tap_pwup_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret = -1; + + if (bypass_proc_create_entry_sd(&(current_pfs->tap_change), TAP_CHANGE_ENTRY_SD, NULL, /* write */ + get_tap_change_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret = -1; + } + if (pbp_device_block->bp_caps & DISC_CAP) { + + if (bypass_proc_create_entry_sd(&(current_pfs->tap), DISC_ENTRY_SD, set_disc_pfs, /* write */ + get_disc_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret = -1; +#if 1 + + if (bypass_proc_create_entry_sd(&(current_pfs->dis_tap), DIS_DISC_ENTRY_SD, set_dis_disc_pfs, /* write */ + get_dis_disc_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret = -1; +#endif + + if (bypass_proc_create_entry_sd(&(current_pfs->tap_pwup), DISC_PWUP_ENTRY_SD, set_disc_pwup_pfs, /* write */ + get_disc_pwup_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret = -1; + + if (bypass_proc_create_entry_sd(&(current_pfs->tap_change), DISC_CHANGE_ENTRY_SD, NULL, /* write */ + get_disc_change_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret = -1; + } + + if (bypass_proc_create_entry_sd(&(current_pfs->wd_exp_mode), WD_EXP_MODE_ENTRY_SD, set_wd_exp_mode_pfs, /* write */ + get_wd_exp_mode_pfs, /* read */ + procfs_dir, pbp_device_block)) + ret = -1; + + if (bypass_proc_create_entry_sd(&(current_pfs->wd_autoreset), WD_AUTORESET_ENTRY_SD, set_wd_autoreset_pfs, /* write */ + get_wd_autoreset_pfs, /* read */ + procfs_dir, pbp_device_block)) + ret = -1; + if (bypass_proc_create_entry_sd(&(current_pfs->tpl), TPL_ENTRY_SD, set_tpl_pfs, /* write */ + get_tpl_pfs, /* read */ + procfs_dir, pbp_device_block)) + ret = -1; +#ifdef PMC_FIX_FLAG + if (bypass_proc_create_entry_sd(&(current_pfs->tpl), WAIT_AT_PWUP_ENTRY_SD, set_wait_at_pwup_pfs, /* write */ + get_wait_at_pwup_pfs, /* read */ + procfs_dir, pbp_device_block)) + ret = -1; + if (bypass_proc_create_entry_sd(&(current_pfs->tpl), HW_RESET_ENTRY_SD, set_hw_reset_pfs, /* write */ + get_hw_reset_pfs, /* read */ + procfs_dir, pbp_device_block)) + ret = -1; + +#endif + + } + if (ret < 0) + printk(KERN_DEBUG "Create proc entry failed\n"); + + return ret; +} + +int bypass_proc_remove_dev_sd(bpctl_dev_t * pbp_device_block) +{ + + struct bypass_pfs_sd *current_pfs = &pbp_device_block->bypass_pfs_set; + struct proc_dir_entry *pde = current_pfs->bypass_entry, *pde_curr = + NULL; + char name[256]; + + if (!pde) + return 0; + for (pde = pde->subdir; pde;) { + strcpy(name, pde->name); + pde_curr = pde; + pde = pde->next; + remove_proc_entry(name, current_pfs->bypass_entry); + } + if (!pde) + remove_proc_entry(current_pfs->dir_name, bp_procfs_dir); + current_pfs->bypass_entry = NULL; + + return 0; +} diff --git a/drivers/staging/silicom/bp_mod.h b/drivers/staging/silicom/bp_mod.h new file mode 100644 index 0000000..9e488c0 --- /dev/null +++ b/drivers/staging/silicom/bp_mod.h @@ -0,0 +1,703 @@ +/******************************************************************************/ +/* */ +/* Bypass Control utility, Copyright (c) 2005 Silicom */ +/* */ +/* This program is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation, located in the file LICENSE. */ +/* */ +/* */ +/* bp_mod.h */ +/* */ +/******************************************************************************/ + +#ifndef BP_MOD_H +#define BP_MOD_H +#include "bits.h" + +#define EXPORT_SYMBOL_NOVERS EXPORT_SYMBOL + +#define usec_delay(x) udelay(x) +#ifndef msec_delay_bp +#define msec_delay_bp(x) do { \ + int i; \ + if(1) { \ + for(i = 0; i < 1000; i++) \ + { \ + udelay(x) ; \ + } \ + } else { \ + msleep(x); \ + } } while(0) + +#endif + +#include + +#ifndef jiffies_to_msecs +#define jiffies_to_msecs(x) _kc_jiffies_to_msecs(x) +static inline unsigned int jiffies_to_msecs(const unsigned long j) +{ +#if HZ <= 1000 && !(1000 % HZ) + return (1000 / HZ) * j; +#elif HZ > 1000 && !(HZ % 1000) + return (j + (HZ / 1000) - 1) / (HZ / 1000); +#else + return (j * 1000) / HZ; +#endif +} +#endif + +#define SILICOM_VID 0x1374 +#define SILICOM_SVID 0x1374 + +#define SILICOM_PXG2BPFI_SSID 0x0026 +#define SILICOM_PXG2BPFILX_SSID 0x0027 +#define SILICOM_PXGBPI_SSID 0x0028 +#define SILICOM_PXGBPIG_SSID 0x0029 +#define SILICOM_PXG2TBFI_SSID 0x002a +#define SILICOM_PXG4BPI_SSID 0x002c +#define SILICOM_PXG4BPFI_SSID 0x002d +#define SILICOM_PXG4BPFILX_SSID 0x002e +#define SILICOM_PXG2BPFIL_SSID 0x002F +#define SILICOM_PXG2BPFILLX_SSID 0x0030 +#define SILICOM_PEG4BPI_SSID 0x0031 +#define SILICOM_PEG2BPI_SSID 0x0037 +#define SILICOM_PEG4BPIN_SSID 0x0038 +#define SILICOM_PEG2BPFI_SSID 0x0039 +#define SILICOM_PEG2BPFILX_SSID 0x003A +#define SILICOM_PMCXG2BPFI_SSID 0x003B +#define NOKIA_PMCXG2BPFIN_SSID 0x0510 +#define NOKIA_PMCXG2BPIN_SSID 0x0513 +#define NOKIA_PMCXG4BPIN_SSID 0x0514 +#define NOKIA_PMCXG2BPFIN_SVID 0x13B8 +#define NOKIA_PMCXG2BPIN2_SSID 0x0515 +#define NOKIA_PMCXG4BPIN2_SSID 0x0516 +#define SILICOM_PMCX2BPI_SSID 0x041 +#define SILICOM_PMCX4BPI_SSID 0x042 +#define SILICOM_PXG2BISC1_SSID 0x003d +#define SILICOM_PEG2TBFI_SSID 0x003E +#define SILICOM_PXG2TBI_SSID 0x003f +#define SILICOM_PXG4BPFID_SSID 0x0043 +#define SILICOM_PEG4BPFI_SSID 0x0040 +#define SILICOM_PEG4BPIPT_SSID 0x0044 +#define SILICOM_PXG6BPI_SSID 0x0045 +#define SILICOM_PEG4BPIL_SSID 0x0046 +#define SILICOM_PEG2BPI5_SSID 0x0052 +#define SILICOM_PEG6BPI_SSID 0x0053 +#define SILICOM_PEG4BPFI5_SSID 0x0050 +#define SILICOM_PEG4BPFI5LX_SSID 0x0051 +#define SILICOM_PEG2BISC6_SSID 0x54 + +#define SILICOM_PEG6BPIFC_SSID 0x55 + +#define SILICOM_PEG2BPFI5_SSID 0x0056 +#define SILICOM_PEG2BPFI5LX_SSID 0x0057 + +#define SILICOM_PXEG4BPFI_SSID 0x0058 + +#define SILICOM_PEG2BPFID_SSID 0x0047 +#define SILICOM_PEG2BPFIDLX_SSID 0x004C +#define SILICOM_MEG2BPFILN_SSID 0x0048 +#define SILICOM_MEG2BPFINX_SSID 0x0049 +#define SILICOM_PEG4BPFILX_SSID 0x004A +#define SILICOM_MHIO8AD_SSID 0x004F + +#define SILICOM_MEG2BPFILXLN_SSID 0x004b +#define SILICOM_PEG2BPIX1_SSID 0x004d +#define SILICOM_MEG2BPFILXNX_SSID 0x004e + +#define SILICOM_PE10G2BPISR_SSID 0x0102 +#define SILICOM_PE10G2BPILR_SSID 0x0103 +#define SILICOM_PE10G2BPICX4_SSID 0x0101 + +#define SILICOM_XE10G2BPILR_SSID 0x0163 +#define SILICOM_XE10G2BPISR_SSID 0x0162 +#define SILICOM_XE10G2BPICX4_SSID 0x0161 +#define SILICOM_XE10G2BPIT_SSID 0x0160 + +#define SILICOM_PE10GDBISR_SSID 0x0181 +#define SILICOM_PE10GDBILR_SSID 0x0182 + +#define SILICOM_PE210G2DBi9SR_SSID 0x0188 +#define SILICOM_PE210G2DBi9SRRB_SSID 0x0188 +#define SILICOM_PE210G2DBi9LR_SSID 0x0189 +#define SILICOM_PE210G2DBi9LRRB_SSID 0x0189 +#define SILICOM_PE310G4DBi940SR_SSID 0x018C + +#define SILICOM_PE310G4BPi9T_SSID 0x130 +#define SILICOM_PE310G4BPi9SR_SSID 0x132 +#define SILICOM_PE310G4BPi9LR_SSID 0x133 + +#define NOKIA_XE10G2BPIXR_SVID 0x13B8 +#define NOKIA_XE10G2BPIXR_SSID 0x051C + +#define INTEL_PEG4BPII_PID 0x10A0 +#define INTEL_PEG4BPFII_PID 0x10A1 +#define INTEL_PEG4BPII_SSID 0x11A0 +#define INTEL_PEG4BPFII_SSID 0x11A1 + +#define INTEL_PEG4BPIIO_SSID 0x10A0 +#define INTEL_PEG4BPIIO_PID 0x105e + +#define BROADCOM_VID 0x14e4 +#define BROADCOM_PE10G2_PID 0x164e + +#define SILICOM_PE10G2BPTCX4_SSID 0x0141 +#define SILICOM_PE10G2BPTSR_SSID 0x0142 +#define SILICOM_PE10G2BPTLR_SSID 0x0143 +#define SILICOM_PE10G2BPTT_SSID 0x0140 + +#define SILICOM_PEG4BPI6_SSID 0x0320 +#define SILICOM_PEG4BPFI6_SSID 0x0321 +#define SILICOM_PEG4BPFI6LX_SSID 0x0322 +#define SILICOM_PEG4BPFI6ZX_SSID 0x0323 + +#define SILICOM_PEG2BPI6_SSID 0x0300 +#define SILICOM_PEG2BPFI6_SSID 0x0301 +#define SILICOM_PEG2BPFI6LX_SSID 0x0302 +#define SILICOM_PEG2BPFI6ZX_SSID 0x0303 +#define SILICOM_PEG2BPFI6FLXM_SSID 0x0304 + +#define SILICOM_PEG2DBI6_SSID 0x0308 +#define SILICOM_PEG2DBFI6_SSID 0x0309 +#define SILICOM_PEG2DBFI6LX_SSID 0x030A +#define SILICOM_PEG2DBFI6ZX_SSID 0x030B + +#define SILICOM_MEG2BPI6_SSID 0x0310 +#define SILICOM_XEG2BPI6_SSID 0x0318 +#define SILICOM_PEG4BPI6FC_SSID 0x0328 +#define SILICOM_PEG4BPFI6FC_SSID 0x0329 +#define SILICOM_PEG4BPFI6FCLX_SSID 0x032A +#define SILICOM_PEG4BPFI6FCZX_SSID 0x032B + +#define SILICOM_PEG6BPI6_SSID 0x0340 + +#define SILICOM_PEG2BPI6SC6_SSID 0x0360 + +#define SILICOM_MEG2BPI6_SSID 0x0310 +#define SILICOM_XEG2BPI6_SSID 0x0318 +#define SILICOM_MEG4BPI6_SSID 0x0330 + +#define SILICOM_PE2G4BPi80L_SSID 0x0380 + +#define SILICOM_M6E2G8BPi80A_SSID 0x0474 + +#define SILICOM_PE2G4BPi35_SSID 0x03d8 + +#define SILICOM_PE2G4BPFi80_SSID 0x0381 +#define SILICOM_PE2G4BPFi80LX_SSID 0x0382 +#define SILICOM_PE2G4BPFi80ZX_SSID 0x0383 + +#define SILICOM_PE2G4BPi80_SSID 0x0388 + +#define SILICOM_PE2G2BPi80_SSID 0x0390 +#define SILICOM_PE2G2BPFi80_SSID 0x0391 +#define SILICOM_PE2G2BPFi80LX_SSID 0x0392 +#define SILICOM_PE2G2BPFi80ZX_SSID 0x0393 + +#define SILICOM_PE2G4BPi35L_SSID 0x03D0 +#define SILICOM_PE2G4BPFi35_SSID 0x03D1 +#define SILICOM_PE2G4BPFi35LX_SSID 0x03D2 +#define SILICOM_PE2G4BPFi35ZX_SSID 0x03D3 + +#define SILICOM_PE2G2BPi35_SSID 0x03c0 +#define SILICOM_PAC1200BPi35_SSID 0x03cc +#define SILICOM_PE2G2BPFi35_SSID 0x03C1 +#define SILICOM_PE2G2BPFi35LX_SSID 0x03C2 +#define SILICOM_PE2G2BPFi35ZX_SSID 0x03C3 + +#define SILICOM_PE2G6BPi35_SSID 0x03E0 +#define SILICOM_PE2G6BPi35CX_SSID 0x0AA0 + +#define INTEL_PE210G2SPI9_SSID 0x00C + +#define SILICOM_M1EG2BPI6_SSID 0x400 + +#define SILICOM_M1EG2BPFI6_SSID 0x0401 +#define SILICOM_M1EG2BPFI6LX_SSID 0x0402 +#define SILICOM_M1EG2BPFI6ZX_SSID 0x0403 + +#define SILICOM_M1EG4BPI6_SSID 0x0420 + +#define SILICOM_M1EG4BPFI6_SSID 0x0421 +#define SILICOM_M1EG4BPFI6LX_SSID 0x0422 +#define SILICOM_M1EG4BPFI6ZX_SSID 0x0423 + +#define SILICOM_M1EG6BPI6_SSID 0x0440 + +#define SILICOM_M1E2G4BPi80_SSID 0x0460 +#define SILICOM_M1E2G4BPFi80_SSID 0x0461 +#define SILICOM_M1E2G4BPFi80LX_SSID 0x0462 +#define SILICOM_M1E2G4BPFi80ZX_SSID 0x0463 + +#define SILICOM_M6E2G8BPi80_SSID 0x0470 +#define SILICOM_PE210G2BPi40_SSID 0x01a0 + +#define PEG540_IF_SERIES(pid) \ + ((pid==SILICOM_PE210G2BPi40_SSID)) + +#define OLD_IF_SERIES(pid) \ + ((pid==SILICOM_PXG2BPFI_SSID)|| \ + (pid==SILICOM_PXG2BPFILX_SSID)) + +#define P2BPFI_IF_SERIES(pid) \ + ((pid==SILICOM_PXG2BPFI_SSID)|| \ + (pid==SILICOM_PXG2BPFILX_SSID)|| \ + (pid==SILICOM_PEG2BPFI_SSID)|| \ + (pid==SILICOM_PEG2BPFID_SSID)|| \ + (pid==SILICOM_PEG2BPFIDLX_SSID)|| \ + (pid==SILICOM_MEG2BPFILN_SSID)|| \ + (pid==SILICOM_MEG2BPFINX_SSID)|| \ + (pid==SILICOM_PEG4BPFILX_SSID)|| \ + (pid==SILICOM_PEG4BPFI_SSID)|| \ + (pid==SILICOM_PXEG4BPFI_SSID)|| \ + (pid==SILICOM_PXG4BPFID_SSID)|| \ + (pid==SILICOM_PEG2TBFI_SSID)|| \ + (pid==SILICOM_PE10G2BPISR_SSID)|| \ + (pid==SILICOM_PE10G2BPILR_SSID)|| \ + (pid==SILICOM_PEG2BPFILX_SSID)|| \ + (pid==SILICOM_PMCXG2BPFI_SSID) || \ + (pid==SILICOM_MHIO8AD_SSID) || \ + (pid==SILICOM_PEG4BPFI5LX_SSID) || \ + (pid==SILICOM_PEG4BPFI5_SSID) || \ + (pid==SILICOM_PEG4BPFI6FC_SSID) || \ + (pid==SILICOM_PEG4BPFI6FCLX_SSID) || \ + (pid==SILICOM_PEG4BPFI6FCZX_SSID) || \ + (pid==NOKIA_PMCXG2BPFIN_SSID)|| \ + (pid==SILICOM_MEG2BPFILXLN_SSID)|| \ + (pid==SILICOM_MEG2BPFILXNX_SSID)|| \ + (pid==SILICOM_XE10G2BPIT_SSID)|| \ + (pid==SILICOM_XE10G2BPICX4_SSID)|| \ + (pid==SILICOM_XE10G2BPISR_SSID)|| \ + (pid==NOKIA_XE10G2BPIXR_SSID)|| \ + (pid==SILICOM_PE10GDBISR_SSID)|| \ + (pid==SILICOM_PE10GDBILR_SSID)|| \ + (pid==SILICOM_XE10G2BPILR_SSID)) + +#define INTEL_IF_SERIES(pid) \ + ((pid==INTEL_PEG4BPII_SSID)|| \ + (pid==INTEL_PEG4BPIIO_SSID)|| \ + (pid==INTEL_PEG4BPFII_SSID)) + +#define NOKIA_SERIES(pid) \ + ((pid==NOKIA_PMCXG2BPIN_SSID)|| \ + (pid==NOKIA_PMCXG4BPIN_SSID)|| \ + (pid==SILICOM_PMCX4BPI_SSID)|| \ + (pid==NOKIA_PMCXG2BPFIN_SSID)|| \ + (pid==SILICOM_PMCXG2BPFI_SSID)|| \ + (pid==NOKIA_PMCXG2BPIN2_SSID)|| \ + (pid==NOKIA_PMCXG4BPIN2_SSID)|| \ + (pid==SILICOM_PMCX2BPI_SSID)) + +#define DISCF_IF_SERIES(pid) \ + (pid==SILICOM_PEG2TBFI_SSID) + +#define PEGF_IF_SERIES(pid) \ + ((pid==SILICOM_PEG2BPFI_SSID)|| \ + (pid==SILICOM_PEG2BPFID_SSID)|| \ + (pid==SILICOM_PEG2BPFIDLX_SSID)|| \ + (pid==SILICOM_PEG2BPFILX_SSID)|| \ + (pid==SILICOM_PEG4BPFI_SSID)|| \ + (pid==SILICOM_PXEG4BPFI_SSID)|| \ + (pid==SILICOM_MEG2BPFILN_SSID)|| \ + (pid==SILICOM_MEG2BPFINX_SSID)|| \ + (pid==SILICOM_PEG4BPFILX_SSID)|| \ + (pid==SILICOM_PEG2TBFI_SSID)|| \ + (pid==SILICOM_MEG2BPFILXLN_SSID)|| \ + (pid==SILICOM_MEG2BPFILXNX_SSID)) + +#define TPL_IF_SERIES(pid) \ + ((pid==SILICOM_PXG2BPFIL_SSID)|| \ + (pid==SILICOM_PXG2BPFILLX_SSID)|| \ + (pid==SILICOM_PXG2TBFI_SSID)|| \ + (pid==SILICOM_PXG4BPFID_SSID)|| \ + (pid==SILICOM_PXG4BPFI_SSID)) + +#define BP10G_IF_SERIES(pid) \ + ((pid==SILICOM_PE10G2BPISR_SSID)|| \ + (pid==SILICOM_PE10G2BPICX4_SSID)|| \ + (pid==SILICOM_PE10G2BPILR_SSID)|| \ + (pid==SILICOM_XE10G2BPIT_SSID)|| \ + (pid==SILICOM_XE10G2BPICX4_SSID)|| \ + (pid==SILICOM_XE10G2BPISR_SSID)|| \ + (pid==NOKIA_XE10G2BPIXR_SSID)|| \ + (pid==SILICOM_PE10GDBISR_SSID)|| \ + (pid==SILICOM_PE10GDBILR_SSID)|| \ + (pid==SILICOM_XE10G2BPILR_SSID)) + +#define BP10GB_IF_SERIES(pid) \ + ((pid==SILICOM_PE10G2BPTCX4_SSID)|| \ + (pid==SILICOM_PE10G2BPTSR_SSID)|| \ + (pid==SILICOM_PE10G2BPTLR_SSID)|| \ + (pid==SILICOM_PE10G2BPTT_SSID)) + +#define BP10G_CX4_SERIES(pid) \ + (pid==SILICOM_PE10G2BPICX4_SSID) + +#define BP10GB_CX4_SERIES(pid) \ + (pid==SILICOM_PE10G2BPTCX4_SSID) + +#define SILICOM_M2EG2BPFI6_SSID 0x0501 +#define SILICOM_M2EG2BPFI6LX_SSID 0x0502 +#define SILICOM_M2EG2BPFI6ZX_SSID 0x0503 +#define SILICOM_M2EG4BPI6_SSID 0x0520 + +#define SILICOM_M2EG4BPFI6_SSID 0x0521 +#define SILICOM_M2EG4BPFI6LX_SSID 0x0522 +#define SILICOM_M2EG4BPFI6ZX_SSID 0x0523 + +#define SILICOM_M2EG6BPI6_SSID 0x0540 + +#define SILICOM_M1E10G2BPI9CX4_SSID 0x481 +#define SILICOM_M1E10G2BPI9SR_SSID 0x482 +#define SILICOM_M1E10G2BPI9LR_SSID 0x483 +#define SILICOM_M1E10G2BPI9T_SSID 0x480 + +#define SILICOM_M2E10G2BPI9CX4_SSID 0x581 +#define SILICOM_M2E10G2BPI9SR_SSID 0x582 +#define SILICOM_M2E10G2BPI9LR_SSID 0x583 +#define SILICOM_M2E10G2BPI9T_SSID 0x580 + +#define SILICOM_PE210G2BPI9CX4_SSID 0x121 +#define SILICOM_PE210G2BPI9SR_SSID 0x122 +#define SILICOM_PE210G2BPI9LR_SSID 0x123 +#define SILICOM_PE210G2BPI9T_SSID 0x120 + +#define DBI_IF_SERIES(pid) \ +((pid==SILICOM_PE10GDBISR_SSID)|| \ + (pid==SILICOM_PE10GDBILR_SSID)|| \ + (pid==SILICOM_XE10G2BPILR_SSID)|| \ + (pid==SILICOM_PE210G2DBi9LR_SSID)) + +#define PEGF5_IF_SERIES(pid) \ +((pid==SILICOM_PEG2BPFI5_SSID)|| \ + (pid==SILICOM_PEG2BPFI5LX_SSID)|| \ + (pid==SILICOM_PEG4BPFI6_SSID)|| \ + (pid==SILICOM_PEG4BPFI6LX_SSID)|| \ + (pid==SILICOM_PEG4BPFI6ZX_SSID)|| \ + (pid==SILICOM_PEG2BPFI6_SSID)|| \ + (pid==SILICOM_PEG2BPFI6LX_SSID)|| \ + (pid==SILICOM_PEG2BPFI6ZX_SSID)|| \ + (pid==SILICOM_PEG2BPFI6FLXM_SSID)|| \ + (pid==SILICOM_PEG2DBFI6_SSID)|| \ + (pid==SILICOM_PEG2DBFI6LX_SSID)|| \ + (pid==SILICOM_PEG2DBFI6ZX_SSID)|| \ + (pid==SILICOM_PEG4BPI6FC_SSID)|| \ + (pid==SILICOM_PEG4BPFI6FCLX_SSID)|| \ + (pid==SILICOM_PEG4BPI6FC_SSID)|| \ + (pid==SILICOM_M1EG2BPFI6_SSID)|| \ + (pid==SILICOM_M1EG2BPFI6LX_SSID)|| \ + (pid==SILICOM_M1EG2BPFI6ZX_SSID)|| \ + (pid==SILICOM_M1EG4BPFI6_SSID)|| \ + (pid==SILICOM_M1EG4BPFI6LX_SSID)|| \ + (pid==SILICOM_M1EG4BPFI6ZX_SSID)|| \ + (pid==SILICOM_M2EG2BPFI6_SSID)|| \ + (pid==SILICOM_M2EG2BPFI6LX_SSID)|| \ + (pid==SILICOM_M2EG2BPFI6ZX_SSID)|| \ + (pid==SILICOM_M2EG4BPFI6_SSID)|| \ + (pid==SILICOM_M2EG4BPFI6LX_SSID)|| \ + (pid==SILICOM_M2EG4BPFI6ZX_SSID)|| \ + (pid==SILICOM_PEG4BPFI6FCZX_SSID)) + +#define PEG5_IF_SERIES(pid) \ +((pid==SILICOM_PEG4BPI6_SSID)|| \ +(pid==SILICOM_PEG2BPI6_SSID)|| \ +(pid==SILICOM_PEG4BPI6FC_SSID)|| \ +(pid==SILICOM_PEG6BPI6_SSID)|| \ +(pid==SILICOM_PEG2BPI6SC6_SSID)|| \ +(pid==SILICOM_MEG2BPI6_SSID)|| \ +(pid==SILICOM_XEG2BPI6_SSID)|| \ +(pid==SILICOM_MEG4BPI6_SSID)|| \ +(pid==SILICOM_M1EG2BPI6_SSID)|| \ +(pid==SILICOM_M1EG4BPI6_SSID)|| \ +(pid==SILICOM_M1EG6BPI6_SSID)|| \ +(pid==SILICOM_PEG6BPI_SSID)|| \ +(pid==SILICOM_PEG4BPIL_SSID)|| \ +(pid==SILICOM_PEG2BISC6_SSID)|| \ +(pid==SILICOM_PEG2BPI5_SSID)) + +#define PEG80_IF_SERIES(pid) \ +((pid==SILICOM_M1E2G4BPi80_SSID)|| \ +(pid==SILICOM_M6E2G8BPi80_SSID)|| \ +(pid==SILICOM_PE2G4BPi80L_SSID)|| \ +(pid==SILICOM_M6E2G8BPi80A_SSID)|| \ +(pid==SILICOM_PE2G2BPi35_SSID)|| \ +(pid==SILICOM_PAC1200BPi35_SSID)|| \ +(pid==SILICOM_PE2G4BPi35_SSID)|| \ +(pid==SILICOM_PE2G4BPi35L_SSID)|| \ +(pid==SILICOM_PE2G6BPi35_SSID)|| \ +(pid==SILICOM_PE2G2BPi80_SSID)|| \ +(pid==SILICOM_PE2G4BPi80_SSID)|| \ +(pid==SILICOM_PE2G4BPFi80_SSID)|| \ +(pid==SILICOM_PE2G4BPFi80LX_SSID)|| \ +(pid==SILICOM_PE2G4BPFi80ZX_SSID)|| \ +(pid==SILICOM_PE2G4BPFi80ZX_SSID)|| \ +(pid==SILICOM_PE2G2BPFi80_SSID)|| \ +(pid==SILICOM_PE2G2BPFi80LX_SSID)|| \ +(pid==SILICOM_PE2G2BPFi80ZX_SSID)|| \ +(pid==SILICOM_PE2G2BPFi35_SSID)|| \ +(pid==SILICOM_PE2G2BPFi35LX_SSID)|| \ +(pid==SILICOM_PE2G2BPFi35ZX_SSID)|| \ +(pid==SILICOM_PE2G4BPFi35_SSID)|| \ +(pid==SILICOM_PE2G4BPFi35LX_SSID)|| \ +(pid==SILICOM_PE2G4BPFi35ZX_SSID)) + +#define PEGF80_IF_SERIES(pid) \ +((pid==SILICOM_PE2G4BPFi80_SSID)|| \ +(pid==SILICOM_PE2G4BPFi80LX_SSID)|| \ +(pid==SILICOM_PE2G4BPFi80ZX_SSID)|| \ +(pid==SILICOM_PE2G4BPFi80ZX_SSID)|| \ +(pid==SILICOM_M1E2G4BPFi80_SSID)|| \ +(pid==SILICOM_M1E2G4BPFi80LX_SSID)|| \ +(pid==SILICOM_M1E2G4BPFi80ZX_SSID)|| \ +(pid==SILICOM_PE2G2BPFi80_SSID)|| \ +(pid==SILICOM_PE2G2BPFi80LX_SSID)|| \ +(pid==SILICOM_PE2G2BPFi80ZX_SSID)|| \ +(pid==SILICOM_PE2G2BPFi35_SSID)|| \ +(pid==SILICOM_PE2G2BPFi35LX_SSID)|| \ +(pid==SILICOM_PE2G2BPFi35ZX_SSID)|| \ +(pid==SILICOM_PE2G4BPFi35_SSID)|| \ +(pid==SILICOM_PE2G4BPFi35LX_SSID)|| \ +(pid==SILICOM_PE2G4BPFi35ZX_SSID)) + +#define BP10G9_IF_SERIES(pid) \ +((pid==INTEL_PE210G2SPI9_SSID)|| \ +(pid==SILICOM_M1E10G2BPI9CX4_SSID)|| \ +(pid==SILICOM_M1E10G2BPI9SR_SSID)|| \ +(pid==SILICOM_M1E10G2BPI9LR_SSID)|| \ +(pid==SILICOM_M1E10G2BPI9T_SSID)|| \ +(pid==SILICOM_M2E10G2BPI9CX4_SSID)|| \ +(pid==SILICOM_M2E10G2BPI9SR_SSID)|| \ +(pid==SILICOM_M2E10G2BPI9LR_SSID)|| \ +(pid==SILICOM_M2E10G2BPI9T_SSID)|| \ +(pid==SILICOM_PE210G2BPI9CX4_SSID)|| \ +(pid==SILICOM_PE210G2BPI9SR_SSID)|| \ +(pid==SILICOM_PE210G2BPI9LR_SSID)|| \ +(pid==SILICOM_PE210G2DBi9SR_SSID)|| \ +(pid==SILICOM_PE210G2DBi9SRRB_SSID)|| \ +(pid==SILICOM_PE210G2DBi9LR_SSID)|| \ +(pid==SILICOM_PE210G2DBi9LRRB_SSID)|| \ +(pid==SILICOM_PE310G4DBi940SR_SSID)|| \ +(pid==SILICOM_PEG2BISC6_SSID)|| \ +(pid==SILICOM_PE310G4BPi9T_SSID)|| \ +(pid==SILICOM_PE310G4BPi9SR_SSID)|| \ +(pid==SILICOM_PE310G4BPi9LR_SSID)|| \ +(pid==SILICOM_PE210G2BPI9T_SSID)) + +/*******************************************************/ +/* 1G INTERFACE ****************************************/ +/*******************************************************/ + +/* Intel Registers */ +#define BPCTLI_CTRL 0x00000 +#define BPCTLI_CTRL_SWDPIO0 0x00400000 +#define BPCTLI_CTRL_SWDPIN0 0x00040000 + +#define BPCTLI_CTRL_EXT 0x00018 /* Extended Device Control - RW */ +#define BPCTLI_STATUS 0x00008 /* Device Status - RO */ + +/* HW related */ +#define BPCTLI_CTRL_EXT_SDP6_DATA 0x00000040 /* Value of SW Defineable Pin 6 */ +#define BPCTLI_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Defineable Pin 7 */ +#define BPCTLI_CTRL_SDP0_DATA 0x00040000 /* SWDPIN 0 value */ +#define BPCTLI_CTRL_EXT_SDP6_DIR 0x00000400 /* Direction of SDP6 0=in 1=out */ +#define BPCTLI_CTRL_EXT_SDP7_DIR 0x00000800 /* Direction of SDP7 0=in 1=out */ +#define BPCTLI_CTRL_SDP0_DIR 0x00400000 /* SDP0 Input or output */ +#define BPCTLI_CTRL_SWDPIN1 0x00080000 +#define BPCTLI_CTRL_SDP1_DIR 0x00800000 + +#define BPCTLI_STATUS_LU 0x00000002 /* Link up.0=no,1=link */ + +#define BPCTLI_CTRL_SDP0_SHIFT 18 +#define BPCTLI_CTRL_EXT_SDP6_SHIFT 6 + +#define BPCTLI_STATUS_TBIMODE 0x00000020 +#define BPCTLI_CTRL_EXT_LINK_MODE_PCIE_SERDES 0x00C00000 +#define BPCTLI_CTRL_EXT_LINK_MODE_MASK 0x00C00000 + +#define BPCTLI_CTRL_EXT_MCLK_DIR BPCTLI_CTRL_EXT_SDP7_DIR +#define BPCTLI_CTRL_EXT_MCLK_DATA BPCTLI_CTRL_EXT_SDP7_DATA +#define BPCTLI_CTRL_EXT_MDIO_DIR BPCTLI_CTRL_EXT_SDP6_DIR +#define BPCTLI_CTRL_EXT_MDIO_DATA BPCTLI_CTRL_EXT_SDP6_DATA + +#define BPCTLI_CTRL_EXT_MCLK_DIR5 BPCTLI_CTRL_SDP1_DIR +#define BPCTLI_CTRL_EXT_MCLK_DATA5 BPCTLI_CTRL_SWDPIN1 +#define BPCTLI_CTRL_EXT_MCLK_DIR80 BPCTLI_CTRL_EXT_SDP6_DIR +#define BPCTLI_CTRL_EXT_MCLK_DATA80 BPCTLI_CTRL_EXT_SDP6_DATA +#define BPCTLI_CTRL_EXT_MDIO_DIR5 BPCTLI_CTRL_SWDPIO0 +#define BPCTLI_CTRL_EXT_MDIO_DATA5 BPCTLI_CTRL_SWDPIN0 +#define BPCTLI_CTRL_EXT_MDIO_DIR80 BPCTLI_CTRL_SWDPIO0 +#define BPCTLI_CTRL_EXT_MDIO_DATA80 BPCTLI_CTRL_SWDPIN0 + +#define BPCTL_WRITE_REG(a, reg, value) \ + (writel((value), (void *)(((a)->mem_map) + BPCTLI_##reg))) + +#define BPCTL_READ_REG(a, reg) ( \ + readl((void *)((a)->mem_map) + BPCTLI_##reg)) + +#define BPCTL_WRITE_FLUSH(a) BPCTL_READ_REG(a, STATUS) + +#define BPCTL_BP_WRITE_REG(a, reg, value) ({ \ + BPCTL_WRITE_REG(a, reg, value); \ + BPCTL_WRITE_FLUSH(a);}) + +/**************************************************************/ +/************** 82575 Interface********************************/ +/**************************************************************/ + +#define BPCTLI_MII_CR_POWER_DOWN 0x0800 +#define BPCTLI_PHY_CONTROL 0x00 /* Control Register */ +#define BPCTLI_MDIC 0x00020 /* MDI Control - RW */ +#define BPCTLI_IGP01E1000_PHY_PAGE_SELECT 0x1F /* Page Select */ +#define BPCTLI_MAX_PHY_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */ + +#define BPCTLI_MDIC_DATA_MASK 0x0000FFFF +#define BPCTLI_MDIC_REG_MASK 0x001F0000 +#define BPCTLI_MDIC_REG_SHIFT 16 +#define BPCTLI_MDIC_PHY_MASK 0x03E00000 +#define BPCTLI_MDIC_PHY_SHIFT 21 +#define BPCTLI_MDIC_OP_WRITE 0x04000000 +#define BPCTLI_MDIC_OP_READ 0x08000000 +#define BPCTLI_MDIC_READY 0x10000000 +#define BPCTLI_MDIC_INT_EN 0x20000000 +#define BPCTLI_MDIC_ERROR 0x40000000 + +#define BPCTLI_SWFW_PHY0_SM 0x02 +#define BPCTLI_SWFW_PHY1_SM 0x04 + +#define BPCTLI_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW */ + +#define BPCTLI_SWSM 0x05B50 /* SW Semaphore */ +#define BPCTLI_FWSM 0x05B54 /* FW Semaphore */ + +#define BPCTLI_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */ +#define BPCTLI_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */ +#define BPCTLI_MAX_PHY_MULTI_PAGE_REG 0xF +#define BPCTLI_GEN_POLL_TIMEOUT 640 + +/********************************************************/ + +/********************************************************/ +/* 10G INTERFACE ****************************************/ +/********************************************************/ + +#define BP10G_I2CCTL 0x28 + +/* I2CCTL Bit Masks */ +#define BP10G_I2C_CLK_IN 0x00000001 +#define BP10G_I2C_CLK_OUT 0x00000002 +#define BP10G_I2C_DATA_IN 0x00000004 +#define BP10G_I2C_DATA_OUT 0x00000008 + +#define BP10G_ESDP 0x20 + +#define BP10G_SDP0_DIR 0x100 +#define BP10G_SDP1_DIR 0x200 +#define BP10G_SDP3_DIR 0x800 +#define BP10G_SDP4_DIR BIT_12 +#define BP10G_SDP5_DIR 0x2000 +#define BP10G_SDP0_DATA 0x001 +#define BP10G_SDP1_DATA 0x002 +#define BP10G_SDP3_DATA 0x008 +#define BP10G_SDP4_DATA 0x010 +#define BP10G_SDP5_DATA 0x020 + +#define BP10G_SDP2_DIR 0x400 +#define BP10G_SDP2_DATA 0x4 + +#define BP10G_EODSDP 0x28 + +#define BP10G_SDP6_DATA_IN 0x001 +#define BP10G_SDP6_DATA_OUT 0x002 + +#define BP10G_SDP7_DATA_IN 0x004 +#define BP10G_SDP7_DATA_OUT 0x008 + +#define BP10G_MCLK_DATA_OUT BP10G_SDP7_DATA_OUT +#define BP10G_MDIO_DATA_OUT BP10G_SDP6_DATA_OUT +#define BP10G_MDIO_DATA_IN BP10G_SDP6_DATA_IN + +#define BP10G_MDIO_DATA /*BP10G_SDP5_DATA*/ BP10G_SDP3_DATA +#define BP10G_MDIO_DIR /*BP10G_SDP5_DIR*/ BP10G_SDP3_DATA + +/*#define BP10G_MCLK_DATA_OUT9 BP10G_I2C_CLK_OUT +#define BP10G_MDIO_DATA_OUT9 BP10G_I2C_DATA_OUT*/ + + /*#define BP10G_MCLK_DATA_OUT9*//*BP10G_I2C_DATA_OUT */ +#define BP10G_MDIO_DATA_OUT9 BP10G_I2C_DATA_OUT /*BP10G_I2C_CLK_OUT */ + +/* VIA EOSDP ! */ +#define BP10G_MCLK_DATA_OUT9 BP10G_SDP4_DATA +#define BP10G_MCLK_DIR_OUT9 BP10G_SDP4_DIR + +/*#define BP10G_MDIO_DATA_IN9 BP10G_I2C_DATA_IN*/ + +#define BP10G_MDIO_DATA_IN9 BP10G_I2C_DATA_IN /*BP10G_I2C_CLK_IN */ + +#define BP540_MDIO_DATA /*BP10G_SDP5_DATA*/ BP10G_SDP0_DATA +#define BP540_MDIO_DIR /*BP10G_SDP5_DIR*/ BP10G_SDP0_DIR +#define BP540_MCLK_DATA BP10G_SDP2_DATA +#define BP540_MCLK_DIR BP10G_SDP2_DIR + +#define BP10G_WRITE_REG(a, reg, value) \ + (writel((value), (void *)(((a)->mem_map) + BP10G_##reg))) + +#define BP10G_READ_REG(a, reg) ( \ + readl((void *)((a)->mem_map) + BP10G_##reg)) + +/*****BROADCOM*******************************************/ + +#define BP10GB_MISC_REG_GPIO 0xa490 +#define BP10GB_GPIO3_P0 BIT_3 +#define BP10GB_GPIO3_P1 BIT_7 + +#define BP10GB_GPIO3_SET_P0 BIT_11 +#define BP10GB_GPIO3_CLR_P0 BIT_19 +#define BP10GB_GPIO3_OE_P0 BIT_27 + +#define BP10GB_GPIO3_SET_P1 BIT_15 +#define BP10GB_GPIO3_CLR_P1 BIT_23 +#define BP10GB_GPIO3_OE_P1 BIT_31 + +#define BP10GB_GPIO0_P1 0x10 +#define BP10GB_GPIO0_P0 0x1 +#define BP10GB_GPIO0_CLR_P0 0x10000 +#define BP10GB_GPIO0_CLR_P1 0x100000 +#define BP10GB_GPIO0_SET_P0 0x100 +#define BP10GB_GPIO0_SET_P1 0x1000 + +#define BP10GB_GPIO0_OE_P1 0x10000000 +#define BP10GB_GPIO0_OE_P0 0x1000000 + +#define BP10GB_MISC_REG_SPIO 0xa4fc +#define BP10GB_GPIO4_OE BIT_28 +#define BP10GB_GPIO5_OE BIT_29 +#define BP10GB_GPIO4_CLR BIT_20 +#define BP10GB_GPIO5_CLR BIT_21 +#define BP10GB_GPIO4_SET BIT_12 +#define BP10GB_GPIO5_SET BIT_13 +#define BP10GB_GPIO4 BIT_4 +#define BP10GB_GPIO5 BIT_5 + +#define BP10GB_MCLK_DIR BP10GB_GPIO5_OE +#define BP10GB_MDIO_DIR BP10GB_GPIO4_OE + +#define BP10GB_MCLK_DATA BP10GB_GPIO5 +#define BP10GB_MDIO_DATA BP10GB_GPIO4 + +#define BP10GB_MCLK_SET BP10GB_GPIO5_SET +#define BP10GB_MDIO_SET BP10GB_GPIO4_SET + +#define BP10GB_MCLK_CLR BP10GB_GPIO5_CLR +#define BP10GB_MDIO_CLR BP10GB_GPIO4_CLR + +#define BP10GB_WRITE_REG(a, reg, value) \ + (writel((value), (void *)(((a)->mem_map) + BP10GB_##reg))) + +#define BP10GB_READ_REG(a, reg) ( \ + readl((void *)((a)->mem_map) + BP10GB_##reg)) + +#endif + +int bp_proc_create(void); diff --git a/drivers/staging/silicom/bp_proc.c b/drivers/staging/silicom/bp_proc.c new file mode 100644 index 0000000..4fe862d --- /dev/null +++ b/drivers/staging/silicom/bp_proc.c @@ -0,0 +1,1351 @@ +/******************************************************************************/ +/* */ +/* Copyright (c) 2004-2006 Silicom, Ltd */ +/* All rights reserved. */ +/* */ +/* This program is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation, located in the file LICENSE. */ +/* */ +/* */ +/******************************************************************************/ + +#include +#if defined(CONFIG_SMP) && ! defined(__SMP__) +#define __SMP__ +#endif + +#include +#include +#include +//#include +#include "bp_mod.h" + +#define BP_PROC_DIR "bypass" +//#define BYPASS_SUPPORT "bypass" + +#ifdef BYPASS_SUPPORT + +#define GPIO6_SET_ENTRY_SD "gpio6_set" +#define GPIO6_CLEAR_ENTRY_SD "gpio6_clear" + +#define GPIO7_SET_ENTRY_SD "gpio7_set" +#define GPIO7_CLEAR_ENTRY_SD "gpio7_clear" + +#define PULSE_SET_ENTRY_SD "pulse_set" +#define ZERO_SET_ENTRY_SD "zero_set" +#define PULSE_GET1_ENTRY_SD "pulse_get1" +#define PULSE_GET2_ENTRY_SD "pulse_get2" + +#define CMND_ON_ENTRY_SD "cmnd_on" +#define CMND_OFF_ENTRY_SD "cmnd_off" +#define RESET_CONT_ENTRY_SD "reset_cont" + + /*COMMANDS*/ +#define BYPASS_INFO_ENTRY_SD "bypass_info" +#define BYPASS_SLAVE_ENTRY_SD "bypass_slave" +#define BYPASS_CAPS_ENTRY_SD "bypass_caps" +#define WD_SET_CAPS_ENTRY_SD "wd_set_caps" +#define BYPASS_ENTRY_SD "bypass" +#define BYPASS_CHANGE_ENTRY_SD "bypass_change" +#define BYPASS_WD_ENTRY_SD "bypass_wd" +#define WD_EXPIRE_TIME_ENTRY_SD "wd_expire_time" +#define RESET_BYPASS_WD_ENTRY_SD "reset_bypass_wd" +#define DIS_BYPASS_ENTRY_SD "dis_bypass" +#define BYPASS_PWUP_ENTRY_SD "bypass_pwup" +#define BYPASS_PWOFF_ENTRY_SD "bypass_pwoff" +#define STD_NIC_ENTRY_SD "std_nic" +#define STD_NIC_ENTRY_SD "std_nic" +#define TAP_ENTRY_SD "tap" +#define TAP_CHANGE_ENTRY_SD "tap_change" +#define DIS_TAP_ENTRY_SD "dis_tap" +#define TAP_PWUP_ENTRY_SD "tap_pwup" +#define TWO_PORT_LINK_ENTRY_SD "two_port_link" +#define WD_EXP_MODE_ENTRY_SD "wd_exp_mode" +#define WD_AUTORESET_ENTRY_SD "wd_autoreset" +#define TPL_ENTRY_SD "tpl" +#define WAIT_AT_PWUP_ENTRY_SD "wait_at_pwup" +#define HW_RESET_ENTRY_SD "hw_reset" +#define DISC_ENTRY_SD "disc" +#define DISC_CHANGE_ENTRY_SD "disc_change" +#define DIS_DISC_ENTRY_SD "dis_disc" +#define DISC_PWUP_ENTRY_SD "disc_pwup" +#endif //bypass_support +static struct proc_dir_entry *bp_procfs_dir; + +static struct proc_dir_entry *proc_getdir(char *name, + struct proc_dir_entry *proc_dir) +{ + struct proc_dir_entry *pde = proc_dir; + for (pde = pde->subdir; pde; pde = pde->next) { + if (pde->namelen && (strcmp(name, pde->name) == 0)) { + /* directory exists */ + break; + } + } + if (pde == (struct proc_dir_entry *)0) { + /* create the directory */ + pde = create_proc_entry(name, S_IFDIR, proc_dir); + if (pde == (struct proc_dir_entry *)0) { + return (pde); + } + } + return (pde); +} + +#ifdef BYPASS_SUPPORT + +int +bypass_proc_create_entry_sd(struct pfs_unit *pfs_unit_curr, + char *proc_name, + write_proc_t * write_proc, + read_proc_t * read_proc, + struct proc_dir_entry *parent_pfs, void *data) +{ + strcpy(pfs_unit_curr->proc_name, proc_name); + pfs_unit_curr->proc_entry = create_proc_entry(pfs_unit_curr->proc_name, + S_IFREG | S_IRUSR | + S_IWUSR | S_IRGRP | + S_IWGRP | S_IROTH | + S_IWOTH, parent_pfs); + if (pfs_unit_curr->proc_entry == 0) { + + return -1; + } + + pfs_unit_curr->proc_entry->read_proc = read_proc; + pfs_unit_curr->proc_entry->write_proc = write_proc; + pfs_unit_curr->proc_entry->data = data; + + return 0; + +} + +int +get_bypass_info_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + int len = 0; + + len += sprintf(page, "Name\t\t\t%s\n", pbp_device_block->bp_name); + len += + sprintf(page + len, "Firmware version\t0x%x\n", + pbp_device_block->bp_fw_ver); + + *eof = 1; + return len; +} + +int +get_bypass_slave_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + struct pci_dev *pci_slave_dev = pbp_device_block->bp_slave; + struct net_device *net_slave_dev; + int len = 0; + + if (is_bypass_fn(pbp_device_block)) { + net_slave_dev = pci_get_drvdata(pci_slave_dev); + if (net_slave_dev) + len = sprintf(page, "%s\n", net_slave_dev->name); + else + len = sprintf(page, "fail\n"); + } else + len = sprintf(page, "fail\n"); + + *eof = 1; + return len; +} + +int +get_bypass_caps_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_bypass_caps_fn(pbp_device_block); + if (ret == BP_NOT_CAP) + len = sprintf(page, "-1\n"); + else + len = sprintf(page, "0x%x\n", ret); + *eof = 1; + return len; + +} + +int +get_wd_set_caps_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_wd_set_caps_fn(pbp_device_block); + if (ret == BP_NOT_CAP) + len = sprintf(page, "-1\n"); + else + len = sprintf(page, "0x%x\n", ret); + *eof = 1; + return len; +} + +int +set_bypass_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int bypass_param = 0, length = 0; + + if (count > (sizeof(kbuf) - 1)) + return -1; + + if (copy_from_user(&kbuf, buffer, count)) { + return -1; + } + + kbuf[count] = '\0'; + length = strlen(kbuf); + if (kbuf[length - 1] == '\n') + kbuf[--length] = '\0'; + + if (strcmp(kbuf, "on") == 0) + bypass_param = 1; + else if (strcmp(kbuf, "off") == 0) + bypass_param = 0; + + set_bypass_fn(pbp_device_block, bypass_param); + + return count; +} + +int +set_tap_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int tap_param = 0, length = 0; + + if (count > (sizeof(kbuf) - 1)) + return -1; + + if (copy_from_user(&kbuf, buffer, count)) { + return -1; + } + + kbuf[count] = '\0'; + length = strlen(kbuf); + if (kbuf[length - 1] == '\n') + kbuf[--length] = '\0'; + + if (strcmp(kbuf, "on") == 0) + tap_param = 1; + else if (strcmp(kbuf, "off") == 0) + tap_param = 0; + + set_tap_fn(pbp_device_block, tap_param); + + return count; +} + +int +set_disc_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int tap_param = 0, length = 0; + + if (count > (sizeof(kbuf) - 1)) + return -1; + + if (copy_from_user(&kbuf, buffer, count)) { + return -1; + } + + kbuf[count] = '\0'; + length = strlen(kbuf); + if (kbuf[length - 1] == '\n') + kbuf[--length] = '\0'; + + if (strcmp(kbuf, "on") == 0) + tap_param = 1; + else if (strcmp(kbuf, "off") == 0) + tap_param = 0; + + set_disc_fn(pbp_device_block, tap_param); + + return count; +} + +int +get_bypass_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_bypass_fn(pbp_device_block); + if (ret == BP_NOT_CAP) + len = sprintf(page, "fail\n"); + else if (ret == 1) + len = sprintf(page, "on\n"); + else if (ret == 0) + len = sprintf(page, "off\n"); + + *eof = 1; + return len; +} + +int +get_tap_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_tap_fn(pbp_device_block); + if (ret == BP_NOT_CAP) + len = sprintf(page, "fail\n"); + else if (ret == 1) + len = sprintf(page, "on\n"); + else if (ret == 0) + len = sprintf(page, "off\n"); + + *eof = 1; + return len; +} + +int +get_disc_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_disc_fn(pbp_device_block); + if (ret == BP_NOT_CAP) + len = sprintf(page, "fail\n"); + else if (ret == 1) + len = sprintf(page, "on\n"); + else if (ret == 0) + len = sprintf(page, "off\n"); + + *eof = 1; + return len; +} + +int +get_bypass_change_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_bypass_change_fn(pbp_device_block); + if (ret == 1) + len = sprintf(page, "on\n"); + else if (ret == 0) + len = sprintf(page, "off\n"); + else + len = sprintf(page, "fail\n"); + + *eof = 1; + return len; +} + +int +get_tap_change_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_tap_change_fn(pbp_device_block); + if (ret == 1) + len = sprintf(page, "on\n"); + else if (ret == 0) + len = sprintf(page, "off\n"); + else + len = sprintf(page, "fail\n"); + + *eof = 1; + return len; +} + +int +get_disc_change_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_disc_change_fn(pbp_device_block); + if (ret == 1) + len = sprintf(page, "on\n"); + else if (ret == 0) + len = sprintf(page, "off\n"); + else + len = sprintf(page, "fail\n"); + + *eof = 1; + return len; +} + +int +set_bypass_wd_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + unsigned int timeout = 0; + char *timeout_ptr = kbuf; + + if (copy_from_user(&kbuf, buffer, count)) { + return -1; + } + + timeout_ptr = kbuf; + timeout = atoi(&timeout_ptr); + + set_bypass_wd_fn(pbp_device_block, timeout); + + return count; +} + +int +get_bypass_wd_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0, timeout = 0; + + ret = get_bypass_wd_fn(pbp_device_block, &timeout); + if (ret == BP_NOT_CAP) + len = sprintf(page, "fail\n"); + else if (timeout == -1) + len = sprintf(page, "unknown\n"); + else if (timeout == 0) + len = sprintf(page, "disable\n"); + else + len = sprintf(page, "%d\n", timeout); + + *eof = 1; + return len; +} + +int +get_wd_expire_time_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0, timeout = 0; + + ret = get_wd_expire_time_fn(pbp_device_block, &timeout); + if (ret == BP_NOT_CAP) + len = sprintf(page, "fail\n"); + else if (timeout == -1) + len = sprintf(page, "expire\n"); + else if (timeout == 0) + len = sprintf(page, "disable\n"); + + else + len = sprintf(page, "%d\n", timeout); + *eof = 1; + return len; +} + +int +get_tpl_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_tpl_fn(pbp_device_block); + if (ret == BP_NOT_CAP) + len = sprintf(page, "fail\n"); + else if (ret == 1) + len = sprintf(page, "on\n"); + else if (ret == 0) + len = sprintf(page, "off\n"); + + *eof = 1; + return len; +} + +#ifdef PMC_FIX_FLAG +int +get_wait_at_pwup_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_bp_wait_at_pwup_fn(pbp_device_block); + if (ret == BP_NOT_CAP) + len = sprintf(page, "fail\n"); + else if (ret == 1) + len = sprintf(page, "on\n"); + else if (ret == 0) + len = sprintf(page, "off\n"); + + *eof = 1; + return len; +} + +int +get_hw_reset_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_bp_hw_reset_fn(pbp_device_block); + if (ret == BP_NOT_CAP) + len = sprintf(page, "fail\n"); + else if (ret == 1) + len = sprintf(page, "on\n"); + else if (ret == 0) + len = sprintf(page, "off\n"); + + *eof = 1; + return len; +} + +#endif /*PMC_WAIT_FLAG */ + +int +reset_bypass_wd_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = reset_bypass_wd_timer_fn(pbp_device_block); + if (ret == BP_NOT_CAP) + len = sprintf(page, "fail\n"); + else if (ret == 0) + len = sprintf(page, "disable\n"); + else if (ret == 1) + len = sprintf(page, "success\n"); + + *eof = 1; + return len; +} + +int +set_dis_bypass_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int bypass_param = 0, length = 0; + + if (copy_from_user(&kbuf, buffer, count)) { + return -1; + } + + kbuf[count] = '\0'; + length = strlen(kbuf); + if (kbuf[length - 1] == '\n') + kbuf[--length] = '\0'; + + if (strcmp(kbuf, "on") == 0) + bypass_param = 1; + else if (strcmp(kbuf, "off") == 0) + bypass_param = 0; + + set_dis_bypass_fn(pbp_device_block, bypass_param); + + return count; +} + +int +set_dis_tap_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int tap_param = 0, length = 0; + + if (copy_from_user(&kbuf, buffer, count)) { + return -1; + } + + kbuf[count] = '\0'; + length = strlen(kbuf); + if (kbuf[length - 1] == '\n') + kbuf[--length] = '\0'; + + if (strcmp(kbuf, "on") == 0) + tap_param = 1; + else if (strcmp(kbuf, "off") == 0) + tap_param = 0; + + set_dis_tap_fn(pbp_device_block, tap_param); + + return count; +} + +int +set_dis_disc_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int tap_param = 0, length = 0; + + if (copy_from_user(&kbuf, buffer, count)) { + return -1; + } + + kbuf[count] = '\0'; + length = strlen(kbuf); + if (kbuf[length - 1] == '\n') + kbuf[--length] = '\0'; + + if (strcmp(kbuf, "on") == 0) + tap_param = 1; + else if (strcmp(kbuf, "off") == 0) + tap_param = 0; + + set_dis_disc_fn(pbp_device_block, tap_param); + + return count; +} + +int +get_dis_bypass_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_dis_bypass_fn(pbp_device_block); + if (ret == BP_NOT_CAP) + len = sprintf(page, "fail\n"); + else if (ret == 0) + len = sprintf(page, "off\n"); + else + len = sprintf(page, "on\n"); + + *eof = 1; + return len; +} + +int +get_dis_tap_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_dis_tap_fn(pbp_device_block); + if (ret == BP_NOT_CAP) + len = sprintf(page, "fail\n"); + else if (ret == 0) + len = sprintf(page, "off\n"); + else + len = sprintf(page, "on\n"); + + *eof = 1; + return len; +} + +int +get_dis_disc_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_dis_disc_fn(pbp_device_block); + if (ret == BP_NOT_CAP) + len = sprintf(page, "fail\n"); + else if (ret == 0) + len = sprintf(page, "off\n"); + else + len = sprintf(page, "on\n"); + + *eof = 1; + return len; +} + +int +set_bypass_pwup_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int bypass_param = 0, length = 0; + + if (copy_from_user(&kbuf, buffer, count)) { + return -1; + } + + kbuf[count] = '\0'; + length = strlen(kbuf); + if (kbuf[length - 1] == '\n') + kbuf[--length] = '\0'; + + if (strcmp(kbuf, "on") == 0) + bypass_param = 1; + else if (strcmp(kbuf, "off") == 0) + bypass_param = 0; + + set_bypass_pwup_fn(pbp_device_block, bypass_param); + + return count; +} + +int +set_bypass_pwoff_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int bypass_param = 0, length = 0; + + if (copy_from_user(&kbuf, buffer, count)) { + return -1; + } + + kbuf[count] = '\0'; + length = strlen(kbuf); + if (kbuf[length - 1] == '\n') + kbuf[--length] = '\0'; + + if (strcmp(kbuf, "on") == 0) + bypass_param = 1; + else if (strcmp(kbuf, "off") == 0) + bypass_param = 0; + + set_bypass_pwoff_fn(pbp_device_block, bypass_param); + + return count; +} + +int +set_tap_pwup_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int tap_param = 0, length = 0; + + if (copy_from_user(&kbuf, buffer, count)) { + return -1; + } + + kbuf[count] = '\0'; + length = strlen(kbuf); + if (kbuf[length - 1] == '\n') + kbuf[--length] = '\0'; + + if (strcmp(kbuf, "on") == 0) + tap_param = 1; + else if (strcmp(kbuf, "off") == 0) + tap_param = 0; + + set_tap_pwup_fn(pbp_device_block, tap_param); + + return count; +} + +int +set_disc_pwup_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int tap_param = 0, length = 0; + + if (copy_from_user(&kbuf, buffer, count)) { + return -1; + } + + kbuf[count] = '\0'; + length = strlen(kbuf); + if (kbuf[length - 1] == '\n') + kbuf[--length] = '\0'; + + if (strcmp(kbuf, "on") == 0) + tap_param = 1; + else if (strcmp(kbuf, "off") == 0) + tap_param = 0; + + set_disc_pwup_fn(pbp_device_block, tap_param); + + return count; +} + +int +get_bypass_pwup_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_bypass_pwup_fn(pbp_device_block); + if (ret == BP_NOT_CAP) + len = sprintf(page, "fail\n"); + else if (ret == 0) + len = sprintf(page, "off\n"); + else + len = sprintf(page, "on\n"); + + *eof = 1; + return len; +} + +int +get_bypass_pwoff_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_bypass_pwoff_fn(pbp_device_block); + if (ret == BP_NOT_CAP) + len = sprintf(page, "fail\n"); + else if (ret == 0) + len = sprintf(page, "off\n"); + else + len = sprintf(page, "on\n"); + + *eof = 1; + return len; +} + +int +get_tap_pwup_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_tap_pwup_fn(pbp_device_block); + if (ret == BP_NOT_CAP) + len = sprintf(page, "fail\n"); + else if (ret == 0) + len = sprintf(page, "off\n"); + else + len = sprintf(page, "on\n"); + + *eof = 1; + return len; +} + +int +get_disc_pwup_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_disc_pwup_fn(pbp_device_block); + if (ret == BP_NOT_CAP) + len = sprintf(page, "fail\n"); + else if (ret == 0) + len = sprintf(page, "off\n"); + else + len = sprintf(page, "on\n"); + + *eof = 1; + return len; +} + +int +set_std_nic_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int bypass_param = 0, length = 0; + + if (copy_from_user(&kbuf, buffer, count)) { + return -1; + } + + kbuf[count] = '\0'; + length = strlen(kbuf); + if (kbuf[length - 1] == '\n') + kbuf[--length] = '\0'; + + if (strcmp(kbuf, "on") == 0) + bypass_param = 1; + else if (strcmp(kbuf, "off") == 0) + bypass_param = 0; + + set_std_nic_fn(pbp_device_block, bypass_param); + + return count; +} + +int +get_std_nic_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_std_nic_fn(pbp_device_block); + if (ret == BP_NOT_CAP) + len = sprintf(page, "fail\n"); + else if (ret == 0) + len = sprintf(page, "off\n"); + else + len = sprintf(page, "on\n"); + + *eof = 1; + return len; +} + +int +get_wd_exp_mode_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_wd_exp_mode_fn(pbp_device_block); + if (ret == 1) + len = sprintf(page, "tap\n"); + else if (ret == 0) + len = sprintf(page, "bypass\n"); + else if (ret == 2) + len = sprintf(page, "disc\n"); + + else + len = sprintf(page, "fail\n"); + + *eof = 1; + return len; +} + +int +set_wd_exp_mode_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int bypass_param = 0, length = 0; + + if (count > (sizeof(kbuf) - 1)) + return -1; + + if (copy_from_user(&kbuf, buffer, count)) { + return -1; + } + + kbuf[count] = '\0'; + length = strlen(kbuf); + if (kbuf[length - 1] == '\n') + kbuf[--length] = '\0'; + + if (strcmp(kbuf, "tap") == 0) + bypass_param = 1; + else if (strcmp(kbuf, "bypass") == 0) + bypass_param = 0; + else if (strcmp(kbuf, "disc") == 0) + bypass_param = 2; + + set_wd_exp_mode_fn(pbp_device_block, bypass_param); + + return count; +} + +int +get_wd_autoreset_pfs(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int len = 0, ret = 0; + + ret = get_wd_autoreset_fn(pbp_device_block); + if (ret >= 0) + len = sprintf(page, "%d\n", ret); + else + len = sprintf(page, "fail\n"); + + *eof = 1; + return len; +} + +int +set_wd_autoreset_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + char kbuf[256]; + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + u32 timeout = 0; + char *timeout_ptr = kbuf; + + if (copy_from_user(&kbuf, buffer, count)) { + return -1; + } + + timeout_ptr = kbuf; + timeout = atoi(&timeout_ptr); + + set_wd_autoreset_fn(pbp_device_block, timeout); + + return count; +} + +int +set_tpl_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int tpl_param = 0, length = 0; + + if (count > (sizeof(kbuf) - 1)) + return -1; + + if (copy_from_user(&kbuf, buffer, count)) { + return -1; + } + + kbuf[count] = '\0'; + length = strlen(kbuf); + if (kbuf[length - 1] == '\n') + kbuf[--length] = '\0'; + + if (strcmp(kbuf, "on") == 0) + tpl_param = 1; + else if (strcmp(kbuf, "off") == 0) + tpl_param = 0; + + set_tpl_fn(pbp_device_block, tpl_param); + + return count; +} + +#ifdef PMC_FIX_FLAG +int +set_wait_at_pwup_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int tpl_param = 0, length = 0; + + if (count > (sizeof(kbuf) - 1)) + return -1; + + if (copy_from_user(&kbuf, buffer, count)) { + return -1; + } + + kbuf[count] = '\0'; + length = strlen(kbuf); + if (kbuf[length - 1] == '\n') + kbuf[--length] = '\0'; + + if (strcmp(kbuf, "on") == 0) + tpl_param = 1; + else if (strcmp(kbuf, "off") == 0) + tpl_param = 0; + + set_bp_wait_at_pwup_fn(pbp_device_block, tpl_param); + + return count; +} + +int +set_hw_reset_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + + int tpl_param = 0, length = 0; + + if (count > (sizeof(kbuf) - 1)) + return -1; + + if (copy_from_user(&kbuf, buffer, count)) { + return -1; + } + + kbuf[count] = '\0'; + length = strlen(kbuf); + if (kbuf[length - 1] == '\n') + kbuf[--length] = '\0'; + + if (strcmp(kbuf, "on") == 0) + tpl_param = 1; + else if (strcmp(kbuf, "off") == 0) + tpl_param = 0; + + set_bp_hw_reset_fn(pbp_device_block, tpl_param); + + return count; +} + +#endif /*PMC_FIX_FLAG */ + +int bypass_proc_create_dev_sd(bpctl_dev_t * pbp_device_block) +{ + struct bypass_pfs_sd *current_pfs = &(pbp_device_block->bypass_pfs_set); + static struct proc_dir_entry *procfs_dir = NULL; + int ret = 0; + + sprintf(current_pfs->dir_name, "bypass_%s", dev->name); + + if (!bp_procfs_dir) + return -1; + + /* create device proc dir */ + procfs_dir = proc_getdir(current_pfs->dir_name, bp_procfs_dir); + if (procfs_dir == 0) { + printk(KERN_DEBUG "Could not create procfs directory %s\n", + current_pfs->dir_name); + return -1; + } + current_pfs->bypass_entry = procfs_dir; + + if (bypass_proc_create_entry(&(current_pfs->bypass_info), BYPASS_INFO_ENTRY_SD, NULL, /* write */ + get_bypass_info_pfs, /* read */ + procfs_dir, pbp_device_block)) + ret = -1; + + if (pbp_device_block->bp_caps & SW_CTL_CAP) { + + /* Create set param proc's */ + if (bypass_proc_create_entry_sd(&(current_pfs->bypass_slave), BYPASS_SLAVE_ENTRY_SD, NULL, /* write */ + get_bypass_slave_pfs, /* read */ + procfs_dir, pbp_device_block)) + ret = -1; + + if (bypass_proc_create_entry_sd(&(current_pfs->bypass_caps), BYPASS_CAPS_ENTRY_SD, NULL, /* write */ + get_bypass_caps_pfs, /* read */ + procfs_dir, pbp_device_block)) + ret = -1; + + if (bypass_proc_create_entry_sd(&(current_pfs->wd_set_caps), WD_SET_CAPS_ENTRY_SD, NULL, /* write */ + get_wd_set_caps_pfs, /* read */ + procfs_dir, pbp_device_block)) + ret = -1; + if (bypass_proc_create_entry_sd(&(current_pfs->bypass_wd), BYPASS_WD_ENTRY_SD, set_bypass_wd_pfs, /* write */ + get_bypass_wd_pfs, /* read */ + procfs_dir, pbp_device_block)) + ret = -1; + + if (bypass_proc_create_entry_sd(&(current_pfs->wd_expire_time), WD_EXPIRE_TIME_ENTRY_SD, NULL, /* write */ + get_wd_expire_time_pfs, /* read */ + procfs_dir, pbp_device_block)) + ret = -1; + + if (bypass_proc_create_entry_sd(&(current_pfs->reset_bypass_wd), RESET_BYPASS_WD_ENTRY_SD, NULL, /* write */ + reset_bypass_wd_pfs, /* read */ + procfs_dir, pbp_device_block)) + ret = -1; + + if (bypass_proc_create_entry_sd(&(current_pfs->std_nic), STD_NIC_ENTRY_SD, set_std_nic_pfs, /* write */ + get_std_nic_pfs, /* read */ + procfs_dir, pbp_device_block)) + ret = -1; + + if (pbp_device_block->bp_caps & BP_CAP) { + if (bypass_proc_create_entry_sd(&(current_pfs->bypass), BYPASS_ENTRY_SD, set_bypass_pfs, /* write */ + get_bypass_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret = -1; + + if (bypass_proc_create_entry_sd(&(current_pfs->dis_bypass), DIS_BYPASS_ENTRY_SD, set_dis_bypass_pfs, /* write */ + get_dis_bypass_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret = -1; + + if (bypass_proc_create_entry_sd(&(current_pfs->bypass_pwup), BYPASS_PWUP_ENTRY_SD, set_bypass_pwup_pfs, /* write */ + get_bypass_pwup_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret = -1; + if (bypass_proc_create_entry_sd(&(current_pfs->bypass_pwoff), BYPASS_PWOFF_ENTRY_SD, set_bypass_pwoff_pfs, /* write */ + get_bypass_pwoff_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret = -1; + + if (bypass_proc_create_entry_sd(&(current_pfs->bypass_change), BYPASS_CHANGE_ENTRY_SD, NULL, /* write */ + get_bypass_change_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret = -1; + } + + if (pbp_device_block->bp_caps & TAP_CAP) { + + if (bypass_proc_create_entry_sd(&(current_pfs->tap), TAP_ENTRY_SD, set_tap_pfs, /* write */ + get_tap_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret = -1; + + if (bypass_proc_create_entry_sd(&(current_pfs->dis_tap), DIS_TAP_ENTRY_SD, set_dis_tap_pfs, /* write */ + get_dis_tap_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret = -1; + + if (bypass_proc_create_entry_sd(&(current_pfs->tap_pwup), TAP_PWUP_ENTRY_SD, set_tap_pwup_pfs, /* write */ + get_tap_pwup_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret = -1; + + if (bypass_proc_create_entry_sd(&(current_pfs->tap_change), TAP_CHANGE_ENTRY_SD, NULL, /* write */ + get_tap_change_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret = -1; + } + if (pbp_device_block->bp_caps & DISC_CAP) { + + if (bypass_proc_create_entry_sd(&(current_pfs->tap), DISC_ENTRY_SD, set_disc_pfs, /* write */ + get_disc_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret = -1; +#if 1 + + if (bypass_proc_create_entry_sd(&(current_pfs->dis_tap), DIS_DISC_ENTRY_SD, set_dis_disc_pfs, /* write */ + get_dis_disc_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret = -1; +#endif + + if (bypass_proc_create_entry_sd(&(current_pfs->tap_pwup), DISC_PWUP_ENTRY_SD, set_disc_pwup_pfs, /* write */ + get_disc_pwup_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret = -1; + + if (bypass_proc_create_entry_sd(&(current_pfs->tap_change), DISC_CHANGE_ENTRY_SD, NULL, /* write */ + get_disc_change_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret = -1; + } + + if (bypass_proc_create_entry_sd(&(current_pfs->wd_exp_mode), WD_EXP_MODE_ENTRY_SD, set_wd_exp_mode_pfs, /* write */ + get_wd_exp_mode_pfs, /* read */ + procfs_dir, pbp_device_block)) + ret = -1; + + if (bypass_proc_create_entry_sd(&(current_pfs->wd_autoreset), WD_AUTORESET_ENTRY_SD, set_wd_autoreset_pfs, /* write */ + get_wd_autoreset_pfs, /* read */ + procfs_dir, pbp_device_block)) + ret = -1; + if (bypass_proc_create_entry_sd(&(current_pfs->tpl), TPL_ENTRY_SD, set_tpl_pfs, /* write */ + get_tpl_pfs, /* read */ + procfs_dir, pbp_device_block)) + ret = -1; +#ifdef PMC_FIX_FLAG + if (bypass_proc_create_entry_sd(&(current_pfs->tpl), WAIT_AT_PWUP_ENTRY_SD, set_wait_at_pwup_pfs, /* write */ + get_wait_at_pwup_pfs, /* read */ + procfs_dir, pbp_device_block)) + ret = -1; + if (bypass_proc_create_entry_sd(&(current_pfs->tpl), HW_RESET_ENTRY_SD, set_hw_reset_pfs, /* write */ + get_hw_reset_pfs, /* read */ + procfs_dir, pbp_device_block)) + ret = -1; + +#endif + + } + if (ret < 0) + printk(KERN_DEBUG "Create proc entry failed\n"); + + return ret; +} + +int bypass_proc_remove_dev_sd(bpctl_dev_t * pbp_device_block) +{ + + struct bypass_pfs_sd *current_pfs = &pbp_device_block->bypass_pfs_set; + struct proc_dir_entry *pde = current_pfs->bypass_entry, *pde_curr = + NULL; + char name[256]; + + for (pde = pde->subdir; pde;) { + strcpy(name, pde->name); + pde_curr = pde; + pde = pde->next; + remove_proc_entry(name, current_pfs->bypass_entry); + } + if (!pde) + remove_proc_entry(current_pfs->dir_name, bp_procfs_dir); + + return 0; +} + +#endif /* BYPASS_SUPPORT */ diff --git a/drivers/staging/silicom/bypass.h b/drivers/staging/silicom/bypass.h new file mode 100644 index 0000000..a1ac3b3 --- /dev/null +++ b/drivers/staging/silicom/bypass.h @@ -0,0 +1,202 @@ +/******************************************************************************/ +/* */ +/* Bypass Control utility, Copyright (c) 2005 Silicom */ +/* All rights reserved. */ +/* */ +/* This program is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation, located in the file LICENSE. */ +/* */ +/* */ +/******************************************************************************/ + +#ifndef BYPASS_H +#define BYPASS_H + +/* Bypass related */ + +#define SYNC_CMD_VAL 2 /* 10b */ +#define SYNC_CMD_LEN 2 + +#define WR_CMD_VAL 2 /* 10b */ +#define WR_CMD_LEN 2 + +#define RD_CMD_VAL 1 /* 10b */ +#define RD_CMD_LEN 2 + +#define ADDR_CMD_LEN 4 + +#define WR_DATA_LEN 8 +#define RD_DATA_LEN 8 + +#define PIC_SIGN_REG_ADDR 0x7 +#define PIC_SIGN_VALUE 0xcd + +#define STATUS_REG_ADDR 0 +#define WDT_EN_MASK 0x01 //BIT_0 +#define CMND_EN_MASK 0x02 //BIT_1 +#define DIS_BYPASS_CAP_MASK 0x04 //BIT_2 /* Bypass Cap is disable*/ +#define DFLT_PWRON_MASK 0x08 //BIT_3 +#define BYPASS_OFF_MASK 0x10 //BIT_4 +#define BYPASS_FLAG_MASK 0x20 //BIT_5 +#define STD_NIC_MASK (DIS_BYPASS_CAP_MASK | BYPASS_OFF_MASK | DFLT_PWRON_MASK) +#define WD_EXP_FLAG_MASK 0x40 //BIT_6 +#define DFLT_PWROFF_MASK 0x80 //BIT_7 +#define STD_NIC_PWOFF_MASK (DIS_BYPASS_CAP_MASK | BYPASS_OFF_MASK | DFLT_PWRON_MASK | DFLT_PWROFF_MASK) + +#define PRODUCT_CAP_REG_ADDR 0x5 +#define BYPASS_SUPPORT_MASK 0x01 //BIT_0 +#define TAP_SUPPORT_MASK 0x02 //BIT_1 +#define NORMAL_UNSUPPORT_MASK 0x04 /*BIT_2 */ +#define DISC_SUPPORT_MASK 0x08 //BIT_3 +#define TPL2_SUPPORT_MASK 0x10 //BIT_4 +#define DISC_PORT_SUPPORT_MASK 0x20 //BIT_5 + +#define STATUS_TAP_REG_ADDR 0x6 +#define WDTE_TAP_BPN_MASK 0x01 //BIT_1 /* 1 when wdt expired -> TAP, 0 - Bypass */ +#define DIS_TAP_CAP_MASK 0x04 //BIT_2 /* TAP Cap is disable*/ +#define DFLT_PWRON_TAP_MASK 0x08 //BIT_3 +#define TAP_OFF_MASK 0x10 //BIT_4 +#define TAP_FLAG_MASK 0x20 //BIT_5 +#define TX_DISA_MASK 0x40 +#define TX_DISB_MASK 0x80 + +#define STD_NIC_TAP_MASK (DIS_TAP_CAP_MASK | TAP_OFF_MASK | DFLT_PWRON_TAP_MASK) + +#define STATUS_DISC_REG_ADDR 13 +#define WDTE_DISC_BPN_MASK 0x01 //BIT_0 /* 1 when wdt expired -> TAP, 0 - Bypass */ +#define STD_NIC_ON_MASK 0x02 //BIT_1 +#define DIS_DISC_CAP_MASK 0x04 //BIT_2 /* TAP Cap is disable*/ +#define DFLT_PWRON_DISC_MASK 0x08 //BIT_3 +#define DISC_OFF_MASK 0x10 //BIT_4 +#define DISC_FLAG_MASK 0x20 //BIT_5 +#define TPL2_FLAG_MASK 0x40 //BIT_6 +#define STD_NIC_DISC_MASK DIS_DISC_CAP_MASK + +#define CONT_CONFIG_REG_ADDR 12 +#define EN_HW_RESET_MASK 0x2 /* BIT_1 */ +#define WAIT_AT_PWUP_MASK 0x1 /* BIT_0 */ + +#define VER_REG_ADDR 0x1 +#define BP_FW_VER_A0 0xa0 +#define BP_FW_VER_A1 0xa1 + +#define INT_VER_MASK 0xf0 +#define EXT_VER_MASK 0xf +/* */ +#define PXG2BPI_VER 0x0 +#define PXG2TBPI_VER 0x1 +#define PXE2TBPI_VER 0x2 +#define PXG4BPFI_VER 0x4 +#define BP_FW_EXT_VER7 0x6 +#define BP_FW_EXT_VER8 0x8 +#define BP_FW_EXT_VER9 0x9 + +#define OLD_IF_VER -1 + +#define CMND_REG_ADDR 10 /* 1010b */ +#define WDT_REG_ADDR 4 +#define TMRL_REG_ADDR 2 +#define TMRH_REG_ADDR 3 + +/* NEW_FW */ +#define WDT_INTERVAL 1 //5 //8 +#define WDT_CMND_INTERVAL 200 //50 +#define CMND_INTERVAL 200 //100 /* usec */ +#define PULSE_TIME 100 + +/* OLD_FW */ +#define INIT_CMND_INTERVAL 40 +#define PULSE_INTERVAL 5 +#define WDT_TIME_CNT 3 + +/* Intel Commands */ + +#define CMND_OFF_INT 0xf +#define PWROFF_BYPASS_ON_INT 0x5 +#define BYPASS_ON_INT 0x6 +#define DIS_BYPASS_CAP_INT 0x4 +#define RESET_WDT_INT 0x1 + +/* Intel timing */ + +#define BYPASS_DELAY_INT 4 /* msec */ +#define CMND_INTERVAL_INT 2 /* msec */ + +/* Silicom Commands */ +#define CMND_ON 0x4 +#define CMND_OFF 0x2 +#define BYPASS_ON 0xa +#define BYPASS_OFF 0x8 +#define PORT_LINK_EN 0xe +#define PORT_LINK_DIS 0xc +#define WDT_ON 0x10 /* 0x1f (11111) - max */ +#define TIMEOUT_UNIT 100 +#define TIMEOUT_MAX_STEP 15 +#define WDT_TIMEOUT_MIN 100 /* msec */ +#define WDT_TIMEOUT_MAX 3276800 /* msec */ +#define WDT_AUTO_MIN_INT 500 +#define WDT_TIMEOUT_DEF WDT_TIMEOUT_MIN +#define WDT_OFF 0x6 +#define WDT_RELOAD 0x9 +#define RESET_CONT 0x20 +#define DIS_BYPASS_CAP 0x22 +#define EN_BYPASS_CAP 0x24 +#define BYPASS_STATE_PWRON 0x26 +#define NORMAL_STATE_PWRON 0x28 +#define BYPASS_STATE_PWROFF 0x27 +#define NORMAL_STATE_PWROFF 0x29 +#define TAP_ON 0xb +#define TAP_OFF 0x9 +#define TAP_STATE_PWRON 0x2a +#define DIS_TAP_CAP 0x2c +#define EN_TAP_CAP 0x2e +#define STD_NIC_OFF 0x86 +#define STD_NIC_ON 0x84 +#define DISC_ON 0x85 +#define DISC_OFF 0x8a +#define DISC_STATE_PWRON 0x87 +#define DIS_DISC_CAP 0x88 +#define EN_DISC_CAP 0x89 +#define TPL2_ON 0x8c +#define TPL2_OFF 0x8b +#define BP_WAIT_AT_PWUP_EN 0x80 +#define BP_WAIT_AT_PWUP_DIS 0x81 +#define BP_HW_RESET_EN 0x82 +#define BP_HW_RESET_DIS 0x83 + +#define TX_DISA 0x8d +#define TX_DISB 0x8e +#define TX_ENA 0xA0 +#define TX_ENB 0xA1 + +#define TX_DISA_PWRUP 0xA2 +#define TX_DISB_PWRUP 0xA3 +#define TX_ENA_PWRUP 0xA4 +#define TX_ENB_PWRUP 0xA5 + +#define BYPASS_CAP_DELAY 21 /* msec */ +#define DFLT_PWRON_DELAY 10 /* msec */ +#define LATCH_DELAY 13 /* msec */ +#define EEPROM_WR_DELAY 8 /* msec */ + +#define BP_LINK_MON_DELAY 4 /* sec */ + +#define BP_FW_EXT_VER0 0xa0 +#define BP_FW_EXT_VER1 0xa1 +#define BP_FW_EXT_VER2 0xb1 + +#define BP_OK 0 +#define BP_NOT_CAP -1 +#define WDT_STATUS_EXP -2 +#define WDT_STATUS_UNKNOWN -1 +#define WDT_STATUS_EN 1 +#define WDT_STATUS_DIS 0 + +#ifdef BP_SELF_TEST +#define ETH_P_BPTEST 0xabba + +#define BPTEST_DATA_LEN 60 +#endif + +#endif /* BYPASS_H */ diff --git a/drivers/staging/silicom/bypasslib/Makefile b/drivers/staging/silicom/bypasslib/Makefile new file mode 100644 index 0000000..80e8b9b --- /dev/null +++ b/drivers/staging/silicom/bypasslib/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for the Bypass network device drivers. +# + +obj-$(CONFIG_SBYPASS) += bypass.o + diff --git a/drivers/staging/silicom/bypasslib/bp_ioctl.h b/drivers/staging/silicom/bypasslib/bp_ioctl.h new file mode 100644 index 0000000..9e736a4 --- /dev/null +++ b/drivers/staging/silicom/bypasslib/bp_ioctl.h @@ -0,0 +1,199 @@ +/******************************************************************************/ +/* */ +/* bypass library, Copyright (c) 2004-2006 Silicom, Ltd */ +/* Corporation. */ +/* */ +/* This program is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation, located in the file LICENSE. */ +/* */ +/* */ +/* */ +/******************************************************************************/ + +#ifndef BP_IOCTL_H +#define BP_IOCTL_H + +#define BP_CAP 0x01 //BIT_0 +#define BP_STATUS_CAP 0x02 //BIT_1 +#define BP_STATUS_CHANGE_CAP 0x04 //BIT_2 +#define SW_CTL_CAP 0x08 //BIT_3 +#define BP_DIS_CAP 0x10 //BIT_4 +#define BP_DIS_STATUS_CAP 0x20 //BIT_5 +#define STD_NIC_CAP 0x40 //BIT_6 +#define BP_PWOFF_ON_CAP 0x80 //BIT_7 +#define BP_PWOFF_OFF_CAP 0x0100 //BIT_8 +#define BP_PWOFF_CTL_CAP 0x0200 //BIT_9 +#define BP_PWUP_ON_CAP 0x0400 //BIT_10 +#define BP_PWUP_OFF_CAP 0x0800 //BIT_11 +#define BP_PWUP_CTL_CAP 0x1000 //BIT_12 +#define WD_CTL_CAP 0x2000 //BIT_13 +#define WD_STATUS_CAP 0x4000 //BIT_14 +#define WD_TIMEOUT_CAP 0x8000 //BIT_15 +#define TX_CTL_CAP 0x10000 //BIT_16 +#define TX_STATUS_CAP 0x20000 //BIT_17 +#define TAP_CAP 0x40000 //BIT_18 +#define TAP_STATUS_CAP 0x80000 //BIT_19 +#define TAP_STATUS_CHANGE_CAP 0x100000 //BIT_20 +#define TAP_DIS_CAP 0x200000 //BIT_21 +#define TAP_DIS_STATUS_CAP 0x400000 //BIT_22 +#define TAP_PWUP_ON_CAP 0x800000 //BIT_23 +#define TAP_PWUP_OFF_CAP 0x1000000 //BIT 24 +#define TAP_PWUP_CTL_CAP 0x2000000 //BIT 25 +#define NIC_CAP_NEG 0x4000000 //BIT 26 +#define TPL_CAP 0x8000000 //BIT 27 +#define DISC_CAP 0x10000000 //BIT 28 +#define DISC_DIS_CAP 0x20000000 //BIT 29 +#define DISC_PWUP_CTL_CAP 0x40000000 //BIT 30 + +#define WD_MIN_TIME_MASK(val) (val & 0xf) +#define WD_STEP_COUNT_MASK(val) ((val & 0xf) << 5) +#define WDT_STEP_TIME 0x10 //BIT_4 + +#define WD_MIN_TIME_GET(desc) (desc & 0xf) +#define WD_STEP_COUNT_GET(desc) (desc>>5) & 0xf + +typedef enum { + IS_BYPASS = 1, + GET_BYPASS_SLAVE, + GET_BYPASS_CAPS, + GET_WD_SET_CAPS, + SET_BYPASS, + GET_BYPASS, + GET_BYPASS_CHANGE, + SET_BYPASS_WD, + GET_BYPASS_WD, + GET_WD_EXPIRE_TIME, + RESET_BYPASS_WD_TIMER, + SET_DIS_BYPASS, + GET_DIS_BYPASS, + SET_BYPASS_PWOFF, + GET_BYPASS_PWOFF, + SET_BYPASS_PWUP, + GET_BYPASS_PWUP, + SET_STD_NIC, + GET_STD_NIC, + SET_TX, + GET_TX, + SET_TAP, + GET_TAP, + GET_TAP_CHANGE, + SET_DIS_TAP, + GET_DIS_TAP, + SET_TAP_PWUP, + GET_TAP_PWUP, + SET_WD_EXP_MODE, + GET_WD_EXP_MODE, + SET_WD_AUTORESET, + GET_WD_AUTORESET, + SET_TPL, + GET_TPL, + SET_DISC, + GET_DISC, + GET_DISC_CHANGE, + SET_DIS_DISC, + GET_DIS_DISC, + SET_DISC_PWUP, + GET_DISC_PWUP, + + GET_BYPASS_INFO = 100, + GET_BP_WAIT_AT_PWUP, + SET_BP_WAIT_AT_PWUP, + GET_BP_HW_RESET, + SET_BP_HW_RESET, +} CMND_TYPE; + +typedef enum { + IF_SCAN_SD, + GET_DEV_NUM_SD, + IS_BYPASS_SD, + GET_BYPASS_SLAVE_SD, + GET_BYPASS_CAPS_SD, + GET_WD_SET_CAPS_SD, + SET_BYPASS_SD, + GET_BYPASS_SD, + GET_BYPASS_CHANGE_SD, + SET_BYPASS_WD_SD, + GET_BYPASS_WD_SD, + GET_WD_EXPIRE_TIME_SD, + RESET_BYPASS_WD_TIMER_SD, + SET_DIS_BYPASS_SD, + GET_DIS_BYPASS_SD, + SET_BYPASS_PWOFF_SD, + GET_BYPASS_PWOFF_SD, + SET_BYPASS_PWUP_SD, + GET_BYPASS_PWUP_SD, + SET_STD_NIC_SD, + GET_STD_NIC_SD, + SET_TX_SD, + GET_TX_SD, + SET_TAP_SD, + GET_TAP_SD, + GET_TAP_CHANGE_SD, + SET_DIS_TAP_SD, + GET_DIS_TAP_SD, + SET_TAP_PWUP_SD, + GET_TAP_PWUP_SD, + SET_WD_EXP_MODE_SD, + GET_WD_EXP_MODE_SD, + SET_WD_AUTORESET_SD, + GET_WD_AUTORESET_SD, + SET_TPL_SD, + GET_TPL_SD, + SET_DISC_SD, + GET_DISC_SD, + GET_DISC_CHANGE_SD, + SET_DIS_DISC_SD, + GET_DIS_DISC_SD, + SET_DISC_PWUP_SD, + GET_DISC_PWUP_SD, + + GET_BYPASS_INFO_SD = 100, + GET_BP_WAIT_AT_PWUP_SD, + SET_BP_WAIT_AT_PWUP_SD, + GET_BP_HW_RESET_SD, + SET_BP_HW_RESET_SD, + +} CMND_TYPE_SD; + +#define SIOCGIFBYPASS SIOCDEVPRIVATE+10 + +struct bp_info { + char prod_name[14]; + unsigned char fw_ver; +}; + +/* for passing single values */ +struct if_bypass { + char if_name[IFNAMSIZ]; + int cmd; + int data; +}; +struct if_bypass_info { + char if_name[IFNAMSIZ]; + char cmd; + struct bp_info bp_info; +}; + +/* +* The major device number. We can't rely on dynamic +* registration any more, because ioctls need to know +* it. +*/ + +#define MAGIC_NUM 'J' + +/* for passing single values */ +struct bpctl_cmd { + int status; + int data[8]; + int in_param[8]; + int out_param[8]; +}; + +#define IOCTL_TX_MSG(cmd) _IOWR(MAGIC_NUM, cmd, struct bpctl_cmd) + +#define DEVICE_NODE "/dev/bpctl0" +#define DEVICE_NAME "bpctl" + +#endif diff --git a/drivers/staging/silicom/bypasslib/bplibk.h b/drivers/staging/silicom/bypasslib/bplibk.h new file mode 100644 index 0000000..a1c85ee --- /dev/null +++ b/drivers/staging/silicom/bypasslib/bplibk.h @@ -0,0 +1,47 @@ +/******************************************************************************/ +/* */ +/* bypass library, Copyright (c) 2004 Silicom, Ltd */ +/* */ +/* This program is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation, located in the file LICENSE. */ +/* */ +/* */ +/* bplib.h */ +/* */ +/******************************************************************************/ +#ifndef BYPASS_H +#define BYPASS_H + +#include "bp_ioctl.h" +#include "libbp_sd.h" + +#define IF_NAME "eth" +#define SILICOM_VID 0x1374 +#define SILICOM_BP_PID_MIN 0x24 +#define SILICOM_BP_PID_MAX 0x5f +#define INTEL_PEG4BPII_PID 0x10a0 +#define INTEL_PEG4BPFII_PID 0x10a1 + +#define PEGII_IF_SERIES(vid, pid) \ + ((vid==0x8086)&& \ + ((pid==INTEL_PEG4BPII_PID)|| \ + (pid==INTEL_PEG4BPFII_PID))) + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)) +#define pci_get_class pci_find_class + +#define pci_get_device pci_find_device + +#endif + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10)) +#define EXPORT_SYMBOL_NOVERS EXPORT_SYMBOL +#endif + +#ifdef BP_VENDOR_SUPPORT +char *bp_desc_array[] = + { "e1000bp", "e1000bpe", "slcm5700", "bnx2xbp", "ixgbp", "ixgbpe", NULL }; +#endif + +#endif diff --git a/drivers/staging/silicom/bypasslib/bypass.c b/drivers/staging/silicom/bypasslib/bypass.c new file mode 100644 index 0000000..527829d --- /dev/null +++ b/drivers/staging/silicom/bypasslib/bypass.c @@ -0,0 +1,529 @@ +/******************************************************************************/ +/* */ +/* bypass library, Copyright (c) 2004-2007 Silicom, Ltd */ +/* */ +/* This program is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation, located in the file LICENSE. */ +/* */ +/* */ +/* bypass.c */ +/* */ +/******************************************************************************/ + +#include +#if defined(CONFIG_SMP) && ! defined(__SMP__) +#define __SMP__ +#endif + +#include +#include +#include + +#include +#include + +#include // struct device, and other headers +#include +#include +#include +#include + +#include + +#include "bplibk.h" + +#define MOD_NAME "bypass" + +#define VERSION "\n"MOD_NAME" version 9.0.4\n" + +MODULE_AUTHOR("www.silicom.co.il"); + +MODULE_LICENSE("GPL"); + +int init_lib_module(void); +void cleanup_lib_module(void); + +static int do_cmd(struct net_device *dev, struct ifreq *ifr, int cmd, int *data) +{ + int ret = -1; + struct if_bypass *bypass_cb; + static int (*ioctl) (struct net_device *, struct ifreq *, int); + + bypass_cb = (struct if_bypass *)ifr; + bypass_cb->cmd = cmd; + bypass_cb->data = *data; + if ((dev->netdev_ops) && (ioctl = dev->netdev_ops->ndo_do_ioctl)) { + ret = ioctl(dev, ifr, SIOCGIFBYPASS); + *data = bypass_cb->data; + } + + return ret; +} + +static int doit(int cmd, int if_index, int *data) +{ + struct ifreq ifr; + int ret = -1; + struct net_device *dev; + struct net_device *n; + for_each_netdev_safe(&init_net, dev, n) { + + if (dev->ifindex == if_index) { + ret = do_cmd(dev, &ifr, cmd, data); + if (ret < 0) + ret = -1; + + } + } + + return ret; +} + +#define bp_symbol_get(fn_name) symbol_get(fn_name) +#define bp_symbol_put(fn_name) symbol_put(fn_name) + +#define SET_BPLIB_INT_FN(fn_name, arg_type, arg, ret) \ + ({ int (* fn_ex)(arg_type)=NULL; \ + fn_ex=bp_symbol_get(fn_name##_sd); \ + if(fn_ex) { \ + ret= fn_ex(arg); \ + bp_symbol_put(fn_name##_sd); \ + } else ret=-1; \ + }) + +#define SET_BPLIB_INT_FN2(fn_name, arg_type, arg, arg_type1, arg1, ret) \ + ({ int (* fn_ex)(arg_type,arg_type1)=NULL; \ + fn_ex=bp_symbol_get(fn_name##_sd); \ + if(fn_ex) { \ + ret= fn_ex(arg,arg1); \ + bp_symbol_put(fn_name##_sd); \ + } else ret=-1; \ + }) +#define SET_BPLIB_INT_FN3(fn_name, arg_type, arg, arg_type1, arg1,arg_type2, arg2, ret) \ + ({ int (* fn_ex)(arg_type,arg_type1, arg_type2)=NULL; \ + fn_ex=bp_symbol_get(fn_name##_sd); \ + if(fn_ex) { \ + ret= fn_ex(arg,arg1,arg2); \ + bp_symbol_put(fn_name##_sd); \ + } else ret=-1; \ + }) + +#define DO_BPLIB_GET_ARG_FN(fn_name,ioctl_val, if_index) \ + ({ int data, ret=0; \ + if(is_dev_sd(if_index)){ \ + SET_BPLIB_INT_FN(fn_name, int, if_index, ret); \ + return ret; \ + } \ + return doit(ioctl_val,if_index, &data); \ + }) + +#define DO_BPLIB_SET_ARG_FN(fn_name,ioctl_val,if_index,arg) \ + ({ int data, ret=0; \ + if(is_dev_sd(if_index)){ \ + SET_BPLIB_INT_FN2(fn_name, int, if_index, int, arg, ret); \ + return ret; \ + } \ + data=arg; \ + return doit(ioctl_val,if_index, &data); \ + }) + +static int is_dev_sd(int if_index) +{ + int ret = 0; + SET_BPLIB_INT_FN(is_bypass, int, if_index, ret); + return (ret >= 0 ? 1 : 0); +} + +int is_bypass_dev(int if_index) +{ + struct pci_dev *pdev = NULL; + struct net_device *dev = NULL; + struct ifreq ifr; + int ret = 0, data = 0; + + while ((pdev = pci_get_class(PCI_CLASS_NETWORK_ETHERNET << 8, pdev))) { + if ((dev = pci_get_drvdata(pdev)) != NULL) + if (((dev = pci_get_drvdata(pdev)) != NULL) && + (dev->ifindex == if_index)) { + if ((pdev->vendor == SILICOM_VID) && + (pdev->device >= SILICOM_BP_PID_MIN) && + (pdev->device <= SILICOM_BP_PID_MAX)) + goto send_cmd; +#if defined(BP_VENDOR_SUPPORT) && defined(ETHTOOL_GDRVINFO) + else { + struct ethtool_drvinfo info; + const struct ethtool_ops *ops = + dev->ethtool_ops; + int k = 0; + + if (ops->get_drvinfo) { + memset(&info, 0, sizeof(info)); + info.cmd = ETHTOOL_GDRVINFO; + ops->get_drvinfo(dev, &info); + for (; bp_desc_array[k]; k++) + if (! + (strcmp + (bp_desc_array[k], + info.driver))) + goto send_cmd; + + } + + } +#endif + return -1; + } + } + send_cmd: + ret = do_cmd(dev, &ifr, IS_BYPASS, &data); + return (ret < 0 ? -1 : ret); +} + +int is_bypass(int if_index) +{ + int ret = 0; + SET_BPLIB_INT_FN(is_bypass, int, if_index, ret); + + if (ret < 0) + return is_bypass_dev(if_index); + return ret; +} + +int get_bypass_slave(int if_index) +{ + DO_BPLIB_GET_ARG_FN(get_bypass_slave, GET_BYPASS_SLAVE, if_index); +} + +int get_bypass_caps(int if_index) +{ + DO_BPLIB_GET_ARG_FN(get_bypass_caps, GET_BYPASS_CAPS, if_index); +} + +int get_wd_set_caps(int if_index) +{ + DO_BPLIB_GET_ARG_FN(get_wd_set_caps, GET_WD_SET_CAPS, if_index); +} + +int set_bypass(int if_index, int bypass_mode) +{ + DO_BPLIB_SET_ARG_FN(set_bypass, SET_BYPASS, if_index, bypass_mode); +} + +int get_bypass(int if_index) +{ + DO_BPLIB_GET_ARG_FN(get_bypass, GET_BYPASS, if_index); +} + +int get_bypass_change(int if_index) +{ + DO_BPLIB_GET_ARG_FN(get_bypass_change, GET_BYPASS_CHANGE, if_index); +} + +int set_dis_bypass(int if_index, int dis_bypass) +{ + DO_BPLIB_SET_ARG_FN(set_dis_bypass, SET_DIS_BYPASS, if_index, + dis_bypass); +} + +int get_dis_bypass(int if_index) +{ + DO_BPLIB_GET_ARG_FN(get_dis_bypass, GET_DIS_BYPASS, if_index); +} + +int set_bypass_pwoff(int if_index, int bypass_mode) +{ + DO_BPLIB_SET_ARG_FN(set_bypass_pwoff, SET_BYPASS_PWOFF, if_index, + bypass_mode); +} + +int get_bypass_pwoff(int if_index) +{ + DO_BPLIB_GET_ARG_FN(get_bypass_pwoff, GET_BYPASS_PWOFF, if_index); +} + +int set_bypass_pwup(int if_index, int bypass_mode) +{ + DO_BPLIB_SET_ARG_FN(set_bypass_pwup, SET_BYPASS_PWUP, if_index, + bypass_mode); +} + +int get_bypass_pwup(int if_index) +{ + DO_BPLIB_GET_ARG_FN(get_bypass_pwup, GET_BYPASS_PWUP, if_index); +} + +int set_bypass_wd(int if_index, int ms_timeout, int *ms_timeout_set) +{ + int data = ms_timeout, ret = 0; + if (is_dev_sd(if_index)) + SET_BPLIB_INT_FN3(set_bypass_wd, int, if_index, int, ms_timeout, + int *, ms_timeout_set, ret); + else { + ret = doit(SET_BYPASS_WD, if_index, &data); + if (ret > 0) { + *ms_timeout_set = ret; + ret = 0; + } + } + return ret; +} + +int get_bypass_wd(int if_index, int *ms_timeout_set) +{ + int *data = ms_timeout_set, ret = 0; + if (is_dev_sd(if_index)) + SET_BPLIB_INT_FN2(get_bypass_wd, int, if_index, int *, + ms_timeout_set, ret); + else + ret = doit(GET_BYPASS_WD, if_index, data); + return ret; +} + +int get_wd_expire_time(int if_index, int *ms_time_left) +{ + int *data = ms_time_left, ret = 0; + if (is_dev_sd(if_index)) + SET_BPLIB_INT_FN2(get_wd_expire_time, int, if_index, int *, + ms_time_left, ret); + else { + ret = doit(GET_WD_EXPIRE_TIME, if_index, data); + if ((ret == 0) && (*data != 0)) + ret = 1; + } + return ret; +} + +int reset_bypass_wd_timer(int if_index) +{ + DO_BPLIB_GET_ARG_FN(reset_bypass_wd_timer, RESET_BYPASS_WD_TIMER, + if_index); +} + +int set_std_nic(int if_index, int bypass_mode) +{ + DO_BPLIB_SET_ARG_FN(set_std_nic, SET_STD_NIC, if_index, bypass_mode); +} + +int get_std_nic(int if_index) +{ + DO_BPLIB_GET_ARG_FN(get_std_nic, GET_STD_NIC, if_index); +} + +int set_tx(int if_index, int tx_state) +{ + DO_BPLIB_SET_ARG_FN(set_tx, SET_TX, if_index, tx_state); +} + +int get_tx(int if_index) +{ + DO_BPLIB_GET_ARG_FN(get_tx, GET_TX, if_index); +} + +int set_tap(int if_index, int tap_mode) +{ + DO_BPLIB_SET_ARG_FN(set_tap, SET_TAP, if_index, tap_mode); +} + +int get_tap(int if_index) +{ + DO_BPLIB_GET_ARG_FN(get_tap, GET_TAP, if_index); +} + +int get_tap_change(int if_index) +{ + DO_BPLIB_GET_ARG_FN(get_tap_change, GET_TAP_CHANGE, if_index); +} + +int set_dis_tap(int if_index, int dis_tap) +{ + DO_BPLIB_SET_ARG_FN(set_dis_tap, SET_DIS_TAP, if_index, dis_tap); +} + +int get_dis_tap(int if_index) +{ + DO_BPLIB_GET_ARG_FN(get_dis_tap, GET_DIS_TAP, if_index); +} + +int set_tap_pwup(int if_index, int tap_mode) +{ + DO_BPLIB_SET_ARG_FN(set_tap_pwup, SET_TAP_PWUP, if_index, tap_mode); +} + +int get_tap_pwup(int if_index) +{ + DO_BPLIB_GET_ARG_FN(get_tap_pwup, GET_TAP_PWUP, if_index); +} + +int set_bp_disc(int if_index, int disc_mode) +{ + DO_BPLIB_SET_ARG_FN(set_bp_disc, SET_DISC, if_index, disc_mode); +} + +int get_bp_disc(int if_index) +{ + DO_BPLIB_GET_ARG_FN(get_bp_disc, GET_DISC, if_index); +} + +int get_bp_disc_change(int if_index) +{ + DO_BPLIB_GET_ARG_FN(get_bp_disc_change, GET_DISC_CHANGE, if_index); +} + +int set_bp_dis_disc(int if_index, int dis_disc) +{ + DO_BPLIB_SET_ARG_FN(set_bp_dis_disc, SET_DIS_DISC, if_index, dis_disc); +} + +int get_bp_dis_disc(int if_index) +{ + DO_BPLIB_GET_ARG_FN(get_bp_dis_disc, GET_DIS_DISC, if_index); +} + +int set_bp_disc_pwup(int if_index, int disc_mode) +{ + DO_BPLIB_SET_ARG_FN(set_bp_disc_pwup, SET_DISC_PWUP, if_index, + disc_mode); +} + +int get_bp_disc_pwup(int if_index) +{ + DO_BPLIB_GET_ARG_FN(get_bp_disc_pwup, GET_DISC_PWUP, if_index); +} + +int set_wd_exp_mode(int if_index, int mode) +{ + DO_BPLIB_SET_ARG_FN(set_wd_exp_mode, SET_WD_EXP_MODE, if_index, mode); +} + +int get_wd_exp_mode(int if_index) +{ + DO_BPLIB_GET_ARG_FN(get_wd_exp_mode, GET_WD_EXP_MODE, if_index); +} + +int set_wd_autoreset(int if_index, int time) +{ + DO_BPLIB_SET_ARG_FN(set_wd_autoreset, SET_WD_AUTORESET, if_index, time); +} + +int get_wd_autoreset(int if_index) +{ + DO_BPLIB_GET_ARG_FN(get_wd_autoreset, GET_WD_AUTORESET, if_index); +} + +int set_tpl(int if_index, int tpl_mode) +{ + DO_BPLIB_SET_ARG_FN(set_tpl, SET_TPL, if_index, tpl_mode); +} + +int get_tpl(int if_index) +{ + DO_BPLIB_GET_ARG_FN(get_tpl, GET_TPL, if_index); +} + +int set_bp_hw_reset(int if_index, int mode) +{ + DO_BPLIB_SET_ARG_FN(set_tpl, SET_BP_HW_RESET, if_index, mode); +} + +int get_bp_hw_reset(int if_index) +{ + DO_BPLIB_GET_ARG_FN(get_tpl, GET_BP_HW_RESET, if_index); +} + +int get_bypass_info(int if_index, struct bp_info *bp_info) +{ + int ret = 0; + if (is_dev_sd(if_index)) { + SET_BPLIB_INT_FN2(get_bypass_info, int, if_index, + struct bp_info *, bp_info, ret); + } else { + static int (*ioctl) (struct net_device *, struct ifreq *, int); + struct net_device *dev; + + struct net_device *n; + for_each_netdev_safe(&init_net, dev, n) { + if (dev->ifindex == if_index) { + struct if_bypass_info *bypass_cb; + struct ifreq ifr; + + memset(&ifr, 0, sizeof(ifr)); + bypass_cb = (struct if_bypass_info *)𝔦 + bypass_cb->cmd = GET_BYPASS_INFO; + + if ((dev->netdev_ops) && + (ioctl = dev->netdev_ops->ndo_do_ioctl)) { + ret = ioctl(dev, &ifr, SIOCGIFBYPASS); + } + + else + ret = -1; + if (ret == 0) + memcpy(bp_info, &bypass_cb->bp_info, + sizeof(struct bp_info)); + ret = (ret < 0 ? -1 : 0); + break; + } + } + } + return ret; +} + +int init_lib_module() +{ + + printk(VERSION); + return 0; +} + +void cleanup_lib_module() +{ +} + +EXPORT_SYMBOL_NOVERS(is_bypass); +EXPORT_SYMBOL_NOVERS(get_bypass_slave); +EXPORT_SYMBOL_NOVERS(get_bypass_caps); +EXPORT_SYMBOL_NOVERS(get_wd_set_caps); +EXPORT_SYMBOL_NOVERS(set_bypass); +EXPORT_SYMBOL_NOVERS(get_bypass); +EXPORT_SYMBOL_NOVERS(get_bypass_change); +EXPORT_SYMBOL_NOVERS(set_dis_bypass); +EXPORT_SYMBOL_NOVERS(get_dis_bypass); +EXPORT_SYMBOL_NOVERS(set_bypass_pwoff); +EXPORT_SYMBOL_NOVERS(get_bypass_pwoff); +EXPORT_SYMBOL_NOVERS(set_bypass_pwup); +EXPORT_SYMBOL_NOVERS(get_bypass_pwup); +EXPORT_SYMBOL_NOVERS(set_bypass_wd); +EXPORT_SYMBOL_NOVERS(get_bypass_wd); +EXPORT_SYMBOL_NOVERS(get_wd_expire_time); +EXPORT_SYMBOL_NOVERS(reset_bypass_wd_timer); +EXPORT_SYMBOL_NOVERS(set_std_nic); +EXPORT_SYMBOL_NOVERS(get_std_nic); +EXPORT_SYMBOL_NOVERS(set_tx); +EXPORT_SYMBOL_NOVERS(get_tx); +EXPORT_SYMBOL_NOVERS(set_tap); +EXPORT_SYMBOL_NOVERS(get_tap); +EXPORT_SYMBOL_NOVERS(get_tap_change); +EXPORT_SYMBOL_NOVERS(set_dis_tap); +EXPORT_SYMBOL_NOVERS(get_dis_tap); +EXPORT_SYMBOL_NOVERS(set_tap_pwup); +EXPORT_SYMBOL_NOVERS(get_tap_pwup); +EXPORT_SYMBOL_NOVERS(set_bp_disc); +EXPORT_SYMBOL_NOVERS(get_bp_disc); +EXPORT_SYMBOL_NOVERS(get_bp_disc_change); +EXPORT_SYMBOL_NOVERS(set_bp_dis_disc); +EXPORT_SYMBOL_NOVERS(get_bp_dis_disc); +EXPORT_SYMBOL_NOVERS(set_bp_disc_pwup); +EXPORT_SYMBOL_NOVERS(get_bp_disc_pwup); +EXPORT_SYMBOL_NOVERS(set_wd_exp_mode); +EXPORT_SYMBOL_NOVERS(get_wd_exp_mode); +EXPORT_SYMBOL_NOVERS(set_wd_autoreset); +EXPORT_SYMBOL_NOVERS(get_wd_autoreset); +EXPORT_SYMBOL_NOVERS(set_tpl); +EXPORT_SYMBOL_NOVERS(get_tpl); +EXPORT_SYMBOL_NOVERS(set_bp_hw_reset); +EXPORT_SYMBOL_NOVERS(get_bp_hw_reset); +EXPORT_SYMBOL_NOVERS(get_bypass_info); + +module_init(init_lib_module); +module_exit(cleanup_lib_module); diff --git a/drivers/staging/silicom/bypasslib/libbp_sd.h b/drivers/staging/silicom/bypasslib/libbp_sd.h new file mode 100644 index 0000000..3b4f836 --- /dev/null +++ b/drivers/staging/silicom/bypasslib/libbp_sd.h @@ -0,0 +1,509 @@ +/******************************************************************************/ +/* */ +/* bypass library, Copyright (c) 2004 Silicom, Ltd */ +/* Corporation. */ +/* */ +/* This program is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation, located in the file LICENSE. */ +/* */ +/* Ver 1.0.0 */ +/* */ +/* libbypass.h */ +/* */ +/******************************************************************************/ + +/** + * is_bypass - check if device is a Bypass controlling device + * @if_index: network device index + * + * Output: + * 1 - if device is bypass controlling device, + * 0 - if device is bypass slave device + * -1 - device not support Bypass + **/ +int is_bypass_sd(int if_index); + +/** + * get_bypass_slave - get second port participate in the Bypass pair + * @if_index: network device index + * + * Output: + * network device index of the slave device + * -1 - on failure (device not support Bypass or it's a slave device) + **/ +int get_bypass_slave_sd(int if_index); + +/** + * get_bypass_caps - get second port participate in the Bypass pair + * @if_index: network device index + * + * Output: + * flags word on success;flag word is a 32-bit mask word with each bit defines different + * capability as described bellow. + * Value of 1 for supporting this feature. 0 for not supporting this feature. + * -1 - on failure (if the device is not capable of the operation or not a Bypass device) + * Bit feature description + * + * 0 BP_CAP The interface is Bypass capable in general + * + * 1 BP_STATUS_CAP The interface can report of the current Bypass mode + * + * 2 BP_STATUS_CHANGE_CAP The interface can report on a change to bypass mode from + * the last time the mode was defined + * + * 3 SW_CTL_CAP The interface is Software controlled capable for bypass/non bypass modes. + * + * 4 BP_DIS_CAP The interface is capable of disabling the Bypass mode at all times. + * This mode will retain its mode even during power loss and also after + * power recovery. This will overcome on any bypass operation due to + * watchdog timeout or set bypass command. + * + * 5 BP_DIS_STATUS_CAP The interface can report of the current DIS_BP_CAP + * + * 6 STD_NIC_CAP The interface is capable to be configured to operate as standard, non Bypass, + * NIC interface (have direct connection to interfaces at all power modes) + * + * 7 BP_PWOFF_NO_CAP The interface can be in Bypass mode at power off state + * + * 8 BP_PWOFF_OFF_CAP The interface can disconnect the Bypass mode at power off state without + * effecting all the other states of operation + * + * 9 BP_PWOFF_CTL_CAP The behavior of the Bypass mode at Power-off state can be controlled by + * software without effecting any other state + * + *10 BP_PWUP_ON_CAP The interface can be in Bypass mode when power is turned on + * (until the system take control of the bypass functionality) + * + *11 BP_PWUP_OFF_CAP The interface can disconnect from Bypass mode when power is turned on + * (until the system take control of the bypass functionality) + * + *12 BP_PWUP_CTL_CAP The behavior of the Bypass mode at Power-up can be controlled by software + * + *13 WD_CTL_CAP The interface has watchdog capabilities to turn to Bypass mode when not reset + * for defined period of time. + * + *14 WD_STATUS_CAP The interface can report on the watchdog status (Active/inactive) + * + *15 WD_TIMEOUT_CAP The interface can report the time left till watchdog triggers to Bypass mode. + * + *16-31 RESERVED + * + * **/ +int get_bypass_caps_sd(int if_index); + +/** + * get_wd_set_caps - Obtain watchdog timer setting capabilities + * @if_index: network device index + * + * Output: + * + * Set of numbers defining the various parameters of the watchdog capable + * to be set to as described bellow. + * -1 - on failure (device not support Bypass or it's a slave device) + * + * Bit feature description + * + * 0-3 WD_MIN_TIME The interface WD minimal time period in 100mS units + * + * 4 WD_STEP_TIME The steps of the WD timer in + * 0 - for linear steps (WD_MIN_TIME * X) + * 1 - for multiply by 2 from previous step (WD_MIN_TIME * 2^X) + * + * 5-8 WD_STEP_COUNT Number of steps the WD timer supports in 2^X + * (X bit available for defining the value) + * + * + * + **/ +int get_wd_set_caps_sd(int if_index); + +/** + * set_bypass - set Bypass state + * @if_index: network device index of the controlling device + * @bypass_mode: bypass mode (1=on, 0=off) + * Output: + * 0 - on success + * -1 - on failure (device not support Bypass or it's a slave device) + **/ +int set_bypass_sd(int if_index, int bypass_mode); + +/** + * get_bypass - Get Bypass mode state + * @if_index: network device index of the controlling device + * Output: + * 0/1 - (off/on) on success + * -1 - on failure (device not support Bypass or it's a slave device) + **/ +int get_bypass_sd(int if_index); + +/** + * get_bypass_change - Get change of Bypass mode state from last status check + * @if_index: network device index of the controlling device + * Output: + * 0/1 - (off/on) on success + * -1 - on failure (device not support Bypass or it's a slave device) + **/ +int get_bypass_change_sd(int if_index); + +/** + * set_dis_bypass - Set Disable Bypass mode + * @if_index: network device index of the controlling device + * @dis_bypass: disable bypass(1=dis, 0=en) + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) + **/ +int set_dis_bypass_sd(int if_index, int dis_bypass); + +/** + * get_dis_bypass - Get Disable Bypass mode state + * @if_index: network device index of the controlling device + * Output: + * 0/1 - on success (normal Bypass mode/ Disable bypass) + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) + **/ +int get_dis_bypass_sd(int if_index); + +/** + * set_bypass_pwoff - Set Bypass mode at power-off state + * @if_index: network device index of the controlling device + * @bypass_mode: bypass mode setting at power off state (1=BP en, 0=BP Dis) + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) + **/ +int set_bypass_pwoff_sd(int if_index, int bypass_mode); + +/** + * get_bypass_pwoff - Get Bypass mode state at power-off state + * @if_index: network device index of the controlling device + * Output: + * 0/1 - on success (Disable bypass at power off state / normal Bypass mode) + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) + **/ +int get_bypass_pwoff_sd(int if_index); + +/** + * set_bypass_pwup - Set Bypass mode at power-up state + * @if_index: network device index of the controlling device + * @bypass_mode: bypass mode setting at power up state (1=BP en, 0=BP Dis) + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) + **/ +int set_bypass_pwup_sd(int if_index, int bypass_mode); + +/** + * get_bypass_pwup - Get Bypass mode state at power-up state + * @if_index: network device index of the controlling device + * Output: + * 0/1 - on success (Disable bypass at power up state / normal Bypass mode) + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) + **/ +int get_bypass_pwup_sd(int if_index); + +/** + * set_bypass_wd - Set watchdog state + * @if_index: network device index of the controlling device + * @ms_timeout: requested timeout (in ms units), 0 for disabling the watchdog timer + * @ms_timeout_set(output): requested timeout (in ms units), + * that the adapter supports and will be used by the watchdog + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) + **/ +int set_bypass_wd_sd(int if_index, int ms_timeout, int *ms_timeout_set); + +/** + * get_bypass_wd - Get watchdog state + * @if_index: network device index of the controlling device + * @ms_timeout (output): WDT timeout (in ms units), + * -1 for unknown wdt status + * 0 if WDT is disabled + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) + **/ +int get_bypass_wd_sd(int if_index, int *ms_timeout_set); + +/** + * get_wd_expire_time - Get watchdog expire + * @if_index: network device index of the controlling device + * @ms_time_left (output): time left till watchdog time expire, + * -1 if WDT has expired + * 0 if WDT is disabled + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device or unknown wdt status) + **/ +int get_wd_expire_time_sd(int if_index, int *ms_time_left); + +/** + * reset_bypass_wd_timer - Reset watchdog timer + * @if_index: network device index of the controlling device + * + * Output: + * 1 - on success + * 0 - watchdog is not configured + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device or unknown wdt status) + **/ +int reset_bypass_wd_timer_sd(int if_index); + +/** + * set_std_nic - Standard NIC mode of operation + * @if_index: network device index of the controlling device + * @nic_mode: 0/1 (Default Bypass mode / Standard NIC mode) + * + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) + **/ +int set_std_nic_sd(int if_index, int nic_mode); + +/** + * get_std_nic - Get Standard NIC mode setting + * @if_index: network device index of the controlling device + * + * Output: + * 0/1 (Default Bypass mode / Standard NIC mode) on success + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) + **/ +int get_std_nic_sd(int if_index); + +/** + * set_tx - set transmitter enable/disable + * @if_index: network device index of the controlling device + * @tx_state: 0/1 (Transmit Disable / Transmit Enable) + * + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ) + **/ +int set_tx_sd(int if_index, int tx_state); + +/** + * get_std_nic - get transmitter state (disable / enable) + * @if_index: network device index of the controlling device + * + * Output: + * 0/1 (ransmit Disable / Transmit Enable) on success + * -1 - on failure (device is not capable of the operation ordevice not support Bypass) + **/ +int get_tx_sd(int if_index); + +/** + * set_tap - set TAP state + * @if_index: network device index of the controlling device + * @tap_mode: 1 tap mode , 0 normal nic mode + * Output: + * 0 - on success + * -1 - on failure (device not support TAP or it's a slave device) + **/ +int set_tap_sd(int if_index, int tap_mode); + +/** + * get_tap - Get TAP mode state + * @if_index: network device index of the controlling device + * Output: + * 0/1 - (off/on) on success + * -1 - on failure (device not support TAP or it's a slave device) + **/ +int get_tap_sd(int if_index); + +/** + * get_tap_change - Get change of TAP mode state from last status check + * @if_index: network device index of the controlling device + * Output: + * 0/1 - (off/on) on success + * -1 - on failure (device not support TAP or it's a slave device) + **/ +int get_tap_change_sd(int if_index); + +/** + * set_dis_tap - Set Disable TAP mode + * @if_index: network device index of the controlling device + * @dis_tap: disable tap(1=dis, 0=en) + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ordevice not support TAP + * or it's a slave device) + **/ +int set_dis_tap_sd(int if_index, int dis_tap); + +/** + * get_dis_tap - Get Disable TAP mode state + * @if_index: network device index of the controlling device + * Output: + * 0/1 - on success (normal TAP mode/ Disable TAP) + * -1 - on failure (device is not capable of the operation ordevice not support TAP + * or it's a slave device) + **/ +int get_dis_tap_sd(int if_index); + +/** + * set_tap_pwup - Set TAP mode at power-up state + * @if_index: network device index of the controlling device + * @bypass_mode: tap mode setting at power up state (1=TAP en, 0=TAP Dis) + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ordevice not support TAP + * or it's a slave device) + **/ +int set_tap_pwup_sd(int if_index, int tap_mode); + +/** + * get_tap_pwup - Get TAP mode state at power-up state + * @if_index: network device index of the controlling device + * Output: + * 0/1 - on success (Disable TAP at power up state / normal TAP mode) + * -1 - on failure (device is not capable of the operation ordevice not support TAP + * or it's a slave device) + **/ +int get_tap_pwup_sd(int if_index); + +/** + * set_bp_disc - set Disconnect state + * @if_index: network device index of the controlling device + * @tap_mode: 1 disc mode , 0 non-disc mode + * Output: + * 0 - on success + * -1 - on failure (device not support Disconnect or it's a slave device) + **/ +int set_bp_disc_sd(int if_index, int disc_mode); + +/** + * get_bp_disc - Get Disconnect mode state + * @if_index: network device index of the controlling device + * Output: + * 0/1 - (off/on) on success + * -1 - on failure (device not support Disconnect or it's a slave device) + **/ +int get_bp_disc_sd(int if_index); + +/** + * get_bp_disc_change - Get change of Disconnect mode state from last status check + * @if_index: network device index of the controlling device + * Output: + * 0/1 - (off/on) on success + * -1 - on failure (device not support Disconnect or it's a slave device) + **/ +int get_bp_disc_change_sd(int if_index); + +/** + * set_bp_dis_disc - Set Disable Disconnect mode + * @if_index: network device index of the controlling device + * @dis_tap: disable tap(1=dis, 0=en) + * Output: + * 0 - on success + * -1 - on failure (device is not capable ofthe operation ordevice not support Disconnect + * or it's a slave device) + **/ +int set_bp_dis_disc_sd(int if_index, int dis_disc); + +/** + * get_dis_tap - Get Disable Disconnect mode state + * @if_index: network device index of the controlling device + * Output: + * 0/1 - on success (normal Disconnect mode/ Disable Disconnect) + * -1 - on failure (device is not capable of the operation ordevice not support Disconnect + * or it's a slave device) + **/ +int get_bp_dis_disc_sd(int if_index); + +/** + * set_bp_disc_pwup - Set Disconnect mode at power-up state + * @if_index: network device index of the controlling device + * @disc_mode: tap mode setting at power up state (1=Disc en, 0=Disc Dis) + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ordevice not support Disconnect + * or it's a slave device) + **/ +int set_bp_disc_pwup_sd(int if_index, int disc_mode); + +/** + * get_bp_disc_pwup - Get Disconnect mode state at power-up state + * @if_index: network device index of the controlling device + * Output: + * 0/1 - on success (Disable Disconnect at power up state / normal Disconnect mode) + * -1 - on failure (device is not capable of the operation ordevice not support TAP + * or it's a slave device) + **/ +int get_bp_disc_pwup_sd(int if_index); + +/** + * set_wd_exp_mode - Set adapter state when WDT expired. + * @if_index: network device index of the controlling device + * @bypass_mode: adapter mode (1=tap mode, 0=bypass mode) + * Output: + * 0 - on success + * -1 - on failure (device not support Bypass or it's a slave device) + **/ +int set_wd_exp_mode_sd(int if_index, int bypass_mode); + +/** + * get_wd_exp_mode - Get adapter state when WDT expired. + * @if_index: network device index of the controlling device + * Output: + * 0/1 - (bypass/tap) on success + * -1 - on failure (device not support Bypass or it's a slave device) + **/ +int get_wd_exp_mode_sd(int if_index); + +/** + * set_wd_autoreset - reset WDT periodically. + * @if_index: network device index of the controlling device + * @bypass_mode: adapter mode (1=tap mode, 0=bypass mode) + * Output: + * 1 - on success + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device or unknown wdt status) + **/ +int set_wd_autoreset_sd(int if_index, int time); + +/** + * set_wd_autoreset - reset WDT periodically. + * @if_index: network device index of the controlling device + * @bypass_mode: adapter mode (1=tap mode, 0=bypass mode) + * Output: + * 1 - on success + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device or unknown wdt status) + **/ +int get_wd_autoreset_sd(int if_index); + +/** + * set_tpl - set TPL state + * @if_index: network device index of the controlling device + * @tpl_mode: 1 tpl mode , 0 normal nic mode + * Output: + * 0 - on success + * -1 - on failure (device not support TPL) + **/ +int set_tpl_sd(int if_index, int tpl_mode); + +/** + * get_tpl - Get TPL mode state + * @if_index: network device index of the controlling device + * Output: + * 0/1 - (off/on) on success + * -1 - on failure (device not support TPL or it's a slave device) + **/ +int get_tpl_sd(int if_index); + +int get_bypass_info_sd(int if_index, struct bp_info *bp_info); +int bp_if_scan_sd(void); +/*int get_dev_num_sd(void);*/ diff --git a/drivers/staging/silicom/libbp_sd.h b/drivers/staging/silicom/libbp_sd.h new file mode 100644 index 0000000..06ddfd5 --- /dev/null +++ b/drivers/staging/silicom/libbp_sd.h @@ -0,0 +1,551 @@ +/******************************************************************************/ +/* */ +/* bypass library, Copyright (c) 2004 Silicom, Ltd */ +/* Corporation. */ +/* */ +/* This program is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation, located in the file LICENSE. */ +/* */ +/* Ver 1.0.0 */ +/* */ +/* libbypass.h */ +/* */ +/******************************************************************************/ + +#define BP_CAP 0x01 //BIT_0 +#define BP_STATUS_CAP 0x02 //BIT_1 +#define BP_STATUS_CHANGE_CAP 0x04 //BIT_2 +#define SW_CTL_CAP 0x08 //BIT_3 +#define BP_DIS_CAP 0x10 //BIT_4 +#define BP_DIS_STATUS_CAP 0x20 //BIT_5 +#define STD_NIC_CAP 0x40 //BIT_6 +#define BP_PWOFF_ON_CAP 0x80 //BIT_7 +#define BP_PWOFF_OFF_CAP 0x0100 //BIT_8 +#define BP_PWOFF_CTL_CAP 0x0200 //BIT_9 +#define BP_PWUP_ON_CAP 0x0400 //BIT_10 +#define BP_PWUP_OFF_CAP 0x0800 //BIT_11 +#define BP_PWUP_CTL_CAP 0x1000 //BIT_12 +#define WD_CTL_CAP 0x2000 //BIT_13 +#define WD_STATUS_CAP 0x4000 //BIT_14 +#define WD_TIMEOUT_CAP 0x8000 //BIT_15 +#define TX_CTL_CAP 0x10000 //BIT_16 +#define TX_STATUS_CAP 0x20000 //BIT_17 +#define TAP_CAP 0x40000 //BIT_18 +#define TAP_STATUS_CAP 0x80000 //BIT_19 +#define TAP_STATUS_CHANGE_CAP 0x100000 //BIT_20 +#define TAP_DIS_CAP 0x200000 //BIT_21 +#define TAP_DIS_STATUS_CAP 0x400000 //BIT_22 +#define TAP_PWUP_ON_CAP 0x800000 //BIT_23 +#define TAP_PWUP_OFF_CAP 0x1000000 //BIT 24 +#define TAP_PWUP_CTL_CAP 0x2000000 //BIT 25 +#define NIC_CAP_NEG 0x4000000 //BIT 26 + +#define WD_MIN_TIME_GET(desc) (desc & 0xf) +#define WD_STEP_COUNT_GET(desc) (desc>>5) & 0xf +#define WDT_STEP_TIME 0x10 + +struct bp_info { + char prod_name[14]; + unsigned char fw_ver; +}; + +/** + * is_bypass - check if device is a Bypass controlling device + * @if_index: network device index + * + * Output: + * 1 - if device is bypass controlling device, + * 0 - if device is bypass slave device + * -1 - device not support Bypass + **/ +int is_bypass_sd(int if_index); + +/** + * get_bypass_slave - get second port participate in the Bypass pair + * @if_index: network device index + * + * Output: + * network device index of the slave device + * -1 - on failure (device not support Bypass or it's a slave device) + **/ +int get_bypass_slave_sd(int if_index); + +/** + * get_bypass_caps - get second port participate in the Bypass pair + * @if_index: network device index + * + * Output: + * flags word on success;flag word is a 32-bit mask word with each bit defines different + * capability as described bellow. + * Value of 1 for supporting this feature. 0 for not supporting this feature. + * -1 - on failure (if the device is not capable of the operation or not a Bypass device) + * Bit feature description + * + * 0 BP_CAP The interface is Bypass capable in general + * + * 1 BP_STATUS_CAP The interface can report of the current Bypass mode + * + * 2 BP_STATUS_CHANGE_CAP The interface can report on a change to bypass mode from + * the last time the mode was defined + * + * 3 SW_CTL_CAP The interface is Software controlled capable for bypass/non bypass modes. + * + * 4 BP_DIS_CAP The interface is capable of disabling the Bypass mode at all times. + * This mode will retain its mode even during power loss and also after + * power recovery. This will overcome on any bypass operation due to + * watchdog timeout or set bypass command. + * + * 5 BP_DIS_STATUS_CAP The interface can report of the current DIS_BP_CAP + * + * 6 STD_NIC_CAP The interface is capable to be configured to operate as standard, non Bypass, + * NIC interface (have direct connection to interfaces at all power modes) + * + * 7 BP_PWOFF_NO_CAP The interface can be in Bypass mode at power off state + * + * 8 BP_PWOFF_OFF_CAP The interface can disconnect the Bypass mode at power off state without + * effecting all the other states of operation + * + * 9 BP_PWOFF_CTL_CAP The behavior of the Bypass mode at Power-off state can be controlled by + * software without effecting any other state + * + *10 BP_PWUP_ON_CAP The interface can be in Bypass mode when power is turned on + * (until the system take control of the bypass functionality) + * + *11 BP_PWUP_OFF_CAP The interface can disconnect from Bypass mode when power is turned on + * (until the system take control of the bypass functionality) + * + *12 BP_PWUP_CTL_CAP The behavior of the Bypass mode at Power-up can be controlled by software + * + *13 WD_CTL_CAP The interface has watchdog capabilities to turn to Bypass mode when not reset + * for defined period of time. + * + *14 WD_STATUS_CAP The interface can report on the watchdog status (Active/inactive) + * + *15 WD_TIMEOUT_CAP The interface can report the time left till watchdog triggers to Bypass mode. + * + *16-31 RESERVED + * + * **/ +int get_bypass_caps_sd(int if_index); + +/** + * get_wd_set_caps - Obtain watchdog timer setting capabilities + * @if_index: network device index + * + * Output: + * + * Set of numbers defining the various parameters of the watchdog capable + * to be set to as described bellow. + * -1 - on failure (device not support Bypass or it's a slave device) + * + * Bit feature description + * + * 0-3 WD_MIN_TIME The interface WD minimal time period in 100mS units + * + * 4 WD_STEP_TIME The steps of the WD timer in + * 0 - for linear steps (WD_MIN_TIME * X) + * 1 - for multiply by 2 from previous step (WD_MIN_TIME * 2^X) + * + * 5-8 WD_STEP_COUNT Number of steps the WD timer supports in 2^X + * (X bit available for defining the value) + * + * + * + **/ +int get_wd_set_caps_sd(int if_index); + +/** + * set_bypass - set Bypass state + * @if_index: network device index of the controlling device + * @bypass_mode: bypass mode (1=on, 0=off) + * Output: + * 0 - on success + * -1 - on failure (device not support Bypass or it's a slave device) + **/ +int set_bypass_sd(int if_index, int bypass_mode); + +/** + * get_bypass - Get Bypass mode state + * @if_index: network device index of the controlling device + * Output: + * 0/1 - (off/on) on success + * -1 - on failure (device not support Bypass or it's a slave device) + **/ +int get_bypass_sd(int if_index); + +/** + * get_bypass_change - Get change of Bypass mode state from last status check + * @if_index: network device index of the controlling device + * Output: + * 0/1 - (off/on) on success + * -1 - on failure (device not support Bypass or it's a slave device) + **/ +int get_bypass_change_sd(int if_index); + +/** + * set_dis_bypass - Set Disable Bypass mode + * @if_index: network device index of the controlling device + * @dis_bypass: disable bypass(1=dis, 0=en) + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) + **/ +int set_dis_bypass_sd(int if_index, int dis_bypass); + +/** + * get_dis_bypass - Get Disable Bypass mode state + * @if_index: network device index of the controlling device + * Output: + * 0/1 - on success (normal Bypass mode/ Disable bypass) + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) + **/ +int get_dis_bypass_sd(int if_index); + +/** + * set_bypass_pwoff - Set Bypass mode at power-off state + * @if_index: network device index of the controlling device + * @bypass_mode: bypass mode setting at power off state (1=BP en, 0=BP Dis) + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) + **/ +int set_bypass_pwoff_sd(int if_index, int bypass_mode); + +/** + * get_bypass_pwoff - Get Bypass mode state at power-off state + * @if_index: network device index of the controlling device + * Output: + * 0/1 - on success (Disable bypass at power off state / normal Bypass mode) + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) + **/ +int get_bypass_pwoff_sd(int if_index); + +/** + * set_bypass_pwup - Set Bypass mode at power-up state + * @if_index: network device index of the controlling device + * @bypass_mode: bypass mode setting at power up state (1=BP en, 0=BP Dis) + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) + **/ +int set_bypass_pwup_sd(int if_index, int bypass_mode); + +/** + * get_bypass_pwup - Get Bypass mode state at power-up state + * @if_index: network device index of the controlling device + * Output: + * 0/1 - on success (Disable bypass at power up state / normal Bypass mode) + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) + **/ +int get_bypass_pwup_sd(int if_index); + +/** + * set_bypass_wd - Set watchdog state + * @if_index: network device index of the controlling device + * @ms_timeout: requested timeout (in ms units), 0 for disabling the watchdog timer + * @ms_timeout_set(output): requested timeout (in ms units), + * that the adapter supports and will be used by the watchdog + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) + **/ +int set_bypass_wd_sd(int if_index, int ms_timeout, int *ms_timeout_set); + +/** + * get_bypass_wd - Get watchdog state + * @if_index: network device index of the controlling device + * @ms_timeout (output): WDT timeout (in ms units), + * -1 for unknown wdt status + * 0 if WDT is disabled + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) + **/ +int get_bypass_wd_sd(int if_index, int *ms_timeout_set); + +/** + * get_wd_expire_time - Get watchdog expire + * @if_index: network device index of the controlling device + * @ms_time_left (output): time left till watchdog time expire, + * -1 if WDT has expired + * 0 if WDT is disabled + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device or unknown wdt status) + **/ +int get_wd_expire_time_sd(int if_index, int *ms_time_left); + +/** + * reset_bypass_wd_timer - Reset watchdog timer + * @if_index: network device index of the controlling device + * + * Output: + * 1 - on success + * 0 - watchdog is not configured + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device or unknown wdt status) + **/ +int reset_bypass_wd_timer_sd(int if_index); + +/** + * set_std_nic - Standard NIC mode of operation + * @if_index: network device index of the controlling device + * @nic_mode: 0/1 (Default Bypass mode / Standard NIC mode) + * + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) + **/ +int set_std_nic_sd(int if_index, int nic_mode); + +/** + * get_std_nic - Get Standard NIC mode setting + * @if_index: network device index of the controlling device + * + * Output: + * 0/1 (Default Bypass mode / Standard NIC mode) on success + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) + **/ +int get_std_nic_sd(int if_index); + +/** + * set_tx - set transmitter enable/disable + * @if_index: network device index of the controlling device + * @tx_state: 0/1 (Transmit Disable / Transmit Enable) + * + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ) + **/ +int set_tx_sd(int if_index, int tx_state); + +/** + * get_tx - get transmitter state (disable / enable) + * @if_index: network device index of the controlling device + * + * Output: + * 0/1 (ransmit Disable / Transmit Enable) on success + * -1 - on failure (device is not capable of the operation ordevice not support Bypass) + **/ +int get_tx_sd(int if_index); + +/** + * set_tpl - set TPL enable/disable + * @if_index: network device index of the controlling device + * @tx_state: 0/1 (TPL Disable / TPL Enable) + * + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ) + **/ +int set_tpl_sd(int if_index, int tpl_state); + +/** + * get_tpl - get TPL state (disable / enable) + * @if_index: network device index of the controlling device + * + * Output: + * 0/1 (TPL Disable / TPL Enable) on success + * -1 - on failure (device is not capable of the operation) + **/ +int get_tpl_sd(int if_index); + +int get_bp_hw_reset_sd(int if_index); + +int set_bp_hw_reset_sd(int if_index, int status); + +/** + * set_tap - set TAP state + * @if_index: network device index of the controlling device + * @tap_mode: 1 tap mode , 0 normal nic mode + * Output: + * 0 - on success + * -1 - on failure (device not support TAP or it's a slave device) + **/ +int set_tap_sd(int if_index, int tap_mode); + +/** + * get_tap - Get TAP mode state + * @if_index: network device index of the controlling device + * Output: + * 0/1 - (off/on) on success + * -1 - on failure (device not support TAP or it's a slave device) + **/ +int get_tap_sd(int if_index); + +/** + * get_tap_change - Get change of TAP mode state from last status check + * @if_index: network device index of the controlling device + * Output: + * 0/1 - (off/on) on success + * -1 - on failure (device not support TAP or it's a slave device) + **/ +int get_tap_change_sd(int if_index); + +/** + * set_dis_tap - Set Disable TAP mode + * @if_index: network device index of the controlling device + * @dis_tap: disable tap(1=dis, 0=en) + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ordevice not support TAP + * or it's a slave device) + **/ +int set_dis_tap_sd(int if_index, int dis_tap); + +/** + * get_dis_tap - Get Disable TAP mode state + * @if_index: network device index of the controlling device + * Output: + * 0/1 - on success (normal TAP mode/ Disable TAP) + * -1 - on failure (device is not capable of the operation ordevice not support TAP + * or it's a slave device) + **/ +int get_dis_tap_sd(int if_index); + +/** + * set_tap_pwup - Set TAP mode at power-up state + * @if_index: network device index of the controlling device + * @bypass_mode: tap mode setting at power up state (1=TAP en, 0=TAP Dis) + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ordevice not support TAP + * or it's a slave device) + **/ +int set_tap_pwup_sd(int if_index, int tap_mode); + +/** + * get_tap_pwup - Get TAP mode state at power-up state + * @if_index: network device index of the controlling device + * Output: + * 0/1 - on success (Disable TAP at power up state / normal TAP mode) + * -1 - on failure (device is not capable of the operation ordevice not support TAP + * or it's a slave device) + **/ +int get_tap_pwup_sd(int if_index); + +/** + * set_wd_exp_mode - Set adapter state when WDT expired. + * @if_index: network device index of the controlling device + * @bypass_mode: adapter mode (1=tap mode, 0=bypass mode) + * Output: + * 0 - on success + * -1 - on failure (device not support Bypass or it's a slave device) + **/ +int set_wd_exp_mode_sd(int if_index, int bypass_mode); + +/** + * get_wd_exp_mode - Get adapter state when WDT expired. + * @if_index: network device index of the controlling device + * Output: + * 0/1 - (bypass/tap) on success + * -1 - on failure (device not support Bypass or it's a slave device) + **/ +int get_wd_exp_mode_sd(int if_index); + +/** + * set_wd_autoreset - reset WDT periodically. + * @if_index: network device index of the controlling device + * @bypass_mode: adapter mode (1=tap mode, 0=bypass mode) + * Output: + * 1 - on success + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device or unknown wdt status) + **/ +int set_wd_autoreset_sd(int if_index, int time); + +/** + * set_wd_autoreset - reset WDT periodically. + * @if_index: network device index of the controlling device + * @bypass_mode: adapter mode (1=tap mode, 0=bypass mode) + * Output: + * 1 - on success + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device or unknown wdt status) + **/ +int get_wd_autoreset_sd(int if_index); +/** + * set_disc - set DISC state + * @if_index: network device index of the controlling device + * @tap_mode: 1 DISC mode , 0 normal nic mode + * Output: + * 0 - on success + * -1 - on failure (device not support disconnect or it's a slave device) + **/ +int set_bp_disc_sd(int if_index, int disc_mode); + +/** + * get_disc - Get disc mode state + * @if_index: network device index of the controlling device + * Output: + * 0/1 - (off/on) on success + * -1 - on failure (device not support disconnect or it's a slave device) + **/ +int get_bp_disc_sd(int if_index); + +/** + * get_disc_change - Get change of DISC mode state from last status check + * @if_index: network device index of the controlling device + * Output: + * 0/1 - (off/on) on success + * -1 - on failure (device not support disconnect or it's a slave device) + **/ +int get_bp_disc_change_sd(int if_index); + +/** + * set_dis_disc - Set Disable DISC mode + * @if_index: network device index of the controlling device + * @dis_disc: disable disconnect(1=dis, 0=en) + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ordevice not support DISC + * or it's a slave device) + **/ +int set_bp_dis_disc_sd(int if_index, int dis_disc); + +/** + * get_dis_disc - Get Disable DISC mode state + * @if_index: network device index of the controlling device + * Output: + * 0/1 - on success (normal DISC mode/ Disable DISC) + * -1 - on failure (device is not capable of the operation ordevice not support TAP + * or it's a slave device) + **/ +int get_bp_dis_disc_sd(int if_index); + +/** + * set_disc_pwup - Set DISC mode at power-up state + * @if_index: network device index of the controlling device + * @disc_mode: DISC mode setting at power up state (1= en, 0= Dis) + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ordevice not support DISC + * or it's a slave device) + **/ +int set_bp_disc_pwup_sd(int if_index, int disc_mode); + +/** + * get_disc_pwup - Get DISC mode state at power-up state + * @if_index: network device index of the controlling device + * Output: + * 0/1 - on success (Disable DISC at power up state / normal DISC mode) + * -1 - on failure (device is not capable of the operation ordevice not support DISC + * or it's a slave device) + **/ +int get_bp_disc_pwup_sd(int if_index); + +int get_bypass_info_sd(int if_index, struct bp_info *bp_info); +int bp_if_scan_sd(void); +/*int get_dev_num_sd(void);*/ -- cgit v0.10.2 From 8b22b0b26fadb60417e18bc4d31b8b0f0b59a92d Mon Sep 17 00:00:00 2001 From: DanielC Date: Fri, 7 Sep 2012 21:29:14 -0700 Subject: Staging: silicom: C99 cleanup of bp_ioctl.h Signed-off-by: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/bp_ioctl.h b/drivers/staging/silicom/bp_ioctl.h index b592221..7621fe8 100644 --- a/drivers/staging/silicom/bp_ioctl.h +++ b/drivers/staging/silicom/bp_ioctl.h @@ -13,44 +13,44 @@ #ifndef BP_IOCTL_H #define BP_IOCTL_H -#define BP_CAP 0x01 //BIT_0 -#define BP_STATUS_CAP 0x02 //BIT_1 -#define BP_STATUS_CHANGE_CAP 0x04 //BIT_2 -#define SW_CTL_CAP 0x08 //BIT_3 -#define BP_DIS_CAP 0x10 //BIT_4 -#define BP_DIS_STATUS_CAP 0x20 //BIT_5 -#define STD_NIC_CAP 0x40 //BIT_6 -#define BP_PWOFF_ON_CAP 0x80 //BIT_7 -#define BP_PWOFF_OFF_CAP 0x0100 //BIT_8 -#define BP_PWOFF_CTL_CAP 0x0200 //BIT_9 -#define BP_PWUP_ON_CAP 0x0400 //BIT_10 -#define BP_PWUP_OFF_CAP 0x0800 //BIT_11 -#define BP_PWUP_CTL_CAP 0x1000 //BIT_12 -#define WD_CTL_CAP 0x2000 //BIT_13 -#define WD_STATUS_CAP 0x4000 //BIT_14 -#define WD_TIMEOUT_CAP 0x8000 //BIT_15 -#define TX_CTL_CAP 0x10000 //BIT_16 -#define TX_STATUS_CAP 0x20000 //BIT_17 -#define TAP_CAP 0x40000 //BIT_18 -#define TAP_STATUS_CAP 0x80000 //BIT_19 -#define TAP_STATUS_CHANGE_CAP 0x100000 //BIT_20 -#define TAP_DIS_CAP 0x200000 //BIT_21 -#define TAP_DIS_STATUS_CAP 0x400000 //BIT_22 -#define TAP_PWUP_ON_CAP 0x800000 //BIT_23 -#define TAP_PWUP_OFF_CAP 0x1000000 //BIT 24 -#define TAP_PWUP_CTL_CAP 0x2000000 //BIT 25 -#define NIC_CAP_NEG 0x4000000 //BIT 26 -#define TPL_CAP 0x8000000 //BIT 27 -#define DISC_CAP 0x10000000 //BIT 28 -#define DISC_DIS_CAP 0x20000000 //BIT 29 -#define DISC_PWUP_CTL_CAP 0x40000000 //BIT 30 +#define BP_CAP 0x01 /* BIT_0 */ +#define BP_STATUS_CAP 0x02 +#define BP_STATUS_CHANGE_CAP 0x04 +#define SW_CTL_CAP 0x08 +#define BP_DIS_CAP 0x10 +#define BP_DIS_STATUS_CAP 0x20 +#define STD_NIC_CAP 0x40 +#define BP_PWOFF_ON_CAP 0x80 +#define BP_PWOFF_OFF_CAP 0x0100 +#define BP_PWOFF_CTL_CAP 0x0200 +#define BP_PWUP_ON_CAP 0x0400 +#define BP_PWUP_OFF_CAP 0x0800 +#define BP_PWUP_CTL_CAP 0x1000 +#define WD_CTL_CAP 0x2000 +#define WD_STATUS_CAP 0x4000 +#define WD_TIMEOUT_CAP 0x8000 +#define TX_CTL_CAP 0x10000 +#define TX_STATUS_CAP 0x20000 +#define TAP_CAP 0x40000 +#define TAP_STATUS_CAP 0x80000 +#define TAP_STATUS_CHANGE_CAP 0x100000 +#define TAP_DIS_CAP 0x200000 +#define TAP_DIS_STATUS_CAP 0x400000 +#define TAP_PWUP_ON_CAP 0x800000 +#define TAP_PWUP_OFF_CAP 0x1000000 +#define TAP_PWUP_CTL_CAP 0x2000000 +#define NIC_CAP_NEG 0x4000000 +#define TPL_CAP 0x8000000 +#define DISC_CAP 0x10000000 +#define DISC_DIS_CAP 0x20000000 +#define DISC_PWUP_CTL_CAP 0x40000000 #define TPL2_CAP_EX 0x01 #define DISC_PORT_CAP_EX 0x02 #define WD_MIN_TIME_MASK(val) (val & 0xf) #define WD_STEP_COUNT_MASK(val) ((val & 0xf) << 5) -#define WDT_STEP_TIME 0x10 //BIT_4 +#define WDT_STEP_TIME 0x10 /* BIT_4 */ #define WD_MIN_TIME_GET(desc) (desc & 0xf) #define WD_STEP_COUNT_GET(desc) (desc>>5) & 0xf -- cgit v0.10.2 From 4bf8a6c0edc4d8953ebbb10e7ab8fa3dd2f6078a Mon Sep 17 00:00:00 2001 From: DanielC Date: Fri, 7 Sep 2012 21:31:17 -0700 Subject: Staging: silicom: C99 cleanup of bypass.h Signed-off-by: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/bypass.h b/drivers/staging/silicom/bypass.h index a1ac3b3..28765f7 100644 --- a/drivers/staging/silicom/bypass.h +++ b/drivers/staging/silicom/bypass.h @@ -33,44 +33,44 @@ #define PIC_SIGN_VALUE 0xcd #define STATUS_REG_ADDR 0 -#define WDT_EN_MASK 0x01 //BIT_0 -#define CMND_EN_MASK 0x02 //BIT_1 -#define DIS_BYPASS_CAP_MASK 0x04 //BIT_2 /* Bypass Cap is disable*/ -#define DFLT_PWRON_MASK 0x08 //BIT_3 -#define BYPASS_OFF_MASK 0x10 //BIT_4 -#define BYPASS_FLAG_MASK 0x20 //BIT_5 +#define WDT_EN_MASK 0x01 /* BIT_0 */ +#define CMND_EN_MASK 0x02 /* BIT_1 */ +#define DIS_BYPASS_CAP_MASK 0x04 /* BIT_2 Bypass Cap is disable*/ +#define DFLT_PWRON_MASK 0x08 /* BIT_3 */ +#define BYPASS_OFF_MASK 0x10 /* BIT_4 */ +#define BYPASS_FLAG_MASK 0x20 /* BIT_5 */ #define STD_NIC_MASK (DIS_BYPASS_CAP_MASK | BYPASS_OFF_MASK | DFLT_PWRON_MASK) -#define WD_EXP_FLAG_MASK 0x40 //BIT_6 -#define DFLT_PWROFF_MASK 0x80 //BIT_7 +#define WD_EXP_FLAG_MASK 0x40 /* BIT_6 */ +#define DFLT_PWROFF_MASK 0x80 /* BIT_7 */ #define STD_NIC_PWOFF_MASK (DIS_BYPASS_CAP_MASK | BYPASS_OFF_MASK | DFLT_PWRON_MASK | DFLT_PWROFF_MASK) #define PRODUCT_CAP_REG_ADDR 0x5 -#define BYPASS_SUPPORT_MASK 0x01 //BIT_0 -#define TAP_SUPPORT_MASK 0x02 //BIT_1 -#define NORMAL_UNSUPPORT_MASK 0x04 /*BIT_2 */ -#define DISC_SUPPORT_MASK 0x08 //BIT_3 -#define TPL2_SUPPORT_MASK 0x10 //BIT_4 -#define DISC_PORT_SUPPORT_MASK 0x20 //BIT_5 +#define BYPASS_SUPPORT_MASK 0x01 /* BIT_0 */ +#define TAP_SUPPORT_MASK 0x02 /* BIT_1 */ +#define NORMAL_UNSUPPORT_MASK 0x04 /* BIT_2 */ +#define DISC_SUPPORT_MASK 0x08 /* BIT_3 */ +#define TPL2_SUPPORT_MASK 0x10 /* BIT_4 */ +#define DISC_PORT_SUPPORT_MASK 0x20 /* BIT_5 */ #define STATUS_TAP_REG_ADDR 0x6 -#define WDTE_TAP_BPN_MASK 0x01 //BIT_1 /* 1 when wdt expired -> TAP, 0 - Bypass */ -#define DIS_TAP_CAP_MASK 0x04 //BIT_2 /* TAP Cap is disable*/ -#define DFLT_PWRON_TAP_MASK 0x08 //BIT_3 -#define TAP_OFF_MASK 0x10 //BIT_4 -#define TAP_FLAG_MASK 0x20 //BIT_5 +#define WDTE_TAP_BPN_MASK 0x01 /* BIT_1 1 when wdt expired -> TAP, 0 - Bypass */ +#define DIS_TAP_CAP_MASK 0x04 /* BIT_2 TAP Cap is disable*/ +#define DFLT_PWRON_TAP_MASK 0x08 /* BIT_3 */ +#define TAP_OFF_MASK 0x10 /* BIT_4 */ +#define TAP_FLAG_MASK 0x20 /* BIT_5 */ #define TX_DISA_MASK 0x40 #define TX_DISB_MASK 0x80 #define STD_NIC_TAP_MASK (DIS_TAP_CAP_MASK | TAP_OFF_MASK | DFLT_PWRON_TAP_MASK) #define STATUS_DISC_REG_ADDR 13 -#define WDTE_DISC_BPN_MASK 0x01 //BIT_0 /* 1 when wdt expired -> TAP, 0 - Bypass */ -#define STD_NIC_ON_MASK 0x02 //BIT_1 -#define DIS_DISC_CAP_MASK 0x04 //BIT_2 /* TAP Cap is disable*/ -#define DFLT_PWRON_DISC_MASK 0x08 //BIT_3 -#define DISC_OFF_MASK 0x10 //BIT_4 -#define DISC_FLAG_MASK 0x20 //BIT_5 -#define TPL2_FLAG_MASK 0x40 //BIT_6 +#define WDTE_DISC_BPN_MASK 0x01 /* BIT_0 1 when wdt expired -> TAP, 0 - Bypass */ +#define STD_NIC_ON_MASK 0x02 /* BIT_1 */ +#define DIS_DISC_CAP_MASK 0x04 /* BIT_2 TAP Cap is disable*/ +#define DFLT_PWRON_DISC_MASK 0x08 /* BIT_3 */ +#define DISC_OFF_MASK 0x10 /* BIT_4 */ +#define DISC_FLAG_MASK 0x20 /* BIT_5 */ +#define TPL2_FLAG_MASK 0x40 /* BIT_6 */ #define STD_NIC_DISC_MASK DIS_DISC_CAP_MASK #define CONT_CONFIG_REG_ADDR 12 @@ -100,9 +100,9 @@ #define TMRH_REG_ADDR 3 /* NEW_FW */ -#define WDT_INTERVAL 1 //5 //8 -#define WDT_CMND_INTERVAL 200 //50 -#define CMND_INTERVAL 200 //100 /* usec */ +#define WDT_INTERVAL 1 /* 5 //8 */ +#define WDT_CMND_INTERVAL 200 /* 50 */ +#define CMND_INTERVAL 200 /* 100 usec */ #define PULSE_TIME 100 /* OLD_FW */ -- cgit v0.10.2 From 6aa2039d81b1ab4b08c85236d8406f1383eddef6 Mon Sep 17 00:00:00 2001 From: DanielC Date: Fri, 7 Sep 2012 21:32:27 -0700 Subject: Staging: silicom: C99 cleanup of libbp_sd.h Signed-off-by: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/libbp_sd.h b/drivers/staging/silicom/libbp_sd.h index 06ddfd5..1ba8b84 100644 --- a/drivers/staging/silicom/libbp_sd.h +++ b/drivers/staging/silicom/libbp_sd.h @@ -13,33 +13,33 @@ /* */ /******************************************************************************/ -#define BP_CAP 0x01 //BIT_0 -#define BP_STATUS_CAP 0x02 //BIT_1 -#define BP_STATUS_CHANGE_CAP 0x04 //BIT_2 -#define SW_CTL_CAP 0x08 //BIT_3 -#define BP_DIS_CAP 0x10 //BIT_4 -#define BP_DIS_STATUS_CAP 0x20 //BIT_5 -#define STD_NIC_CAP 0x40 //BIT_6 -#define BP_PWOFF_ON_CAP 0x80 //BIT_7 -#define BP_PWOFF_OFF_CAP 0x0100 //BIT_8 -#define BP_PWOFF_CTL_CAP 0x0200 //BIT_9 -#define BP_PWUP_ON_CAP 0x0400 //BIT_10 -#define BP_PWUP_OFF_CAP 0x0800 //BIT_11 -#define BP_PWUP_CTL_CAP 0x1000 //BIT_12 -#define WD_CTL_CAP 0x2000 //BIT_13 -#define WD_STATUS_CAP 0x4000 //BIT_14 -#define WD_TIMEOUT_CAP 0x8000 //BIT_15 -#define TX_CTL_CAP 0x10000 //BIT_16 -#define TX_STATUS_CAP 0x20000 //BIT_17 -#define TAP_CAP 0x40000 //BIT_18 -#define TAP_STATUS_CAP 0x80000 //BIT_19 -#define TAP_STATUS_CHANGE_CAP 0x100000 //BIT_20 -#define TAP_DIS_CAP 0x200000 //BIT_21 -#define TAP_DIS_STATUS_CAP 0x400000 //BIT_22 -#define TAP_PWUP_ON_CAP 0x800000 //BIT_23 -#define TAP_PWUP_OFF_CAP 0x1000000 //BIT 24 -#define TAP_PWUP_CTL_CAP 0x2000000 //BIT 25 -#define NIC_CAP_NEG 0x4000000 //BIT 26 +#define BP_CAP 0x01 /* BIT_0 */ +#define BP_STATUS_CAP 0x02 +#define BP_STATUS_CHANGE_CAP 0x04 +#define SW_CTL_CAP 0x08 +#define BP_DIS_CAP 0x10 +#define BP_DIS_STATUS_CAP 0x20 +#define STD_NIC_CAP 0x40 +#define BP_PWOFF_ON_CAP 0x80 +#define BP_PWOFF_OFF_CAP 0x0100 +#define BP_PWOFF_CTL_CAP 0x0200 +#define BP_PWUP_ON_CAP 0x0400 +#define BP_PWUP_OFF_CAP 0x0800 +#define BP_PWUP_CTL_CAP 0x1000 +#define WD_CTL_CAP 0x2000 +#define WD_STATUS_CAP 0x4000 +#define WD_TIMEOUT_CAP 0x8000 +#define TX_CTL_CAP 0x10000 +#define TX_STATUS_CAP 0x20000 +#define TAP_CAP 0x40000 +#define TAP_STATUS_CAP 0x80000 +#define TAP_STATUS_CHANGE_CAP 0x100000 +#define TAP_DIS_CAP 0x200000 +#define TAP_DIS_STATUS_CAP 0x400000 +#define TAP_PWUP_ON_CAP 0x800000 +#define TAP_PWUP_OFF_CAP 0x1000000 +#define TAP_PWUP_CTL_CAP 0x2000000 +#define NIC_CAP_NEG 0x4000000 /* BIT 26 */ #define WD_MIN_TIME_GET(desc) (desc & 0xf) #define WD_STEP_COUNT_GET(desc) (desc>>5) & 0xf -- cgit v0.10.2 From ce56ade6ae74e604a4b5d6ea5b1d58960fa8e7aa Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 4 Sep 2012 13:38:00 +0100 Subject: iio: Drop timestamp parameter from buffer store_to callback Drop timestamp parameter from buffer store_to callback and subsequently from iio_push_to_buffer. The timestamp parameter is unused and it seems likely that it will stay unused in the future, so it should be safe to remove it. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c index c593eb23..314a405 100644 --- a/drivers/iio/accel/hid-sensor-accel-3d.c +++ b/drivers/iio/accel/hid-sensor-accel-3d.c @@ -198,7 +198,6 @@ static const struct iio_info accel_3d_info = { static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len) { struct iio_buffer *buffer = indio_dev->buffer; - s64 timestamp = iio_get_time_ns(); int datum_sz; dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n"); @@ -212,7 +211,7 @@ static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len) datum_sz); return; } - iio_push_to_buffer(buffer, (u8 *)data, timestamp); + iio_push_to_buffer(buffer, (u8 *)data); } /* Callback handler to send event after all samples are received and captured */ diff --git a/drivers/iio/adc/ad7266.c b/drivers/iio/adc/ad7266.c index 5c3f1ba..b11f214 100644 --- a/drivers/iio/adc/ad7266.c +++ b/drivers/iio/adc/ad7266.c @@ -99,7 +99,7 @@ static irqreturn_t ad7266_trigger_handler(int irq, void *p) if (ret == 0) { if (indio_dev->scan_timestamp) ((s64 *)st->data)[1] = pf->timestamp; - iio_push_to_buffer(buffer, (u8 *)st->data, pf->timestamp); + iio_push_to_buffer(buffer, (u8 *)st->data); } iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c index ae847c5..67baa13 100644 --- a/drivers/iio/adc/ad_sigma_delta.c +++ b/drivers/iio/adc/ad_sigma_delta.c @@ -391,7 +391,7 @@ static irqreturn_t ad_sd_trigger_handler(int irq, void *p) break; } - iio_push_to_buffer(indio_dev->buffer, (uint8_t *)data, pf->timestamp); + iio_push_to_buffer(indio_dev->buffer, (uint8_t *)data); iio_trigger_notify_done(indio_dev->trig); sigma_delta->irq_dis = false; diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index c1e4690..bc10091 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -82,7 +82,7 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p) *timestamp = pf->timestamp; } - buffer->access->store_to(buffer, (u8 *)st->buffer, pf->timestamp); + buffer->access->store_to(buffer, (u8 *)st->buffer); iio_trigger_notify_done(idev->trig); st->irq_enabled = true; diff --git a/drivers/iio/gyro/hid-sensor-gyro-3d.c b/drivers/iio/gyro/hid-sensor-gyro-3d.c index 94a4740..4c56ada 100644 --- a/drivers/iio/gyro/hid-sensor-gyro-3d.c +++ b/drivers/iio/gyro/hid-sensor-gyro-3d.c @@ -198,7 +198,6 @@ static const struct iio_info gyro_3d_info = { static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len) { struct iio_buffer *buffer = indio_dev->buffer; - s64 timestamp = iio_get_time_ns(); int datum_sz; dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n"); @@ -212,7 +211,7 @@ static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len) datum_sz); return; } - iio_push_to_buffer(buffer, (u8 *)data, timestamp); + iio_push_to_buffer(buffer, (u8 *)data); } /* Callback handler to send event after all samples are received and captured */ diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 774891c..d4ad374 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -682,12 +682,11 @@ static unsigned char *iio_demux(struct iio_buffer *buffer, return buffer->demux_bounce; } -int iio_push_to_buffer(struct iio_buffer *buffer, unsigned char *data, - s64 timestamp) +int iio_push_to_buffer(struct iio_buffer *buffer, unsigned char *data) { unsigned char *dataout = iio_demux(buffer, data); - return buffer->access->store_to(buffer, dataout, timestamp); + return buffer->access->store_to(buffer, dataout); } EXPORT_SYMBOL_GPL(iio_push_to_buffer); diff --git a/drivers/iio/kfifo_buf.c b/drivers/iio/kfifo_buf.c index 63da424..5bc5c86 100644 --- a/drivers/iio/kfifo_buf.c +++ b/drivers/iio/kfifo_buf.c @@ -95,8 +95,7 @@ static int iio_set_length_kfifo(struct iio_buffer *r, int length) } static int iio_store_to_kfifo(struct iio_buffer *r, - u8 *data, - s64 timestamp) + u8 *data) { int ret; struct iio_kfifo *kf = iio_to_kfifo(r); diff --git a/drivers/iio/light/adjd_s311.c b/drivers/iio/light/adjd_s311.c index 9a99f43..164b62b 100644 --- a/drivers/iio/light/adjd_s311.c +++ b/drivers/iio/light/adjd_s311.c @@ -187,7 +187,7 @@ static irqreturn_t adjd_s311_trigger_handler(int irq, void *p) if (indio_dev->scan_timestamp) *(s64 *)((u8 *)data->buffer + ALIGN(len, sizeof(s64))) = time_ns; - iio_push_to_buffer(buffer, (u8 *)data->buffer, time_ns); + iio_push_to_buffer(buffer, (u8 *)data->buffer); done: iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/iio/light/hid-sensor-als.c b/drivers/iio/light/hid-sensor-als.c index b3c8e91..96e3691 100644 --- a/drivers/iio/light/hid-sensor-als.c +++ b/drivers/iio/light/hid-sensor-als.c @@ -177,7 +177,6 @@ static const struct iio_info als_info = { static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len) { struct iio_buffer *buffer = indio_dev->buffer; - s64 timestamp = iio_get_time_ns(); int datum_sz; dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n"); @@ -191,7 +190,7 @@ static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len) datum_sz); return; } - iio_push_to_buffer(buffer, (u8 *)data, timestamp); + iio_push_to_buffer(buffer, (u8 *)data); } /* Callback handler to send event after all samples are received and captured */ diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c b/drivers/iio/magnetometer/hid-sensor-magn-3d.c index 397704e..c4f0d27 100644 --- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c +++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c @@ -199,7 +199,6 @@ static const struct iio_info magn_3d_info = { static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len) { struct iio_buffer *buffer = indio_dev->buffer; - s64 timestamp = iio_get_time_ns(); int datum_sz; dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n"); @@ -213,7 +212,7 @@ static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len) datum_sz); return; } - iio_push_to_buffer(buffer, (u8 *)data, timestamp); + iio_push_to_buffer(buffer, (u8 *)data); } /* Callback handler to send event after all samples are received and captured */ diff --git a/drivers/staging/iio/accel/adis16201_ring.c b/drivers/staging/iio/accel/adis16201_ring.c index 884dcf8..97c09f0 100644 --- a/drivers/staging/iio/accel/adis16201_ring.c +++ b/drivers/staging/iio/accel/adis16201_ring.c @@ -82,7 +82,7 @@ static irqreturn_t adis16201_trigger_handler(int irq, void *p) if (indio_dev->scan_timestamp) *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; - iio_push_to_buffer(indio_dev->buffer, (u8 *)data, pf->timestamp); + iio_push_to_buffer(indio_dev->buffer, (u8 *)data); kfree(data); done: diff --git a/drivers/staging/iio/accel/adis16203_ring.c b/drivers/staging/iio/accel/adis16203_ring.c index a7ff804..7507e1a 100644 --- a/drivers/staging/iio/accel/adis16203_ring.c +++ b/drivers/staging/iio/accel/adis16203_ring.c @@ -81,7 +81,7 @@ static irqreturn_t adis16203_trigger_handler(int irq, void *p) if (indio_dev->scan_timestamp) *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; - iio_push_to_buffer(indio_dev->buffer, (u8 *)data, pf->timestamp); + iio_push_to_buffer(indio_dev->buffer, (u8 *)data); kfree(data); done: diff --git a/drivers/staging/iio/accel/adis16204_ring.c b/drivers/staging/iio/accel/adis16204_ring.c index 16e36e3..4c976be 100644 --- a/drivers/staging/iio/accel/adis16204_ring.c +++ b/drivers/staging/iio/accel/adis16204_ring.c @@ -78,7 +78,7 @@ static irqreturn_t adis16204_trigger_handler(int irq, void *p) if (indio_dev->scan_timestamp) *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; - iio_push_to_buffer(indio_dev->buffer, (u8 *)data, pf->timestamp); + iio_push_to_buffer(indio_dev->buffer, (u8 *)data); kfree(data); done: diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c index 5cfeff4..f939e29 100644 --- a/drivers/staging/iio/accel/adis16209_ring.c +++ b/drivers/staging/iio/accel/adis16209_ring.c @@ -78,7 +78,7 @@ static irqreturn_t adis16209_trigger_handler(int irq, void *p) if (indio_dev->scan_timestamp) *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; - iio_push_to_buffer(indio_dev->buffer, (u8 *)data, pf->timestamp); + iio_push_to_buffer(indio_dev->buffer, (u8 *)data); kfree(data); done: diff --git a/drivers/staging/iio/accel/adis16240_ring.c b/drivers/staging/iio/accel/adis16240_ring.c index d5ec43e..caff8e2 100644 --- a/drivers/staging/iio/accel/adis16240_ring.c +++ b/drivers/staging/iio/accel/adis16240_ring.c @@ -76,7 +76,7 @@ static irqreturn_t adis16240_trigger_handler(int irq, void *p) if (indio_dev->scan_timestamp) *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; - iio_push_to_buffer(indio_dev->buffer, (u8 *)data, pf->timestamp); + iio_push_to_buffer(indio_dev->buffer, (u8 *)data); kfree(data); done: diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c index 9332762..247605c 100644 --- a/drivers/staging/iio/accel/lis3l02dq_ring.c +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c @@ -152,7 +152,7 @@ static irqreturn_t lis3l02dq_trigger_handler(int irq, void *p) if (indio_dev->scan_timestamp) *(s64 *)((u8 *)data + ALIGN(len, sizeof(s64))) = pf->timestamp; - iio_push_to_buffer(indio_dev->buffer, (u8 *)data, pf->timestamp); + iio_push_to_buffer(indio_dev->buffer, (u8 *)data); kfree(data); done: diff --git a/drivers/staging/iio/adc/ad7298_ring.c b/drivers/staging/iio/adc/ad7298_ring.c index 9fce404..c2906a8 100644 --- a/drivers/staging/iio/adc/ad7298_ring.c +++ b/drivers/staging/iio/adc/ad7298_ring.c @@ -93,7 +93,7 @@ static irqreturn_t ad7298_trigger_handler(int irq, void *p) indio_dev->masklength); i++) buf[i] = be16_to_cpu(st->rx_buf[i]); - iio_push_to_buffer(indio_dev->buffer, (u8 *)buf, time_ns); + iio_push_to_buffer(indio_dev->buffer, (u8 *)buf); done: iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/staging/iio/adc/ad7476_ring.c b/drivers/staging/iio/adc/ad7476_ring.c index 3741ac6..940681f 100644 --- a/drivers/staging/iio/adc/ad7476_ring.c +++ b/drivers/staging/iio/adc/ad7476_ring.c @@ -44,7 +44,7 @@ static irqreturn_t ad7476_trigger_handler(int irq, void *p) memcpy(rxbuf + indio_dev->scan_bytes - sizeof(s64), &time_ns, sizeof(time_ns)); - iio_push_to_buffer(indio_dev->buffer, rxbuf, time_ns); + iio_push_to_buffer(indio_dev->buffer, rxbuf); done: iio_trigger_notify_done(indio_dev->trig); kfree(rxbuf); diff --git a/drivers/staging/iio/adc/ad7606_ring.c b/drivers/staging/iio/adc/ad7606_ring.c index f4b009e..ba04d0f 100644 --- a/drivers/staging/iio/adc/ad7606_ring.c +++ b/drivers/staging/iio/adc/ad7606_ring.c @@ -83,7 +83,7 @@ static void ad7606_poll_bh_to_ring(struct work_struct *work_s) if (indio_dev->scan_timestamp) *((s64 *)(buf + indio_dev->scan_bytes - sizeof(s64))) = time_ns; - iio_push_to_buffer(indio_dev->buffer, buf, time_ns); + iio_push_to_buffer(indio_dev->buffer, buf); done: gpio_set_value(st->pdata->gpio_convst, 0); iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/staging/iio/adc/ad7887_ring.c b/drivers/staging/iio/adc/ad7887_ring.c index a4ff493..b39923b 100644 --- a/drivers/staging/iio/adc/ad7887_ring.c +++ b/drivers/staging/iio/adc/ad7887_ring.c @@ -95,7 +95,7 @@ static irqreturn_t ad7887_trigger_handler(int irq, void *p) memcpy(buf + indio_dev->scan_bytes - sizeof(s64), &time_ns, sizeof(time_ns)); - iio_push_to_buffer(indio_dev->buffer, buf, time_ns); + iio_push_to_buffer(indio_dev->buffer, buf); done: kfree(buf); iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/staging/iio/adc/ad799x_ring.c b/drivers/staging/iio/adc/ad799x_ring.c index 84275c3..86026d9 100644 --- a/drivers/staging/iio/adc/ad799x_ring.c +++ b/drivers/staging/iio/adc/ad799x_ring.c @@ -77,7 +77,7 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p) memcpy(rxbuf + indio_dev->scan_bytes - sizeof(s64), &time_ns, sizeof(time_ns)); - iio_push_to_buffer(indio_dev->buffer, rxbuf, time_ns); + iio_push_to_buffer(indio_dev->buffer, rxbuf); done: kfree(rxbuf); out: diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c index 774ae1b..5f74f3b 100644 --- a/drivers/staging/iio/adc/max1363_ring.c +++ b/drivers/staging/iio/adc/max1363_ring.c @@ -80,7 +80,7 @@ static irqreturn_t max1363_trigger_handler(int irq, void *p) if (indio_dev->scan_timestamp) memcpy(rxbuf + d_size - sizeof(s64), &time_ns, sizeof(time_ns)); - iio_push_to_buffer(indio_dev->buffer, rxbuf, time_ns); + iio_push_to_buffer(indio_dev->buffer, rxbuf); done_free: kfree(rxbuf); diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c index ae549e5..ca7c1fa 100644 --- a/drivers/staging/iio/adc/mxs-lradc.c +++ b/drivers/staging/iio/adc/mxs-lradc.c @@ -256,7 +256,7 @@ static irqreturn_t mxs_lradc_trigger_handler(int irq, void *p) *timestamp = pf->timestamp; } - iio_push_to_buffer(buffer, (u8 *)lradc->buffer, pf->timestamp); + iio_push_to_buffer(buffer, (u8 *)lradc->buffer); iio_trigger_notify_done(iio->trig); diff --git a/drivers/staging/iio/gyro/adis16260_ring.c b/drivers/staging/iio/gyro/adis16260_ring.c index e6e2345..e294cb4 100644 --- a/drivers/staging/iio/gyro/adis16260_ring.c +++ b/drivers/staging/iio/gyro/adis16260_ring.c @@ -81,7 +81,7 @@ static irqreturn_t adis16260_trigger_handler(int irq, void *p) if (indio_dev->scan_timestamp) *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; - iio_push_to_buffer(indio_dev->buffer, (u8 *)data, pf->timestamp); + iio_push_to_buffer(indio_dev->buffer, (u8 *)data); kfree(data); done: diff --git a/drivers/staging/iio/iio_simple_dummy_buffer.c b/drivers/staging/iio/iio_simple_dummy_buffer.c index e080213..1fd3809 100644 --- a/drivers/staging/iio/iio_simple_dummy_buffer.c +++ b/drivers/staging/iio/iio_simple_dummy_buffer.c @@ -87,7 +87,7 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p) if (indio_dev->scan_timestamp) *(s64 *)((u8 *)data + ALIGN(len, sizeof(s64))) = iio_get_time_ns(); - iio_push_to_buffer(buffer, (u8 *)data, pf->timestamp); + iio_push_to_buffer(buffer, (u8 *)data); kfree(data); diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c index 39a9be8..de21d47 100644 --- a/drivers/staging/iio/impedance-analyzer/ad5933.c +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c @@ -678,7 +678,7 @@ static void ad5933_work(struct work_struct *work) buf[0] = be16_to_cpu(buf[0]); } /* save datum to the ring */ - iio_push_to_buffer(ring, (u8 *)buf, iio_get_time_ns()); + iio_push_to_buffer(ring, (u8 *)buf); } else { /* no data available - try again later */ schedule_delayed_work(&st->work, st->poll_time_jiffies); diff --git a/drivers/staging/iio/imu/adis16400_ring.c b/drivers/staging/iio/imu/adis16400_ring.c index 6b71788..260bdd1 100644 --- a/drivers/staging/iio/imu/adis16400_ring.c +++ b/drivers/staging/iio/imu/adis16400_ring.c @@ -150,7 +150,7 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p) /* Guaranteed to be aligned with 8 byte boundary */ if (ring->scan_timestamp) *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; - iio_push_to_buffer(ring, (u8 *) data, pf->timestamp); + iio_push_to_buffer(ring, (u8 *) data); done: kfree(data); diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c index 23c107a..9e49bac 100644 --- a/drivers/staging/iio/meter/ade7758_ring.c +++ b/drivers/staging/iio/meter/ade7758_ring.c @@ -73,7 +73,7 @@ static irqreturn_t ade7758_trigger_handler(int irq, void *p) if (indio_dev->scan_timestamp) dat64[1] = pf->timestamp; - iio_push_to_buffer(indio_dev->buffer, (u8 *)dat64, pf->timestamp); + iio_push_to_buffer(indio_dev->buffer, (u8 *)dat64); iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c index f61c8fd..3a45f9a 100644 --- a/drivers/staging/iio/ring_sw.c +++ b/drivers/staging/iio/ring_sw.c @@ -65,7 +65,7 @@ static inline void __iio_free_sw_ring_buffer(struct iio_sw_ring_buffer *ring) /* Lock always held if their is a chance this may be called */ /* Only one of these per ring may run concurrently - enforced by drivers */ static int iio_store_to_sw_ring(struct iio_sw_ring_buffer *ring, - unsigned char *data, s64 timestamp) + unsigned char *data) { int ret = 0; unsigned char *temp_ptr, *change_test_ptr; @@ -256,11 +256,10 @@ error_ret: } static int iio_store_to_sw_rb(struct iio_buffer *r, - u8 *data, - s64 timestamp) + u8 *data) { struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r); - return iio_store_to_sw_ring(ring, data, timestamp); + return iio_store_to_sw_ring(ring, data); } static int iio_request_update_sw_rb(struct iio_buffer *r) diff --git a/include/linux/iio/buffer.h b/include/linux/iio/buffer.h index 8ba516f..c629b3a 100644 --- a/include/linux/iio/buffer.h +++ b/include/linux/iio/buffer.h @@ -36,7 +36,7 @@ struct iio_buffer; * any of them not existing. **/ struct iio_buffer_access_funcs { - int (*store_to)(struct iio_buffer *buffer, u8 *data, s64 timestamp); + int (*store_to)(struct iio_buffer *buffer, u8 *data); int (*read_first_n)(struct iio_buffer *buffer, size_t n, char __user *buf); @@ -118,10 +118,8 @@ int iio_scan_mask_set(struct iio_dev *indio_dev, * iio_push_to_buffer() - push to a registered buffer. * @buffer: IIO buffer structure for device * @data: the data to push to the buffer - * @timestamp: timestamp to associate with the data */ -int iio_push_to_buffer(struct iio_buffer *buffer, unsigned char *data, - s64 timestamp); +int iio_push_to_buffer(struct iio_buffer *buffer, unsigned char *data); int iio_update_demux(struct iio_dev *indio_dev); -- cgit v0.10.2 From 2fafbce25063ae2732f2f2d9f853f1d97145eab5 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 4 Sep 2012 10:10:00 +0100 Subject: iio:ad5446: Add support for the ad5300/ad5310/ad5320 The ad5300/ad5310/ad5320 is a family of single channel DACs with a SPI interface similar to the ad5601/ad5611/ad5621 but use a different shift factor for the data word. While we are at it also reorder the device part numbers in the ad5446 driver Kconfig to be ordered alphabetically. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig index 293b61d..7599d62 100644 --- a/drivers/iio/dac/Kconfig +++ b/drivers/iio/dac/Kconfig @@ -59,10 +59,10 @@ config AD5446 tristate "Analog Devices AD5446 and similar single channel DACs driver" depends on (SPI_MASTER || I2C) help - Say yes here to build support for Analog Devices AD5602, AD5612, AD5622, + Say yes here to build support for Analog Devices AD5300, AD5310, AD5320, AD5444, AD5446, AD5450, AD5451, AD5452, AD5453, AD5512A, AD5541A, AD5542A, - AD5543, AD5553, AD5601, AD5611, AD5620, AD5621, AD5640, AD5660, AD5662 - DACs. + AD5543, AD5553, AD5601, AD5602, AD5611, AD5612, AD5620, AD5621, AD5622, + AD5640, AD5660, AD5662 DACs. To compile this driver as a module, choose M here: the module will be called ad5446. diff --git a/drivers/iio/dac/ad5446.c b/drivers/iio/dac/ad5446.c index 7f11c1c..2b0968f 100644 --- a/drivers/iio/dac/ad5446.c +++ b/drivers/iio/dac/ad5446.c @@ -321,6 +321,9 @@ static int ad5660_write(struct ad5446_state *st, unsigned val) * parts are supported here. */ enum ad5446_supported_spi_device_ids { + ID_AD5300, + ID_AD5310, + ID_AD5320, ID_AD5444, ID_AD5446, ID_AD5450, @@ -341,6 +344,18 @@ enum ad5446_supported_spi_device_ids { }; static const struct ad5446_chip_info ad5446_spi_chip_info[] = { + [ID_AD5300] = { + .channel = AD5446_CHANNEL_POWERDOWN(8, 16, 4), + .write = ad5446_write, + }, + [ID_AD5310] = { + .channel = AD5446_CHANNEL_POWERDOWN(10, 16, 2), + .write = ad5446_write, + }, + [ID_AD5320] = { + .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 0), + .write = ad5446_write, + }, [ID_AD5444] = { .channel = AD5446_CHANNEL(12, 16, 2), .write = ad5446_write, @@ -418,6 +433,9 @@ static const struct ad5446_chip_info ad5446_spi_chip_info[] = { }; static const struct spi_device_id ad5446_spi_ids[] = { + {"ad5300", ID_AD5300}, + {"ad5310", ID_AD5310}, + {"ad5320", ID_AD5320}, {"ad5444", ID_AD5444}, {"ad5446", ID_AD5446}, {"ad5450", ID_AD5450}, -- cgit v0.10.2 From bf83238019cf091a32d3a8aeddf22282af992843 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 4 Sep 2012 10:10:00 +0100 Subject: iio:ad5446: Add device ids for ad5301/ad5311/ad5321 The ad5301/ad5311/ad5321 are software compatible to the ad5602/ad5612/ad5622. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig index 7599d62..7845263 100644 --- a/drivers/iio/dac/Kconfig +++ b/drivers/iio/dac/Kconfig @@ -59,10 +59,10 @@ config AD5446 tristate "Analog Devices AD5446 and similar single channel DACs driver" depends on (SPI_MASTER || I2C) help - Say yes here to build support for Analog Devices AD5300, AD5310, AD5320, - AD5444, AD5446, AD5450, AD5451, AD5452, AD5453, AD5512A, AD5541A, AD5542A, - AD5543, AD5553, AD5601, AD5602, AD5611, AD5612, AD5620, AD5621, AD5622, - AD5640, AD5660, AD5662 DACs. + Say yes here to build support for Analog Devices AD5300, AD5301, AD5310, + AD5311, AD5320, AD5321, AD5444, AD5446, AD5450, AD5451, AD5452, AD5453, + AD5512A, AD5541A, AD5542A, AD5543, AD5553, AD5601, AD5602, AD5611, AD5612, + AD5620, AD5621, AD5622, AD5640, AD5660, AD5662 DACs. To compile this driver as a module, choose M here: the module will be called ad5446. diff --git a/drivers/iio/dac/ad5446.c b/drivers/iio/dac/ad5446.c index 2b0968f..3310cbb 100644 --- a/drivers/iio/dac/ad5446.c +++ b/drivers/iio/dac/ad5446.c @@ -552,6 +552,9 @@ static int __devexit ad5446_i2c_remove(struct i2c_client *i2c) } static const struct i2c_device_id ad5446_i2c_ids[] = { + {"ad5301", ID_AD5602}, + {"ad5311", ID_AD5612}, + {"ad5321", ID_AD5622}, {"ad5602", ID_AD5602}, {"ad5612", ID_AD5612}, {"ad5622", ID_AD5622}, -- cgit v0.10.2 From 7b123c85bbb3fadbd02b82d77d5aee0c399b0e06 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 4 Sep 2012 16:26:00 +0100 Subject: staging:iio:adc: Add AD7791 driver This patch adds support for the Analog Devices AD7787, AD7788, AD7789, AD7790 and AD7791 Sigma Delta Analog-to-Digital converters. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index a2c5071..d0ae71e 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -18,6 +18,18 @@ config AD7266 Say yes here to build support for Analog Devices AD7265 and AD7266 ADCs. +config AD7791 + tristate "Analog Devices AD7791 ADC driver" + depends on SPI + select AD_SIGMA_DELTA + help + Say yes here to build support for Analog Devices AD7787, AD7788, AD7789, + AD7790 and AD7791 SPI analog to digital converters (ADC). If unsure, say + N (but it is safe to say "Y"). + + To compile this driver as a module, choose M here: the module will be + called ad7791. + config AT91_ADC tristate "Atmel AT91 ADC" depends on ARCH_AT91 diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index 5989356..f187ff6 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -4,4 +4,5 @@ obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o obj-$(CONFIG_AD7266) += ad7266.o +obj-$(CONFIG_AD7791) += ad7791.o obj-$(CONFIG_AT91_ADC) += at91_adc.o diff --git a/drivers/iio/adc/ad7791.c b/drivers/iio/adc/ad7791.c new file mode 100644 index 0000000..e937408 --- /dev/null +++ b/drivers/iio/adc/ad7791.c @@ -0,0 +1,460 @@ +/* + * AD7787/AD7788/AD7789/AD7790/AD7791 SPI ADC driver + * + * Copyright 2012 Analog Devices Inc. + * Author: Lars-Peter Clausen + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define AD7791_REG_COMM 0x0 /* For writes */ +#define AD7791_REG_STATUS 0x0 /* For reads */ +#define AD7791_REG_MODE 0x1 +#define AD7791_REG_FILTER 0x2 +#define AD7791_REG_DATA 0x3 + +#define AD7791_MODE_CONTINUOUS 0x00 +#define AD7791_MODE_SINGLE 0x02 +#define AD7791_MODE_POWERDOWN 0x03 + +#define AD7791_CH_AIN1P_AIN1N 0x00 +#define AD7791_CH_AIN2 0x01 +#define AD7791_CH_AIN1N_AIN1N 0x02 +#define AD7791_CH_AVDD_MONITOR 0x03 + +#define AD7791_FILTER_CLK_DIV_1 (0x0 << 4) +#define AD7791_FILTER_CLK_DIV_2 (0x1 << 4) +#define AD7791_FILTER_CLK_DIV_4 (0x2 << 4) +#define AD7791_FILTER_CLK_DIV_8 (0x3 << 4) +#define AD7791_FILTER_CLK_MASK (0x3 << 4) +#define AD7791_FILTER_RATE_120 0x0 +#define AD7791_FILTER_RATE_100 0x1 +#define AD7791_FILTER_RATE_33_3 0x2 +#define AD7791_FILTER_RATE_20 0x3 +#define AD7791_FILTER_RATE_16_6 0x4 +#define AD7791_FILTER_RATE_16_7 0x5 +#define AD7791_FILTER_RATE_13_3 0x6 +#define AD7791_FILTER_RATE_9_5 0x7 +#define AD7791_FILTER_RATE_MASK 0x7 + +#define AD7791_MODE_BUFFER BIT(1) +#define AD7791_MODE_UNIPOLAR BIT(2) +#define AD7791_MODE_BURNOUT BIT(3) +#define AD7791_MODE_SEL_MASK (0x3 << 6) +#define AD7791_MODE_SEL(x) ((x) << 6) + +#define DECLARE_AD7787_CHANNELS(name, bits, storagebits) \ +const struct iio_chan_spec name[] = { \ + AD_SD_DIFF_CHANNEL(0, 0, 0, AD7791_CH_AIN1P_AIN1N, \ + (bits), (storagebits), 0), \ + AD_SD_CHANNEL(1, 1, AD7791_CH_AIN2, (bits), (storagebits), 0), \ + AD_SD_SHORTED_CHANNEL(2, 0, AD7791_CH_AIN1N_AIN1N, \ + (bits), (storagebits), 0), \ + AD_SD_SUPPLY_CHANNEL(3, 2, AD7791_CH_AVDD_MONITOR, \ + (bits), (storagebits), 0), \ + IIO_CHAN_SOFT_TIMESTAMP(4), \ +} + +#define DECLARE_AD7791_CHANNELS(name, bits, storagebits) \ +const struct iio_chan_spec name[] = { \ + AD_SD_DIFF_CHANNEL(0, 0, 0, AD7791_CH_AIN1P_AIN1N, \ + (bits), (storagebits), 0), \ + AD_SD_SHORTED_CHANNEL(1, 0, AD7791_CH_AIN1N_AIN1N, \ + (bits), (storagebits), 0), \ + AD_SD_SUPPLY_CHANNEL(2, 1, AD7791_CH_AVDD_MONITOR, \ + (bits), (storagebits), 0), \ + IIO_CHAN_SOFT_TIMESTAMP(3), \ +} + +static DECLARE_AD7787_CHANNELS(ad7787_channels, 24, 32); +static DECLARE_AD7791_CHANNELS(ad7790_channels, 16, 16); +static DECLARE_AD7791_CHANNELS(ad7791_channels, 24, 32); + +enum { + AD7787, + AD7788, + AD7789, + AD7790, + AD7791, +}; + +enum ad7791_chip_info_flags { + AD7791_FLAG_HAS_FILTER = (1 << 0), + AD7791_FLAG_HAS_BUFFER = (1 << 1), + AD7791_FLAG_HAS_UNIPOLAR = (1 << 2), + AD7791_FLAG_HAS_BURNOUT = (1 << 3), +}; + +struct ad7791_chip_info { + const struct iio_chan_spec *channels; + unsigned int num_channels; + enum ad7791_chip_info_flags flags; +}; + +static const struct ad7791_chip_info ad7791_chip_infos[] = { + [AD7787] = { + .channels = ad7787_channels, + .num_channels = ARRAY_SIZE(ad7787_channels), + .flags = AD7791_FLAG_HAS_FILTER | AD7791_FLAG_HAS_BUFFER | + AD7791_FLAG_HAS_UNIPOLAR | AD7791_FLAG_HAS_BURNOUT, + }, + [AD7788] = { + .channels = ad7790_channels, + .num_channels = ARRAY_SIZE(ad7790_channels), + .flags = AD7791_FLAG_HAS_UNIPOLAR, + }, + [AD7789] = { + .channels = ad7791_channels, + .num_channels = ARRAY_SIZE(ad7791_channels), + .flags = AD7791_FLAG_HAS_UNIPOLAR, + }, + [AD7790] = { + .channels = ad7790_channels, + .num_channels = ARRAY_SIZE(ad7790_channels), + .flags = AD7791_FLAG_HAS_FILTER | AD7791_FLAG_HAS_BUFFER | + AD7791_FLAG_HAS_BURNOUT, + }, + [AD7791] = { + .channels = ad7791_channels, + .num_channels = ARRAY_SIZE(ad7791_channels), + .flags = AD7791_FLAG_HAS_FILTER | AD7791_FLAG_HAS_BUFFER | + AD7791_FLAG_HAS_UNIPOLAR | AD7791_FLAG_HAS_BURNOUT, + }, +}; + +struct ad7791_state { + struct ad_sigma_delta sd; + uint8_t mode; + uint8_t filter; + + struct regulator *reg; + const struct ad7791_chip_info *info; +}; + +static struct ad7791_state *ad_sigma_delta_to_ad7791(struct ad_sigma_delta *sd) +{ + return container_of(sd, struct ad7791_state, sd); +} + +static int ad7791_set_channel(struct ad_sigma_delta *sd, unsigned int channel) +{ + ad_sd_set_comm(sd, channel); + + return 0; +} + +static int ad7791_set_mode(struct ad_sigma_delta *sd, + enum ad_sigma_delta_mode mode) +{ + struct ad7791_state *st = ad_sigma_delta_to_ad7791(sd); + + switch (mode) { + case AD_SD_MODE_CONTINUOUS: + mode = AD7791_MODE_CONTINUOUS; + break; + case AD_SD_MODE_SINGLE: + mode = AD7791_MODE_SINGLE; + break; + case AD_SD_MODE_IDLE: + case AD_SD_MODE_POWERDOWN: + mode = AD7791_MODE_POWERDOWN; + break; + } + + st->mode &= ~AD7791_MODE_SEL_MASK; + st->mode |= AD7791_MODE_SEL(mode); + + return ad_sd_write_reg(sd, AD7791_REG_MODE, sizeof(st->mode), st->mode); +} + +static const struct ad_sigma_delta_info ad7791_sigma_delta_info = { + .set_channel = ad7791_set_channel, + .set_mode = ad7791_set_mode, + .has_registers = true, + .addr_shift = 4, + .read_mask = BIT(3), +}; + +static int ad7791_read_raw(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, int *val, int *val2, long info) +{ + struct ad7791_state *st = iio_priv(indio_dev); + bool unipolar = !!(st->mode & AD7791_MODE_UNIPOLAR); + unsigned long long scale_pv; + + switch (info) { + case IIO_CHAN_INFO_RAW: + return ad_sigma_delta_single_conversion(indio_dev, chan, val); + case IIO_CHAN_INFO_OFFSET: + /** + * Unipolar: 0 to VREF + * Bipolar -VREF to VREF + **/ + if (unipolar) + *val = 0; + else + *val = -(1 << (chan->scan_type.realbits - 1)); + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + /* The monitor channel uses an internal reference. */ + if (chan->address == AD7791_CH_AVDD_MONITOR) { + scale_pv = 5850000000000ULL; + } else { + int voltage_uv; + + voltage_uv = regulator_get_voltage(st->reg); + if (voltage_uv < 0) + return voltage_uv; + scale_pv = (unsigned long long)voltage_uv * 1000000; + } + if (unipolar) + scale_pv >>= chan->scan_type.realbits; + else + scale_pv >>= chan->scan_type.realbits - 1; + *val2 = do_div(scale_pv, 1000000000); + *val = scale_pv; + + return IIO_VAL_INT_PLUS_NANO; + } + + return -EINVAL; +} + +static const char * const ad7791_sample_freq_avail[] = { + [AD7791_FILTER_RATE_120] = "120", + [AD7791_FILTER_RATE_100] = "100", + [AD7791_FILTER_RATE_33_3] = "33.3", + [AD7791_FILTER_RATE_20] = "20", + [AD7791_FILTER_RATE_16_6] = "16.6", + [AD7791_FILTER_RATE_16_7] = "16.7", + [AD7791_FILTER_RATE_13_3] = "13.3", + [AD7791_FILTER_RATE_9_5] = "9.5", +}; + +static ssize_t ad7791_read_frequency(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct ad7791_state *st = iio_priv(indio_dev); + unsigned int rate = st->filter & AD7791_FILTER_RATE_MASK; + + return sprintf(buf, "%s\n", ad7791_sample_freq_avail[rate]); +} + +static ssize_t ad7791_write_frequency(struct device *dev, + struct device_attribute *attr, const char *buf, size_t len) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct ad7791_state *st = iio_priv(indio_dev); + int i, ret; + + mutex_lock(&indio_dev->mlock); + if (iio_buffer_enabled(indio_dev)) { + mutex_unlock(&indio_dev->mlock); + return -EBUSY; + } + mutex_unlock(&indio_dev->mlock); + + ret = -EINVAL; + + for (i = 0; i < ARRAY_SIZE(ad7791_sample_freq_avail); i++) { + if (sysfs_streq(ad7791_sample_freq_avail[i], buf)) { + + mutex_lock(&indio_dev->mlock); + st->filter &= ~AD7791_FILTER_RATE_MASK; + st->filter |= i; + ad_sd_write_reg(&st->sd, AD7791_REG_FILTER, + sizeof(st->filter), st->filter); + mutex_unlock(&indio_dev->mlock); + ret = 0; + break; + } + } + + return ret ? ret : len; +} + +static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, + ad7791_read_frequency, + ad7791_write_frequency); + +static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("120 100 33.3 20 16.7 16.6 13.3 9.5"); + +static struct attribute *ad7791_attributes[] = { + &iio_dev_attr_sampling_frequency.dev_attr.attr, + &iio_const_attr_sampling_frequency_available.dev_attr.attr, + NULL +}; + +static const struct attribute_group ad7791_attribute_group = { + .attrs = ad7791_attributes, +}; + +static const struct iio_info ad7791_info = { + .read_raw = &ad7791_read_raw, + .attrs = &ad7791_attribute_group, + .validate_trigger = ad_sd_validate_trigger, + .driver_module = THIS_MODULE, +}; + +static const struct iio_info ad7791_no_filter_info = { + .read_raw = &ad7791_read_raw, + .validate_trigger = ad_sd_validate_trigger, + .driver_module = THIS_MODULE, +}; + +static int __devinit ad7791_setup(struct ad7791_state *st, + struct ad7791_platform_data *pdata) +{ + /* Set to poweron-reset default values */ + st->mode = AD7791_MODE_BUFFER; + st->filter = AD7791_FILTER_RATE_16_6; + + if (!pdata) + return 0; + + if ((st->info->flags & AD7791_FLAG_HAS_BUFFER) && !pdata->buffered) + st->mode &= ~AD7791_MODE_BUFFER; + + if ((st->info->flags & AD7791_FLAG_HAS_BURNOUT) && + pdata->burnout_current) + st->mode |= AD7791_MODE_BURNOUT; + + if ((st->info->flags & AD7791_FLAG_HAS_UNIPOLAR) && pdata->unipolar) + st->mode |= AD7791_MODE_UNIPOLAR; + + return ad_sd_write_reg(&st->sd, AD7791_REG_MODE, sizeof(st->mode), + st->mode); +} + +static int __devinit ad7791_probe(struct spi_device *spi) +{ + struct ad7791_platform_data *pdata = spi->dev.platform_data; + struct iio_dev *indio_dev; + struct ad7791_state *st; + int ret; + + if (!spi->irq) { + dev_err(&spi->dev, "Missing IRQ.\n"); + return -ENXIO; + } + + indio_dev = iio_device_alloc(sizeof(*st)); + if (!indio_dev) + return -ENOMEM; + + st = iio_priv(indio_dev); + + st->reg = regulator_get(&spi->dev, "refin"); + if (IS_ERR(st->reg)) { + ret = PTR_ERR(st->reg); + goto err_iio_free; + } + + ret = regulator_enable(st->reg); + if (ret) + goto error_put_reg; + + st->info = &ad7791_chip_infos[spi_get_device_id(spi)->driver_data]; + ad_sd_init(&st->sd, indio_dev, spi, &ad7791_sigma_delta_info); + + spi_set_drvdata(spi, indio_dev); + + indio_dev->dev.parent = &spi->dev; + indio_dev->name = spi_get_device_id(spi)->name; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = st->info->channels; + indio_dev->num_channels = st->info->num_channels; + if (st->info->flags & AD7791_FLAG_HAS_FILTER) + indio_dev->info = &ad7791_info; + else + indio_dev->info = &ad7791_no_filter_info; + + ret = ad_sd_setup_buffer_and_trigger(indio_dev); + if (ret) + goto error_disable_reg; + + ret = ad7791_setup(st, pdata); + if (ret) + goto error_remove_trigger; + + ret = iio_device_register(indio_dev); + if (ret) + goto error_remove_trigger; + + return 0; + +error_remove_trigger: + ad_sd_cleanup_buffer_and_trigger(indio_dev); +error_disable_reg: + regulator_disable(st->reg); +error_put_reg: + regulator_put(st->reg); +err_iio_free: + iio_device_free(indio_dev); + + return ret; +} + +static int __devexit ad7791_remove(struct spi_device *spi) +{ + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct ad7791_state *st = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + ad_sd_cleanup_buffer_and_trigger(indio_dev); + + regulator_disable(st->reg); + regulator_put(st->reg); + + iio_device_free(indio_dev); + + return 0; +} + +static const struct spi_device_id ad7791_spi_ids[] = { + { "ad7787", AD7787 }, + { "ad7788", AD7788 }, + { "ad7789", AD7789 }, + { "ad7790", AD7790 }, + { "ad7791", AD7791 }, + {} +}; +MODULE_DEVICE_TABLE(spi, ad7791_spi_ids); + +static struct spi_driver ad7791_driver = { + .driver = { + .name = "ad7791", + .owner = THIS_MODULE, + }, + .probe = ad7791_probe, + .remove = __devexit_p(ad7791_remove), + .id_table = ad7791_spi_ids, +}; +module_spi_driver(ad7791_driver); + +MODULE_AUTHOR("Lars-Peter Clausen "); +MODULE_DESCRIPTION("Analog Device AD7787/AD7788/AD7789/AD7790/AD7791 ADC driver"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/platform_data/ad7791.h b/include/linux/platform_data/ad7791.h new file mode 100644 index 0000000..f9e4db1 --- /dev/null +++ b/include/linux/platform_data/ad7791.h @@ -0,0 +1,17 @@ +#ifndef __LINUX_PLATFORM_DATA_AD7791__ +#define __LINUX_PLATFORM_DATA_AD7791__ + +/** + * struct ad7791_platform_data - AD7791 device platform data + * @buffered: If set to true configure the device for buffered input mode. + * @burnout_current: If set to true the 100mA burnout current is enabled. + * @unipolar: If set to true sample in unipolar mode, if set to false sample in + * bipolar mode. + */ +struct ad7791_platform_data { + bool buffered; + bool burnout_current; + bool unipolar; +}; + +#endif -- cgit v0.10.2 From 932323b74e2535dbb6a1b245dfa1aa8cd2bbd8e2 Mon Sep 17 00:00:00 2001 From: Bryan Freed Date: Wed, 5 Sep 2012 20:55:00 +0100 Subject: iio: isl29018: Support fractional ALS scaling. The Industrial IO framework supports scaling ADC values by fractions, but most drivers default to using whole numbers. This change turns on fractional scaling in the isl29018 driver. Signed-off-by: Bryan Freed Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/light/isl29018.c b/drivers/staging/iio/light/isl29018.c index 31d22f5..6ee5567 100644 --- a/drivers/staging/iio/light/isl29018.c +++ b/drivers/staging/iio/light/isl29018.c @@ -63,6 +63,7 @@ struct isl29018_chip { struct regmap *regmap; struct mutex lock; unsigned int lux_scale; + unsigned int lux_uscale; unsigned int range; unsigned int adc_bit; int prox_scheme; @@ -145,13 +146,22 @@ static int isl29018_read_sensor_input(struct isl29018_chip *chip, int mode) static int isl29018_read_lux(struct isl29018_chip *chip, int *lux) { int lux_data; + unsigned int data_x_range, lux_unshifted; lux_data = isl29018_read_sensor_input(chip, COMMMAND1_OPMODE_ALS_ONCE); if (lux_data < 0) return lux_data; - *lux = (lux_data * chip->range * chip->lux_scale) >> chip->adc_bit; + /* To support fractional scaling, separate the unshifted lux + * into two calculations: int scaling and micro-scaling. + * lux_uscale ranges from 0-999999, so about 20 bits. Split + * the /1,000,000 in two to reduce the risk of over/underflow. + */ + data_x_range = lux_data * chip->range; + lux_unshifted = data_x_range * chip->lux_scale; + lux_unshifted += data_x_range / 1000 * chip->lux_uscale / 1000; + *lux = lux_unshifted >> chip->adc_bit; return 0; } @@ -339,6 +349,8 @@ static int isl29018_write_raw(struct iio_dev *indio_dev, mutex_lock(&chip->lock); if (mask == IIO_CHAN_INFO_CALIBSCALE && chan->type == IIO_LIGHT) { chip->lux_scale = val; + /* With no write_raw_get_fmt(), val2 is a MICRO fraction. */ + chip->lux_uscale = val2; ret = 0; } mutex_unlock(&chip->lock); @@ -379,7 +391,8 @@ static int isl29018_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_CALIBSCALE: if (chan->type == IIO_LIGHT) { *val = chip->lux_scale; - ret = IIO_VAL_INT; + *val2 = chip->lux_uscale; + ret = IIO_VAL_INT_PLUS_MICRO; } break; default: -- cgit v0.10.2 From 9869a937d3a93c75c1d32e61df29149ce78ec3f9 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 10 Sep 2012 11:14:01 -0700 Subject: staging: ipack: make function tables const. Make some variables const: 1. bus oerations table 2. driver name 3. tpci control register table Signed-off-by: Stephen Hemminger Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 0d61090..302fc21 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -14,10 +14,8 @@ #include #include "tpci200.h" -static struct ipack_bus_ops tpci200_bus_ops; - /* TPCI200 controls registers */ -static int control_reg[] = { +static const int control_reg[] = { TPCI200_CONTROL_A_REG, TPCI200_CONTROL_B_REG, TPCI200_CONTROL_C_REG, @@ -532,7 +530,7 @@ static void tpci200_uninstall(struct tpci200_board *tpci200) kfree(tpci200->slots); } -static struct ipack_bus_ops tpci200_bus_ops = { +static const struct ipack_bus_ops tpci200_bus_ops = { .map_space = tpci200_slot_map_space, .unmap_space = tpci200_slot_unmap_space, .request_irq = tpci200_request_irq, diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c index 659aadc..af47772 100644 --- a/drivers/staging/ipack/ipack.c +++ b/drivers/staging/ipack/ipack.c @@ -209,7 +209,7 @@ static struct bus_type ipack_bus_type = { }; struct ipack_bus_device *ipack_bus_register(struct device *parent, int slots, - struct ipack_bus_ops *ops) + const struct ipack_bus_ops *ops) { int bus_nr; struct ipack_bus_device *bus; @@ -241,7 +241,7 @@ int ipack_bus_unregister(struct ipack_bus_device *bus) EXPORT_SYMBOL_GPL(ipack_bus_unregister); int ipack_driver_register(struct ipack_driver *edrv, struct module *owner, - char *name) + const char *name) { edrv->driver.owner = owner; edrv->driver.name = name; diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h index 0f482fd..4d73f75 100644 --- a/drivers/staging/ipack/ipack.h +++ b/drivers/staging/ipack/ipack.h @@ -134,7 +134,7 @@ struct ipack_bus_device { struct device *parent; int slots; int bus_nr; - struct ipack_bus_ops *ops; + const struct ipack_bus_ops *ops; }; /** @@ -148,7 +148,7 @@ struct ipack_bus_device { * available bus device in ipack. */ struct ipack_bus_device *ipack_bus_register(struct device *parent, int slots, - struct ipack_bus_ops *ops); + const struct ipack_bus_ops *ops); /** * ipack_bus_unregister -- unregister an ipack bus @@ -161,7 +161,8 @@ int ipack_bus_unregister(struct ipack_bus_device *bus); * Called by a ipack driver to register itself as a driver * that can manage ipack devices. */ -int ipack_driver_register(struct ipack_driver *edrv, struct module *owner, char *name); +int ipack_driver_register(struct ipack_driver *edrv, struct module *owner, + const char *name); void ipack_driver_unregister(struct ipack_driver *edrv); /** @@ -174,7 +175,8 @@ void ipack_driver_unregister(struct ipack_driver *edrv); * Register a new ipack device (mezzanine device). The call is done by * the carrier device driver. */ -struct ipack_device *ipack_device_register(struct ipack_bus_device *bus, int slot, int irqv); +struct ipack_device *ipack_device_register(struct ipack_bus_device *bus, + int slot, int irqv); void ipack_device_unregister(struct ipack_device *dev); /** -- cgit v0.10.2 From 739309d0cd8ad15234cba1d8df587c7eced5882a Mon Sep 17 00:00:00 2001 From: DanielC Date: Mon, 10 Sep 2012 19:18:12 -0700 Subject: Staging: silicom: Force depend on module Staging: silicom: Force depend on module until monolithic build fixed Reported-by: Stephen Rothwell Signed-off-by: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/Kconfig b/drivers/staging/silicom/Kconfig index 3493ee8..cb07a0d 100644 --- a/drivers/staging/silicom/Kconfig +++ b/drivers/staging/silicom/Kconfig @@ -5,7 +5,7 @@ config NET_VENDOR_SILICOM bool "Silicom devices" default y - depends on (SSB_POSSIBLE && HAS_DMA) || PCI + depends on PCI ---help--- If you have a network card (Ethernet) belonging to this class, say Y. @@ -19,6 +19,8 @@ if NET_VENDOR_SILICOM config SBYPASS tristate "Silicom BypassCTL library support" + depends on PCI + depends on m ---help--- If you have a network (Ethernet) controller of this type, say Y @@ -28,6 +30,7 @@ config SBYPASS config BPCTL tristate "Silicom BypassCTL net support" depends on PCI + depends on m select SBYPASS select NET_CORE select MII diff --git a/drivers/staging/silicom/TODO b/drivers/staging/silicom/TODO index bf60714..09d07b0 100644 --- a/drivers/staging/silicom/TODO +++ b/drivers/staging/silicom/TODO @@ -3,5 +3,6 @@ TODO: - locking audit - single module with all functionality - userland + - fix monolithic build. -- cgit v0.10.2 From 6935118817d40683bfac39837d0823d87dfc1678 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 10 Sep 2012 09:03:41 -0700 Subject: staging: fix ccg build when NET is not enabled Fix build errors in ccg when CONFIG_NET is not enabled by adding "depends on NET": ERROR: "netif_carrier_on" [drivers/staging/ccg/g_ccg.ko] undefined! ERROR: "netif_carrier_off" [drivers/staging/ccg/g_ccg.ko] undefined! ERROR: "skb_realloc_headroom" [drivers/staging/ccg/g_ccg.ko] undefined! ERROR: "skb_trim" [drivers/staging/ccg/g_ccg.ko] undefined! ERROR: "netif_rx" [drivers/staging/ccg/g_ccg.ko] undefined! ERROR: "ethtool_op_get_link" [drivers/staging/ccg/g_ccg.ko] undefined! ERROR: "free_netdev" [drivers/staging/ccg/g_ccg.ko] undefined! ERROR: "register_netdev" [drivers/staging/ccg/g_ccg.ko] undefined! ERROR: "skb_push" [drivers/staging/ccg/g_ccg.ko] undefined! ERROR: "skb_pull" [drivers/staging/ccg/g_ccg.ko] undefined! ERROR: "dev_kfree_skb_any" [drivers/staging/ccg/g_ccg.ko] undefined! ERROR: "skb_queue_tail" [drivers/staging/ccg/g_ccg.ko] undefined! ERROR: "__alloc_skb" [drivers/staging/ccg/g_ccg.ko] undefined! ERROR: "eth_type_trans" [drivers/staging/ccg/g_ccg.ko] undefined! ERROR: "eth_validate_addr" [drivers/staging/ccg/g_ccg.ko] undefined! ERROR: "skb_dequeue" [drivers/staging/ccg/g_ccg.ko] undefined! ERROR: "unregister_netdev" [drivers/staging/ccg/g_ccg.ko] undefined! ERROR: "__netif_schedule" [drivers/staging/ccg/g_ccg.ko] undefined! ERROR: "skb_put" [drivers/staging/ccg/g_ccg.ko] undefined! ERROR: "eth_mac_addr" [drivers/staging/ccg/g_ccg.ko] undefined! ERROR: "dev_get_stats" [drivers/staging/ccg/g_ccg.ko] undefined! ERROR: "alloc_etherdev_mqs" [drivers/staging/ccg/g_ccg.ko] undefined! Signed-off-by: Randy Dunlap Cc: Andrzej Pietrasiewicz Cc: Mike Lockwood Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ccg/Kconfig b/drivers/staging/ccg/Kconfig index 1f00d70..8598111 100644 --- a/drivers/staging/ccg/Kconfig +++ b/drivers/staging/ccg/Kconfig @@ -2,7 +2,7 @@ if USB_GADGET config USB_G_CCG tristate "Configurable Composite Gadget (STAGING)" - depends on STAGING && BLOCK && !USB_ZERO && !USB_ZERO_HNPTEST && !USB_AUDIO && !GADGET_UAC1 && !USB_ETH && !USB_ETH_RNDIS && !USB_ETH_EEM && !USB_G_NCM && !USB_GADGETFS && !USB_FUNCTIONFS && !USB_FUNCTIONFS_ETH && !USB_FUNCTIONFS_RNDIS && !USB_FUNCTIONFS_GENERIC && !USB_FILE_STORAGE && !USB_FILE_STORAGE_TEST && !USB_MASS_STORAGE && !USB_G_SERIAL && !USB_MIDI_GADGET && !USB_G_PRINTER && !USB_CDC_COMPOSITE && !USB_G_NOKIA && !USB_G_ACM_MS && !USB_G_MULTI && !USB_G_MULTI_RNDIS && !USB_G_MULTI_CDC && !USB_G_HID && !USB_G_DBGP && !USB_G_WEBCAM + depends on STAGING && BLOCK && NET && !USB_ZERO && !USB_ZERO_HNPTEST && !USB_AUDIO && !GADGET_UAC1 && !USB_ETH && !USB_ETH_RNDIS && !USB_ETH_EEM && !USB_G_NCM && !USB_GADGETFS && !USB_FUNCTIONFS && !USB_FUNCTIONFS_ETH && !USB_FUNCTIONFS_RNDIS && !USB_FUNCTIONFS_GENERIC && !USB_FILE_STORAGE && !USB_FILE_STORAGE_TEST && !USB_MASS_STORAGE && !USB_G_SERIAL && !USB_MIDI_GADGET && !USB_G_PRINTER && !USB_CDC_COMPOSITE && !USB_G_NOKIA && !USB_G_ACM_MS && !USB_G_MULTI && !USB_G_MULTI_RNDIS && !USB_G_MULTI_CDC && !USB_G_HID && !USB_G_DBGP && !USB_G_WEBCAM help The Configurable Composite Gadget supports multiple USB functions: acm, mass storage, rndis and FunctionFS. -- cgit v0.10.2 From d4d2dbcaedb9334d0c462129099346d617f61768 Mon Sep 17 00:00:00 2001 From: Fengguang Wu Date: Sun, 9 Sep 2012 16:23:46 +0800 Subject: Staging: panel: fix spinlock trylock failure on UP Use spin_lock_irq() to quiet warning: [ 8.232324] BUG: spinlock trylock failure on UP on CPU#0, reboot/85 [ 8.234138] lock: c161c760, .magic: dead4ead, .owner: reboot/85, .owner_cpu: 0 [ 8.236132] Pid: 85, comm: reboot Not tainted 3.4.0-rc7-00656-g82163ed #5 [ 8.237965] Call Trace: [ 8.238648] [] ? printk+0x18/0x1a [ 8.239827] [] spin_dump+0x80/0xd0 [ 8.241016] [] spin_bug+0x22/0x30 [ 8.242181] [] do_raw_spin_trylock+0x5b/0x70 [ 8.243611] [] _raw_spin_trylock+0xe/0x60 [ 8.244975] [] ? keypad_send_key.constprop.9+0xe0/0xe0 ==> [ 8.246638] [] panel_scan_timer+0xba/0x570 [ 8.248019] [] ? keypad_send_key.constprop.9+0xe0/0xe0 [ 8.249689] [] run_timer_softirq+0x1e5/0x370 [ 8.251191] [] ? run_timer_softirq+0x135/0x370 [ 8.252718] [] ? keypad_send_key.constprop.9+0xe0/0xe0 [ 8.254462] [] __do_softirq+0xc2/0x1c0 [ 8.255758] [] ? local_bh_enable_ip+0x130/0x130 [ 8.257228] [] ? irq_exit+0x65/0x70 [ 8.258647] [] ? smp_apic_timer_interrupt+0x49/0x80 [ 8.260226] [] ? apic_timer_interrupt+0x31/0x38 [ 8.261737] [] ? drm_vm_open_locked+0x70/0xb0 [ 8.263166] [] ? delay_tsc+0x1a/0x30 [ 8.264452] [] ? __delay+0x9/0x10 [ 8.265621] [] ? __const_udelay+0x1c/0x20 ==> [ 8.266967] [] ? lcd_clear_fast_p8+0x9c/0xe0 [ 8.268386] [] ? lcd_write+0x226/0x810 [ 8.269653] [] ? md_set_readonly+0xc0/0xc0 [ 8.271013] [] ? do_raw_spin_unlock+0x9d/0xe0 [ 8.272470] [] ? panel_lcd_print+0x38/0x40 [ 8.273837] [] ? panel_notify_sys+0x2e/0x60 [ 8.275224] [] ? notifier_call_chain+0x84/0xb0 [ 8.276754] [] ? __blocking_notifier_call_chain+0x3e/0x60 [ 8.278576] [] ? blocking_notifier_call_chain+0x1a/0x20 [ 8.280267] [] ? kernel_restart_prepare+0x14/0x40 [ 8.281901] [] ? kernel_restart+0xe/0x50 [ 8.283216] [] ? sys_reboot+0x149/0x1e0 [ 8.284532] [] ? handle_pte_fault+0x93/0xd70 [ 8.285956] [] ? do_page_fault+0x215/0x5e0 [ 8.287330] [] ? do_page_fault+0x4f3/0x5e0 [ 8.288704] [] ? up_read+0x16/0x30 [ 8.289890] [] ? do_page_fault+0x4f3/0x5e0 [ 8.291252] [] ? iterate_supers+0x86/0xd0 [ 8.292615] [] ? do_raw_spin_unlock+0x9d/0xe0 [ 8.294049] [] ? _raw_spin_unlock+0x1d/0x20 [ 8.295449] [] ? iterate_supers+0xab/0xd0 [ 8.296795] [] ? __sync_filesystem+0xa0/0xa0 [ 8.298199] [] ? sysenter_do_call+0x12/0x37 [ 8.306899] Restarting system. [ 8.307747] machine restart Signed-off-by: Fengguang Wu Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c index d9fec5b..f7426b4 100644 --- a/drivers/staging/panel/panel.c +++ b/drivers/staging/panel/panel.c @@ -757,38 +757,38 @@ static void lcd_backlight(int on) return; /* The backlight is activated by setting the AUTOFEED line to +5V */ - spin_lock(&pprt_lock); + spin_lock_irq(&pprt_lock); bits.bl = on; panel_set_bits(); - spin_unlock(&pprt_lock); + spin_unlock_irq(&pprt_lock); } /* send a command to the LCD panel in serial mode */ static void lcd_write_cmd_s(int cmd) { - spin_lock(&pprt_lock); + spin_lock_irq(&pprt_lock); lcd_send_serial(0x1F); /* R/W=W, RS=0 */ lcd_send_serial(cmd & 0x0F); lcd_send_serial((cmd >> 4) & 0x0F); udelay(40); /* the shortest command takes at least 40 us */ - spin_unlock(&pprt_lock); + spin_unlock_irq(&pprt_lock); } /* send data to the LCD panel in serial mode */ static void lcd_write_data_s(int data) { - spin_lock(&pprt_lock); + spin_lock_irq(&pprt_lock); lcd_send_serial(0x5F); /* R/W=W, RS=1 */ lcd_send_serial(data & 0x0F); lcd_send_serial((data >> 4) & 0x0F); udelay(40); /* the shortest data takes at least 40 us */ - spin_unlock(&pprt_lock); + spin_unlock_irq(&pprt_lock); } /* send a command to the LCD panel in 8 bits parallel mode */ static void lcd_write_cmd_p8(int cmd) { - spin_lock(&pprt_lock); + spin_lock_irq(&pprt_lock); /* present the data to the data port */ w_dtr(pprt, cmd); udelay(20); /* maintain the data during 20 us before the strobe */ @@ -804,13 +804,13 @@ static void lcd_write_cmd_p8(int cmd) set_ctrl_bits(); udelay(120); /* the shortest command takes at least 120 us */ - spin_unlock(&pprt_lock); + spin_unlock_irq(&pprt_lock); } /* send data to the LCD panel in 8 bits parallel mode */ static void lcd_write_data_p8(int data) { - spin_lock(&pprt_lock); + spin_lock_irq(&pprt_lock); /* present the data to the data port */ w_dtr(pprt, data); udelay(20); /* maintain the data during 20 us before the strobe */ @@ -826,27 +826,27 @@ static void lcd_write_data_p8(int data) set_ctrl_bits(); udelay(45); /* the shortest data takes at least 45 us */ - spin_unlock(&pprt_lock); + spin_unlock_irq(&pprt_lock); } /* send a command to the TI LCD panel */ static void lcd_write_cmd_tilcd(int cmd) { - spin_lock(&pprt_lock); + spin_lock_irq(&pprt_lock); /* present the data to the control port */ w_ctr(pprt, cmd); udelay(60); - spin_unlock(&pprt_lock); + spin_unlock_irq(&pprt_lock); } /* send data to the TI LCD panel */ static void lcd_write_data_tilcd(int data) { - spin_lock(&pprt_lock); + spin_lock_irq(&pprt_lock); /* present the data to the data port */ w_dtr(pprt, data); udelay(60); - spin_unlock(&pprt_lock); + spin_unlock_irq(&pprt_lock); } static void lcd_gotoxy(void) @@ -879,14 +879,14 @@ static void lcd_clear_fast_s(void) lcd_addr_x = lcd_addr_y = 0; lcd_gotoxy(); - spin_lock(&pprt_lock); + spin_lock_irq(&pprt_lock); for (pos = 0; pos < lcd_height * lcd_hwidth; pos++) { lcd_send_serial(0x5F); /* R/W=W, RS=1 */ lcd_send_serial(' ' & 0x0F); lcd_send_serial((' ' >> 4) & 0x0F); udelay(40); /* the shortest data takes at least 40 us */ } - spin_unlock(&pprt_lock); + spin_unlock_irq(&pprt_lock); lcd_addr_x = lcd_addr_y = 0; lcd_gotoxy(); @@ -899,7 +899,7 @@ static void lcd_clear_fast_p8(void) lcd_addr_x = lcd_addr_y = 0; lcd_gotoxy(); - spin_lock(&pprt_lock); + spin_lock_irq(&pprt_lock); for (pos = 0; pos < lcd_height * lcd_hwidth; pos++) { /* present the data to the data port */ w_dtr(pprt, ' '); @@ -921,7 +921,7 @@ static void lcd_clear_fast_p8(void) /* the shortest data takes at least 45 us */ udelay(45); } - spin_unlock(&pprt_lock); + spin_unlock_irq(&pprt_lock); lcd_addr_x = lcd_addr_y = 0; lcd_gotoxy(); @@ -934,14 +934,14 @@ static void lcd_clear_fast_tilcd(void) lcd_addr_x = lcd_addr_y = 0; lcd_gotoxy(); - spin_lock(&pprt_lock); + spin_lock_irq(&pprt_lock); for (pos = 0; pos < lcd_height * lcd_hwidth; pos++) { /* present the data to the data port */ w_dtr(pprt, ' '); udelay(60); } - spin_unlock(&pprt_lock); + spin_unlock_irq(&pprt_lock); lcd_addr_x = lcd_addr_y = 0; lcd_gotoxy(); @@ -1886,11 +1886,11 @@ static void panel_process_inputs(void) static void panel_scan_timer(void) { if (keypad_enabled && keypad_initialized) { - if (spin_trylock(&pprt_lock)) { + if (spin_trylock_irq(&pprt_lock)) { phys_scan_contacts(); /* no need for the parport anymore */ - spin_unlock(&pprt_lock); + spin_unlock_irq(&pprt_lock); } if (!inputs_stable || phys_curr != phys_prev) -- cgit v0.10.2 From a677ff913d594393cc98c6d01aa91e5b8bd76a6e Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:16:27 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_send_cmd_get_rsp) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks -WARNING: braces {} are not necessary for any arm of this statement Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 3cc9a48..3a7f869 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -192,9 +192,9 @@ RTY_SEND_CMD: stat_idx = 16; } else if (rsp_type != SD_RSP_TYPE_R0) { - for (reg_addr = REG_SD_CMD0; reg_addr <= REG_SD_CMD4; reg_addr++) { + for (reg_addr = REG_SD_CMD0; reg_addr <= REG_SD_CMD4; reg_addr++) rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); - } + stat_idx = 5; } @@ -273,9 +273,8 @@ RTY_SEND_CMD: if ((rsp_type == SD_RSP_TYPE_R1) || (rsp_type == SD_RSP_TYPE_R1b)) { if ((cmd_idx != SEND_RELATIVE_ADDR) && (cmd_idx != SEND_IF_COND)) { if (cmd_idx != STOP_TRANSMISSION) { - if (ptr[1] & 0x80) { + if (ptr[1] & 0x80) TRACE_RET(chip, STATUS_FAIL); - } } #ifdef SUPPORT_SD_LOCK if (ptr[1] & 0x7D) @@ -294,11 +293,10 @@ RTY_SEND_CMD: RTSX_DEBUGP("ptr[3]: 0x%02x\n", ptr[3]); TRACE_RET(chip, STATUS_FAIL); } - if (ptr[3] & 0x01) { + if (ptr[3] & 0x01) sd_card->sd_data_buf_ready = 1; - } else { + else sd_card->sd_data_buf_ready = 0; - } } } -- cgit v0.10.2 From 4857e2b09575be1eb7bb1196011f5b32d2b13bd7 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:22:43 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_read_data) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 3a7f869..4575212 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -320,17 +320,15 @@ static int sd_read_data(struct rtsx_chip *chip, if (!buf) buf_len = 0; - if (buf_len > 512) { + if (buf_len > 512) TRACE_RET(chip, STATUS_FAIL); - } rtsx_init_cmd(chip); if (cmd_len) { RTSX_DEBUGP("SD/MMC CMD %d\n", cmd[0] - 0x40); - for (i = 0; i < (cmd_len < 6 ? cmd_len : 6); i++) { + for (i = 0; i < (cmd_len < 6 ? cmd_len : 6); i++) rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0 + i, 0xFF, cmd[i]); - } } rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, (u8)byte_cnt); rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, (u8)(byte_cnt >> 8)); @@ -342,9 +340,9 @@ static int sd_read_data(struct rtsx_chip *chip, rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_6); - if (trans_mode != SD_TM_AUTO_TUNING) { + if (trans_mode != SD_TM_AUTO_TUNING) rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); - } + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, trans_mode | SD_TRANSFER_START); rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, SD_TRANSFER_END); @@ -360,9 +358,8 @@ static int sd_read_data(struct rtsx_chip *chip, if (buf && buf_len) { retval = rtsx_read_ppbuf(chip, buf, buf_len); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } return STATUS_SUCCESS; -- cgit v0.10.2 From 94c33a94845b19e16f97d73c4136810130c59b73 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:23:09 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_write_data) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 4575212..b9624f2 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -385,9 +385,8 @@ static int sd_write_data(struct rtsx_chip *chip, u8 trans_mode, if (buf && buf_len) { retval = rtsx_write_ppbuf(chip, buf, buf_len); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } rtsx_init_cmd(chip); -- cgit v0.10.2 From 9872233c2675df184230eace41177823554dfd36 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:23:29 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_check_csd) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks -WARNING: braces {} are not necessary for any arm of this statement Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index b9624f2..88163e1 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -444,15 +444,13 @@ static int sd_check_csd(struct rtsx_chip *chip, char check_wp) break; } - if (i == 6) { + if (i == 6) TRACE_RET(chip, STATUS_FAIL); - } memcpy(sd_card->raw_csd, rsp + 1, 15); - if (CHECK_PID(chip, 0x5209)) { + if (CHECK_PID(chip, 0x5209)) RTSX_READ_REG(chip, REG_SD_CMD5, sd_card->raw_csd + 15); - } RTSX_DEBUGP("CSD Response:\n"); RTSX_DUMP(sd_card->raw_csd, 16); @@ -463,35 +461,34 @@ static int sd_check_csd(struct rtsx_chip *chip, char check_wp) trans_speed = rsp[4]; if ((trans_speed & 0x07) == 0x02) { if ((trans_speed & 0xf8) >= 0x30) { - if (chip->asic_code) { + if (chip->asic_code) sd_card->sd_clock = 47; - } else { + else sd_card->sd_clock = CLK_50; - } + } else if ((trans_speed & 0xf8) == 0x28) { - if (chip->asic_code) { + if (chip->asic_code) sd_card->sd_clock = 39; - } else { + else sd_card->sd_clock = CLK_40; - } + } else if ((trans_speed & 0xf8) == 0x20) { - if (chip->asic_code) { + if (chip->asic_code) sd_card->sd_clock = 29; - } else { + else sd_card->sd_clock = CLK_30; - } + } else if ((trans_speed & 0xf8) >= 0x10) { - if (chip->asic_code) { + if (chip->asic_code) sd_card->sd_clock = 23; - } else { + else sd_card->sd_clock = CLK_20; - } + } else if ((trans_speed & 0x08) >= 0x08) { - if (chip->asic_code) { + if (chip->asic_code) sd_card->sd_clock = 19; - } else { + else sd_card->sd_clock = CLK_20; - } } else { TRACE_RET(chip, STATUS_FAIL); } @@ -521,9 +518,9 @@ static int sd_check_csd(struct rtsx_chip *chip, char check_wp) } if (check_wp) { - if (rsp[15] & 0x30) { + if (rsp[15] & 0x30) chip->card_wp |= SD_CARD; - } + RTSX_DEBUGP("CSD WP Status: 0x%x\n", rsp[15]); } -- cgit v0.10.2 From f75e617bcb21a43912696263efaec0c4ba9ef823 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:23:46 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_set_sample_push_timing) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks -WARNING: braces {} are not necessary for any arm of this statement Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 88163e1..28fc8a2 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -559,22 +559,21 @@ static int sd_set_sample_push_timing(struct rtsx_chip *chip) CRC_FIX_CLK | SD30_VAR_CLK0 | SAMPLE_VAR_CLK1); RTSX_WRITE_REG(chip, CLK_CTL, CLK_LOW_FREQ, 0); - if ((chip->sd_ctl & SD_PUSH_POINT_CTL_MASK) == SD_PUSH_POINT_AUTO) { + if ((chip->sd_ctl & SD_PUSH_POINT_CTL_MASK) == SD_PUSH_POINT_AUTO) val = SD20_TX_NEG_EDGE; - } else if ((chip->sd_ctl & SD_PUSH_POINT_CTL_MASK) == SD_PUSH_POINT_DELAY) { + else if ((chip->sd_ctl & SD_PUSH_POINT_CTL_MASK) == SD_PUSH_POINT_DELAY) val = SD20_TX_14_AHEAD; - } else { + else val = SD20_TX_NEG_EDGE; - } + RTSX_WRITE_REG(chip, SD_PUSH_POINT_CTL, SD20_TX_SEL_MASK, val); if ((chip->sd_ctl & SD_SAMPLE_POINT_CTL_MASK) == SD_SAMPLE_POINT_AUTO) { if (chip->asic_code) { - if (CHK_SD_HS(sd_card) || CHK_MMC_52M(sd_card)) { + if (CHK_SD_HS(sd_card) || CHK_MMC_52M(sd_card)) val = SD20_RX_14_DELAY; - } else { + else val = SD20_RX_POS_EDGE; - } } else { val = SD20_RX_14_DELAY; } @@ -588,32 +587,28 @@ static int sd_set_sample_push_timing(struct rtsx_chip *chip) } else { u8 val = 0; - if ((chip->sd_ctl & SD_PUSH_POINT_CTL_MASK) == SD_PUSH_POINT_DELAY) { + if ((chip->sd_ctl & SD_PUSH_POINT_CTL_MASK) == SD_PUSH_POINT_DELAY) val |= 0x10; - } if ((chip->sd_ctl & SD_SAMPLE_POINT_CTL_MASK) == SD_SAMPLE_POINT_AUTO) { if (chip->asic_code) { if (CHK_SD_HS(sd_card) || CHK_MMC_52M(sd_card)) { - if (val & 0x10) { + if (val & 0x10) val |= 0x04; - } else { + else val |= 0x08; - } } } else { - if (val & 0x10) { + if (val & 0x10) val |= 0x04; - } else { + else val |= 0x08; - } } } else if ((chip->sd_ctl & SD_SAMPLE_POINT_CTL_MASK) == SD_SAMPLE_POINT_DELAY) { - if (val & 0x10) { + if (val & 0x10) val |= 0x04; - } else { + else val |= 0x08; - } } RTSX_WRITE_REG(chip, REG_SD_CFG1, 0x1C, val); -- cgit v0.10.2 From 7ae856ebbc1f5fdbf1fba4c796fcf6cec2ae0f3f Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:24:03 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_choose_proper_clock) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for any arm of this statement Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 28fc8a2..4021295 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -622,41 +622,40 @@ static void sd_choose_proper_clock(struct rtsx_chip *chip) struct sd_info *sd_card = &(chip->sd_card); if (CHK_SD_SDR104(sd_card)) { - if (chip->asic_code) { + if (chip->asic_code) sd_card->sd_clock = chip->asic_sd_sdr104_clk; - } else { + else sd_card->sd_clock = chip->fpga_sd_sdr104_clk; - } + } else if (CHK_SD_DDR50(sd_card)) { - if (chip->asic_code) { + if (chip->asic_code) sd_card->sd_clock = chip->asic_sd_ddr50_clk; - } else { + else sd_card->sd_clock = chip->fpga_sd_ddr50_clk; - } + } else if (CHK_SD_SDR50(sd_card)) { - if (chip->asic_code) { + if (chip->asic_code) sd_card->sd_clock = chip->asic_sd_sdr50_clk; - } else { + else sd_card->sd_clock = chip->fpga_sd_sdr50_clk; - } + } else if (CHK_SD_HS(sd_card)) { - if (chip->asic_code) { + if (chip->asic_code) sd_card->sd_clock = chip->asic_sd_hs_clk; - } else { + else sd_card->sd_clock = chip->fpga_sd_hs_clk; - } + } else if (CHK_MMC_52M(sd_card) || CHK_MMC_DDR52(sd_card)) { - if (chip->asic_code) { + if (chip->asic_code) sd_card->sd_clock = chip->asic_mmc_52m_clk; - } else { + else sd_card->sd_clock = chip->fpga_mmc_52m_clk; - } + } else if (CHK_MMC_26M(sd_card)) { - if (chip->asic_code) { + if (chip->asic_code) sd_card->sd_clock = 48; - } else { + else sd_card->sd_clock = CLK_50; - } } } -- cgit v0.10.2 From 2d57f965c554d368c6f46d361c431fb5af9de541 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:24:26 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_set_clock_divider) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for any arm of this statement Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 4021295..1af5210 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -668,13 +668,12 @@ static int sd_set_clock_divider(struct rtsx_chip *chip, u8 clk_div) val = clk_div; } else { mask = 0x60; - if (clk_div == SD_CLK_DIVIDE_0) { + if (clk_div == SD_CLK_DIVIDE_0) val = 0x00; - } else if (clk_div == SD_CLK_DIVIDE_128) { + else if (clk_div == SD_CLK_DIVIDE_128) val = 0x40; - } else if (clk_div == SD_CLK_DIVIDE_256) { + else if (clk_div == SD_CLK_DIVIDE_256) val = 0x20; - } } RTSX_WRITE_REG(chip, REG_SD_CFG1, mask, val); -- cgit v0.10.2 From e06ed0db9709c968da1e78d3692b733a8ebc5f45 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:25:08 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_set_init_para) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 1af5210..89d0487 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -687,16 +687,14 @@ static int sd_set_init_para(struct rtsx_chip *chip) int retval; retval = sd_set_sample_push_timing(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } sd_choose_proper_clock(chip); retval = switch_clock(chip, sd_card->sd_clock); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } return STATUS_SUCCESS; } -- cgit v0.10.2 From c18a261a915cd1acc5ece124fb336fb64cc0b41a Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:25:48 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_select_card) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 89d0487..4b1763c 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -717,9 +717,8 @@ int sd_select_card(struct rtsx_chip *chip, int select) } retval = sd_send_cmd_get_rsp(chip, cmd_idx, addr, cmd_type, NULL, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } return STATUS_SUCCESS; } -- cgit v0.10.2 From 5e0738c1f4a76fa089566b1d528720348c6b5840 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:26:16 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_update_lock_status) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks -WARNING: braces {} are not necessary for any arm of this statement Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 4b1763c..2ace2a0 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -731,21 +731,18 @@ static int sd_update_lock_status(struct rtsx_chip *chip) u8 rsp[5]; retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, SD_RSP_TYPE_R1, rsp, 5); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } - if (rsp[1] & 0x02) { + if (rsp[1] & 0x02) sd_card->sd_lock_status |= SD_LOCKED; - } else { + else sd_card->sd_lock_status &= ~SD_LOCKED; - } RTSX_DEBUGP("sd_card->sd_lock_status = 0x%x\n", sd_card->sd_lock_status); - if (rsp[1] & 0x01) { + if (rsp[1] & 0x01) TRACE_RET(chip, STATUS_FAIL); - } return STATUS_SUCCESS; } -- cgit v0.10.2 From 4fd3f6a3ccead33fd14eb91df662e5cd8f6daff7 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:26:35 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_wait_state_data_ready) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 2ace2a0..8228231 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -757,13 +757,11 @@ static int sd_wait_state_data_ready(struct rtsx_chip *chip, u8 state, u8 data_re for (i = 0; i < polling_cnt; i++) { retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, SD_RSP_TYPE_R1, rsp, 5); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } - if (((rsp[3] & 0x1E) == state) && ((rsp[3] & 0x01) == data_ready)) { + if (((rsp[3] & 0x1E) == state) && ((rsp[3] & 0x01) == data_ready)) return STATUS_SUCCESS; - } } TRACE_RET(chip, STATUS_FAIL); -- cgit v0.10.2 From 3e49983827279204b33efbffb585de8ffe2d002f Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:27:08 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_change_bank_voltage) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 8228231..ed95a1a 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -774,18 +774,16 @@ static int sd_change_bank_voltage(struct rtsx_chip *chip, u8 voltage) if (voltage == SD_IO_3V3) { if (chip->asic_code) { retval = rtsx_write_phy_register(chip, 0x08, 0x4FC0 | chip->phy_voltage); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } else { RTSX_WRITE_REG(chip, SD_PAD_CTL, SD_IO_USING_1V8, 0); } } else if (voltage == SD_IO_1V8) { if (chip->asic_code) { retval = rtsx_write_phy_register(chip, 0x08, 0x4C40 | chip->phy_voltage); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } else { RTSX_WRITE_REG(chip, SD_PAD_CTL, SD_IO_USING_1V8, SD_IO_USING_1V8); } -- cgit v0.10.2 From ff514c1c53fb2a839b4a419df8e265ebb3facc95 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:27:24 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_voltage_switch) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index ed95a1a..6badbc4 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -802,9 +802,8 @@ static int sd_voltage_switch(struct rtsx_chip *chip) RTSX_WRITE_REG(chip, SD_BUS_STAT, SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, SD_CLK_TOGGLE_EN); retval = sd_send_cmd_get_rsp(chip, VOLTAGE_SWITCH, 0, SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } udelay(chip->sd_voltage_switch_delay); @@ -816,9 +815,9 @@ static int sd_voltage_switch(struct rtsx_chip *chip) RTSX_WRITE_REG(chip, SD_BUS_STAT, 0xFF, SD_CLK_FORCE_STOP); retval = sd_change_bank_voltage(chip, SD_IO_1V8); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + wait_timeout(50); RTSX_WRITE_REG(chip, SD_BUS_STAT, 0xFF, SD_CLK_TOGGLE_EN); -- cgit v0.10.2 From f6c608910ebfa53c98aee34eeb5a00829c970025 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:27:38 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_change_phase) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for any arm of this statement -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 6badbc4..67420f4 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -866,9 +866,8 @@ static int sd_change_phase(struct rtsx_chip *chip, u8 sample_point, u8 tune_dir) if (tune_dir == TUNE_RX) { SD_VP_CTL = SD_VPRX_CTL; SD_DCMPS_CTL = SD_DCMPS_RX_CTL; - if (CHK_SD_DDR50(sd_card)) { + if (CHK_SD_DDR50(sd_card)) ddr_rx = 1; - } } else { SD_VP_CTL = SD_VPTX_CTL; SD_DCMPS_CTL = SD_DCMPS_TX_CTL; @@ -905,23 +904,22 @@ static int sd_change_phase(struct rtsx_chip *chip, u8 sample_point, u8 tune_dir) rtsx_add_cmd(chip, WRITE_REG_CMD, SD_DCMPS_CTL, DCMPS_CHANGE, DCMPS_CHANGE); rtsx_add_cmd(chip, CHECK_REG_CMD, SD_DCMPS_CTL, DCMPS_CHANGE_DONE, DCMPS_CHANGE_DONE); retval = rtsx_send_cmd(chip, SD_CARD, 100); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, Fail); - } val = *rtsx_get_cmd_data(chip); - if (val & DCMPS_ERROR) { + if (val & DCMPS_ERROR) TRACE_GOTO(chip, Fail); - } - if ((val & DCMPS_CURRENT_PHASE) != sample_point) { + + if ((val & DCMPS_CURRENT_PHASE) != sample_point) TRACE_GOTO(chip, Fail); - } + RTSX_WRITE_REG(chip, SD_DCMPS_CTL, DCMPS_CHANGE, 0); - if (ddr_rx) { + if (ddr_rx) RTSX_WRITE_REG(chip, SD_VP_CTL, PHASE_CHANGE, 0); - } else { + else RTSX_WRITE_REG(chip, CLK_CTL, CHANGE_CLK, 0); - } + udelay(50); } -- cgit v0.10.2 From 97d31286b77e997dee9a78f945d84662d981eab9 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:27:54 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_check_spec) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 67420f4..aae9c72 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -949,9 +949,8 @@ static int sd_check_spec(struct rtsx_chip *chip, u8 bus_width) u8 cmd[5], buf[8]; retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } cmd[0] = 0x40 | SEND_SCR; cmd[1] = 0; @@ -967,9 +966,8 @@ static int sd_check_spec(struct rtsx_chip *chip, u8 bus_width) memcpy(sd_card->raw_scr, buf, 8); - if ((buf[0] & 0x0F) == 0) { + if ((buf[0] & 0x0F) == 0) TRACE_RET(chip, STATUS_FAIL); - } return STATUS_SUCCESS; } -- cgit v0.10.2 From 220e7b3cb5ed36347fb6c7f87207d8cb0387d71a Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:28:09 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_check_switch_mode) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index aae9c72..2b7a4e1 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -1141,13 +1141,12 @@ static int sd_check_switch_mode(struct rtsx_chip *chip, u8 mode, */ u16 cc = ((u16)buf[0] << 8) | buf[1]; RTSX_DEBUGP("Maximum current consumption: %dmA\n", cc); - if ((cc == 0) || (cc > 800)) { + if ((cc == 0) || (cc > 800)) TRACE_RET(chip, STATUS_FAIL); - } + retval = sd_query_switch_result(chip, func_group, func_to_switch, buf, 64); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if ((cc > 400) || (func_to_switch > CURRENT_LIMIT_400)) { RTSX_WRITE_REG(chip, OCPPARA2, SD_OCP_THD_MASK, chip->sd_800mA_ocp_thd); -- cgit v0.10.2 From 211ccb397b51ccb0953b0374c5c4f7e4df5574a8 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:28:28 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (downgrade_switch_mode) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 2b7a4e1..36b7f49 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -1160,13 +1160,12 @@ static int sd_check_switch_mode(struct rtsx_chip *chip, u8 mode, static u8 downgrade_switch_mode(u8 func_group, u8 func_to_switch) { if (func_group == SD_FUNC_GROUP_1) { - if (func_to_switch > HS_SUPPORT) { + if (func_to_switch > HS_SUPPORT) func_to_switch--; - } + } else if (func_group == SD_FUNC_GROUP_4) { - if (func_to_switch > CURRENT_LIMIT_200) { + if (func_to_switch > CURRENT_LIMIT_200) func_to_switch--; - } } return func_to_switch; -- cgit v0.10.2 From 04934c4747fd5459a918df0e9e8c2aa1d629b637 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:28:44 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_check_switch) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 36b7f49..c90deb6 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -1208,9 +1208,8 @@ static int sd_check_switch(struct rtsx_chip *chip, wait_timeout(20); } - if (!switch_good) { + if (!switch_good) TRACE_RET(chip, STATUS_FAIL); - } return STATUS_SUCCESS; } -- cgit v0.10.2 From 07d1aeace9eedc4e24b928796a4640493df295bd Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:29:00 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_switch_function) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for any arm of this statement -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index c90deb6..558f25b3 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -1224,9 +1224,8 @@ static int sd_switch_function(struct rtsx_chip *chip, u8 bus_width) /* Get supported functions */ retval = sd_check_switch_mode(chip, SD_CHECK_MODE, NO_ARGUMENT, NO_ARGUMENT, bus_width); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } sd_card->func_group1_mask &= ~(sd_card->sd_switch_fail); @@ -1255,9 +1254,9 @@ static int sd_switch_function(struct rtsx_chip *chip, u8 bus_width) break; case HS_SUPPORT: - if (sd_card->func_group1_mask & HS_SUPPORT_MASK) { + if (sd_card->func_group1_mask & HS_SUPPORT_MASK) func_to_switch = HS_SUPPORT; - } + break; default: @@ -1265,9 +1264,9 @@ static int sd_switch_function(struct rtsx_chip *chip, u8 bus_width) } - if (func_to_switch) { + if (func_to_switch) break; - } + } RTSX_DEBUGP("SD_FUNC_GROUP_1: func_to_switch = 0x%02x", func_to_switch); @@ -1296,23 +1295,21 @@ static int sd_switch_function(struct rtsx_chip *chip, u8 bus_width) TRACE_RET(chip, STATUS_FAIL); } - if (func_to_switch == SDR104_SUPPORT) { + if (func_to_switch == SDR104_SUPPORT) SET_SD_SDR104(sd_card); - } else if (func_to_switch == DDR50_SUPPORT) { + else if (func_to_switch == DDR50_SUPPORT) SET_SD_DDR50(sd_card); - } else if (func_to_switch == SDR50_SUPPORT) { + else if (func_to_switch == SDR50_SUPPORT) SET_SD_SDR50(sd_card); - } else { + else SET_SD_HS(sd_card); - } } if (CHK_SD_DDR50(sd_card)) { RTSX_WRITE_REG(chip, SD_PUSH_POINT_CTL, 0x06, 0x04); retval = sd_set_sample_push_timing(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } if (!func_to_switch || (func_to_switch == HS_SUPPORT)) { @@ -1328,36 +1325,35 @@ static int sd_switch_function(struct rtsx_chip *chip, u8 bus_width) for (i = 0; i < 4; i++) { switch ((u8)(chip->sd_current_prior >> (i*8))) { case CURRENT_LIMIT_800: - if (sd_card->func_group4_mask & CURRENT_LIMIT_800_MASK) { + if (sd_card->func_group4_mask & CURRENT_LIMIT_800_MASK) func_to_switch = CURRENT_LIMIT_800; - } + break; case CURRENT_LIMIT_600: - if (sd_card->func_group4_mask & CURRENT_LIMIT_600_MASK) { + if (sd_card->func_group4_mask & CURRENT_LIMIT_600_MASK) func_to_switch = CURRENT_LIMIT_600; - } + break; case CURRENT_LIMIT_400: - if (sd_card->func_group4_mask & CURRENT_LIMIT_400_MASK) { + if (sd_card->func_group4_mask & CURRENT_LIMIT_400_MASK) func_to_switch = CURRENT_LIMIT_400; - } + break; case CURRENT_LIMIT_200: - if (sd_card->func_group4_mask & CURRENT_LIMIT_200_MASK) { + if (sd_card->func_group4_mask & CURRENT_LIMIT_200_MASK) func_to_switch = CURRENT_LIMIT_200; - } + break; default: continue; } - if (func_to_switch != 0xFF) { + if (func_to_switch != 0xFF) break; - } } RTSX_DEBUGP("SD_FUNC_GROUP_4: func_to_switch = 0x%02x", func_to_switch); @@ -1365,16 +1361,14 @@ static int sd_switch_function(struct rtsx_chip *chip, u8 bus_width) if (func_to_switch <= CURRENT_LIMIT_800) { retval = sd_check_switch(chip, SD_FUNC_GROUP_4, func_to_switch, bus_width); if (retval != STATUS_SUCCESS) { - if (sd_check_err_code(chip, SD_NO_CARD)) { + if (sd_check_err_code(chip, SD_NO_CARD)) TRACE_RET(chip, STATUS_FAIL); - } } RTSX_DEBUGP("Switch current limit finished! (%d)\n", retval); } - if (CHK_SD_DDR50(sd_card)) { + if (CHK_SD_DDR50(sd_card)) RTSX_WRITE_REG(chip, SD_PUSH_POINT_CTL, 0x06, 0); - } return STATUS_SUCCESS; } -- cgit v0.10.2 From 79da2c59aa91930b6a3dd36e7cf948fc27f22940 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:29:15 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_sdr_tuning_rx_cmd) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 558f25b3..73ed6d8 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -1398,9 +1398,8 @@ static int sd_sdr_tuning_rx_cmd(struct rtsx_chip *chip, u8 sample_point) u8 cmd[5]; retval = sd_change_phase(chip, sample_point, TUNE_RX); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } cmd[0] = 0x40 | SEND_TUNING_PATTERN; cmd[1] = 0; -- cgit v0.10.2 From a616acb42f934d62e466937488fb60711ee16561 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:29:29 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_ddr_tuning_rx_cmd) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 73ed6d8..74c84e8 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -1426,16 +1426,14 @@ static int sd_ddr_tuning_rx_cmd(struct rtsx_chip *chip, u8 sample_point) u8 cmd[5]; retval = sd_change_phase(chip, sample_point, TUNE_RX); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } RTSX_DEBUGP("sd ddr tuning rx\n"); retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } cmd[0] = 0x40 | SD_STATUS; cmd[1] = 0; -- cgit v0.10.2 From cdca2196cd4793c157ddbf49f4f682a271510720 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:29:46 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (mmc_ddr_tunning_rx_cmd) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for any arm of this statement -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 74c84e8..bc91ff3 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -1459,18 +1459,16 @@ static int mmc_ddr_tunning_rx_cmd(struct rtsx_chip *chip, u8 sample_point) int retval; u8 cmd[5], bus_width; - if (CHK_MMC_8BIT(sd_card)) { + if (CHK_MMC_8BIT(sd_card)) bus_width = SD_BUS_WIDTH_8; - } else if (CHK_MMC_4BIT(sd_card)) { + else if (CHK_MMC_4BIT(sd_card)) bus_width = SD_BUS_WIDTH_4; - } else { + else bus_width = SD_BUS_WIDTH_1; - } retval = sd_change_phase(chip, sample_point, TUNE_RX); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } RTSX_DEBUGP("mmc ddr tuning rx\n"); -- cgit v0.10.2 From 8c0ede7818a813380ea4415283f82a74f626a9f7 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:30:01 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_sdr_tuning_tx_cmd) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index bc91ff3..6088d93 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -1496,9 +1496,8 @@ static int sd_sdr_tuning_tx_cmd(struct rtsx_chip *chip, u8 sample_point) int retval; retval = sd_change_phase(chip, sample_point, TUNE_TX); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } RTSX_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, SD_RSP_80CLK_TIMEOUT_EN); -- cgit v0.10.2 From 01d410af541c19a5c08a0bb7bdce7e50081a098a Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:30:16 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_ddr_tuning_tx_cmd) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for any arm of this statement -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 6088d93..24daabb 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -1522,26 +1522,23 @@ static int sd_ddr_tuning_tx_cmd(struct rtsx_chip *chip, u8 sample_point) u8 cmd[5], bus_width; retval = sd_change_phase(chip, sample_point, TUNE_TX); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (CHK_SD(sd_card)) { bus_width = SD_BUS_WIDTH_4; } else { - if (CHK_MMC_8BIT(sd_card)) { + if (CHK_MMC_8BIT(sd_card)) bus_width = SD_BUS_WIDTH_8; - } else if (CHK_MMC_4BIT(sd_card)) { + else if (CHK_MMC_4BIT(sd_card)) bus_width = SD_BUS_WIDTH_4; - } else { + else bus_width = SD_BUS_WIDTH_1; - } } retval = sd_wait_state_data_ready(chip, 0x08, 1, 1000); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } RTSX_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, SD_RSP_80CLK_TIMEOUT_EN); -- cgit v0.10.2 From 282dadbc4994030b0bec7ea3d59345bde5ab2d82 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:30:30 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_search_final_phase) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for any arm of this statement -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 24daabb..1dfabcf 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -1572,11 +1572,10 @@ static u8 sd_search_final_phase(struct rtsx_chip *chip, u32 phase_map, u8 tune_d u8 final_phase = 0xFF; if (phase_map == 0xFFFFFFFF) { - if (tune_dir == TUNE_RX) { + if (tune_dir == TUNE_RX) final_phase = (u8)chip->sd_default_rx_phase; - } else { + else final_phase = (u8)chip->sd_default_tx_phase; - } goto Search_Finish; } @@ -1617,9 +1616,9 @@ static u8 sd_search_final_phase(struct rtsx_chip *chip, u32 phase_map, u8 tune_d path[0].start = path[cont_path_cnt - 1].start - MAX_PHASE - 1; path[0].len += path[cont_path_cnt - 1].len; path[0].mid = path[0].start + path[0].len / 2; - if (path[0].mid < 0) { + if (path[0].mid < 0) path[0].mid += MAX_PHASE + 1; - } + cont_path_cnt--; } @@ -1647,11 +1646,10 @@ static u8 sd_search_final_phase(struct rtsx_chip *chip, u32 phase_map, u8 tune_d int temp_final_phase = path[final_path_idx].end - (max_len - (6 + temp_mid)); - if (temp_final_phase < 0) { + if (temp_final_phase < 0) final_phase = (u8)(temp_final_phase + MAX_PHASE + 1); - } else { + else final_phase = (u8)temp_final_phase; - } } } else if (CHK_SD_SDR50(sd_card)) { if (max_len > 12) { @@ -1659,11 +1657,10 @@ static u8 sd_search_final_phase(struct rtsx_chip *chip, u32 phase_map, u8 tune_d int temp_final_phase = path[final_path_idx].end - (max_len - (3 + temp_mid)); - if (temp_final_phase < 0) { + if (temp_final_phase < 0) final_phase = (u8)(temp_final_phase + MAX_PHASE + 1); - } else { + else final_phase = (u8)temp_final_phase; - } } } } -- cgit v0.10.2 From 5c39c0584a6dd5f4449869fed308ee4e91aec719 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:30:45 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_tuning_rx) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for any arm of this statement -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 1dfabcf..cb6ba17 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -1680,17 +1680,16 @@ static int sd_tuning_rx(struct rtsx_chip *chip) int (*tuning_cmd)(struct rtsx_chip *chip, u8 sample_point); if (CHK_SD(sd_card)) { - if (CHK_SD_DDR50(sd_card)) { + if (CHK_SD_DDR50(sd_card)) tuning_cmd = sd_ddr_tuning_rx_cmd; - } else { + else tuning_cmd = sd_sdr_tuning_rx_cmd; - } + } else { - if (CHK_MMC_DDR52(sd_card)) { + if (CHK_MMC_DDR52(sd_card)) tuning_cmd = mmc_ddr_tunning_rx_cmd; - } else { + else TRACE_RET(chip, STATUS_FAIL); - } } for (i = 0; i < 3; i++) { @@ -1702,27 +1701,24 @@ static int sd_tuning_rx(struct rtsx_chip *chip) } retval = tuning_cmd(chip, (u8)j); - if (retval == STATUS_SUCCESS) { + if (retval == STATUS_SUCCESS) raw_phase_map[i] |= 1 << j; - } } } phase_map = raw_phase_map[0] & raw_phase_map[1] & raw_phase_map[2]; - for (i = 0; i < 3; i++) { + for (i = 0; i < 3; i++) RTSX_DEBUGP("RX raw_phase_map[%d] = 0x%08x\n", i, raw_phase_map[i]); - } + RTSX_DEBUGP("RX phase_map = 0x%08x\n", phase_map); final_phase = sd_search_final_phase(chip, phase_map, TUNE_RX); - if (final_phase == 0xFF) { + if (final_phase == 0xFF) TRACE_RET(chip, STATUS_FAIL); - } retval = sd_change_phase(chip, final_phase, TUNE_RX); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } return STATUS_SUCCESS; } -- cgit v0.10.2 From 82ee0c898b358084248463355ad8f8cbadcf971d Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:31:04 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_ddr_pre_tuning_tx) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index cb6ba17..9812c00 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -1743,15 +1743,13 @@ static int sd_ddr_pre_tuning_tx(struct rtsx_chip *chip) } retval = sd_change_phase(chip, (u8)i, TUNE_TX); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) continue; - } retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); - if ((retval == STATUS_SUCCESS) || !sd_check_err_code(chip, SD_RSP_TIMEOUT)) { + if ((retval == STATUS_SUCCESS) || !sd_check_err_code(chip, SD_RSP_TIMEOUT)) phase_map |= 1 << i; - } } RTSX_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, 0); @@ -1759,14 +1757,12 @@ static int sd_ddr_pre_tuning_tx(struct rtsx_chip *chip) RTSX_DEBUGP("DDR TX pre tune phase_map = 0x%08x\n", phase_map); final_phase = sd_search_final_phase(chip, phase_map, TUNE_TX); - if (final_phase == 0xFF) { + if (final_phase == 0xFF) TRACE_RET(chip, STATUS_FAIL); - } retval = sd_change_phase(chip, final_phase, TUNE_TX); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } RTSX_DEBUGP("DDR TX pre tune phase: %d\n", (int)final_phase); -- cgit v0.10.2 From 25a52911a90838cc37b8eda092bed42381317791 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:31:19 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_tuning_tx) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for any arm of this statement -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 9812c00..02139b4 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -1779,17 +1779,16 @@ static int sd_tuning_tx(struct rtsx_chip *chip) int (*tuning_cmd)(struct rtsx_chip *chip, u8 sample_point); if (CHK_SD(sd_card)) { - if (CHK_SD_DDR50(sd_card)) { + if (CHK_SD_DDR50(sd_card)) tuning_cmd = sd_ddr_tuning_tx_cmd; - } else { + else tuning_cmd = sd_sdr_tuning_tx_cmd; - } + } else { - if (CHK_MMC_DDR52(sd_card)) { + if (CHK_MMC_DDR52(sd_card)) tuning_cmd = sd_ddr_tuning_tx_cmd; - } else { + else TRACE_RET(chip, STATUS_FAIL); - } } for (i = 0; i < 3; i++) { @@ -1803,27 +1802,24 @@ static int sd_tuning_tx(struct rtsx_chip *chip) } retval = tuning_cmd(chip, (u8)j); - if (retval == STATUS_SUCCESS) { + if (retval == STATUS_SUCCESS) raw_phase_map[i] |= 1 << j; - } } } phase_map = raw_phase_map[0] & raw_phase_map[1] & raw_phase_map[2]; - for (i = 0; i < 3; i++) { + for (i = 0; i < 3; i++) RTSX_DEBUGP("TX raw_phase_map[%d] = 0x%08x\n", i, raw_phase_map[i]); - } + RTSX_DEBUGP("TX phase_map = 0x%08x\n", phase_map); final_phase = sd_search_final_phase(chip, phase_map, TUNE_TX); - if (final_phase == 0xFF) { + if (final_phase == 0xFF) TRACE_RET(chip, STATUS_FAIL); - } retval = sd_change_phase(chip, final_phase, TUNE_TX); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } return STATUS_SUCCESS; } -- cgit v0.10.2 From 1b0ecf7f6c9e357e58a5ee6a5f9e98d13341602c Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:31:49 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_sdr_tuning) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 02139b4..b623c9f 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -1829,14 +1829,12 @@ static int sd_sdr_tuning(struct rtsx_chip *chip) int retval; retval = sd_tuning_tx(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = sd_tuning_rx(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } return STATUS_SUCCESS; } -- cgit v0.10.2 From 74bb35c389c564d98d162ae30ea084349ef0850d Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:32:32 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_ddr_tuning) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index b623c9f..0871a5d 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -1845,26 +1845,22 @@ static int sd_ddr_tuning(struct rtsx_chip *chip) if (!(chip->sd_ctl & SD_DDR_TX_PHASE_SET_BY_USER)) { retval = sd_ddr_pre_tuning_tx(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } else { retval = sd_change_phase(chip, (u8)chip->sd_ddr_tx_phase, TUNE_TX); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } retval = sd_tuning_rx(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (!(chip->sd_ctl & SD_DDR_TX_PHASE_SET_BY_USER)) { retval = sd_tuning_tx(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } return STATUS_SUCCESS; -- cgit v0.10.2 From d6cfef0bf6642d9e368d5b39b7896ea9de7d73bc Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:32:56 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (mmc_ddr_tuning) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 0871a5d..c22689c 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -1872,26 +1872,22 @@ static int mmc_ddr_tuning(struct rtsx_chip *chip) if (!(chip->sd_ctl & MMC_DDR_TX_PHASE_SET_BY_USER)) { retval = sd_ddr_pre_tuning_tx(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } else { retval = sd_change_phase(chip, (u8)chip->mmc_ddr_tx_phase, TUNE_TX); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } retval = sd_tuning_rx(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (!(chip->sd_ctl & MMC_DDR_TX_PHASE_SET_BY_USER)) { retval = sd_tuning_tx(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } return STATUS_SUCCESS; -- cgit v0.10.2 From 81f2ff3ba5bfe04088d151a8ba5040c5ed048f0f Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:33:16 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_switch_clock) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for any arm of this statement -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index c22689c..5e4e007 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -1900,9 +1900,8 @@ int sd_switch_clock(struct rtsx_chip *chip) int re_tuning = 0; retval = select_card(chip, SD_CARD); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (CHECK_PID(chip, 0x5209) && (CHK_SD30_SPEED(sd_card) || CHK_MMC_DDR52(sd_card))) { @@ -1913,26 +1912,22 @@ int sd_switch_clock(struct rtsx_chip *chip) } retval = switch_clock(chip, sd_card->sd_clock); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (re_tuning) { if (CHK_SD(sd_card)) { - if (CHK_SD_DDR50(sd_card)) { + if (CHK_SD_DDR50(sd_card)) retval = sd_ddr_tuning(chip); - } else { + else retval = sd_sdr_tuning(chip); - } } else { - if (CHK_MMC_DDR52(sd_card)) { + if (CHK_MMC_DDR52(sd_card)) retval = mmc_ddr_tuning(chip); - } } - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } return STATUS_SUCCESS; -- cgit v0.10.2 From 9e80f375e07c4d823e749ba9791c04958acf7f6b Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:33:45 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_prepare_reset) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for any arm of this statement -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 5e4e007..667e93d 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -1938,11 +1938,10 @@ static int sd_prepare_reset(struct rtsx_chip *chip) struct sd_info *sd_card = &(chip->sd_card); int retval; - if (chip->asic_code) { + if (chip->asic_code) sd_card->sd_clock = 29; - } else { + else sd_card->sd_clock = CLK_30; - } sd_card->sd_type = 0; sd_card->seq_mode = 0; @@ -1958,9 +1957,8 @@ static int sd_prepare_reset(struct rtsx_chip *chip) chip->sd_io = 0; retval = sd_set_init_para(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, retval); - } if (CHECK_PID(chip, 0x5209)) { RTSX_WRITE_REG(chip, REG_SD_CFG1, 0xFF, @@ -1974,9 +1972,8 @@ static int sd_prepare_reset(struct rtsx_chip *chip) RTSX_WRITE_REG(chip, CARD_STOP, SD_STOP | SD_CLR_ERR, SD_STOP | SD_CLR_ERR); retval = select_card(chip, SD_CARD); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } return STATUS_SUCCESS; } -- cgit v0.10.2 From 30b717e205c7ab5c7df0e12cfeaad9eec69e3fcb Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:34:00 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_pull_ctl_enable) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 667e93d..fa8cc86 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -2040,9 +2040,8 @@ int sd_pull_ctl_enable(struct rtsx_chip *chip) } retval = rtsx_send_cmd(chip, SD_CARD, 100); - if (retval < 0) { + if (retval < 0) TRACE_RET(chip, STATUS_FAIL); - } return STATUS_SUCCESS; } -- cgit v0.10.2 From 4a871500d2b545a5e99c2f3e5d1f216d2b97ff1e Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:34:14 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_init_power) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index fa8cc86..7be3805 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -2050,42 +2050,37 @@ static int sd_init_power(struct rtsx_chip *chip) { int retval; - if (CHECK_PID(chip, 0x5209)) { + if (CHECK_PID(chip, 0x5209)) RTSX_WRITE_REG(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_OFF); - } retval = sd_power_off_card3v3(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } - if (!chip->ft2_fast_mode) { + if (!chip->ft2_fast_mode) wait_timeout(250); - } retval = enable_card_clock(chip, SD_CARD); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (chip->asic_code) { retval = sd_pull_ctl_enable(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } else { RTSX_WRITE_REG(chip, FPGA_PULL_CTL, FPGA_SD_PULL_CTL_BIT | 0x20, 0); } if (chip->ft2_fast_mode) { - if (CHECK_PID(chip, 0x5209)) { + if (CHECK_PID(chip, 0x5209)) RTSX_WRITE_REG(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_ON); - } + } else { retval = card_power_on(chip, SD_CARD); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + wait_timeout(260); #ifdef SUPPORT_OCP -- cgit v0.10.2 From 715c7c8c27bd3cc1e1c577b25d27757d44795b63 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:34:28 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_read_lba0) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for any arm of this statement Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 7be3805..7318349 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -2126,13 +2126,12 @@ static int sd_read_lba0(struct rtsx_chip *chip) if (CHK_SD(sd_card)) { bus_width = SD_BUS_WIDTH_4; } else { - if (CHK_MMC_8BIT(sd_card)) { + if (CHK_MMC_8BIT(sd_card)) bus_width = SD_BUS_WIDTH_8; - } else if (CHK_MMC_4BIT(sd_card)) { + else if (CHK_MMC_4BIT(sd_card)) bus_width = SD_BUS_WIDTH_4; - } else { + else bus_width = SD_BUS_WIDTH_1; - } } retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, -- cgit v0.10.2 From 90538e412c5d70d41f6b89cd8617558f687534e3 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:34:44 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_check_wp_state) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 7318349..c9dc000 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -2154,9 +2154,8 @@ static int sd_check_wp_state(struct rtsx_chip *chip) retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } cmd[0] = 0x40 | SD_STATUS; cmd[1] = 0; @@ -2184,9 +2183,8 @@ static int sd_check_wp_state(struct rtsx_chip *chip) /* Check SD Machanical Write-Protect Switch */ val = rtsx_readl(chip, RTSX_BIPR); - if (val & SD_WRITE_PROTECT) { + if (val & SD_WRITE_PROTECT) chip->card_wp |= SD_CARD; - } return STATUS_SUCCESS; } -- cgit v0.10.2 From a1cf1468efa6273ddaf28ad00faa74a59aca489a Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:35:00 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (reset_sd) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for any arm of this statement -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index c9dc000..23fe9f2 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -2216,14 +2216,12 @@ Switch_Fail: #endif retval = sd_prepare_reset(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = sd_dummy_clock(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip) && try_sdio) { int rty_cnt = 0; @@ -2257,9 +2255,8 @@ Switch_Fail: /* Start Initialization Process of SD Card */ RTY_SD_RST: retval = sd_send_cmd_get_rsp(chip, GO_IDLE_STATE, 0, SD_RSP_TYPE_R0, NULL, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } wait_timeout(20); @@ -2286,9 +2283,8 @@ RTY_SD_RST: voltage = SUPPORT_VOLTAGE; retval = sd_send_cmd_get_rsp(chip, GO_IDLE_STATE, 0, SD_RSP_TYPE_R0, NULL, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } wait_timeout(20); } @@ -2302,42 +2298,38 @@ RTY_SD_RST: } j++; - if (j < 3) { + if (j < 3) goto RTY_SD_RST; - } else { + else TRACE_RET(chip, STATUS_FAIL); - } } retval = sd_send_cmd_get_rsp(chip, SD_APP_OP_COND, voltage, SD_RSP_TYPE_R3, rsp, 5); if (retval != STATUS_SUCCESS) { k++; - if (k < 3) { + if (k < 3) goto RTY_SD_RST; - } else { + else TRACE_RET(chip, STATUS_FAIL); - } } i++; wait_timeout(20); } while (!(rsp[1] & 0x80) && (i < 255)); - if (i == 255) { + if (i == 255) TRACE_RET(chip, STATUS_FAIL); - } if (hi_cap_flow) { - if (rsp[1] & 0x40) { + if (rsp[1] & 0x40) SET_SD_HCXC(sd_card); - } else { + else CLR_SD_HCXC(sd_card); - } - if (CHECK_PID(chip, 0x5209) && CHK_SD_HCXC(sd_card) && !sd20_mode) { + + if (CHECK_PID(chip, 0x5209) && CHK_SD_HCXC(sd_card) && !sd20_mode) support_1v8 = (rsp[1] & 0x01) ? 1 : 0; - } else { + else support_1v8 = 0; - } } else { CLR_SD_HCXC(sd_card); support_1v8 = 0; @@ -2346,46 +2338,39 @@ RTY_SD_RST: if (support_1v8) { retval = sd_voltage_switch(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } retval = sd_send_cmd_get_rsp(chip, ALL_SEND_CID, 0, SD_RSP_TYPE_R2, NULL, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } for (i = 0; i < 3; i++) { retval = sd_send_cmd_get_rsp(chip, SEND_RELATIVE_ADDR, 0, SD_RSP_TYPE_R6, rsp, 5); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } sd_card->sd_addr = (u32)rsp[1] << 24; sd_card->sd_addr += (u32)rsp[2] << 16; - if (sd_card->sd_addr) { + if (sd_card->sd_addr) break; - } } retval = sd_check_csd(chip, 1); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = sd_select_card(chip, 1); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } #ifdef SUPPORT_SD_LOCK SD_UNLOCK_ENTRY: retval = sd_update_lock_status(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (sd_card->sd_lock_status & SD_LOCKED) { sd_card->sd_lock_status |= (SD_LOCK_1BIT_MODE | SD_PWD_EXIST); @@ -2396,23 +2381,21 @@ SD_UNLOCK_ENTRY: #endif retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + retval = sd_send_cmd_get_rsp(chip, SET_CLR_CARD_DETECT, 0, SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (support_1v8) { retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + retval = sd_send_cmd_get_rsp(chip, SET_BUS_WIDTH, 2, SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } switch_bus_width = SD_BUS_WIDTH_4; } else { @@ -2420,14 +2403,12 @@ SD_UNLOCK_ENTRY: } retval = sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = sd_set_clock_divider(chip, SD_CLK_DIVIDE_0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (!(sd_card->raw_csd[4] & 0x40)) sd_dont_switch = 1; @@ -2446,9 +2427,9 @@ SD_UNLOCK_ENTRY: if (retval == STATUS_SUCCESS) { retval = sd_switch_function(chip, switch_bus_width); if (retval != STATUS_SUCCESS) { - if (CHECK_PID(chip, 0x5209)) { + if (CHECK_PID(chip, 0x5209)) sd_change_bank_voltage(chip, SD_IO_3V3); - } + sd_init_power(chip); sd_dont_switch = 1; try_sdio = 0; @@ -2457,9 +2438,9 @@ SD_UNLOCK_ENTRY: } } else { if (support_1v8) { - if (CHECK_PID(chip, 0x5209)) { + if (CHECK_PID(chip, 0x5209)) sd_change_bank_voltage(chip, SD_IO_3V3); - } + sd_init_power(chip); sd_dont_switch = 1; try_sdio = 0; @@ -2471,13 +2452,12 @@ SD_UNLOCK_ENTRY: if (!support_1v8) { retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + retval = sd_send_cmd_get_rsp(chip, SET_BUS_WIDTH, 2, SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } #ifdef SUPPORT_SD_LOCK @@ -2490,24 +2470,22 @@ SD_UNLOCK_ENTRY: RTSX_WRITE_REG(chip, SD30_DRIVE_SEL, 0x07, chip->sd30_drive_sel_1v8); retval = sd_set_init_para(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } - if (CHK_SD_DDR50(sd_card)) { + if (CHK_SD_DDR50(sd_card)) retval = sd_ddr_tuning(chip); - } else { + else retval = sd_sdr_tuning(chip); - } if (retval != STATUS_SUCCESS) { if (sd20_mode) { TRACE_RET(chip, STATUS_FAIL); } else { retval = sd_init_power(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + try_sdio = 0; sd20_mode = 1; goto Switch_Fail; @@ -2518,9 +2496,8 @@ SD_UNLOCK_ENTRY: if (CHK_SD_DDR50(sd_card)) { retval = sd_wait_state_data_ready(chip, 0x08, 1, 1000); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) read_lba0 = 0; - } } if (read_lba0) { @@ -2530,9 +2507,9 @@ SD_UNLOCK_ENTRY: TRACE_RET(chip, STATUS_FAIL); } else { retval = sd_init_power(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + try_sdio = 0; sd20_mode = 1; goto Switch_Fail; @@ -2542,9 +2519,8 @@ SD_UNLOCK_ENTRY: } retval = sd_check_wp_state(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } chip->card_bus_width[chip->card2lun[SD_CARD]] = 4; -- cgit v0.10.2 From 39ab26778bec39fe2a08e43ea0a7c2dc03d600e8 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:35:14 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (mmc_test_switch_bus) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for any arm of this statement -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 23fe9f2..ff8eb96 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -2544,9 +2544,8 @@ static int mmc_test_switch_bus(struct rtsx_chip *chip, u8 width) int len; retval = sd_send_cmd_get_rsp(chip, BUSTEST_W, 0, SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, SWITCH_FAIL); - } if (width == MMC_8BIT_BUS) { buf[0] = 0x55; @@ -2575,9 +2574,8 @@ static int mmc_test_switch_bus(struct rtsx_chip *chip, u8 width) rtsx_read_register(chip, REG_SD_STAT1, &val1); rtsx_read_register(chip, REG_SD_STAT2, &val2); rtsx_clear_sd_error(chip); - if ((val1 & 0xE0) || val2) { + if ((val1 & 0xE0) || val2) TRACE_RET(chip, SWITCH_ERR); - } } else { rtsx_clear_sd_error(chip); rtsx_write_register(chip, REG_SD_CFG3, 0x02, 0); @@ -2597,11 +2595,10 @@ static int mmc_test_switch_bus(struct rtsx_chip *chip, u8 width) rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, 0x40 | BUSTEST_R); - if (width == MMC_8BIT_BUS) { + if (width == MMC_8BIT_BUS) rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, 0x08); - } else { + else rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, 0x04); - } rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, 1); rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, 0); @@ -2614,9 +2611,8 @@ static int mmc_test_switch_bus(struct rtsx_chip *chip, u8 width) rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, SD_TRANSFER_END); rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2, 0, 0); - if (width == MMC_8BIT_BUS) { + if (width == MMC_8BIT_BUS) rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 1, 0, 0); - } retval = rtsx_send_cmd(chip, SD_CARD, 100); if (retval < 0) { @@ -2632,15 +2628,14 @@ static int mmc_test_switch_bus(struct rtsx_chip *chip, u8 width) u8 rsp[5]; u32 arg; - if (CHK_MMC_DDR52(sd_card)) { + if (CHK_MMC_DDR52(sd_card)) arg = 0x03B70600; - } else { + else arg = 0x03B70200; - } + retval = sd_send_cmd_get_rsp(chip, SWITCH, arg, SD_RSP_TYPE_R1b, rsp, 5); - if ((retval == STATUS_SUCCESS) && !(rsp[4] & MMC_SWITCH_ERR)) { + if ((retval == STATUS_SUCCESS) && !(rsp[4] & MMC_SWITCH_ERR)) return SWITCH_SUCCESS; - } } } else { RTSX_DEBUGP("BUSTEST_R [4bits]: 0x%02x\n", ptr[0]); @@ -2648,15 +2643,14 @@ static int mmc_test_switch_bus(struct rtsx_chip *chip, u8 width) u8 rsp[5]; u32 arg; - if (CHK_MMC_DDR52(sd_card)) { + if (CHK_MMC_DDR52(sd_card)) arg = 0x03B70500; - } else { + else arg = 0x03B70100; - } + retval = sd_send_cmd_get_rsp(chip, SWITCH, arg, SD_RSP_TYPE_R1b, rsp, 5); - if ((retval == STATUS_SUCCESS) && !(rsp[4] & MMC_SWITCH_ERR)) { + if ((retval == STATUS_SUCCESS) && !(rsp[4] & MMC_SWITCH_ERR)) return SWITCH_SUCCESS; - } } } -- cgit v0.10.2 From 35918dda5f9c20682a3d24702f974eecdc66467e Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:35:28 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (mmc_switch_timing_bus) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for any arm of this statement -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index ff8eb96..dfb728b 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -2724,11 +2724,10 @@ static int mmc_switch_timing_bus(struct rtsx_chip *chip, int switch_ddr) card_type_mask = 0x03; } #else - if (chip->sd_ctl & SUPPORT_MMC_DDR_MODE) { + if (chip->sd_ctl & SUPPORT_MMC_DDR_MODE) card_type_mask = 0x07; - } else { + else card_type_mask = 0x03; - } #endif } else { card_type_mask = 0x03; @@ -2738,11 +2737,10 @@ static int mmc_switch_timing_bus(struct rtsx_chip *chip, int switch_ddr) u8 rsp[5]; if (card_type & 0x04) { - if (switch_ddr) { + if (switch_ddr) SET_MMC_DDR52(sd_card); - } else { + else SET_MMC_52M(sd_card); - } } else if (card_type & 0x02) { SET_MMC_52M(sd_card); } else { @@ -2751,16 +2749,14 @@ static int mmc_switch_timing_bus(struct rtsx_chip *chip, int switch_ddr) retval = sd_send_cmd_get_rsp(chip, SWITCH, 0x03B90100, SD_RSP_TYPE_R1b, rsp, 5); - if ((retval != STATUS_SUCCESS) || (rsp[4] & MMC_SWITCH_ERR)) { + if ((retval != STATUS_SUCCESS) || (rsp[4] & MMC_SWITCH_ERR)) CLR_MMC_HS(sd_card); - } } sd_choose_proper_clock(chip); retval = switch_clock(chip, sd_card->sd_clock); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } /* Test Bus Procedure */ retval = mmc_test_switch_bus(chip, MMC_8BIT_BUS); -- cgit v0.10.2 From d8701f8be94ae25e757ef85dce955c31494d4ce7 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:35:41 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (reset_mmc) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for any arm of this statement -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index dfb728b..c117dc4 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -2804,17 +2804,15 @@ static int reset_mmc(struct rtsx_chip *chip) Switch_Fail: retval = sd_prepare_reset(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, retval); - } SET_MMC(sd_card); RTY_MMC_RST: retval = sd_send_cmd_get_rsp(chip, GO_IDLE_STATE, 0, SD_RSP_TYPE_R0, NULL, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } do { if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { @@ -2848,56 +2846,47 @@ RTY_MMC_RST: i++; } while (!(rsp[1] & 0x80) && (i < 255)); - if (i == 255) { + if (i == 255) TRACE_RET(chip, STATUS_FAIL); - } - if ((rsp[1] & 0x60) == 0x40) { + if ((rsp[1] & 0x60) == 0x40) SET_MMC_SECTOR_MODE(sd_card); - } else { + else CLR_MMC_SECTOR_MODE(sd_card); - } retval = sd_send_cmd_get_rsp(chip, ALL_SEND_CID, 0, SD_RSP_TYPE_R2, NULL, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } sd_card->sd_addr = 0x00100000; retval = sd_send_cmd_get_rsp(chip, SET_RELATIVE_ADDR, sd_card->sd_addr, SD_RSP_TYPE_R6, rsp, 5); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = sd_check_csd(chip, 1); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } spec_ver = (sd_card->raw_csd[0] & 0x3C) >> 2; retval = sd_select_card(chip, 1); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } #ifdef SUPPORT_SD_LOCK MMC_UNLOCK_ENTRY: retval = sd_update_lock_status(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } #endif retval = sd_set_clock_divider(chip, SD_CLK_DIVIDE_0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } chip->card_bus_width[chip->card2lun[SD_CARD]] = 1; @@ -2914,22 +2903,20 @@ MMC_UNLOCK_ENTRY: } } - if (CHK_MMC_SECTOR_MODE(sd_card) && (sd_card->capacity == 0)) { + if (CHK_MMC_SECTOR_MODE(sd_card) && (sd_card->capacity == 0)) TRACE_RET(chip, STATUS_FAIL); - } if (switch_ddr && CHK_MMC_DDR52(sd_card)) { retval = sd_set_init_para(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = mmc_ddr_tuning(chip); if (retval != STATUS_SUCCESS) { retval = sd_init_power(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + switch_ddr = 0; TRACE_GOTO(chip, Switch_Fail); } @@ -2939,9 +2926,9 @@ MMC_UNLOCK_ENTRY: retval = sd_read_lba0(chip); if (retval != STATUS_SUCCESS) { retval = sd_init_power(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + switch_ddr = 0; TRACE_GOTO(chip, Switch_Fail); } @@ -2957,9 +2944,8 @@ MMC_UNLOCK_ENTRY: #endif temp = rtsx_readl(chip, RTSX_BIPR); - if (temp & SD_WRITE_PROTECT) { + if (temp & SD_WRITE_PROTECT) chip->card_wp |= SD_CARD; - } return STATUS_SUCCESS; } -- cgit v0.10.2 From 891e1901b47cedb79b254c891090f558c1b1e614 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:35:56 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (reset_sd_card) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index c117dc4..f0b11a4 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -2961,36 +2961,31 @@ int reset_sd_card(struct rtsx_chip *chip) chip->capacity[chip->card2lun[SD_CARD]] = 0; retval = enable_card_clock(chip, SD_CARD); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (chip->ignore_sd && CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) { if (chip->asic_code) { retval = sd_pull_ctl_enable(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } else { retval = rtsx_write_register(chip, FPGA_PULL_CTL, FPGA_SD_PULL_CTL_BIT | 0x20, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } retval = card_share_mode(chip, SD_CARD); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } chip->sd_io = 1; TRACE_RET(chip, STATUS_FAIL); } retval = sd_init_power(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (chip->sd_ctl & RESET_MMC_FIRST) { retval = reset_mmc(chip); @@ -3029,18 +3024,17 @@ int reset_sd_card(struct rtsx_chip *chip) } retval = sd_set_clock_divider(chip, SD_CLK_DIVIDE_0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + RTSX_WRITE_REG(chip, REG_SD_BYTE_CNT_L, 0xFF, 0); RTSX_WRITE_REG(chip, REG_SD_BYTE_CNT_H, 0xFF, 2); chip->capacity[chip->card2lun[SD_CARD]] = sd_card->capacity; retval = sd_set_init_para(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } RTSX_DEBUGP("sd_card->sd_type = 0x%x\n", sd_card->sd_type); -- cgit v0.10.2 From 0c0276a6f2864914c4f72757222037ae7caca483 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:36:11 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (reset_mmc_only) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index f0b11a4..f109bbc 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -3060,33 +3060,29 @@ static int reset_mmc_only(struct rtsx_chip *chip) chip->capacity[chip->card2lun[SD_CARD]] = sd_card->capacity = 0; retval = enable_card_clock(chip, SD_CARD); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = sd_init_power(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = reset_mmc(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = sd_set_clock_divider(chip, SD_CLK_DIVIDE_0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + RTSX_WRITE_REG(chip, REG_SD_BYTE_CNT_L, 0xFF, 0); RTSX_WRITE_REG(chip, REG_SD_BYTE_CNT_H, 0xFF, 2); chip->capacity[chip->card2lun[SD_CARD]] = sd_card->capacity; retval = sd_set_init_para(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } RTSX_DEBUGP("In reset_mmc_only, sd_card->sd_type = 0x%x\n", sd_card->sd_type); -- cgit v0.10.2 From 629ec906db57eb339766c9018e2fc42dc5329fc5 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:36:24 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (wait_data_buf_ready) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index f109bbc..918caf5 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -3106,9 +3106,8 @@ static int wait_data_buf_ready(struct rtsx_chip *chip) retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (sd_card->sd_data_buf_ready) { return sd_send_cmd_get_rsp(chip, SEND_STATUS, -- cgit v0.10.2 From 3712cbd9435a5f8c2885193e1d894525f7716cad Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:36:37 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_stop_seq_mode) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 918caf5..272b2d4 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -3127,19 +3127,18 @@ void sd_stop_seq_mode(struct rtsx_chip *chip) if (sd_card->seq_mode) { retval = sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) return; - } retval = sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, 0, SD_RSP_TYPE_R1b, NULL, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) sd_set_err_code(chip, SD_STS_ERR); - } + retval = sd_wait_state_data_ready(chip, 0x08, 1, 1000); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) sd_set_err_code(chip, SD_STS_ERR); - } + sd_card->seq_mode = 0; rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH); -- cgit v0.10.2 From b324db1df36ddf352d5824d1ccf8c987e124e9d2 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:36:52 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_auto_tune_clock) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 272b2d4..d0f5512 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -3151,9 +3151,8 @@ static inline int sd_auto_tune_clock(struct rtsx_chip *chip) int retval; if (chip->asic_code) { - if (sd_card->sd_clock > 30) { + if (sd_card->sd_clock > 30) sd_card->sd_clock -= 20; - } } else { switch (sd_card->sd_clock) { case CLK_200: @@ -3186,9 +3185,8 @@ static inline int sd_auto_tune_clock(struct rtsx_chip *chip) } retval = sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } return STATUS_SUCCESS; } -- cgit v0.10.2 From 4225c65fdb9e57be70896771efbc37215c5aea45 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:37:05 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_rw) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for any arm of this statement -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index d0f5512..f2580a4 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -3224,11 +3224,10 @@ int sd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, u16 s } } - if (!CHK_SD_HCXC(sd_card) && !CHK_MMC_SECTOR_MODE(sd_card)) { + if (!CHK_SD_HCXC(sd_card) && !CHK_MMC_SECTOR_MODE(sd_card)) data_addr = start_sector << 9; - } else { + else data_addr = start_sector; - } sd_clr_err_code(chip); @@ -3283,21 +3282,19 @@ int sd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, u16 s rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); - if (CHK_MMC_8BIT(sd_card)) { + if (CHK_MMC_8BIT(sd_card)) rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_8); - } else if (CHK_MMC_4BIT(sd_card) || CHK_SD(sd_card)) { + else if (CHK_MMC_4BIT(sd_card) || CHK_SD(sd_card)) rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_4); - } else { + else rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_1); - } if (sd_card->seq_mode) { cfg2 = SD_NO_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END | SD_NO_CHECK_CRC7 | SD_RSP_LEN_0; if (CHECK_PID(chip, 0x5209)) { - if (!CHK_SD30_SPEED(sd_card)) { + if (!CHK_SD30_SPEED(sd_card)) cfg2 |= SD_NO_CHECK_WAIT_CRC_TO; - } } rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, cfg2); @@ -3327,9 +3324,8 @@ int sd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, u16 s cfg2 = SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_6; if (CHECK_PID(chip, 0x5209)) { - if (!CHK_SD30_SPEED(sd_card)) { + if (!CHK_SD30_SPEED(sd_card)) cfg2 |= SD_NO_CHECK_WAIT_CRC_TO; - } } rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, cfg2); @@ -3370,9 +3366,8 @@ int sd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, u16 s cfg2 = SD_NO_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END | SD_NO_CHECK_CRC7 | SD_RSP_LEN_0; if (CHECK_PID(chip, 0x5209)) { - if (!CHK_SD30_SPEED(sd_card)) { + if (!CHK_SD30_SPEED(sd_card)) cfg2 |= SD_NO_CHECK_WAIT_CRC_TO; - } } rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, cfg2); @@ -3397,11 +3392,10 @@ int sd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, u16 s sd_card->seq_mode = 0; - if (retval == -ETIMEDOUT) { + if (retval == -ETIMEDOUT) err = STATUS_TIMEDOUT; - } else { + else err = STATUS_FAIL; - } rtsx_read_register(chip, REG_SD_STAT1, &stat); rtsx_clear_sd_error(chip); -- cgit v0.10.2 From 0e72ad9e2eef7c7a897066b32e162d58fb82e87f Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:37:20 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (ext_sd_send_cmd_get_rsp) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index f2580a4..4168af6 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -3481,9 +3481,8 @@ int ext_sd_send_cmd_get_rsp(struct rtsx_chip *chip, u8 cmd_idx, RTSX_DEBUGP("EXT SD/MMC CMD %d\n", cmd_idx); - if (rsp_type == SD_RSP_TYPE_R1b) { + if (rsp_type == SD_RSP_TYPE_R1b) timeout = 3000; - } RTY_SEND_CMD: @@ -3503,14 +3502,14 @@ RTY_SEND_CMD: rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, SD_TRANSFER_END); if (rsp_type == SD_RSP_TYPE_R2) { - for (reg_addr = PPBUF_BASE2; reg_addr < PPBUF_BASE2 + 16; reg_addr++) { + for (reg_addr = PPBUF_BASE2; reg_addr < PPBUF_BASE2 + 16; reg_addr++) rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); - } + stat_idx = 17; } else if (rsp_type != SD_RSP_TYPE_R0) { - for (reg_addr = REG_SD_CMD0; reg_addr <= REG_SD_CMD4; reg_addr++) { + for (reg_addr = REG_SD_CMD0; reg_addr <= REG_SD_CMD4; reg_addr++) rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); - } + stat_idx = 6; } rtsx_add_cmd(chip, READ_REG_CMD, REG_SD_CMD5, 0, 0); @@ -3524,9 +3523,8 @@ RTY_SEND_CMD: if (rsp_type & SD_WAIT_BUSY_END) { retval = sd_check_data0_status(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, retval); - } } else { sd_set_err_code(chip, SD_TO_ERR); } @@ -3534,9 +3532,8 @@ RTY_SEND_CMD: TRACE_RET(chip, STATUS_FAIL); } - if (rsp_type == SD_RSP_TYPE_R0) { + if (rsp_type == SD_RSP_TYPE_R0) return STATUS_SUCCESS; - } ptr = rtsx_get_cmd_data(chip) + 1; @@ -3565,9 +3562,8 @@ RTY_SEND_CMD: if ((cmd_idx == SELECT_CARD) || (cmd_idx == APP_CMD) || (cmd_idx == SEND_STATUS) || (cmd_idx == STOP_TRANSMISSION)) { if ((cmd_idx != STOP_TRANSMISSION) && (special_check == 0)) { - if (ptr[1] & 0x80) { + if (ptr[1] & 0x80) TRACE_RET(chip, STATUS_FAIL); - } } #ifdef SUPPORT_SD_LOCK if (ptr[1] & 0x7D) @@ -3577,26 +3573,23 @@ RTY_SEND_CMD: { TRACE_RET(chip, STATUS_FAIL); } - if (ptr[2] & 0xF8) { + if (ptr[2] & 0xF8) TRACE_RET(chip, STATUS_FAIL); - } if (cmd_idx == SELECT_CARD) { if (rsp_type == SD_RSP_TYPE_R2) { - if ((ptr[3] & 0x1E) != 0x04) { + if ((ptr[3] & 0x1E) != 0x04) TRACE_RET(chip, STATUS_FAIL); - } + } else if (rsp_type == SD_RSP_TYPE_R0) { - if ((ptr[3] & 0x1E) != 0x03) { + if ((ptr[3] & 0x1E) != 0x03) TRACE_RET(chip, STATUS_FAIL); - } } } } - if (rsp && rsp_len) { + if (rsp && rsp_len) memcpy(rsp, ptr, rsp_len); - } return STATUS_SUCCESS; } -- cgit v0.10.2 From 7087f83c4d3356da13dbcd24c08ade1a5938b6ed Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:37:47 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (ext_sd_get_rsp) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 4168af6..9091700 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -3599,29 +3599,27 @@ int ext_sd_get_rsp(struct rtsx_chip *chip, int len, u8 *rsp, u8 rsp_type) int retval, rsp_len; u16 reg_addr; - if (rsp_type == SD_RSP_TYPE_R0) { + if (rsp_type == SD_RSP_TYPE_R0) return STATUS_SUCCESS; - } rtsx_init_cmd(chip); if (rsp_type == SD_RSP_TYPE_R2) { - for (reg_addr = PPBUF_BASE2; reg_addr < PPBUF_BASE2 + 16; reg_addr++) { + for (reg_addr = PPBUF_BASE2; reg_addr < PPBUF_BASE2 + 16; reg_addr++) rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0xFF, 0); - } + rsp_len = 17; } else if (rsp_type != SD_RSP_TYPE_R0) { - for (reg_addr = REG_SD_CMD0; reg_addr <= REG_SD_CMD4; reg_addr++) { + for (reg_addr = REG_SD_CMD0; reg_addr <= REG_SD_CMD4; reg_addr++) rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0xFF, 0); - } + rsp_len = 6; } rtsx_add_cmd(chip, READ_REG_CMD, REG_SD_CMD5, 0xFF, 0); retval = rtsx_send_cmd(chip, SD_CARD, 100); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (rsp) { int min_len = (rsp_len < len) ? rsp_len : len; -- cgit v0.10.2 From effda72de0cffbfe90de07786da7592b94e43fac Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:38:02 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_pass_thru_mode) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 9091700..b352f20 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -3690,9 +3690,8 @@ int sd_pass_thru_mode(struct scsi_cmnd *srb, struct rtsx_chip *chip) } buf[5] = (1 == CHK_SD(sd_card)) ? 0x01 : 0x02; - if (chip->card_wp & SD_CARD) { + if (chip->card_wp & SD_CARD) buf[5] |= 0x80; - } buf[6] = (u8)(sd_card->sd_addr >> 16); buf[7] = (u8)(sd_card->sd_addr >> 24); -- cgit v0.10.2 From f5a708764237ced9bf97981ea81d9a44b36fed90 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:38:15 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (get_rsp_type) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index b352f20..23090cb 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -3706,9 +3706,8 @@ int sd_pass_thru_mode(struct scsi_cmnd *srb, struct rtsx_chip *chip) static inline int get_rsp_type(struct scsi_cmnd *srb, u8 *rsp_type, int *rsp_len) { - if (!rsp_type || !rsp_len) { + if (!rsp_type || !rsp_len) return STATUS_FAIL; - } switch (srb->cmnd[10]) { case 0x03: -- cgit v0.10.2 From 44e323a7f017475438b30c5632c999c719b86907 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:38:28 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_execute_no_data) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 23090cb..ccd6f88 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -3757,9 +3757,8 @@ int sd_execute_no_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) } retval = sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); - } if (sd_card->pre_cmd_err) { sd_card->pre_cmd_err = 0; @@ -3768,12 +3767,11 @@ int sd_execute_no_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) } cmd_idx = srb->cmnd[2] & 0x3F; - if (srb->cmnd[1] & 0x02) { + if (srb->cmnd[1] & 0x02) standby = 1; - } - if (srb->cmnd[1] & 0x01) { + + if (srb->cmnd[1] & 0x01) acmd = 1; - } arg = ((u32)srb->cmnd[3] << 24) | ((u32)srb->cmnd[4] << 16) | ((u32)srb->cmnd[5] << 8) | srb->cmnd[6]; @@ -3786,64 +3784,56 @@ int sd_execute_no_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) sd_card->last_rsp_type = rsp_type; retval = sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); - } #ifdef SUPPORT_SD_LOCK if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) { if (CHK_MMC_8BIT(sd_card)) { retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_8); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); - } + } else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) { retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_4); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); - } } } #else retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_4); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); - } #endif if (standby) { retval = sd_select_card(chip, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Cmd_Failed); - } } if (acmd) { retval = ext_sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Cmd_Failed); - } } retval = ext_sd_send_cmd_get_rsp(chip, cmd_idx, arg, rsp_type, sd_card->rsp, rsp_len, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Cmd_Failed); - } if (standby) { retval = sd_select_card(chip, 1); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Cmd_Failed); - } } #ifdef SUPPORT_SD_LOCK retval = sd_update_lock_status(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Cmd_Failed); - } #endif scsi_set_resid(srb, 0); @@ -3854,9 +3844,8 @@ SD_Execute_Cmd_Failed: set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); release_sd_card(chip); do_reset_sd_card(chip); - if (!(chip->card_ready & SD_CARD)) { + if (!(chip->card_ready & SD_CARD)) set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - } TRACE_RET(chip, TRANSPORT_FAILED); } -- cgit v0.10.2 From ced159d530f0bdccb16b5baa0c5c2349e201e4e0 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:38:43 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_execute_read_data) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for any arm of this statement -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index ccd6f88..39f23f0 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -3872,20 +3872,18 @@ int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) } retval = sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); - } cmd_idx = srb->cmnd[2] & 0x3F; - if (srb->cmnd[1] & 0x04) { + if (srb->cmnd[1] & 0x04) send_cmd12 = 1; - } - if (srb->cmnd[1] & 0x02) { + + if (srb->cmnd[1] & 0x02) standby = 1; - } - if (srb->cmnd[1] & 0x01) { + + if (srb->cmnd[1] & 0x01) acmd = 1; - } data_len = ((u32)srb->cmnd[7] << 16) | ((u32)srb->cmnd[8] << 8) | srb->cmnd[9]; @@ -3897,19 +3895,17 @@ int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) sd_card->last_rsp_type = rsp_type; retval = sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); - } #ifdef SUPPORT_SD_LOCK if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) { - if (CHK_MMC_8BIT(sd_card)) { + if (CHK_MMC_8BIT(sd_card)) bus_width = SD_BUS_WIDTH_8; - } else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) { + else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) bus_width = SD_BUS_WIDTH_4; - } else { + else bus_width = SD_BUS_WIDTH_1; - } } else { bus_width = SD_BUS_WIDTH_4; } @@ -3921,24 +3917,21 @@ int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) if (data_len < 512) { retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, data_len, SD_RSP_TYPE_R1, NULL, 0, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); - } } if (standby) { retval = sd_select_card(chip, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); - } } if (acmd) { retval = ext_sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); - } } if (data_len <= 512) { @@ -3957,9 +3950,8 @@ int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) cmd[4] = srb->cmnd[6]; buf = kmalloc(data_len, GFP_KERNEL); - if (buf == NULL) { + if (buf == NULL) TRACE_RET(chip, TRANSPORT_ERROR); - } retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, byte_cnt, blk_cnt, bus_width, buf, data_len, 2000); @@ -4014,56 +4006,48 @@ int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) } retval = ext_sd_get_rsp(chip, rsp_len, sd_card->rsp, rsp_type); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); - } if (standby) { retval = sd_select_card(chip, 1); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); - } } if (send_cmd12) { retval = ext_sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, 0, SD_RSP_TYPE_R1b, NULL, 0, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); - } } if (data_len < 512) { retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, SD_RSP_TYPE_R1, NULL, 0, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); - } retval = rtsx_write_register(chip, SD_BYTE_CNT_H, 0xFF, 0x02); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); - } + retval = rtsx_write_register(chip, SD_BYTE_CNT_L, 0xFF, 0x00); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); - } } - if ((srb->cmnd[1] & 0x02) || (srb->cmnd[1] & 0x04)) { + if ((srb->cmnd[1] & 0x02) || (srb->cmnd[1] & 0x04)) cmd13_checkbit = 1; - } for (i = 0; i < 3; i++) { retval = ext_sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0, cmd13_checkbit); - if (retval == STATUS_SUCCESS) { + if (retval == STATUS_SUCCESS) break; - } } - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); - } scsi_set_resid(srb, 0); return TRANSPORT_GOOD; @@ -4071,14 +4055,13 @@ int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) SD_Execute_Read_Cmd_Failed: sd_card->pre_cmd_err = 1; set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); - if (read_err) { + if (read_err) set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - } + release_sd_card(chip); do_reset_sd_card(chip); - if (!(chip->card_ready & SD_CARD)) { + if (!(chip->card_ready & SD_CARD)) set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - } TRACE_RET(chip, TRANSPORT_FAILED); } -- cgit v0.10.2 From e0e762536d7d1b15adbbdeefe820decd3aa24b56 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:38:56 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_execute_write_data) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for any arm of this statement -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 39f23f0..3fd1cce 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -4093,20 +4093,18 @@ int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) } retval = sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); - } cmd_idx = srb->cmnd[2] & 0x3F; - if (srb->cmnd[1] & 0x04) { + if (srb->cmnd[1] & 0x04) send_cmd12 = 1; - } - if (srb->cmnd[1] & 0x02) { + + if (srb->cmnd[1] & 0x02) standby = 1; - } - if (srb->cmnd[1] & 0x01) { + + if (srb->cmnd[1] & 0x01) acmd = 1; - } data_len = ((u32)srb->cmnd[7] << 16) | ((u32)srb->cmnd[8] << 8) | srb->cmnd[9]; arg = ((u32)srb->cmnd[3] << 24) | ((u32)srb->cmnd[4] << 16) | @@ -4127,75 +4125,66 @@ int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) sd_card->last_rsp_type = rsp_type; retval = sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); - } #ifdef SUPPORT_SD_LOCK if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) { if (CHK_MMC_8BIT(sd_card)) { retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_8); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); - } + } else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) { retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_4); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); - } } } #else retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_4); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); - } #endif if (data_len < 512) { retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, data_len, SD_RSP_TYPE_R1, NULL, 0, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - } } if (standby) { retval = sd_select_card(chip, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - } } if (acmd) { retval = ext_sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - } } retval = ext_sd_send_cmd_get_rsp(chip, cmd_idx, arg, rsp_type, sd_card->rsp, rsp_len, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - } if (data_len <= 512) { u16 i; u8 *buf; buf = kmalloc(data_len, GFP_KERNEL); - if (buf == NULL) { + if (buf == NULL) TRACE_RET(chip, TRANSPORT_ERROR); - } rtsx_stor_get_xfer_buf(buf, data_len, srb); #ifdef SUPPORT_SD_LOCK - if (cmd_idx == LOCK_UNLOCK) { + if (cmd_idx == LOCK_UNLOCK) lock_cmd_type = buf[0] & 0x0F; - } #endif if (data_len > 256) { @@ -4287,11 +4276,11 @@ int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) } rtsx_init_cmd(chip); - if (CHECK_PID(chip, 0x5209)) { + if (CHECK_PID(chip, 0x5209)) rtsx_add_cmd(chip, CHECK_REG_CMD, SD_BUS_STAT, SD_DAT0_STATUS, SD_DAT0_STATUS); - } else { + else rtsx_add_cmd(chip, CHECK_REG_CMD, 0xFD30, 0x02, 0x02); - } + rtsx_send_cmd(chip, SD_CARD, 250); retval = sd_update_lock_status(chip); @@ -4304,61 +4293,53 @@ int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) if (standby) { retval = sd_select_card(chip, 1); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - } } if (send_cmd12) { retval = ext_sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, 0, SD_RSP_TYPE_R1b, NULL, 0, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - } } if (data_len < 512) { retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, SD_RSP_TYPE_R1, NULL, 0, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - } retval = rtsx_write_register(chip, SD_BYTE_CNT_H, 0xFF, 0x02); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - } + rtsx_write_register(chip, SD_BYTE_CNT_L, 0xFF, 0x00); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - } } - if ((srb->cmnd[1] & 0x02) || (srb->cmnd[1] & 0x04)) { + if ((srb->cmnd[1] & 0x02) || (srb->cmnd[1] & 0x04)) cmd13_checkbit = 1; - } for (i = 0; i < 3; i++) { retval = ext_sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0, cmd13_checkbit); - if (retval == STATUS_SUCCESS) { + if (retval == STATUS_SUCCESS) break; - } } - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - } #ifdef SUPPORT_SD_LOCK if (cmd_idx == LOCK_UNLOCK) { if (!lock_cmd_fail) { RTSX_DEBUGP("lock_cmd_type = 0x%x\n", lock_cmd_type); - if (lock_cmd_type & SD_CLR_PWD) { + if (lock_cmd_type & SD_CLR_PWD) sd_card->sd_lock_status &= ~SD_PWD_EXIST; - } - if (lock_cmd_type & SD_SET_PWD) { + + if (lock_cmd_type & SD_SET_PWD) sd_card->sd_lock_status |= SD_PWD_EXIST; - } } RTSX_DEBUGP("sd_lock_state = 0x%x, sd_card->sd_lock_status = 0x%x\n", @@ -4395,14 +4376,13 @@ int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) SD_Execute_Write_Cmd_Failed: sd_card->pre_cmd_err = 1; set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); - if (write_err) { + if (write_err) set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); - } + release_sd_card(chip); do_reset_sd_card(chip); - if (!(chip->card_ready & SD_CARD)) { + if (!(chip->card_ready & SD_CARD)) set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - } TRACE_RET(chip, TRANSPORT_FAILED); } -- cgit v0.10.2 From 00e9c108a66482d833ff45303ea85fe20914279a Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:39:09 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_hw_rst) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 3fd1cce..cf054b6 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -4452,9 +4452,8 @@ int sd_hw_rst(struct scsi_cmnd *srb, struct rtsx_chip *chip) switch (srb->cmnd[1] & 0x0F) { case 0: #ifdef SUPPORT_SD_LOCK - if (0x64 == srb->cmnd[9]) { + if (0x64 == srb->cmnd[9]) sd_card->sd_lock_status |= SD_SDR_RST; - } #endif retval = reset_sd_card(chip); if (retval != STATUS_SUCCESS) { -- cgit v0.10.2 From a13ce21fe1abac678a22d1dbc5b8fa1286f0029d Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:39:22 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (sd_power_off_card3v3) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index cf054b6..c1f293a 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -4504,26 +4504,23 @@ int sd_power_off_card3v3(struct rtsx_chip *chip) int retval; retval = disable_card_clock(chip, SD_CARD); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } RTSX_WRITE_REG(chip, CARD_OE, SD_OUTPUT_EN, 0); if (!chip->ft2_fast_mode) { retval = card_power_off(chip, SD_CARD); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } wait_timeout(50); } if (chip->asic_code) { retval = sd_pull_ctl_disable(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } else { RTSX_WRITE_REG(chip, FPGA_PULL_CTL, FPGA_SD_PULL_CTL_BIT | 0x20, FPGA_SD_PULL_CTL_BIT); -- cgit v0.10.2 From 7c77e3898cf92e3a0a954cfa74b24fcc6880e4f8 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Fri, 7 Sep 2012 13:39:36 +0900 Subject: staging/rts_pstor: remove braces {} in sd.c (release_sd_card) fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index c1f293a..c6a581c 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -4552,19 +4552,16 @@ int release_sd_card(struct rtsx_chip *chip) memset(sd_card->raw_scr, 0, 8); retval = sd_power_off_card3v3(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (CHECK_PID(chip, 0x5209)) { retval = sd_change_bank_voltage(chip, SD_IO_3V3); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } - if (CHK_SD30_SPEED(sd_card)) { + if (CHK_SD30_SPEED(sd_card)) RTSX_WRITE_REG(chip, SD30_DRIVE_SEL, 0x07, chip->sd30_drive_sel_3v3); - } RTSX_WRITE_REG(chip, OCPPARA2, SD_OCP_THD_MASK, chip->sd_400mA_ocp_thd); } -- cgit v0.10.2 From 01e6a6b5adfaf2bc7025d90ebba05aa30b11891a Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Sat, 8 Sep 2012 21:53:24 +0900 Subject: staging/rts_pstor: remove braces {} in rtsx_scsi.c fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks -WARNING: braces {} are not necessary for any arm of this statement Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/rtsx_scsi.c b/drivers/staging/rts_pstor/rtsx_scsi.c index 936b82d..86c41b3 100644 --- a/drivers/staging/rts_pstor/rtsx_scsi.c +++ b/drivers/staging/rts_pstor/rtsx_scsi.c @@ -135,9 +135,9 @@ void scsi_show_command(struct scsi_cmnd *srb) default: what = "(unknown command)"; unknown_cmd = 1; break; } - if (srb->cmnd[0] != TEST_UNIT_READY) { + if (srb->cmnd[0] != TEST_UNIT_READY) RTSX_DEBUGP("Command %s (%d bytes)\n", what, srb->cmd_len); - } + if (unknown_cmd) { RTSX_DEBUGP(""); for (i = 0; i < srb->cmd_len && i < 16; i++) @@ -317,11 +317,11 @@ static int inquiry(struct scsi_cmnd *srb, struct rtsx_chip *chip) }; if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { - if (chip->lun2card[lun] == SD_CARD) { + if (chip->lun2card[lun] == SD_CARD) inquiry_string = inquiry_sd; - } else { + else inquiry_string = inquiry_ms; - } + } else if (CHECK_LUN_MODE(chip, SD_MS_1LUN)) { inquiry_string = inquiry_sdms; } else { @@ -329,9 +329,8 @@ static int inquiry(struct scsi_cmnd *srb, struct rtsx_chip *chip) } buf = vmalloc(scsi_bufflen(srb)); - if (buf == NULL) { + if (buf == NULL) TRACE_RET(chip, TRANSPORT_ERROR); - } #ifdef SUPPORT_MAGIC_GATE if ((chip->mspro_formatter_enable) && @@ -340,23 +339,21 @@ static int inquiry(struct scsi_cmnd *srb, struct rtsx_chip *chip) if (chip->mspro_formatter_enable) #endif { - if (!card || (card == MS_CARD)) { + if (!card || (card == MS_CARD)) pro_formatter_flag = 1; - } } if (pro_formatter_flag) { - if (scsi_bufflen(srb) < 56) { + if (scsi_bufflen(srb) < 56) sendbytes = (unsigned char)(scsi_bufflen(srb)); - } else { + else sendbytes = 56; - } + } else { - if (scsi_bufflen(srb) < 36) { + if (scsi_bufflen(srb) < 36) sendbytes = (unsigned char)(scsi_bufflen(srb)); - } else { + else sendbytes = 36; - } } if (sendbytes > 8) { @@ -371,9 +368,8 @@ static int inquiry(struct scsi_cmnd *srb, struct rtsx_chip *chip) } if (pro_formatter_flag) { - if (sendbytes > 36) { + if (sendbytes > 36) memcpy(buf + 36, formatter_inquiry_str, sendbytes - 36); - } } scsi_set_resid(srb, 0); @@ -467,9 +463,8 @@ static int request_sense(struct scsi_cmnd *srb, struct rtsx_chip *chip) } buf = vmalloc(scsi_bufflen(srb)); - if (buf == NULL) { + if (buf == NULL) TRACE_RET(chip, TRANSPORT_ERROR); - } tmp = (unsigned char *)sense; memcpy(buf, tmp, scsi_bufflen(srb)); @@ -494,15 +489,15 @@ static void ms_mode_sense(struct rtsx_chip *chip, u8 cmd, if (cmd == MODE_SENSE) { sys_info_offset = 8; - if (data_size > 0x68) { + if (data_size > 0x68) data_size = 0x68; - } + buf[i++] = 0x67; /* Mode Data Length */ } else { sys_info_offset = 12; - if (data_size > 0x6C) { + if (data_size > 0x6C) data_size = 0x6C; - } + buf[i++] = 0x00; /* Mode Data Length (MSB) */ buf[i++] = 0x6A; /* Mode Data Length (LSB) */ } @@ -520,11 +515,11 @@ static void ms_mode_sense(struct rtsx_chip *chip, u8 cmd, } /* WP */ - if (check_card_wp(chip, lun)) { + if (check_card_wp(chip, lun)) buf[i++] = 0x80; - } else { + else buf[i++] = 0x00; - } + } else { buf[i++] = 0x00; /* MediaType */ buf[i++] = 0x00; /* WP */ @@ -545,11 +540,10 @@ static void ms_mode_sense(struct rtsx_chip *chip, u8 cmd, if (data_size >= 11) buf[i++] = 0x00; /* No Access Control */ if (data_size >= 12) { - if (support_format) { + if (support_format) buf[i++] = 0xC0; /* SF, SGM */ - } else { + else buf[i++] = 0x00; - } } } else { /* The Following Data is the content of "Page 0x20" */ @@ -560,11 +554,10 @@ static void ms_mode_sense(struct rtsx_chip *chip, u8 cmd, if (data_size >= 7) buf[i++] = 0x00; /* No Access Control */ if (data_size >= 8) { - if (support_format) { + if (support_format) buf[i++] = 0xC0; /* SF, SGM */ - } else { + else buf[i++] = 0x00; - } } } @@ -600,9 +593,8 @@ static int mode_sense(struct scsi_cmnd *srb, struct rtsx_chip *chip) if ((chip->lun2card[lun] & MS_CARD)) { if (!card || (card == MS_CARD)) { dataSize = 108; - if (chip->mspro_formatter_enable) { + if (chip->mspro_formatter_enable) pro_formatter_flag = 1; - } } } #else @@ -615,9 +607,8 @@ static int mode_sense(struct scsi_cmnd *srb, struct rtsx_chip *chip) #endif buf = kmalloc(dataSize, GFP_KERNEL); - if (buf == NULL) { + if (buf == NULL) TRACE_RET(chip, TRANSPORT_ERROR); - } pageCode = srb->cmnd[2] & 0x3f; @@ -632,11 +623,11 @@ static int mode_sense(struct scsi_cmnd *srb, struct rtsx_chip *chip) dataSize = 4; buf[0] = 0x03; buf[1] = 0x00; - if (check_card_wp(chip, lun)) { + if (check_card_wp(chip, lun)) buf[2] = 0x80; - } else { + else buf[2] = 0x00; - } + buf[3] = 0x00; } } else { @@ -648,11 +639,10 @@ static int mode_sense(struct scsi_cmnd *srb, struct rtsx_chip *chip) buf[0] = 0x00; buf[1] = 0x06; buf[2] = 0x00; - if (check_card_wp(chip, lun)) { + if (check_card_wp(chip, lun)) buf[3] = 0x80; - } else { + else buf[3] = 0x00; - } buf[4] = 0x00; buf[5] = 0x00; buf[6] = 0x00; @@ -759,11 +749,11 @@ static int read_write(struct scsi_cmnd *srb, struct rtsx_chip *chip) if (chip->rw_fail_cnt[lun] == 3) { RTSX_DEBUGP("read/write fail three times in succession\n"); - if (srb->sc_data_direction == DMA_FROM_DEVICE) { + if (srb->sc_data_direction == DMA_FROM_DEVICE) set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - } else { + else set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); - } + TRACE_RET(chip, TRANSPORT_FAILED); } @@ -776,9 +766,8 @@ static int read_write(struct scsi_cmnd *srb, struct rtsx_chip *chip) if (CHECK_PID(chip, 0x5209) && chip->max_payload) { u8 val = 0x10 | (chip->max_payload << 5); retval = rtsx_write_cfg_dw(chip, 0, 0x78, 0xFF, val); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_ERROR); - } } } @@ -789,11 +778,10 @@ static int read_write(struct scsi_cmnd *srb, struct rtsx_chip *chip) set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); } else { chip->rw_fail_cnt[lun]++; - if (srb->sc_data_direction == DMA_FROM_DEVICE) { + if (srb->sc_data_direction == DMA_FROM_DEVICE) set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - } else { + else set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); - } } retval = TRANSPORT_FAILED; TRACE_GOTO(chip, Exit); @@ -808,9 +796,8 @@ Exit: if (srb->sc_data_direction == DMA_TO_DEVICE) { if (CHECK_PID(chip, 0x5209) && chip->max_payload) { retval = rtsx_write_cfg_dw(chip, 0, 0x78, 0xFF, 0x10); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_ERROR); - } } } @@ -837,9 +824,8 @@ static int read_format_capacity(struct scsi_cmnd *srb, struct rtsx_chip *chip) buf_len = (scsi_bufflen(srb) > 12) ? 0x14 : 12; buf = kmalloc(buf_len, GFP_KERNEL); - if (buf == NULL) { + if (buf == NULL) TRACE_RET(chip, TRANSPORT_ERROR); - } buf[i++] = 0; buf[i++] = 0; @@ -864,22 +850,20 @@ static int read_format_capacity(struct scsi_cmnd *srb, struct rtsx_chip *chip) buf[i++] = (unsigned char)(card_size >> 8); buf[i++] = (unsigned char)card_size; - if (desc_cnt == 2) { + if (desc_cnt == 2) buf[i++] = 2; - } else { + else buf[i++] = 0; - } } else { buf[i++] = 0xFF; buf[i++] = 0xFF; buf[i++] = 0xFF; buf[i++] = 0xFF; - if (desc_cnt == 2) { + if (desc_cnt == 2) buf[i++] = 3; - } else { + else buf[i++] = 0; - } } buf[i++] = 0x00; @@ -916,9 +900,8 @@ static int read_capacity(struct scsi_cmnd *srb, struct rtsx_chip *chip) } buf = kmalloc(8, GFP_KERNEL); - if (buf == NULL) { + if (buf == NULL) TRACE_RET(chip, TRANSPORT_ERROR); - } card_size = get_card_size(chip, lun); buf[0] = (unsigned char)((card_size - 1) >> 24); @@ -956,9 +939,8 @@ static int read_eeprom(struct scsi_cmnd *srb, struct rtsx_chip *chip) len = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; buf = (u8 *)vmalloc(len); - if (!buf) { + if (!buf) TRACE_RET(chip, TRANSPORT_ERROR); - } retval = rtsx_force_power_on(chip, SSC_PDCTL); if (retval != STATUS_SUCCESS) { @@ -1016,9 +998,8 @@ static int write_eeprom(struct scsi_cmnd *srb, struct rtsx_chip *chip) } else { len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len); buf = (u8 *)vmalloc(len); - if (buf == NULL) { + if (buf == NULL) TRACE_RET(chip, TRANSPORT_ERROR); - } rtsx_stor_get_xfer_buf(buf, len, srb); scsi_set_resid(srb, scsi_bufflen(srb) - len); @@ -1061,9 +1042,8 @@ static int read_mem(struct scsi_cmnd *srb, struct rtsx_chip *chip) } buf = (u8 *)vmalloc(len); - if (!buf) { + if (!buf) TRACE_RET(chip, TRANSPORT_ERROR); - } retval = rtsx_force_power_on(chip, SSC_PDCTL); if (retval != STATUS_SUCCESS) { @@ -1114,9 +1094,8 @@ static int write_mem(struct scsi_cmnd *srb, struct rtsx_chip *chip) len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len); buf = (u8 *)vmalloc(len); - if (buf == NULL) { + if (buf == NULL) TRACE_RET(chip, TRANSPORT_ERROR); - } rtsx_stor_get_xfer_buf(buf, len, srb); scsi_set_resid(srb, scsi_bufflen(srb) - len); @@ -1200,16 +1179,15 @@ static int trace_msg_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip) clear = srb->cmnd[2]; buf = (unsigned char *)vmalloc(scsi_bufflen(srb)); - if (buf == NULL) { + if (buf == NULL) TRACE_RET(chip, TRANSPORT_ERROR); - } ptr = buf; - if (chip->trace_msg[chip->msg_idx].valid) { + if (chip->trace_msg[chip->msg_idx].valid) msg_cnt = TRACE_ITEM_CNT; - } else { + else msg_cnt = chip->msg_idx; - } + *(ptr++) = (u8)(msg_cnt >> 24); *(ptr++) = (u8)(msg_cnt >> 16); *(ptr++) = (u8)(msg_cnt >> 8); @@ -1225,15 +1203,14 @@ static int trace_msg_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip) *(ptr++) = (u8)(chip->trace_msg[idx].line >> 8); *(ptr++) = (u8)(chip->trace_msg[idx].line); - for (j = 0; j < MSG_FUNC_LEN; j++) { + for (j = 0; j < MSG_FUNC_LEN; j++) *(ptr++) = chip->trace_msg[idx].func[j]; - } - for (j = 0; j < MSG_FILE_LEN; j++) { + + for (j = 0; j < MSG_FILE_LEN; j++) *(ptr++) = chip->trace_msg[idx].file[j]; - } - for (j = 0; j < TIME_VAL_LEN; j++) { + + for (j = 0; j < TIME_VAL_LEN; j++) *(ptr++) = chip->trace_msg[idx].timeval_buf[j]; - } } rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb); @@ -1424,20 +1401,19 @@ static int dma_access_ring_buffer(struct scsi_cmnd *srb, struct rtsx_chip *chip) len = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5]; len = min(len, (u16)scsi_bufflen(srb)); - if (srb->sc_data_direction == DMA_FROM_DEVICE) { + if (srb->sc_data_direction == DMA_FROM_DEVICE) RTSX_DEBUGP("Read from device\n"); - } else { + else RTSX_DEBUGP("Write to device\n"); - } retval = rtsx_transfer_data(chip, 0, scsi_sglist(srb), len, scsi_sg_count(srb), srb->sc_data_direction, 1000); if (retval < 0) { - if (srb->sc_data_direction == DMA_FROM_DEVICE) { + if (srb->sc_data_direction == DMA_FROM_DEVICE) set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - } else { + else set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); - } + TRACE_RET(chip, TRANSPORT_FAILED); } scsi_set_resid(srb, 0); @@ -1462,22 +1438,20 @@ static int get_dev_status(struct scsi_cmnd *srb, struct rtsx_chip *chip) status[0] = (u8)(chip->product_id); status[1] = chip->ic_version; - if (chip->auto_delink_en) { + if (chip->auto_delink_en) status[2] = 0x10; - } else { + else status[2] = 0x00; - } status[3] = 20; status[4] = 10; status[5] = 05; status[6] = 21; - if (chip->card_wp) { + if (chip->card_wp) status[7] = 0x20; - } else { + else status[7] = 0x00; - } #ifdef SUPPORT_OCP status[8] = 0; @@ -1489,67 +1463,60 @@ static int get_dev_status(struct scsi_cmnd *srb, struct rtsx_chip *chip) oc_ever_mask = SD_OC_EVER; } - if (chip->ocp_stat & oc_now_mask) { + if (chip->ocp_stat & oc_now_mask) status[8] |= 0x02; - } - if (chip->ocp_stat & oc_ever_mask) { + + if (chip->ocp_stat & oc_ever_mask) status[8] |= 0x01; - } #endif if (card == SD_CARD) { if (CHK_SD(sd_card)) { if (CHK_SD_HCXC(sd_card)) { - if (sd_card->capacity > 0x4000000) { + if (sd_card->capacity > 0x4000000) status[0x0E] = 0x02; - } else { + else status[0x0E] = 0x01; - } } else { status[0x0E] = 0x00; } - if (CHK_SD_SDR104(sd_card)) { + if (CHK_SD_SDR104(sd_card)) status[0x0F] = 0x03; - } else if (CHK_SD_DDR50(sd_card)) { + else if (CHK_SD_DDR50(sd_card)) status[0x0F] = 0x04; - } else if (CHK_SD_SDR50(sd_card)) { + else if (CHK_SD_SDR50(sd_card)) status[0x0F] = 0x02; - } else if (CHK_SD_HS(sd_card)) { + else if (CHK_SD_HS(sd_card)) status[0x0F] = 0x01; - } else { + else status[0x0F] = 0x00; - } } else { - if (CHK_MMC_SECTOR_MODE(sd_card)) { + if (CHK_MMC_SECTOR_MODE(sd_card)) status[0x0E] = 0x01; - } else { + else status[0x0E] = 0x00; - } - if (CHK_MMC_DDR52(sd_card)) { + if (CHK_MMC_DDR52(sd_card)) status[0x0F] = 0x03; - } else if (CHK_MMC_52M(sd_card)) { + else if (CHK_MMC_52M(sd_card)) status[0x0F] = 0x02; - } else if (CHK_MMC_26M(sd_card)) { + else if (CHK_MMC_26M(sd_card)) status[0x0F] = 0x01; - } else { + else status[0x0F] = 0x00; - } } } else if (card == MS_CARD) { if (CHK_MSPRO(ms_card)) { - if (CHK_MSXC(ms_card)) { + if (CHK_MSXC(ms_card)) status[0x0E] = 0x01; - } else { + else status[0x0E] = 0x00; - } - if (CHK_HG8BIT(ms_card)) { + if (CHK_HG8BIT(ms_card)) status[0x0F] = 0x01; - } else { + else status[0x0F] = 0x00; - } } } @@ -1600,37 +1567,35 @@ static int set_chip_mode(struct scsi_cmnd *srb, struct rtsx_chip *chip) if (phy_debug_mode) { chip->phy_debug_mode = 1; retval = rtsx_write_register(chip, CDRESUMECTL, 0x77, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); - } + rtsx_disable_bus_int(chip); retval = rtsx_read_phy_register(chip, 0x1C, ®); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); - } + reg |= 0x0001; retval = rtsx_write_phy_register(chip, 0x1C, reg); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); - } } else { chip->phy_debug_mode = 0; retval = rtsx_write_register(chip, CDRESUMECTL, 0x77, 0x77); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); - } + rtsx_enable_bus_int(chip); retval = rtsx_read_phy_register(chip, 0x1C, ®); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); - } + reg &= 0xFFFE; retval = rtsx_write_phy_register(chip, 0x1C, reg); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); - } } return TRANSPORT_GOOD; @@ -1737,9 +1702,8 @@ static int read_phy_register(struct scsi_cmnd *srb, struct rtsx_chip *chip) if (len) { buf = (u8 *)vmalloc(len); - if (!buf) { + if (!buf) TRACE_RET(chip, TRANSPORT_ERROR); - } retval = rtsx_force_power_on(chip, SSC_PDCTL); if (retval != STATUS_SUCCESS) { @@ -1795,9 +1759,8 @@ static int write_phy_register(struct scsi_cmnd *srb, struct rtsx_chip *chip) len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len); buf = (u8 *)vmalloc(len); - if (buf == NULL) { + if (buf == NULL) TRACE_RET(chip, TRANSPORT_ERROR); - } rtsx_stor_get_xfer_buf(buf, len, srb); scsi_set_resid(srb, scsi_bufflen(srb) - len); @@ -1886,9 +1849,8 @@ static int read_eeprom2(struct scsi_cmnd *srb, struct rtsx_chip *chip) len = ((u16)srb->cmnd[6] << 8) | srb->cmnd[7]; buf = (u8 *)vmalloc(len); - if (!buf) { + if (!buf) TRACE_RET(chip, TRANSPORT_ERROR); - } retval = rtsx_force_power_on(chip, SSC_PDCTL); if (retval != STATUS_SUCCESS) { @@ -1934,9 +1896,8 @@ static int write_eeprom2(struct scsi_cmnd *srb, struct rtsx_chip *chip) len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len); buf = (u8 *)vmalloc(len); - if (buf == NULL) { + if (buf == NULL) TRACE_RET(chip, TRANSPORT_ERROR); - } rtsx_stor_get_xfer_buf(buf, len, srb); scsi_set_resid(srb, scsi_bufflen(srb) - len); @@ -1980,9 +1941,8 @@ static int read_efuse(struct scsi_cmnd *srb, struct rtsx_chip *chip) len = srb->cmnd[5]; buf = (u8 *)vmalloc(len); - if (!buf) { + if (!buf) TRACE_RET(chip, TRANSPORT_ERROR); - } retval = rtsx_force_power_on(chip, SSC_PDCTL); if (retval != STATUS_SUCCESS) { @@ -2029,9 +1989,8 @@ static int write_efuse(struct scsi_cmnd *srb, struct rtsx_chip *chip) len = (u8)min(scsi_bufflen(srb), (unsigned int)len); buf = (u8 *)vmalloc(len); - if (buf == NULL) { + if (buf == NULL) TRACE_RET(chip, TRANSPORT_ERROR); - } rtsx_stor_get_xfer_buf(buf, len, srb); scsi_set_resid(srb, scsi_bufflen(srb) - len); @@ -2093,27 +2052,23 @@ Exit: vfree(buf); retval = card_power_off(chip, SPI_CARD); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_ERROR); - } if (chip->asic_code) { retval = rtsx_write_register(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_OFF); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_ERROR); - } wait_timeout(600); retval = rtsx_write_phy_register(chip, 0x08, val); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_ERROR); - } retval = rtsx_write_register(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_ON); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_ERROR); - } } return result; @@ -2140,11 +2095,10 @@ static int read_cfg_byte(struct scsi_cmnd *srb, struct rtsx_chip *chip) RTSX_DEBUGP("%s: func = %d, addr = 0x%x, len = %d\n", __func__, func, addr, len); - if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) { + if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) func_max = 1; - } else { + else func_max = 0; - } if (func > func_max) { set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); @@ -2152,9 +2106,8 @@ static int read_cfg_byte(struct scsi_cmnd *srb, struct rtsx_chip *chip) } buf = (u8 *)vmalloc(len); - if (!buf) { + if (!buf) TRACE_RET(chip, TRANSPORT_ERROR); - } retval = rtsx_read_cfg_seq(chip, func, addr, buf, len); if (retval != STATUS_SUCCESS) { @@ -2193,11 +2146,10 @@ static int write_cfg_byte(struct scsi_cmnd *srb, struct rtsx_chip *chip) RTSX_DEBUGP("%s: func = %d, addr = 0x%x\n", __func__, func, addr); - if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) { + if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) func_max = 1; - } else { + else func_max = 0; - } if (func > func_max) { set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); @@ -2206,9 +2158,8 @@ static int write_cfg_byte(struct scsi_cmnd *srb, struct rtsx_chip *chip) len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len); buf = (u8 *)vmalloc(len); - if (!buf) { + if (!buf) TRACE_RET(chip, TRANSPORT_ERROR); - } rtsx_stor_get_xfer_buf(buf, len, srb); scsi_set_resid(srb, scsi_bufflen(srb) - len); @@ -2328,63 +2279,56 @@ static int read_status(struct scsi_cmnd *srb, struct rtsx_chip *chip) rtsx_status[4] = (u8)lun; if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { - if (chip->lun2card[lun] == SD_CARD) { + if (chip->lun2card[lun] == SD_CARD) rtsx_status[5] = 2; - } else { + else rtsx_status[5] = 3; - } } else { if (chip->card_exist) { - if (chip->card_exist & XD_CARD) { + if (chip->card_exist & XD_CARD) rtsx_status[5] = 4; - } else if (chip->card_exist & SD_CARD) { + else if (chip->card_exist & SD_CARD) rtsx_status[5] = 2; - } else if (chip->card_exist & MS_CARD) { + else if (chip->card_exist & MS_CARD) rtsx_status[5] = 3; - } else { + else rtsx_status[5] = 7; - } } else { rtsx_status[5] = 7; } } - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { + if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) rtsx_status[6] = 2; - } else { + else rtsx_status[6] = 1; - } rtsx_status[7] = (u8)(chip->product_id); rtsx_status[8] = chip->ic_version; - if (check_card_exist(chip, lun)) { + if (check_card_exist(chip, lun)) rtsx_status[9] = 1; - } else { + else rtsx_status[9] = 0; - } - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { + if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) rtsx_status[10] = 0; - } else { + else rtsx_status[10] = 1; - } if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { - if (chip->lun2card[lun] == SD_CARD) { + if (chip->lun2card[lun] == SD_CARD) rtsx_status[11] = SD_CARD; - } else { + else rtsx_status[11] = MS_CARD; - } } else { rtsx_status[11] = XD_CARD | SD_CARD | MS_CARD; } - if (check_card_ready(chip, lun)) { + if (check_card_ready(chip, lun)) rtsx_status[12] = 1; - } else { + else rtsx_status[12] = 0; - } if (get_lun_card(chip, lun) == XD_CARD) { rtsx_status[13] = 0x40; @@ -2421,29 +2365,26 @@ static int read_status(struct scsi_cmnd *srb, struct rtsx_chip *chip) } else { if (CHECK_LUN_MODE(chip, DEFAULT_SINGLE)) { #ifdef SUPPORT_SDIO - if (chip->sd_io && chip->sd_int) { + if (chip->sd_io && chip->sd_int) rtsx_status[13] = 0x60; - } else { + else rtsx_status[13] = 0x70; - } #else rtsx_status[13] = 0x70; #endif } else { - if (chip->lun2card[lun] == SD_CARD) { + if (chip->lun2card[lun] == SD_CARD) rtsx_status[13] = 0x20; - } else { + else rtsx_status[13] = 0x30; - } } } rtsx_status[14] = 0x78; - if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) { + if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) rtsx_status[15] = 0x83; - } else { + else rtsx_status[15] = 0x82; - } buf_len = min(scsi_bufflen(srb), (unsigned int)sizeof(rtsx_status)); rtsx_stor_set_xfer_buf(rtsx_status, buf_len, srb); @@ -2538,9 +2479,8 @@ static int spi_vendor_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip) rtsx_write_register(chip, CARD_GPIO_DIR, 0x07, gpio_dir); - if (result != STATUS_SUCCESS) { + if (result != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); - } return TRANSPORT_GOOD; } @@ -2610,13 +2550,12 @@ void led_shine(struct scsi_cmnd *srb, struct rtsx_chip *chip) unsigned int lun = SCSI_LUN(srb); u16 sec_cnt; - if ((srb->cmnd[0] == READ_10) || (srb->cmnd[0] == WRITE_10)) { + if ((srb->cmnd[0] == READ_10) || (srb->cmnd[0] == WRITE_10)) sec_cnt = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8]; - } else if ((srb->cmnd[0] == READ_6) || (srb->cmnd[0] == WRITE_6)) { + else if ((srb->cmnd[0] == READ_6) || (srb->cmnd[0] == WRITE_6)) sec_cnt = srb->cmnd[4]; - } else { + else return; - } if (chip->rw_cap[lun] >= GPIO_TOGGLE_THRESHOLD) { toggle_gpio(chip, LED_GPIO); @@ -2659,11 +2598,10 @@ static int ms_format_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip) } rtsx_set_stat(chip, RTSX_STAT_RUN); - if (srb->cmnd[8] & 0x01) { + if (srb->cmnd[8] & 0x01) quick_format = 0; - } else { + else quick_format = 1; - } if (!(chip->card_ready & MS_CARD)) { set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); @@ -2724,27 +2662,25 @@ static int get_ms_information(struct scsi_cmnd *srb, struct rtsx_chip *chip) TRACE_RET(chip, TRANSPORT_FAILED); } - if (dev_info_id == 0x15) { + if (dev_info_id == 0x15) buf_len = data_len = 0x3A; - } else { + else buf_len = data_len = 0x6A; - } buf = kmalloc(buf_len, GFP_KERNEL); - if (!buf) { + if (!buf) TRACE_RET(chip, TRANSPORT_ERROR); - } i = 0; /* GET Memory Stick Media Information Response Header */ buf[i++] = 0x00; /* Data length MSB */ buf[i++] = data_len; /* Data length LSB */ /* Device Information Type Code */ - if (CHK_MSXC(ms_card)) { + if (CHK_MSXC(ms_card)) buf[i++] = 0x03; - } else { + else buf[i++] = 0x02; - } + /* SGM bit */ buf[i++] = 0x01; /* Reserved */ @@ -2759,11 +2695,11 @@ static int get_ms_information(struct scsi_cmnd *srb, struct rtsx_chip *chip) /* Device Information ID Number */ buf[i++] = dev_info_id; /* Device Information Length */ - if (dev_info_id == 0x15) { + if (dev_info_id == 0x15) data_len = 0x31; - } else { + else data_len = 0x61; - } + buf[i++] = 0x00; /* Data length MSB */ buf[i++] = data_len; /* Data length LSB */ /* Valid Bit */ @@ -2778,11 +2714,10 @@ static int get_ms_information(struct scsi_cmnd *srb, struct rtsx_chip *chip) rtsx_stor_set_xfer_buf(buf, buf_len, srb); - if (dev_info_id == 0x15) { + if (dev_info_id == 0x15) scsi_set_resid(srb, scsi_bufflen(srb)-0x3C); - } else { + else scsi_set_resid(srb, scsi_bufflen(srb)-0x6C); - } kfree(buf); return STATUS_SUCCESS; @@ -2793,13 +2728,11 @@ static int ms_sp_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip) { int retval = TRANSPORT_ERROR; - if (srb->cmnd[2] == MS_FORMAT) { + if (srb->cmnd[2] == MS_FORMAT) retval = ms_format_cmnd(srb, chip); - } #ifdef SUPPORT_PCGL_1P18 - else if (srb->cmnd[2] == GET_MS_INFORMATION) { + else if (srb->cmnd[2] == GET_MS_INFORMATION) retval = get_ms_information(srb, chip); - } #endif return retval; @@ -2912,9 +2845,9 @@ static int mg_report_key(struct scsi_cmnd *srb, struct rtsx_chip *chip) (srb->cmnd[8] == 0x04) && (srb->cmnd[9] == 0x1C)) { retval = mg_get_local_EKB(srb, chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); - } + } else { set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); @@ -2926,9 +2859,9 @@ static int mg_report_key(struct scsi_cmnd *srb, struct rtsx_chip *chip) (srb->cmnd[8] == 0x00) && (srb->cmnd[9] == 0x24)) { retval = mg_get_rsp_chg(srb, chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); - } + } else { set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); @@ -2945,9 +2878,9 @@ static int mg_report_key(struct scsi_cmnd *srb, struct rtsx_chip *chip) (srb->cmnd[4] == 0x00) && (srb->cmnd[5] < 32)) { retval = mg_get_ICV(srb, chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); - } + } else { set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); @@ -3014,9 +2947,9 @@ static int mg_send_key(struct scsi_cmnd *srb, struct rtsx_chip *chip) (srb->cmnd[8] == 0x00) && (srb->cmnd[9] == 0x0C)) { retval = mg_set_leaf_id(srb, chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); - } + } else { set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); @@ -3028,9 +2961,9 @@ static int mg_send_key(struct scsi_cmnd *srb, struct rtsx_chip *chip) (srb->cmnd[8] == 0x00) && (srb->cmnd[9] == 0x0C)) { retval = mg_chg(srb, chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); - } + } else { set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); @@ -3042,9 +2975,9 @@ static int mg_send_key(struct scsi_cmnd *srb, struct rtsx_chip *chip) (srb->cmnd[8] == 0x00) && (srb->cmnd[9] == 0x0C)) { retval = mg_rsp(srb, chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); - } + } else { set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); @@ -3061,9 +2994,9 @@ static int mg_send_key(struct scsi_cmnd *srb, struct rtsx_chip *chip) (srb->cmnd[4] == 0x00) && (srb->cmnd[5] < 32)) { retval = mg_set_ICV(srb, chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); - } + } else { set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); -- cgit v0.10.2 From 2ea5d82f618f368711a9e076211950bf2d67ba80 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Sun, 9 Sep 2012 22:01:35 +0900 Subject: staging/rts_pstor: remove braces {} in ms.c fixed below checkpatch warnings. -WARNING: braces {} are not necessary for single statement blocks -WARNING: braces {} are not necessary for any arm of this statement Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/ms.c b/drivers/staging/rts_pstor/ms.c index 7cc2b53..16a5c16 100644 --- a/drivers/staging/rts_pstor/ms.c +++ b/drivers/staging/rts_pstor/ms.c @@ -109,9 +109,8 @@ static int ms_transfer_data(struct rtsx_chip *chip, u8 trans_mode, u8 tpc, u16 s u8 val, err_code = 0; enum dma_data_direction dir; - if (!buf || !buf_len) { + if (!buf || !buf_len) TRACE_RET(chip, STATUS_FAIL); - } if (trans_mode == MS_TM_AUTO_READ) { dir = DMA_FROM_DEVICE; @@ -151,18 +150,17 @@ static int ms_transfer_data(struct rtsx_chip *chip, u8 trans_mode, u8 tpc, u16 s use_sg, dir, chip->mspro_timeout); if (retval < 0) { ms_set_err_code(chip, err_code); - if (retval == -ETIMEDOUT) { + if (retval == -ETIMEDOUT) retval = STATUS_TIMEDOUT; - } else { + else retval = STATUS_FAIL; - } + TRACE_RET(chip, retval); } RTSX_READ_REG(chip, MS_TRANS_CFG, &val); - if (val & (MS_INT_CMDNK | MS_INT_ERR | MS_CRC16_ERR | MS_RDY_TIMEOUT)) { + if (val & (MS_INT_CMDNK | MS_INT_ERR | MS_CRC16_ERR | MS_RDY_TIMEOUT)) TRACE_RET(chip, STATUS_FAIL); - } return STATUS_SUCCESS; } @@ -173,9 +171,8 @@ static int ms_write_bytes(struct rtsx_chip *chip, struct ms_info *ms_card = &(chip->ms_card); int retval, i; - if (!data || (data_len < cnt)) { + if (!data || (data_len < cnt)) TRACE_RET(chip, STATUS_ERROR); - } rtsx_init_cmd(chip); @@ -183,9 +180,8 @@ static int ms_write_bytes(struct rtsx_chip *chip, rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2 + i, 0xFF, data[i]); } - if (cnt % 2) { + if (cnt % 2) rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2 + i, 0xFF, 0xFF); - } rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); rtsx_add_cmd(chip, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt); @@ -238,9 +234,8 @@ static int ms_read_bytes(struct rtsx_chip *chip, u8 tpc, u8 cnt, u8 cfg, u8 *dat int retval, i; u8 *ptr; - if (!data) { + if (!data) TRACE_RET(chip, STATUS_ERROR); - } rtsx_init_cmd(chip); @@ -252,14 +247,13 @@ static int ms_read_bytes(struct rtsx_chip *chip, u8 tpc, u8 cnt, u8 cfg, u8 *dat rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, MS_TRANSFER_START | MS_TM_READ_BYTES); rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, MS_TRANSFER_END, MS_TRANSFER_END); - for (i = 0; i < data_len - 1; i++) { + for (i = 0; i < data_len - 1; i++) rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + i, 0, 0); - } - if (data_len % 2) { + + if (data_len % 2) rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + data_len, 0, 0); - } else { + else rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + data_len - 1, 0, 0); - } retval = rtsx_send_cmd(chip, MS_CARD, 5000); if (retval < 0) { @@ -293,9 +287,8 @@ static int ms_read_bytes(struct rtsx_chip *chip, u8 tpc, u8 cnt, u8 cfg, u8 *dat ptr = rtsx_get_cmd_data(chip) + 1; - for (i = 0; i < data_len; i++) { + for (i = 0; i < data_len; i++) data[i] = ptr[i]; - } if ((tpc == PRO_READ_SHORT_DATA) && (data_len == 8)) { RTSX_DEBUGP("Read format progress:\n"); @@ -343,34 +336,31 @@ static int ms_set_init_para(struct rtsx_chip *chip) int retval; if (CHK_HG8BIT(ms_card)) { - if (chip->asic_code) { + if (chip->asic_code) ms_card->ms_clock = chip->asic_ms_hg_clk; - } else { + else ms_card->ms_clock = chip->fpga_ms_hg_clk; - } + } else if (CHK_MSPRO(ms_card) || CHK_MS4BIT(ms_card)) { - if (chip->asic_code) { + if (chip->asic_code) ms_card->ms_clock = chip->asic_ms_4bit_clk; - } else { + else ms_card->ms_clock = chip->fpga_ms_4bit_clk; - } + } else { - if (chip->asic_code) { + if (chip->asic_code) ms_card->ms_clock = chip->asic_ms_1bit_clk; - } else { + else ms_card->ms_clock = chip->fpga_ms_1bit_clk; - } } retval = switch_clock(chip, ms_card->ms_clock); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = select_card(chip, MS_CARD); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } return STATUS_SUCCESS; } @@ -381,14 +371,12 @@ static int ms_switch_clock(struct rtsx_chip *chip) int retval; retval = select_card(chip, MS_CARD); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = switch_clock(chip, ms_card->ms_clock); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } return STATUS_SUCCESS; } @@ -461,9 +449,8 @@ static int ms_pull_ctl_enable(struct rtsx_chip *chip) } retval = rtsx_send_cmd(chip, MS_CARD, 100); - if (retval < 0) { + if (retval < 0) TRACE_RET(chip, STATUS_FAIL); - } return STATUS_SUCCESS; } @@ -482,40 +469,37 @@ static int ms_prepare_reset(struct rtsx_chip *chip) ms_card->pro_under_formatting = 0; retval = ms_power_off_card3v3(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (!chip->ft2_fast_mode) wait_timeout(250); retval = enable_card_clock(chip, MS_CARD); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (chip->asic_code) { retval = ms_pull_ctl_enable(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } else { RTSX_WRITE_REG(chip, FPGA_PULL_CTL, FPGA_MS_PULL_CTL_BIT | 0x20, 0); } if (!chip->ft2_fast_mode) { retval = card_power_on(chip, MS_CARD); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + wait_timeout(150); #ifdef SUPPORT_OCP - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { + if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) oc_mask = MS_OC_NOW | MS_OC_EVER; - } else { + else oc_mask = SD_OC_NOW | SD_OC_EVER; - } + if (chip->ocp_stat & oc_mask) { RTSX_DEBUGP("Over current, OCPSTAT is 0x%x\n", chip->ocp_stat); @@ -539,9 +523,8 @@ static int ms_prepare_reset(struct rtsx_chip *chip) RTSX_WRITE_REG(chip, CARD_STOP, MS_STOP | MS_CLR_ERR, MS_STOP | MS_CLR_ERR); retval = ms_set_init_para(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } return STATUS_SUCCESS; } @@ -553,26 +536,23 @@ static int ms_identify_media_type(struct rtsx_chip *chip, int switch_8bit_bus) u8 val; retval = ms_set_rw_reg_addr(chip, Pro_StatusReg, 6, SystemParm, 1); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { retval = ms_transfer_tpc(chip, MS_TM_READ_BYTES, READ_REG, 6, NO_WAIT_INT); - if (retval == STATUS_SUCCESS) { + if (retval == STATUS_SUCCESS) break; - } } - if (i == MS_MAX_RETRY_COUNT) { + if (i == MS_MAX_RETRY_COUNT) TRACE_RET(chip, STATUS_FAIL); - } RTSX_READ_REG(chip, PPBUF_BASE2 + 2, &val); RTSX_DEBUGP("Type register: 0x%x\n", val); if (val != 0x01) { - if (val != 0x02) { + if (val != 0x02) ms_card->check_ms_flow = 1; - } + TRACE_RET(chip, STATUS_FAIL); } @@ -587,11 +567,11 @@ static int ms_identify_media_type(struct rtsx_chip *chip, int switch_8bit_bus) RTSX_DEBUGP("Class register: 0x%x\n", val); if (val == 0) { RTSX_READ_REG(chip, PPBUF_BASE2, &val); - if (val & WRT_PRTCT) { + if (val & WRT_PRTCT) chip->card_wp |= MS_CARD; - } else { + else chip->card_wp &= ~MS_CARD; - } + } else if ((val == 0x01) || (val == 0x02) || (val == 0x03)) { chip->card_wp |= MS_CARD; } else { @@ -606,11 +586,11 @@ static int ms_identify_media_type(struct rtsx_chip *chip, int switch_8bit_bus) if (val == 0) { ms_card->ms_type &= 0x0F; } else if (val == 7) { - if (switch_8bit_bus) { + if (switch_8bit_bus) ms_card->ms_type |= MS_HG; - } else { + else ms_card->ms_type &= 0x0F; - } + } else { TRACE_RET(chip, STATUS_FAIL); } @@ -633,17 +613,15 @@ static int ms_confirm_cpu_startup(struct rtsx_chip *chip) for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval == STATUS_SUCCESS) { + if (retval == STATUS_SUCCESS) break; - } } - if (i == MS_MAX_RETRY_COUNT) { + if (i == MS_MAX_RETRY_COUNT) TRACE_RET(chip, STATUS_FAIL); - } - if (k > 100) { + if (k > 100) TRACE_RET(chip, STATUS_FAIL); - } + k++; wait_timeout(100); } while (!(val & INT_REG_CED)); @@ -653,16 +631,14 @@ static int ms_confirm_cpu_startup(struct rtsx_chip *chip) if (retval == STATUS_SUCCESS) break; } - if (i == MS_MAX_RETRY_COUNT) { + if (i == MS_MAX_RETRY_COUNT) TRACE_RET(chip, STATUS_FAIL); - } if (val & INT_REG_ERR) { - if (val & INT_REG_CMDNK) { + if (val & INT_REG_CMDNK) chip->card_wp |= (MS_CARD); - } else { + else TRACE_RET(chip, STATUS_FAIL); - } } /* -- end confirm CPU startup */ @@ -681,9 +657,8 @@ static int ms_switch_parallel_bus(struct rtsx_chip *chip) if (retval == STATUS_SUCCESS) break; } - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } return STATUS_SUCCESS; } @@ -698,26 +673,22 @@ static int ms_switch_8bit_bus(struct rtsx_chip *chip) data[1] = 0; for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { retval = ms_write_bytes(chip, WRITE_REG, 1, NO_WAIT_INT, data, 2); - if (retval == STATUS_SUCCESS) { + if (retval == STATUS_SUCCESS) break; - } } - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } RTSX_WRITE_REG(chip, MS_CFG, 0x98, MS_BUS_WIDTH_8 | SAMPLE_TIME_FALLING); ms_card->ms_type |= MS_8BIT; retval = ms_set_init_para(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { retval = ms_transfer_tpc(chip, MS_TM_READ_BYTES, GET_INT, 1, NO_WAIT_INT); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } return STATUS_SUCCESS; @@ -730,19 +701,16 @@ static int ms_pro_reset_flow(struct rtsx_chip *chip, int switch_8bit_bus) for (i = 0; i < 3; i++) { retval = ms_prepare_reset(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = ms_identify_media_type(chip, switch_8bit_bus); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = ms_confirm_cpu_startup(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = ms_switch_parallel_bus(chip); if (retval != STATUS_SUCCESS) { @@ -756,18 +724,16 @@ static int ms_pro_reset_flow(struct rtsx_chip *chip, int switch_8bit_bus) } } - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } /* Switch MS-PRO into Parallel mode */ RTSX_WRITE_REG(chip, MS_CFG, 0x18, MS_BUS_WIDTH_4); RTSX_WRITE_REG(chip, MS_CFG, PUSH_TIME_ODD, PUSH_TIME_ODD); retval = ms_set_init_para(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } /* If MSPro HG Card, We shall try to switch to 8-bit bus */ if (CHK_MSHG(ms_card) && chip->support_ms_8bit && switch_8bit_bus) { @@ -790,9 +756,8 @@ static int msxc_change_power(struct rtsx_chip *chip, u8 mode) ms_cleanup_work(chip); retval = ms_set_rw_reg_addr(chip, 0, 0, Pro_DataCount1, 6); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } buf[0] = 0; buf[1] = mode; @@ -802,19 +767,16 @@ static int msxc_change_power(struct rtsx_chip *chip, u8 mode) buf[5] = 0; retval = ms_write_bytes(chip, PRO_WRITE_REG , 6, NO_WAIT_INT, buf, 6); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = ms_send_cmd(chip, XC_CHG_POWER, WAIT_INT); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } RTSX_READ_REG(chip, MS_TRANS_CFG, buf); - if (buf[0] & (MS_INT_CMDNK | MS_INT_ERR)) { + if (buf[0] & (MS_INT_CMDNK | MS_INT_ERR)) TRACE_RET(chip, STATUS_FAIL); - } return STATUS_SUCCESS; } @@ -836,15 +798,14 @@ static int ms_read_attribute_info(struct rtsx_chip *chip) #endif retval = ms_set_rw_reg_addr(chip, Pro_IntReg, 2, Pro_SystemParm, 7); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } - if (CHK_MS8BIT(ms_card)) { + if (CHK_MS8BIT(ms_card)) data[0] = PARALLEL_8BIT_IF; - } else { + else data[0] = PARALLEL_4BIT_IF; - } + data[1] = 0; data[2] = 0x40; @@ -856,24 +817,21 @@ static int ms_read_attribute_info(struct rtsx_chip *chip) for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { retval = ms_write_bytes(chip, PRO_WRITE_REG, 7, NO_WAIT_INT, data, 8); - if (retval == STATUS_SUCCESS) { + if (retval == STATUS_SUCCESS) break; - } } - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } buf = kmalloc(64 * 512, GFP_KERNEL); - if (buf == NULL) { + if (buf == NULL) TRACE_RET(chip, STATUS_ERROR); - } for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { retval = ms_send_cmd(chip, PRO_READ_ATRB, WAIT_INT); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) continue; - } + retval = rtsx_read_register(chip, MS_TRANS_CFG, &val); if (retval != STATUS_SUCCESS) { kfree(buf); @@ -885,11 +843,10 @@ static int ms_read_attribute_info(struct rtsx_chip *chip) } retval = ms_transfer_data(chip, MS_TM_AUTO_READ, PRO_READ_LONG_DATA, 0x40, WAIT_INT, 0, 0, buf, 64 * 512); - if (retval == STATUS_SUCCESS) { + if (retval == STATUS_SUCCESS) break; - } else { + else rtsx_clear_ms_error(chip); - } } if (retval != STATUS_SUCCESS) { kfree(buf); @@ -963,9 +920,8 @@ static int ms_read_attribute_info(struct rtsx_chip *chip) } #ifdef SUPPORT_MSXC - if (buf[cur_addr_off + 8] == 0x13) { + if (buf[cur_addr_off + 8] == 0x13) ms_card->ms_type |= MS_XC; - } #endif #ifdef SUPPORT_PCGL_1P18 found_sys_info = 1; @@ -1046,18 +1002,15 @@ static int ms_read_attribute_info(struct rtsx_chip *chip) #ifdef SUPPORT_MSXC if (CHK_MSXC(ms_card)) { - if (class_code != 0x03) { + if (class_code != 0x03) TRACE_RET(chip, STATUS_FAIL); - } } else { - if (class_code != 0x02) { + if (class_code != 0x02) TRACE_RET(chip, STATUS_FAIL); - } } #else - if (class_code != 0x02) { + if (class_code != 0x02) TRACE_RET(chip, STATUS_FAIL); - } #endif if (device_type != 0x00) { @@ -1069,9 +1022,8 @@ static int ms_read_attribute_info(struct rtsx_chip *chip) } } - if (sub_class & 0xC0) { + if (sub_class & 0xC0) TRACE_RET(chip, STATUS_FAIL); - } RTSX_DEBUGP("class_code: 0x%x, device_type: 0x%x, sub_class: 0x%x\n", class_code, device_type, sub_class); @@ -1117,23 +1069,20 @@ Retry: if (retval != STATUS_SUCCESS) { if (ms_card->switch_8bit_fail) { retval = ms_pro_reset_flow(chip, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } else { TRACE_RET(chip, STATUS_FAIL); } } retval = ms_read_attribute_info(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } #ifdef XC_POWERCLASS - if (CHK_HG8BIT(ms_card)) { + if (CHK_HG8BIT(ms_card)) change_power_class = 0; - } if (change_power_class && CHK_MSXC(ms_card)) { u8 power_class_en = chip->ms_power_class_en; @@ -1141,11 +1090,10 @@ Retry: RTSX_DEBUGP("power_class_en = 0x%x\n", power_class_en); RTSX_DEBUGP("change_power_class = %d\n", change_power_class); - if (change_power_class) { + if (change_power_class) power_class_en &= (1 << (change_power_class - 1)); - } else { + else power_class_en = 0; - } if (power_class_en) { u8 power_class_mode = (ms_card->raw_sys_info[46] & 0x18) >> 3; @@ -1165,16 +1113,14 @@ Retry: #ifdef SUPPORT_MAGIC_GATE retval = mg_set_tpc_para_sub(chip, 0, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } #endif - if (CHK_HG8BIT(ms_card)) { + if (CHK_HG8BIT(ms_card)) chip->card_bus_width[chip->card2lun[MS_CARD]] = 8; - } else { + else chip->card_bus_width[chip->card2lun[MS_CARD]] = 4; - } return STATUS_SUCCESS; } @@ -1185,14 +1131,12 @@ static int ms_read_status_reg(struct rtsx_chip *chip) u8 val[2]; retval = ms_set_rw_reg_addr(chip, StatusReg0, 2, 0, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = ms_read_bytes(chip, READ_REG, 2, NO_WAIT_INT, val, 2); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (val[1] & (STS_UCDT | STS_UCEX | STS_UCFG)) { ms_set_err_code(chip, MS_FLASH_READ_ERROR); @@ -1211,9 +1155,8 @@ static int ms_read_extra_data(struct rtsx_chip *chip, u8 val, data[10]; retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (CHK_MS4BIT(ms_card)) { /* Parallel interface */ @@ -1233,9 +1176,8 @@ static int ms_read_extra_data(struct rtsx_chip *chip, if (retval == STATUS_SUCCESS) break; } - if (i == MS_MAX_RETRY_COUNT) { + if (i == MS_MAX_RETRY_COUNT) TRACE_RET(chip, STATUS_FAIL); - } ms_set_err_code(chip, MS_NO_ERROR); @@ -1244,15 +1186,14 @@ static int ms_read_extra_data(struct rtsx_chip *chip, if (retval == STATUS_SUCCESS) break; } - if (i == MS_MAX_RETRY_COUNT) { + if (i == MS_MAX_RETRY_COUNT) TRACE_RET(chip, STATUS_FAIL); - } ms_set_err_code(chip, MS_NO_ERROR); retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + if (val & INT_REG_CMDNK) { ms_set_err_code(chip, MS_CMD_NK); TRACE_RET(chip, STATUS_FAIL); @@ -1260,20 +1201,18 @@ static int ms_read_extra_data(struct rtsx_chip *chip, if (val & INT_REG_CED) { if (val & INT_REG_ERR) { retval = ms_read_status_reg(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } } retval = ms_read_bytes(chip, READ_REG, MS_EXTRA_SIZE, NO_WAIT_INT, data, MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (buf && buf_len) { if (buf_len > MS_EXTRA_SIZE) @@ -1291,45 +1230,40 @@ static int ms_write_extra_data(struct rtsx_chip *chip, int retval, i; u8 val, data[16]; - if (!buf || (buf_len < MS_EXTRA_SIZE)) { + if (!buf || (buf_len < MS_EXTRA_SIZE)) TRACE_RET(chip, STATUS_FAIL); - } retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6 + MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } - if (CHK_MS4BIT(ms_card)) { + if (CHK_MS4BIT(ms_card)) data[0] = 0x88; - } else { + else data[0] = 0x80; - } + data[1] = 0; data[2] = (u8)(block_addr >> 8); data[3] = (u8)block_addr; data[4] = 0x40; data[5] = page_num; - for (i = 6; i < MS_EXTRA_SIZE + 6; i++) { + for (i = 6; i < MS_EXTRA_SIZE + 6; i++) data[i] = buf[i - 6]; - } retval = ms_write_bytes(chip, WRITE_REG , (6+MS_EXTRA_SIZE), NO_WAIT_INT, data, 16); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } ms_set_err_code(chip, MS_NO_ERROR); retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + if (val & INT_REG_CMDNK) { ms_set_err_code(chip, MS_CMD_NK); TRACE_RET(chip, STATUS_FAIL); @@ -1352,15 +1286,14 @@ static int ms_read_page(struct rtsx_chip *chip, u16 block_addr, u8 page_num) u8 val, data[6]; retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } - if (CHK_MS4BIT(ms_card)) { + if (CHK_MS4BIT(ms_card)) data[0] = 0x88; - } else { + else data[0] = 0x80; - } + data[1] = 0; data[2] = (u8)(block_addr >> 8); data[3] = (u8)block_addr; @@ -1368,20 +1301,18 @@ static int ms_read_page(struct rtsx_chip *chip, u16 block_addr, u8 page_num) data[5] = page_num; retval = ms_write_bytes(chip, WRITE_REG , 6, NO_WAIT_INT, data, 6); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } ms_set_err_code(chip, MS_NO_ERROR); retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + if (val & INT_REG_CMDNK) { ms_set_err_code(chip, MS_CMD_NK); TRACE_RET(chip, STATUS_FAIL); @@ -1394,9 +1325,9 @@ static int ms_read_page(struct rtsx_chip *chip, u16 block_addr, u8 page_num) TRACE_RET(chip, STATUS_FAIL); } retval = ms_read_status_reg(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); - } + } else { if (!(val & INT_REG_BREQ)) { ms_set_err_code(chip, MS_BREQ_ERROR); @@ -1406,13 +1337,11 @@ static int ms_read_page(struct rtsx_chip *chip, u16 block_addr, u8 page_num) } retval = ms_transfer_tpc(chip, MS_TM_NORMAL_READ, READ_PAGE_DATA, 0, NO_WAIT_INT); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } - if (ms_check_err_code(chip, MS_FLASH_WRITE_ERROR)) { + if (ms_check_err_code(chip, MS_FLASH_WRITE_ERROR)) TRACE_RET(chip, STATUS_FAIL); - } return STATUS_SUCCESS; } @@ -1425,22 +1354,20 @@ static int ms_set_bad_block(struct rtsx_chip *chip, u16 phy_blk) u8 val, data[8], extra[MS_EXTRA_SIZE]; retval = ms_read_extra_data(chip, phy_blk, 0, extra, MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 7); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } ms_set_err_code(chip, MS_NO_ERROR); - if (CHK_MS4BIT(ms_card)) { + if (CHK_MS4BIT(ms_card)) data[0] = 0x88; - } else { + else data[0] = 0x80; - } + data[1] = 0; data[2] = (u8)(phy_blk >> 8); data[3] = (u8)phy_blk; @@ -1450,20 +1377,17 @@ static int ms_set_bad_block(struct rtsx_chip *chip, u16 phy_blk) data[7] = 0xFF; retval = ms_write_bytes(chip, WRITE_REG , 7, NO_WAIT_INT, data, 7); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } ms_set_err_code(chip, MS_NO_ERROR); retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (val & INT_REG_CMDNK) { ms_set_err_code(chip, MS_CMD_NK); @@ -1488,17 +1412,16 @@ static int ms_erase_block(struct rtsx_chip *chip, u16 phy_blk) u8 val, data[6]; retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } ms_set_err_code(chip, MS_NO_ERROR); - if (CHK_MS4BIT(ms_card)) { + if (CHK_MS4BIT(ms_card)) data[0] = 0x88; - } else { + else data[0] = 0x80; - } + data[1] = 0; data[2] = (u8)(phy_blk >> 8); data[3] = (u8)phy_blk; @@ -1506,21 +1429,18 @@ static int ms_erase_block(struct rtsx_chip *chip, u16 phy_blk) data[5] = 0; retval = ms_write_bytes(chip, WRITE_REG, 6, NO_WAIT_INT, data, 6); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } ERASE_RTY: retval = ms_send_cmd(chip, BLOCK_ERASE, WAIT_INT); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } ms_set_err_code(chip, MS_NO_ERROR); retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (val & INT_REG_CMDNK) { if (i < 3) { @@ -1546,9 +1466,8 @@ ERASE_RTY: static void ms_set_page_status(u16 log_blk, u8 type, u8 *extra, int extra_len) { - if (!extra || (extra_len < MS_EXTRA_SIZE)) { + if (!extra || (extra_len < MS_EXTRA_SIZE)) return; - } memset(extra, 0xFF, MS_EXTRA_SIZE); @@ -1583,9 +1502,8 @@ static int ms_init_page(struct rtsx_chip *chip, u16 phy_blk, u16 log_blk, u8 sta } retval = ms_write_extra_data(chip, phy_blk, i, extra, MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } return STATUS_SUCCESS; @@ -1603,27 +1521,23 @@ static int ms_copy_page(struct rtsx_chip *chip, u16 old_blk, u16 new_blk, RTSX_DEBUGP("start_page = %d, end_page = %d\n", start_page, end_page); retval = ms_read_extra_data(chip, new_blk, 0, extra, MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = ms_read_status_reg(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } RTSX_READ_REG(chip, PPBUF_BASE2, &val); if (val & BUF_FULL) { retval = ms_send_cmd(chip, CLEAR_BUF, WAIT_INT); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (!(val & INT_REG_CED)) { ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); @@ -1640,17 +1554,16 @@ static int ms_copy_page(struct rtsx_chip *chip, u16 old_blk, u16 new_blk, ms_read_extra_data(chip, old_blk, i, extra, MS_EXTRA_SIZE); retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } ms_set_err_code(chip, MS_NO_ERROR); - if (CHK_MS4BIT(ms_card)) { + if (CHK_MS4BIT(ms_card)) data[0] = 0x88; - } else { + else data[0] = 0x80; - } + data[1] = 0; data[2] = (u8)(old_blk >> 8); data[3] = (u8)old_blk; @@ -1658,20 +1571,17 @@ static int ms_copy_page(struct rtsx_chip *chip, u16 old_blk, u16 new_blk, data[5] = i; retval = ms_write_bytes(chip, WRITE_REG , 6, NO_WAIT_INT, data, 6); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } ms_set_err_code(chip, MS_NO_ERROR); retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (val & INT_REG_CMDNK) { ms_set_err_code(chip, MS_CMD_NK); @@ -1689,15 +1599,14 @@ static int ms_copy_page(struct rtsx_chip *chip, u16 old_blk, u16 new_blk, } retval = ms_transfer_tpc(chip, MS_TM_NORMAL_READ, READ_PAGE_DATA, 0, NO_WAIT_INT); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (uncorrect_flag) { ms_set_page_status(log_blk, setPS_NG, extra, MS_EXTRA_SIZE); - if (i == 0) { + if (i == 0) extra[0] &= 0xEF; - } + ms_write_extra_data(chip, old_blk, i, extra, MS_EXTRA_SIZE); RTSX_DEBUGP("page %d : extra[0] = 0x%x\n", i, extra[0]); MS_SET_BAD_BLOCK_FLG(ms_card); @@ -1710,13 +1619,11 @@ static int ms_copy_page(struct rtsx_chip *chip, u16 old_blk, u16 new_blk, for (rty_cnt = 0; rty_cnt < MS_MAX_RETRY_COUNT; rty_cnt++) { retval = ms_transfer_tpc(chip, MS_TM_NORMAL_WRITE, WRITE_PAGE_DATA, 0, NO_WAIT_INT); - if (retval == STATUS_SUCCESS) { + if (retval == STATUS_SUCCESS) break; - } } - if (rty_cnt == MS_MAX_RETRY_COUNT) { + if (rty_cnt == MS_MAX_RETRY_COUNT) TRACE_RET(chip, STATUS_FAIL); - } } if (!(val & INT_REG_BREQ)) { @@ -1730,45 +1637,41 @@ static int ms_copy_page(struct rtsx_chip *chip, u16 old_blk, u16 new_blk, ms_set_err_code(chip, MS_NO_ERROR); - if (CHK_MS4BIT(ms_card)) { + if (CHK_MS4BIT(ms_card)) data[0] = 0x88; - } else { + else data[0] = 0x80; - } + data[1] = 0; data[2] = (u8)(new_blk >> 8); data[3] = (u8)new_blk; data[4] = 0x20; data[5] = i; - if ((extra[0] & 0x60) != 0x60) { + if ((extra[0] & 0x60) != 0x60) data[6] = extra[0]; - } else { + else data[6] = 0xF8; - } + data[6 + 1] = 0xFF; data[6 + 2] = (u8)(log_blk >> 8); data[6 + 3] = (u8)log_blk; - for (j = 4; j <= MS_EXTRA_SIZE; j++) { + for (j = 4; j <= MS_EXTRA_SIZE; j++) data[6 + j] = 0xFF; - } retval = ms_write_bytes(chip, WRITE_REG, (6 + MS_EXTRA_SIZE), NO_WAIT_INT, data, 16); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } ms_set_err_code(chip, MS_NO_ERROR); retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (val & INT_REG_CMDNK) { ms_set_err_code(chip, MS_CMD_NK); @@ -1784,17 +1687,16 @@ static int ms_copy_page(struct rtsx_chip *chip, u16 old_blk, u16 new_blk, if (i == 0) { retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 7); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } ms_set_err_code(chip, MS_NO_ERROR); - if (CHK_MS4BIT(ms_card)) { + if (CHK_MS4BIT(ms_card)) data[0] = 0x88; - } else { + else data[0] = 0x80; - } + data[1] = 0; data[2] = (u8)(old_blk >> 8); data[3] = (u8)old_blk; @@ -1804,20 +1706,17 @@ static int ms_copy_page(struct rtsx_chip *chip, u16 old_blk, u16 new_blk, data[7] = 0xFF; retval = ms_write_bytes(chip, WRITE_REG, 7, NO_WAIT_INT, data, 8); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } ms_set_err_code(chip, MS_NO_ERROR); retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (val & INT_REG_CMDNK) { ms_set_err_code(chip, MS_CMD_NK); @@ -1848,28 +1747,24 @@ static int reset_ms(struct rtsx_chip *chip) #endif retval = ms_prepare_reset(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } ms_card->ms_type |= TYPE_MS; retval = ms_send_cmd(chip, MS_RESET, NO_WAIT_INT); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = ms_read_status_reg(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } RTSX_READ_REG(chip, PPBUF_BASE2, &val); - if (val & WRT_PRTCT) { + if (val & WRT_PRTCT) chip->card_wp |= MS_CARD; - } else { + else chip->card_wp &= ~MS_CARD; - } i = 0; @@ -1913,21 +1808,18 @@ RE_SEARCH: } retval = ms_read_page(chip, ms_card->boot_block, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } /* Read MS system information as sys_info */ rtsx_init_cmd(chip); - for (i = 0; i < 96; i++) { + for (i = 0; i < 96; i++) rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 0x1A0 + i, 0, 0); - } retval = rtsx_send_cmd(chip, MS_CARD, 100); - if (retval < 0) { + if (retval < 0) TRACE_RET(chip, STATUS_FAIL); - } ptr = rtsx_get_cmd_data(chip); memcpy(ms_card->raw_sys_info, ptr, 96); @@ -1938,21 +1830,18 @@ RE_SEARCH: rtsx_add_cmd(chip, READ_REG_CMD, HEADER_ID0, 0, 0); rtsx_add_cmd(chip, READ_REG_CMD, HEADER_ID1, 0, 0); - for (reg_addr = DISABLED_BLOCK0; reg_addr <= DISABLED_BLOCK3; reg_addr++) { + for (reg_addr = DISABLED_BLOCK0; reg_addr <= DISABLED_BLOCK3; reg_addr++) rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); - } - for (reg_addr = BLOCK_SIZE_0; reg_addr <= PAGE_SIZE_1; reg_addr++) { + for (reg_addr = BLOCK_SIZE_0; reg_addr <= PAGE_SIZE_1; reg_addr++) rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); - } rtsx_add_cmd(chip, READ_REG_CMD, MS_Device_Type, 0, 0); rtsx_add_cmd(chip, READ_REG_CMD, MS_4bit_Support, 0, 0); retval = rtsx_send_cmd(chip, MS_CARD, 100); - if (retval < 0) { + if (retval < 0) TRACE_RET(chip, STATUS_FAIL); - } ptr = rtsx_get_cmd_data(chip); @@ -1975,9 +1864,8 @@ RE_SEARCH: goto RE_SEARCH; } - if ((ptr[14] == 1) || (ptr[14] == 3)) { + if ((ptr[14] == 1) || (ptr[14] == 3)) chip->card_wp |= MS_CARD; - } /* BLOCK_SIZE_0, BLOCK_SIZE_1 */ block_size = ((u16)ptr[6] << 8) | ptr[7]; @@ -2026,17 +1914,15 @@ RE_SEARCH: /* Switch I/F Mode */ if (ptr[15]) { retval = ms_set_rw_reg_addr(chip, 0, 0, SystemParm, 1); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } RTSX_WRITE_REG(chip, PPBUF_BASE2, 0xFF, 0x88); RTSX_WRITE_REG(chip, PPBUF_BASE2 + 1, 0xFF, 0); retval = ms_transfer_tpc(chip, MS_TM_WRITE_BYTES, WRITE_REG , 1, NO_WAIT_INT); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } RTSX_WRITE_REG(chip, MS_CFG, 0x58 | MS_NO_CHECK_INT, MS_BUS_WIDTH_4 | PUSH_TIME_ODD | MS_NO_CHECK_INT); @@ -2044,11 +1930,10 @@ RE_SEARCH: ms_card->ms_type |= MS_4BIT; } - if (CHK_MS4BIT(ms_card)) { + if (CHK_MS4BIT(ms_card)) chip->card_bus_width[chip->card2lun[MS_CARD]] = 4; - } else { + else chip->card_bus_width[chip->card2lun[MS_CARD]] = 1; - } return STATUS_SUCCESS; } @@ -2065,30 +1950,27 @@ static int ms_init_l2p_tbl(struct rtsx_chip *chip) size = ms_card->segment_cnt * sizeof(struct zone_entry); ms_card->segment = vzalloc(size); - if (ms_card->segment == NULL) { + if (ms_card->segment == NULL) TRACE_RET(chip, STATUS_FAIL); - } retval = ms_read_page(chip, ms_card->boot_block, 1); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, INIT_FAIL); - } reg_addr = PPBUF_BASE2; for (i = 0; i < (((ms_card->total_block >> 9) * 10) + 1); i++) { retval = rtsx_read_register(chip, reg_addr++, &val1); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, INIT_FAIL); - } + retval = rtsx_read_register(chip, reg_addr++, &val2); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, INIT_FAIL); - } defect_block = ((u16)val1 << 8) | val2; - if (defect_block == 0xFFFF) { + if (defect_block == 0xFFFF) break; - } + seg_no = defect_block / 512; ms_card->segment[seg_no].defect_list[ms_card->segment[seg_no].disable_count++] = defect_block; } @@ -2141,9 +2023,8 @@ static void ms_set_l2p_tbl(struct rtsx_chip *chip, int seg_no, u16 log_off, u16 return; segment = &(ms_card->segment[seg_no]); - if (segment->l2p_table) { + if (segment->l2p_table) segment->l2p_table[log_off] = phy_blk; - } } static void ms_set_unused_block(struct rtsx_chip *chip, u16 phy_blk) @@ -2156,9 +2037,9 @@ static void ms_set_unused_block(struct rtsx_chip *chip, u16 phy_blk) segment = &(ms_card->segment[seg_no]); segment->free_table[segment->set_index++] = phy_blk; - if (segment->set_index >= MS_FREE_TABLE_CNT) { + if (segment->set_index >= MS_FREE_TABLE_CNT) segment->set_index = 0; - } + segment->unused_blk_cnt++; } @@ -2175,9 +2056,9 @@ static u16 ms_get_unused_block(struct rtsx_chip *chip, int seg_no) phy_blk = segment->free_table[segment->get_index]; segment->free_table[segment->get_index++] = 0xFFFF; - if (segment->get_index >= MS_FREE_TABLE_CNT) { + if (segment->get_index >= MS_FREE_TABLE_CNT) segment->get_index = 0; - } + segment->unused_blk_cnt--; return phy_blk; @@ -2199,27 +2080,27 @@ static int ms_arbitrate_l2p(struct rtsx_chip *chip, u16 phy_blk, u16 log_off, u8 if (us1 != us2) { if (us1 == 0) { - if (!(chip->card_wp & MS_CARD)) { + if (!(chip->card_wp & MS_CARD)) ms_erase_block(chip, tmp_blk); - } + ms_set_unused_block(chip, tmp_blk); segment->l2p_table[log_off] = phy_blk; } else { - if (!(chip->card_wp & MS_CARD)) { + if (!(chip->card_wp & MS_CARD)) ms_erase_block(chip, phy_blk); - } + ms_set_unused_block(chip, phy_blk); } } else { if (phy_blk < tmp_blk) { - if (!(chip->card_wp & MS_CARD)) { + if (!(chip->card_wp & MS_CARD)) ms_erase_block(chip, phy_blk); - } + ms_set_unused_block(chip, phy_blk); } else { - if (!(chip->card_wp & MS_CARD)) { + if (!(chip->card_wp & MS_CARD)) ms_erase_block(chip, tmp_blk); - } + ms_set_unused_block(chip, tmp_blk); segment->l2p_table[log_off] = phy_blk; } @@ -2240,9 +2121,8 @@ static int ms_build_l2p_tbl(struct rtsx_chip *chip, int seg_no) if (ms_card->segment == NULL) { retval = ms_init_l2p_tbl(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, retval); - } } if (ms_card->segment[seg_no].build_flag) { @@ -2250,27 +2130,24 @@ static int ms_build_l2p_tbl(struct rtsx_chip *chip, int seg_no) return STATUS_SUCCESS; } - if (seg_no == 0) { + if (seg_no == 0) table_size = 494; - } else { + else table_size = 496; - } segment = &(ms_card->segment[seg_no]); if (segment->l2p_table == NULL) { segment->l2p_table = (u16 *)vmalloc(table_size * 2); - if (segment->l2p_table == NULL) { + if (segment->l2p_table == NULL) TRACE_GOTO(chip, BUILD_FAIL); - } } memset((u8 *)(segment->l2p_table), 0xff, table_size * 2); if (segment->free_table == NULL) { segment->free_table = (u16 *)vmalloc(MS_FREE_TABLE_CNT * 2); - if (segment->free_table == NULL) { + if (segment->free_table == NULL) TRACE_GOTO(chip, BUILD_FAIL); - } } memset((u8 *)(segment->free_table), 0xff, MS_FREE_TABLE_CNT * 2); @@ -2368,13 +2245,11 @@ static int ms_build_l2p_tbl(struct rtsx_chip *chip, int seg_no) /* Logical Address Confirmation Process */ if (seg_no == ms_card->segment_cnt - 1) { - if (segment->unused_blk_cnt < 2) { + if (segment->unused_blk_cnt < 2) chip->card_wp |= MS_CARD; - } } else { - if (segment->unused_blk_cnt < 1) { + if (segment->unused_blk_cnt < 1) chip->card_wp |= MS_CARD; - } } if (chip->card_wp & MS_CARD) @@ -2388,9 +2263,9 @@ static int ms_build_l2p_tbl(struct rtsx_chip *chip, int seg_no) return STATUS_SUCCESS; } retval = ms_init_page(chip, phy_blk, log_blk, 0, 1); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, BUILD_FAIL); - } + segment->l2p_table[log_blk-ms_start_idx[seg_no]] = phy_blk; if (seg_no == ms_card->segment_cnt - 1) { if (segment->unused_blk_cnt < 2) { @@ -2419,16 +2294,14 @@ static int ms_build_l2p_tbl(struct rtsx_chip *chip, int seg_no) phy_blk = ms_get_unused_block(chip, 0); retval = ms_copy_page(chip, tmp_blk, phy_blk, log_blk, 0, ms_card->page_off + 1); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } segment->l2p_table[log_blk] = phy_blk; retval = ms_set_bad_block(chip, tmp_blk); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } } } @@ -2458,14 +2331,12 @@ int reset_ms_card(struct rtsx_chip *chip) memset(ms_card, 0, sizeof(struct ms_info)); retval = enable_card_clock(chip, MS_CARD); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = select_card(chip, MS_CARD); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } ms_card->ms_type = 0; @@ -2473,27 +2344,24 @@ int reset_ms_card(struct rtsx_chip *chip) if (retval != STATUS_SUCCESS) { if (ms_card->check_ms_flow) { retval = reset_ms(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } else { TRACE_RET(chip, STATUS_FAIL); } } retval = ms_set_init_para(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (!CHK_MSPRO(ms_card)) { /* Build table for the last segment, * to check if L2P table block exists, erasing it */ retval = ms_build_l2p_tbl(chip, ms_card->total_block / 512 - 1); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } RTSX_DEBUGP("ms_card->ms_type = 0x%x\n", ms_card->ms_type); @@ -2520,9 +2388,8 @@ static int mspro_set_rw_cmd(struct rtsx_chip *chip, u32 start_sec, u16 sec_cnt, if (retval == STATUS_SUCCESS) break; } - if (i == MS_MAX_RETRY_COUNT) { + if (i == MS_MAX_RETRY_COUNT) TRACE_RET(chip, STATUS_FAIL); - } return STATUS_SUCCESS; } @@ -2556,21 +2423,18 @@ static inline int ms_auto_tune_clock(struct rtsx_chip *chip) RTSX_DEBUGP("--%s--\n", __func__); if (chip->asic_code) { - if (ms_card->ms_clock > 30) { + if (ms_card->ms_clock > 30) ms_card->ms_clock -= 20; - } } else { - if (ms_card->ms_clock == CLK_80) { + if (ms_card->ms_clock == CLK_80) ms_card->ms_clock = CLK_60; - } else if (ms_card->ms_clock == CLK_60) { + else if (ms_card->ms_clock == CLK_60) ms_card->ms_clock = CLK_40; - } } retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } return STATUS_SUCCESS; } @@ -2616,15 +2480,13 @@ static int mspro_rw_multi_sector(struct scsi_cmnd *srb, struct rtsx_chip *chip, } retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } - if (srb->sc_data_direction == DMA_FROM_DEVICE) { + if (srb->sc_data_direction == DMA_FROM_DEVICE) trans_mode = MS_TM_AUTO_READ; - } else { + else trans_mode = MS_TM_AUTO_WRITE; - } RTSX_READ_REG(chip, MS_TRANS_CFG, &val); @@ -2639,9 +2501,8 @@ static int mspro_rw_multi_sector(struct scsi_cmnd *srb, struct rtsx_chip *chip, ms_card->total_sec_cnt = 0; if (val & MS_INT_BREQ) { retval = ms_send_cmd(chip, PRO_STOP, WAIT_INT); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH); } @@ -2651,17 +2512,16 @@ static int mspro_rw_multi_sector(struct scsi_cmnd *srb, struct rtsx_chip *chip, if (!ms_card->seq_mode) { ms_card->total_sec_cnt = 0; if (sector_cnt >= SEQ_START_CRITERIA) { - if ((ms_card->capacity - start_sector) > 0xFE00) { + if ((ms_card->capacity - start_sector) > 0xFE00) count = 0xFE00; - } else { + else count = (u16)(ms_card->capacity - start_sector); - } + if (count > sector_cnt) { - if (mode_2k) { + if (mode_2k) ms_card->seq_mode |= MODE_2K_SEQ; - } else { + else ms_card->seq_mode |= MODE_512_SEQ; - } } } else { count = sector_cnt; @@ -2686,9 +2546,9 @@ static int mspro_rw_multi_sector(struct scsi_cmnd *srb, struct rtsx_chip *chip, TRACE_RET(chip, STATUS_FAIL); } - if (val & MS_INT_BREQ) { + if (val & MS_INT_BREQ) ms_send_cmd(chip, PRO_STOP, WAIT_INT); - } + if (val & (MS_CRC16_ERR | MS_RDY_TIMEOUT)) { RTSX_DEBUGP("MSPro CRC error, tune clock!\n"); chip->rw_need_retry = 1; @@ -2739,11 +2599,10 @@ static int mspro_read_format_progress(struct rtsx_chip *chip, const int short_da TRACE_RET(chip, STATUS_FAIL); } - if (short_data_len >= 256) { + if (short_data_len >= 256) cnt = 0; - } else { + else cnt = (u8)short_data_len; - } retval = rtsx_write_register(chip, MS_CFG, MS_NO_CHECK_INT, MS_NO_CHECK_INT); if (retval != STATUS_SUCCESS) { @@ -2778,9 +2637,8 @@ static int mspro_read_format_progress(struct rtsx_chip *chip, const int short_da ms_card->format_status = FORMAT_FAIL; TRACE_RET(chip, STATUS_FAIL); } - if (tmp & (MS_INT_CED | MS_INT_CMDNK | MS_INT_BREQ | MS_INT_ERR)) { + if (tmp & (MS_INT_CED | MS_INT_CMDNK | MS_INT_BREQ | MS_INT_ERR)) break; - } wait_timeout(1); } @@ -2843,14 +2701,12 @@ int mspro_format(struct scsi_cmnd *srb, struct rtsx_chip *chip, int short_data_l RTSX_DEBUGP("--%s--\n", __func__); retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = ms_set_rw_reg_addr(chip, 0x00, 0x00, Pro_TPCParm, 0x01); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } memset(buf, 0, 2); switch (short_data_len) { @@ -2874,25 +2730,22 @@ int mspro_format(struct scsi_cmnd *srb, struct rtsx_chip *chip, int short_data_l if (retval == STATUS_SUCCESS) break; } - if (i == MS_MAX_RETRY_COUNT) { + if (i == MS_MAX_RETRY_COUNT) TRACE_RET(chip, STATUS_FAIL); - } - if (quick_format) { + if (quick_format) para = 0x0000; - } else { + else para = 0x0001; - } + retval = mspro_set_rw_cmd(chip, 0, para, PRO_FORMAT); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } RTSX_READ_REG(chip, MS_TRANS_CFG, &tmp); - if (tmp & (MS_INT_CMDNK | MS_INT_ERR)) { + if (tmp & (MS_INT_CMDNK | MS_INT_ERR)) TRACE_RET(chip, STATUS_FAIL); - } if ((tmp & (MS_INT_BREQ | MS_INT_CED)) == MS_INT_BREQ) { ms_card->pro_under_formatting = 1; @@ -2930,15 +2783,14 @@ static int ms_read_multiple_pages(struct rtsx_chip *chip, u16 phy_blk, u16 log_b } retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } - if (CHK_MS4BIT(ms_card)) { + if (CHK_MS4BIT(ms_card)) data[0] = 0x88; - } else { + else data[0] = 0x80; - } + data[1] = 0; data[2] = (u8)(phy_blk >> 8); data[3] = (u8)phy_blk; @@ -2950,16 +2802,14 @@ static int ms_read_multiple_pages(struct rtsx_chip *chip, u16 phy_blk, u16 log_b if (retval == STATUS_SUCCESS) break; } - if (i == MS_MAX_RETRY_COUNT) { + if (i == MS_MAX_RETRY_COUNT) TRACE_RET(chip, STATUS_FAIL); - } ms_set_err_code(chip, MS_NO_ERROR); retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } ptr = buf; @@ -2972,9 +2822,9 @@ static int ms_read_multiple_pages(struct rtsx_chip *chip, u16 phy_blk, u16 log_b } retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + if (val & INT_REG_CMDNK) { ms_set_err_code(chip, MS_CMD_NK); TRACE_RET(chip, STATUS_FAIL); @@ -3006,15 +2856,14 @@ static int ms_read_multiple_pages(struct rtsx_chip *chip, u16 phy_blk, u16 log_b if (page_addr == (end_page - 1)) { if (!(val & INT_REG_CED)) { retval = ms_send_cmd(chip, BLOCK_END, WAIT_INT); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + if (!(val & INT_REG_CED)) { ms_set_err_code(chip, MS_FLASH_READ_ERROR); TRACE_RET(chip, STATUS_FAIL); @@ -3079,15 +2928,14 @@ static int ms_write_multiple_pages(struct rtsx_chip *chip, u16 old_blk, u16 new_ if (!start_page) { retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 7); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } - if (CHK_MS4BIT(ms_card)) { + if (CHK_MS4BIT(ms_card)) data[0] = 0x88; - } else { + else data[0] = 0x80; - } + data[1] = 0; data[2] = (u8)(old_blk >> 8); data[3] = (u8)old_blk; @@ -3097,74 +2945,66 @@ static int ms_write_multiple_pages(struct rtsx_chip *chip, u16 old_blk, u16 new_ data[7] = 0xFF; retval = ms_write_bytes(chip, WRITE_REG, 7, NO_WAIT_INT, data, 8); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } ms_set_err_code(chip, MS_NO_ERROR); retval = ms_transfer_tpc(chip, MS_TM_READ_BYTES, GET_INT, 1, NO_WAIT_INT); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, (6 + MS_EXTRA_SIZE)); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } ms_set_err_code(chip, MS_NO_ERROR); - if (CHK_MS4BIT(ms_card)) { + if (CHK_MS4BIT(ms_card)) data[0] = 0x88; - } else { + else data[0] = 0x80; - } + data[1] = 0; data[2] = (u8)(new_blk >> 8); data[3] = (u8)new_blk; - if ((end_page - start_page) == 1) { + if ((end_page - start_page) == 1) data[4] = 0x20; - } else { + else data[4] = 0; - } + data[5] = start_page; data[6] = 0xF8; data[7] = 0xFF; data[8] = (u8)(log_blk >> 8); data[9] = (u8)log_blk; - for (i = 0x0A; i < 0x10; i++) { + for (i = 0x0A; i < 0x10; i++) data[i] = 0xFF; - } for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { retval = ms_write_bytes(chip, WRITE_REG, 6 + MS_EXTRA_SIZE, NO_WAIT_INT, data, 16); if (retval == STATUS_SUCCESS) break; } - if (i == MS_MAX_RETRY_COUNT) { + if (i == MS_MAX_RETRY_COUNT) TRACE_RET(chip, STATUS_FAIL); - } for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); if (retval == STATUS_SUCCESS) break; } - if (i == MS_MAX_RETRY_COUNT) { + if (i == MS_MAX_RETRY_COUNT) TRACE_RET(chip, STATUS_FAIL); - } retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } ptr = buf; for (page_addr = start_page; page_addr < end_page; page_addr++) { @@ -3210,17 +3050,15 @@ static int ms_write_multiple_pages(struct rtsx_chip *chip, u16 old_blk, u16 new_ ms_set_err_code(chip, MS_TO_ERROR); rtsx_clear_ms_error(chip); - if (retval == -ETIMEDOUT) { + if (retval == -ETIMEDOUT) TRACE_RET(chip, STATUS_TIMEDOUT); - } else { + else TRACE_RET(chip, STATUS_FAIL); - } } retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if ((end_page - start_page) == 1) { if (!(val & INT_REG_CED)) { @@ -3231,15 +3069,13 @@ static int ms_write_multiple_pages(struct rtsx_chip *chip, u16 old_blk, u16 new_ if (page_addr == (end_page - 1)) { if (!(val & INT_REG_CED)) { retval = ms_send_cmd(chip, BLOCK_END, WAIT_INT); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } if ((page_addr == (end_page - 1)) || (page_addr == ms_card->page_off)) { @@ -3266,9 +3102,8 @@ static int ms_finish_write(struct rtsx_chip *chip, u16 old_blk, u16 new_blk, retval = ms_copy_page(chip, old_blk, new_blk, log_blk, page_off, ms_card->page_off + 1); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } seg_no = old_blk >> 9; @@ -3277,9 +3112,8 @@ static int ms_finish_write(struct rtsx_chip *chip, u16 old_blk, u16 new_blk, ms_set_bad_block(chip, old_blk); } else { retval = ms_erase_block(chip, old_blk); - if (retval == STATUS_SUCCESS) { + if (retval == STATUS_SUCCESS) ms_set_unused_block(chip, old_blk); - } } ms_set_l2p_tbl(chip, seg_no, log_blk - ms_start_idx[seg_no], new_blk); @@ -3294,9 +3128,8 @@ static int ms_prepare_write(struct rtsx_chip *chip, u16 old_blk, u16 new_blk, if (start_page) { retval = ms_copy_page(chip, old_blk, new_blk, log_blk, 0, start_page); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } return STATUS_SUCCESS; @@ -3311,17 +3144,15 @@ int ms_delay_write(struct rtsx_chip *chip) if (delay_write->delay_write_flag) { retval = ms_set_init_para(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } delay_write->delay_write_flag = 0; retval = ms_finish_write(chip, delay_write->old_phyblock, delay_write->new_phyblock, delay_write->logblock, delay_write->pageoff); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } return STATUS_SUCCESS; @@ -3330,11 +3161,10 @@ int ms_delay_write(struct rtsx_chip *chip) static inline void ms_rw_fail(struct scsi_cmnd *srb, struct rtsx_chip *chip) { - if (srb->sc_data_direction == DMA_FROM_DEVICE) { + if (srb->sc_data_direction == DMA_FROM_DEVICE) set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - } else { + else set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); - } } static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, u16 sector_cnt) @@ -3449,11 +3279,11 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 RTSX_DEBUGP("seg_no = %d, old_blk = 0x%x, new_blk = 0x%x\n", seg_no, old_blk, new_blk); while (total_sec_cnt) { - if ((start_page + total_sec_cnt) > (ms_card->page_off + 1)) { + if ((start_page + total_sec_cnt) > (ms_card->page_off + 1)) end_page = ms_card->page_off + 1; - } else { + else end_page = start_page + (u8)total_sec_cnt; - } + page_cnt = end_page - start_page; RTSX_DEBUGP("start_page = %d, end_page = %d, page_cnt = %d\n", @@ -3482,9 +3312,9 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 if (srb->sc_data_direction == DMA_TO_DEVICE) { if (end_page == (ms_card->page_off + 1)) { retval = ms_erase_block(chip, old_blk); - if (retval == STATUS_SUCCESS) { + if (retval == STATUS_SUCCESS) ms_set_unused_block(chip, old_blk); - } + ms_set_l2p_tbl(chip, seg_no, log_blk - ms_start_idx[seg_no], new_blk); } } @@ -3565,11 +3395,10 @@ int ms_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, u16 s struct ms_info *ms_card = &(chip->ms_card); int retval; - if (CHK_MSPRO(ms_card)) { + if (CHK_MSPRO(ms_card)) retval = mspro_rw_multi_sector(srb, chip, start_sector, sector_cnt); - } else { + else retval = ms_rw_multi_sector(srb, chip, start_sector, sector_cnt); - } return retval; } @@ -3609,14 +3438,12 @@ static int ms_poll_int(struct rtsx_chip *chip) rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANS_CFG, MS_INT_CED, MS_INT_CED); retval = rtsx_send_cmd(chip, MS_CARD, 5000); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } val = *rtsx_get_cmd_data(chip); - if (val & MS_INT_ERR) { + if (val & MS_INT_ERR) TRACE_RET(chip, STATUS_FAIL); - } return STATUS_SUCCESS; } @@ -3678,9 +3505,8 @@ static int mg_send_ex_cmd(struct rtsx_chip *chip, u8 cmd, u8 entry_num) if (retval == STATUS_SUCCESS) break; } - if (i == MS_MAX_RETRY_COUNT) { + if (i == MS_MAX_RETRY_COUNT) TRACE_RET(chip, STATUS_FAIL); - } if (check_ms_err(chip)) { rtsx_clear_ms_error(chip); @@ -3697,14 +3523,13 @@ static int mg_set_tpc_para_sub(struct rtsx_chip *chip, int type, u8 mg_entry_num RTSX_DEBUGP("--%s--\n", __func__); - if (type == 0) { + if (type == 0) retval = ms_set_rw_reg_addr(chip, 0, 0, Pro_TPCParm, 1); - } else { + else retval = ms_set_rw_reg_addr(chip, 0, 0, Pro_DataCount1, 6); - } - if (retval != STATUS_SUCCESS) { + + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } buf[0] = 0; buf[1] = 0; @@ -3715,9 +3540,8 @@ static int mg_set_tpc_para_sub(struct rtsx_chip *chip, int type, u8 mg_entry_num buf[5] = mg_entry_num; } retval = ms_write_bytes(chip, PRO_WRITE_REG, (type == 0) ? 1 : 6, NO_WAIT_INT, buf, 6); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } return STATUS_SUCCESS; } @@ -3739,9 +3563,8 @@ int mg_set_leaf_id(struct scsi_cmnd *srb, struct rtsx_chip *chip) ms_cleanup_work(chip); retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = mg_send_ex_cmd(chip, MG_SET_LID, 0); if (retval != STATUS_SUCCESS) { @@ -3751,9 +3574,9 @@ int mg_set_leaf_id(struct scsi_cmnd *srb, struct rtsx_chip *chip) memset(buf1, 0, 32); rtsx_stor_get_xfer_buf(buf2, min(12, (int)scsi_bufflen(srb)), srb); - for (i = 0; i < 8; i++) { + for (i = 0; i < 8; i++) buf1[8+i] = buf2[4+i]; - } + retval = ms_write_bytes(chip, PRO_WRITE_SHORT_DATA, 32, WAIT_INT, buf1, 32); if (retval != STATUS_SUCCESS) { set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); @@ -3780,14 +3603,12 @@ int mg_get_local_EKB(struct scsi_cmnd *srb, struct rtsx_chip *chip) ms_cleanup_work(chip); retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } buf = kmalloc(1540, GFP_KERNEL); - if (!buf) { + if (!buf) TRACE_RET(chip, STATUS_ERROR); - } buf[0] = 0x04; buf[1] = 0x1A; @@ -3835,9 +3656,8 @@ int mg_chg(struct scsi_cmnd *srb, struct rtsx_chip *chip) ms_cleanup_work(chip); retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = mg_send_ex_cmd(chip, MG_GET_ID, 0); if (retval != STATUS_SUCCESS) { @@ -3875,12 +3695,12 @@ int mg_chg(struct scsi_cmnd *srb, struct rtsx_chip *chip) bufflen = min(12, (int)scsi_bufflen(srb)); rtsx_stor_get_xfer_buf(buf, bufflen, srb); - for (i = 0; i < 8; i++) { + for (i = 0; i < 8; i++) buf[i] = buf[4+i]; - } - for (i = 0; i < 24; i++) { + + for (i = 0; i < 24; i++) buf[8+i] = 0; - } + retval = ms_write_bytes(chip, PRO_WRITE_SHORT_DATA, 32, WAIT_INT, buf, 32); if (retval != STATUS_SUCCESS) { @@ -3911,9 +3731,8 @@ int mg_get_rsp_chg(struct scsi_cmnd *srb, struct rtsx_chip *chip) ms_cleanup_work(chip); retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = mg_send_ex_cmd(chip, MG_MAKE_RMS, 0); if (retval != STATUS_SUCCESS) { @@ -3968,9 +3787,8 @@ int mg_rsp(struct scsi_cmnd *srb, struct rtsx_chip *chip) ms_cleanup_work(chip); retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = mg_send_ex_cmd(chip, MG_MAKE_KSE, 0); if (retval != STATUS_SUCCESS) { @@ -3981,12 +3799,12 @@ int mg_rsp(struct scsi_cmnd *srb, struct rtsx_chip *chip) bufflen = min(12, (int)scsi_bufflen(srb)); rtsx_stor_get_xfer_buf(buf, bufflen, srb); - for (i = 0; i < 8; i++) { + for (i = 0; i < 8; i++) buf[i] = buf[4+i]; - } - for (i = 0; i < 24; i++) { + + for (i = 0; i < 24; i++) buf[8+i] = 0; - } + retval = ms_write_bytes(chip, PRO_WRITE_SHORT_DATA, 32, WAIT_INT, buf, 32); if (retval != STATUS_SUCCESS) { set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); @@ -4016,14 +3834,12 @@ int mg_get_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip) ms_cleanup_work(chip); retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } buf = kmalloc(1028, GFP_KERNEL); - if (!buf) { + if (!buf) TRACE_RET(chip, STATUS_ERROR); - } buf[0] = 0x04; buf[1] = 0x02; @@ -4073,14 +3889,12 @@ int mg_set_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip) ms_cleanup_work(chip); retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } buf = kmalloc(1028, GFP_KERNEL); - if (!buf) { + if (!buf) TRACE_RET(chip, STATUS_ERROR); - } bufflen = min(1028, (int)scsi_bufflen(srb)); rtsx_stor_get_xfer_buf(buf, bufflen, srb); @@ -4088,11 +3902,10 @@ int mg_set_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip) retval = mg_send_ex_cmd(chip, MG_SET_IBD, ms_card->mg_entry_num); if (retval != STATUS_SUCCESS) { if (ms_card->mg_auth == 0) { - if ((buf[5] & 0xC0) != 0) { + if ((buf[5] & 0xC0) != 0) set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); - } else { + else set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); - } } else { set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); } @@ -4121,11 +3934,10 @@ int mg_set_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip) if ((retval < 0) || check_ms_err(chip)) { rtsx_clear_ms_error(chip); if (ms_card->mg_auth == 0) { - if ((buf[5] & 0xC0) != 0) { + if ((buf[5] & 0xC0) != 0) set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); - } else { + else set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); - } } else { set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); } @@ -4139,11 +3951,10 @@ int mg_set_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip) if ((retval != STATUS_SUCCESS) || check_ms_err(chip)) { rtsx_clear_ms_error(chip); if (ms_card->mg_auth == 0) { - if ((buf[5] & 0xC0) != 0) { + if ((buf[5] & 0xC0) != 0) set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); - } else { + else set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); - } } else { set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); } @@ -4187,14 +3998,13 @@ int ms_power_off_card3v3(struct rtsx_chip *chip) int retval; retval = disable_card_clock(chip, MS_CARD); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + if (chip->asic_code) { retval = ms_pull_ctl_disable(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } else { RTSX_WRITE_REG(chip, FPGA_PULL_CTL, FPGA_MS_PULL_CTL_BIT | 0x20, FPGA_MS_PULL_CTL_BIT); @@ -4202,9 +4012,8 @@ int ms_power_off_card3v3(struct rtsx_chip *chip) RTSX_WRITE_REG(chip, CARD_OE, MS_OUTPUT_EN, 0); if (!chip->ft2_fast_mode) { retval = card_power_off(chip, MS_CARD); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } return STATUS_SUCCESS; @@ -4234,9 +4043,8 @@ int release_ms_card(struct rtsx_chip *chip) #endif retval = ms_power_off_card3v3(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } return STATUS_SUCCESS; } -- cgit v0.10.2 From 023aeaa496557193743ccfab313fcb9c148f1079 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sun, 9 Sep 2012 18:40:51 +0530 Subject: staging:wlan-ng: slove sparse warnings drivers/staging/wlan-ng/prism2fw.c:127:18: warning: symbol 's3data' was not declared. Should it be static? drivers/staging/wlan-ng/prism2fw.c:130:14: warning: symbol 'ns3plug' was not declared. Should it be static? drivers/staging/wlan-ng/prism2fw.c:131:18: warning: symbol 's3plug' was not declared. Should it be static? drivers/staging/wlan-ng/prism2fw.c:134:14: warning: symbol 'ns3crc' was not declared. Should it be static? drivers/staging/wlan-ng/prism2fw.c:135:17: warning: symbol 's3crc' was not declared. Should it be static? drivers/staging/wlan-ng/prism2fw.c:138:14: warning: symbol 'ns3info' was not declared. Should it be static? drivers/staging/wlan-ng/prism2fw.c:139:18: warning: symbol 's3info' was not declared. Should it be static? drivers/staging/wlan-ng/prism2fw.c:142:5: warning: symbol 'startaddr' was not declared. Should it be static? drivers/staging/wlan-ng/prism2fw.c:145:14: warning: symbol 'nfchunks' was not declared. Should it be static? drivers/staging/wlan-ng/prism2fw.c:146:17: warning: symbol 'fchunk' was not declared. Should it be static? drivers/staging/wlan-ng/prism2fw.c:154:12: warning: symbol 'pda' was not declared. Should it be static? drivers/staging/wlan-ng/prism2fw.c:155:21: warning: symbol 'nicid' was not declared. Should it be static? drivers/staging/wlan-ng/prism2fw.c:156:20: warning: symbol 'rfid' was not declared. Should it be static? drivers/staging/wlan-ng/prism2fw.c:157:20: warning: symbol 'macid' was not declared. Should it be static? drivers/staging/wlan-ng/prism2fw.c:158:20: warning: symbol 'priid' was not declared. Should it be static? Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlan-ng/prism2fw.c b/drivers/staging/wlan-ng/prism2fw.c index 66c9aa9..9d04e2c 100644 --- a/drivers/staging/wlan-ng/prism2fw.c +++ b/drivers/staging/wlan-ng/prism2fw.c @@ -123,27 +123,27 @@ struct imgchunk { /* s-record image processing */ /* Data records */ -unsigned int ns3data; -struct s3datarec s3data[S3DATA_MAX]; +static unsigned int ns3data; +static struct s3datarec s3data[S3DATA_MAX]; /* Plug records */ -unsigned int ns3plug; -struct s3plugrec s3plug[S3PLUG_MAX]; +static unsigned int ns3plug; +static struct s3plugrec s3plug[S3PLUG_MAX]; /* CRC records */ -unsigned int ns3crc; -struct s3crcrec s3crc[S3CRC_MAX]; +static unsigned int ns3crc; +static struct s3crcrec s3crc[S3CRC_MAX]; /* Info records */ -unsigned int ns3info; -struct s3inforec s3info[S3INFO_MAX]; +static unsigned int ns3info; +static struct s3inforec s3info[S3INFO_MAX]; /* S7 record (there _better_ be only one) */ -u32 startaddr; +static u32 startaddr; /* Load image chunks */ -unsigned int nfchunks; -struct imgchunk fchunk[CHUNKS_MAX]; +static unsigned int nfchunks; +static struct imgchunk fchunk[CHUNKS_MAX]; /* Note that for the following pdrec_t arrays, the len and code */ /* fields are stored in HOST byte order. The mkpdrlist() function */ @@ -151,11 +151,11 @@ struct imgchunk fchunk[CHUNKS_MAX]; /*----------------------------------------------------------------*/ /* PDA, built from [card|newfile]+[addfile1+addfile2...] */ -struct pda pda; -hfa384x_compident_t nicid; -hfa384x_caplevel_t rfid; -hfa384x_caplevel_t macid; -hfa384x_caplevel_t priid; +static struct pda pda; +static hfa384x_compident_t nicid; +static hfa384x_caplevel_t rfid; +static hfa384x_caplevel_t macid; +static hfa384x_caplevel_t priid; /*================================================================*/ /* Local Function Declarations */ -- cgit v0.10.2 From ae24e13a6485a65802e0483ace9f657a89680c6a Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sun, 9 Sep 2012 18:40:52 +0530 Subject: staging:wlan-ng: fix sparse warnings drivers/staging/wlan-ng/prism2fw.c:240:5: warning: symbol 'prism2_fwapply' was not declared. Should it be static? drivers/staging/wlan-ng/prism2fw.c:379:5: warning: symbol 'crcimage' was not declared. Should it be static? drivers/staging/wlan-ng/prism2fw.c:443:6: warning: symbol 'free_chunks' was not declared. Should it be static? drivers/staging/wlan-ng/prism2fw.c:465:6: warning: symbol 'free_srecs' was not declared. Should it be static? drivers/staging/wlan-ng/prism2fw.c:492:5: warning: symbol 'mkimage' was not declared. Should it be static? drivers/staging/wlan-ng/prism2fw.c:585:5: warning: symbol 'mkpdrlist' was not declared. Should it be static? drivers/staging/wlan-ng/prism2fw.c:659:5: warning: symbol 'plugimage' was not declared. Should it be static? drivers/staging/wlan-ng/prism2fw.c:767:5: warning: symbol 'read_cardpda' was not declared. Should it be static? drivers/staging/wlan-ng/prism2fw.c:857:5: warning: symbol 'read_fwfile' was not declared. Should it be static? drivers/staging/wlan-ng/prism2fw.c:981:5: warning: symbol 'writeimage' was not declared. Should it be static? drivers/staging/wlan-ng/prism2fw.c:1133:5: warning: symbol 'validate_identity' was not declared. Should it be static? Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlan-ng/prism2fw.c b/drivers/staging/wlan-ng/prism2fw.c index 9d04e2c..e22784e 100644 --- a/drivers/staging/wlan-ng/prism2fw.c +++ b/drivers/staging/wlan-ng/prism2fw.c @@ -237,7 +237,7 @@ int prism2_fwtry(struct usb_device *udev, wlandevice_t *wlandev) * 0 - success * ~0 - failure ----------------------------------------------------------------*/ -int prism2_fwapply(const struct ihex_binrec *rfptr, wlandevice_t *wlandev) +static int prism2_fwapply(const struct ihex_binrec *rfptr, wlandevice_t *wlandev) { signed int result = 0; struct p80211msg_dot11req_mibget getmsg; @@ -376,7 +376,7 @@ int prism2_fwapply(const struct ihex_binrec *rfptr, wlandevice_t *wlandev) * 0 success * ~0 failure ----------------------------------------------------------------*/ -int crcimage(struct imgchunk *fchunk, unsigned int nfchunks, +static int crcimage(struct imgchunk *fchunk, unsigned int nfchunks, struct s3crcrec *s3crc, unsigned int ns3crc) { int result = 0; @@ -440,7 +440,7 @@ int crcimage(struct imgchunk *fchunk, unsigned int nfchunks, * Returns: * nothing ----------------------------------------------------------------*/ -void free_chunks(struct imgchunk *fchunk, unsigned int *nfchunks) +static void free_chunks(struct imgchunk *fchunk, unsigned int *nfchunks) { int i; for (i = 0; i < *nfchunks; i++) @@ -462,7 +462,7 @@ void free_chunks(struct imgchunk *fchunk, unsigned int *nfchunks) * Returns: * nothing ----------------------------------------------------------------*/ -void free_srecs(void) +static void free_srecs(void) { ns3data = 0; memset(s3data, 0, sizeof(s3data)); @@ -489,7 +489,7 @@ void free_srecs(void) * 0 - success * ~0 - failure (probably an errno) ----------------------------------------------------------------*/ -int mkimage(struct imgchunk *clist, unsigned int *ccnt) +static int mkimage(struct imgchunk *clist, unsigned int *ccnt) { int result = 0; int i; @@ -582,7 +582,7 @@ int mkimage(struct imgchunk *clist, unsigned int *ccnt) * 0 - success * ~0 - failure (probably an errno) ----------------------------------------------------------------*/ -int mkpdrlist(struct pda *pda) +static int mkpdrlist(struct pda *pda) { int result = 0; u16 *pda16 = (u16 *) pda->buf; @@ -656,7 +656,7 @@ int mkpdrlist(struct pda *pda) * 0 success * ~0 failure ----------------------------------------------------------------*/ -int plugimage(struct imgchunk *fchunk, unsigned int nfchunks, +static int plugimage(struct imgchunk *fchunk, unsigned int nfchunks, struct s3plugrec *s3plug, unsigned int ns3plug, struct pda *pda) { int result = 0; @@ -764,7 +764,7 @@ int plugimage(struct imgchunk *fchunk, unsigned int nfchunks, * 0 - success * ~0 - failure (probably an errno) ----------------------------------------------------------------*/ -int read_cardpda(struct pda *pda, wlandevice_t *wlandev) +static int read_cardpda(struct pda *pda, wlandevice_t *wlandev) { int result = 0; struct p80211msg_p2req_readpda msg; @@ -854,7 +854,7 @@ int read_cardpda(struct pda *pda, wlandevice_t *wlandev) * 0 - success * ~0 - failure (probably an errno) ----------------------------------------------------------------*/ -int read_fwfile(const struct ihex_binrec *record) +static int read_fwfile(const struct ihex_binrec *record) { int i; int rcnt = 0; @@ -978,7 +978,7 @@ int read_fwfile(const struct ihex_binrec *record) * 0 success * ~0 failure ----------------------------------------------------------------*/ -int writeimage(wlandevice_t *wlandev, struct imgchunk *fchunk, +static int writeimage(wlandevice_t *wlandev, struct imgchunk *fchunk, unsigned int nfchunks) { int result = 0; @@ -1130,7 +1130,7 @@ free_result: return result; } -int validate_identity(void) +static int validate_identity(void) { int i; int result = 1; -- cgit v0.10.2 From 3f5142583066d6d9a9484b060779dad419780720 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sun, 9 Sep 2012 18:40:53 +0530 Subject: staging:wlan-ng: cleanup hfa384x_usbctlx_resptimerfn goto done is not required and simple return is fine Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c b/drivers/staging/wlan-ng/hfa384x_usb.c index 7843dfd..01a20d5 100644 --- a/drivers/staging/wlan-ng/hfa384x_usb.c +++ b/drivers/staging/wlan-ng/hfa384x_usb.c @@ -3985,15 +3985,10 @@ static void hfa384x_usbctlx_resptimerfn(unsigned long data) if (unlocked_usbctlx_cancel_async(hw, ctlx) == 0) { spin_unlock_irqrestore(&hw->ctlxq.lock, flags); hfa384x_usbctlxq_run(hw); - goto done; + return; } } - spin_unlock_irqrestore(&hw->ctlxq.lock, flags); - -done: - ; - } /*---------------------------------------------------------------- -- cgit v0.10.2 From 89e6302ce7125d3be40637c2080be2b4728e4510 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sun, 9 Sep 2012 18:40:54 +0530 Subject: staging:wlan-ng: cleanup hfa384x_ctlxout_callback goto done is not required and actually having goto done does jumps the program to end of the function and calls return. instead call return directly Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c b/drivers/staging/wlan-ng/hfa384x_usb.c index 01a20d5..25dd263 100644 --- a/drivers/staging/wlan-ng/hfa384x_usb.c +++ b/drivers/staging/wlan-ng/hfa384x_usb.c @@ -3790,7 +3790,7 @@ static void hfa384x_ctlxout_callback(struct urb *urb) #endif if ((urb->status == -ESHUTDOWN) || (urb->status == -ENODEV) || (hw == NULL)) - goto done; + return; retry: spin_lock_irqsave(&hw->ctlxq.lock, flags); @@ -3803,7 +3803,7 @@ retry: */ if (list_empty(&hw->ctlxq.active)) { spin_unlock_irqrestore(&hw->ctlxq.lock, flags); - goto done; + return; } /* @@ -3886,9 +3886,6 @@ delresp: if (run_queue) hfa384x_usbctlxq_run(hw); - -done: - ; } /*---------------------------------------------------------------- -- cgit v0.10.2 From c3016c45df91a22bc7756d86bbd682b4a3007e17 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sun, 9 Sep 2012 18:40:55 +0530 Subject: staging:wlan-ng: remove default case in the p80211req_handlemsg default is redundant and remove it Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlan-ng/p80211req.c b/drivers/staging/wlan-ng/p80211req.c index 179194e..679299f 100644 --- a/drivers/staging/wlan-ng/p80211req.c +++ b/drivers/staging/wlan-ng/p80211req.c @@ -173,11 +173,7 @@ static void p80211req_handlemsg(wlandevice_t *wlandev, struct p80211msg *msg) (struct p80211msg_dot11req_mibget *) msg; p80211req_mibset_mibget(wlandev, mib_msg, isget); } - default: - ; } /* switch msg->msgcode */ - - return; } static int p80211req_mibset_mibget(wlandevice_t *wlandev, -- cgit v0.10.2 From 009629ef440bbac6758988195f79b875e3e2f3df Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sun, 9 Sep 2012 18:40:56 +0530 Subject: staging:wlan-ng: clean p80211req_handlemsg the switch case doesn't have a break statement of DIDmsg_dot11req_mibget, and DIDmsg_dot11req_mibset cases, and also cleanup the code to follow the kernel coding way Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlan-ng/p80211req.c b/drivers/staging/wlan-ng/p80211req.c index 679299f..ccb0601 100644 --- a/drivers/staging/wlan-ng/p80211req.c +++ b/drivers/staging/wlan-ng/p80211req.c @@ -155,24 +155,25 @@ static void p80211req_handlemsg(wlandevice_t *wlandev, struct p80211msg *msg) switch (msg->msgcode) { case DIDmsg_lnxreq_hostwep:{ - struct p80211msg_lnxreq_hostwep *req = - (struct p80211msg_lnxreq_hostwep *) msg; - wlandev->hostwep &= - ~(HOSTWEP_DECRYPT | HOSTWEP_ENCRYPT); - if (req->decrypt.data == P80211ENUM_truth_true) - wlandev->hostwep |= HOSTWEP_DECRYPT; - if (req->encrypt.data == P80211ENUM_truth_true) - wlandev->hostwep |= HOSTWEP_ENCRYPT; + struct p80211msg_lnxreq_hostwep *req = + (struct p80211msg_lnxreq_hostwep *) msg; + wlandev->hostwep &= + ~(HOSTWEP_DECRYPT | HOSTWEP_ENCRYPT); + if (req->decrypt.data == P80211ENUM_truth_true) + wlandev->hostwep |= HOSTWEP_DECRYPT; + if (req->encrypt.data == P80211ENUM_truth_true) + wlandev->hostwep |= HOSTWEP_ENCRYPT; - break; - } + break; + } case DIDmsg_dot11req_mibget: case DIDmsg_dot11req_mibset:{ - int isget = (msg->msgcode == DIDmsg_dot11req_mibget); - struct p80211msg_dot11req_mibget *mib_msg = - (struct p80211msg_dot11req_mibget *) msg; - p80211req_mibset_mibget(wlandev, mib_msg, isget); - } + int isget = (msg->msgcode == DIDmsg_dot11req_mibget); + struct p80211msg_dot11req_mibget *mib_msg = + (struct p80211msg_dot11req_mibget *) msg; + p80211req_mibset_mibget(wlandev, mib_msg, isget); + break; + } } /* switch msg->msgcode */ } -- cgit v0.10.2 From bdced87c370288dbc1954be63348495c404b53b7 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sun, 9 Sep 2012 18:40:57 +0530 Subject: staging:wlan-ng: p80211req_mibset_mibget should be void this function always returning 0, there are no callers that checks the return of this function, make this function return void Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlan-ng/p80211req.c b/drivers/staging/wlan-ng/p80211req.c index ccb0601..bafd9358 100644 --- a/drivers/staging/wlan-ng/p80211req.c +++ b/drivers/staging/wlan-ng/p80211req.c @@ -73,7 +73,7 @@ #include "p80211req.h" static void p80211req_handlemsg(wlandevice_t *wlandev, struct p80211msg *msg); -static int p80211req_mibset_mibget(wlandevice_t *wlandev, +static void p80211req_mibset_mibget(wlandevice_t *wlandev, struct p80211msg_dot11req_mibget *mib_msg, int isget); @@ -177,7 +177,7 @@ static void p80211req_handlemsg(wlandevice_t *wlandev, struct p80211msg *msg) } /* switch msg->msgcode */ } -static int p80211req_mibset_mibget(wlandevice_t *wlandev, +static void p80211req_mibset_mibget(wlandevice_t *wlandev, struct p80211msg_dot11req_mibget *mib_msg, int isget) { @@ -254,9 +254,5 @@ static int p80211req_mibset_mibget(wlandevice_t *wlandev, } break; } - default: - ; } - - return 0; } -- cgit v0.10.2 From 7694538cfa3636d217bdafa1328fb0cf85119540 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sun, 9 Sep 2012 18:40:58 +0530 Subject: staging:wlan-ng: clean coding style problems in p80211req_mibset_mibget clean this function to follow kernel coding way remove double tabs remove spaces Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlan-ng/p80211req.c b/drivers/staging/wlan-ng/p80211req.c index bafd9358..cdfd808 100644 --- a/drivers/staging/wlan-ng/p80211req.c +++ b/drivers/staging/wlan-ng/p80211req.c @@ -187,72 +187,65 @@ static void p80211req_mibset_mibget(wlandevice_t *wlandev, switch (mibitem->did) { case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0:{ - if (!isget) - wep_change_key(wlandev, 0, key, pstr->len); - break; - } + if (!isget) + wep_change_key(wlandev, 0, key, pstr->len); + break; + } case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1:{ - if (!isget) - wep_change_key(wlandev, 1, key, pstr->len); - break; - } + if (!isget) + wep_change_key(wlandev, 1, key, pstr->len); + break; + } case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2:{ - if (!isget) - wep_change_key(wlandev, 2, key, pstr->len); - break; - } + if (!isget) + wep_change_key(wlandev, 2, key, pstr->len); + break; + } case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3:{ - if (!isget) - wep_change_key(wlandev, 3, key, pstr->len); - break; - } + if (!isget) + wep_change_key(wlandev, 3, key, pstr->len); + break; + } case DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID:{ - u32 *data = (u32 *) mibitem->data; - - if (isget) { - *data = - wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK; - } else { - wlandev->hostwep &= ~(HOSTWEP_DEFAULTKEY_MASK); + u32 *data = (u32 *) mibitem->data; - wlandev->hostwep |= - (*data & HOSTWEP_DEFAULTKEY_MASK); - } - break; + if (isget) { + *data = wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK; + } else { + wlandev->hostwep &= ~(HOSTWEP_DEFAULTKEY_MASK); + wlandev->hostwep |= (*data & HOSTWEP_DEFAULTKEY_MASK); } + break; + } case DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked:{ - u32 *data = (u32 *) mibitem->data; - - if (isget) { - if (wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) - *data = P80211ENUM_truth_true; - else - *data = P80211ENUM_truth_false; - } else { - wlandev->hostwep &= ~(HOSTWEP_PRIVACYINVOKED); - if (*data == P80211ENUM_truth_true) - wlandev->hostwep |= - HOSTWEP_PRIVACYINVOKED; - } - break; + u32 *data = (u32 *) mibitem->data; + + if (isget) { + if (wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) + *data = P80211ENUM_truth_true; + else + *data = P80211ENUM_truth_false; + } else { + wlandev->hostwep &= ~(HOSTWEP_PRIVACYINVOKED); + if (*data == P80211ENUM_truth_true) + wlandev->hostwep |= HOSTWEP_PRIVACYINVOKED; } + break; + } case DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted:{ - u32 *data = (u32 *) mibitem->data; - - if (isget) { - if (wlandev->hostwep & - HOSTWEP_EXCLUDEUNENCRYPTED) - *data = P80211ENUM_truth_true; - else - *data = P80211ENUM_truth_false; - } else { - wlandev->hostwep &= - ~(HOSTWEP_EXCLUDEUNENCRYPTED); - if (*data == P80211ENUM_truth_true) - wlandev->hostwep |= - HOSTWEP_EXCLUDEUNENCRYPTED; - } - break; + u32 *data = (u32 *) mibitem->data; + + if (isget) { + if (wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED) + *data = P80211ENUM_truth_true; + else + *data = P80211ENUM_truth_false; + } else { + wlandev->hostwep &= ~(HOSTWEP_EXCLUDEUNENCRYPTED); + if (*data == P80211ENUM_truth_true) + wlandev->hostwep |= HOSTWEP_EXCLUDEUNENCRYPTED; } + break; + } } } -- cgit v0.10.2 From 311e24fb1a654a260697793880979142fbbd185d Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sun, 9 Sep 2012 18:40:59 +0530 Subject: staging:wlan-ng: cleanup p80211skb_free and p80211skb_rxmeta_detach these functions doesn't need return at the end of the function Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlan-ng/p80211conv.c b/drivers/staging/wlan-ng/p80211conv.c index f53a27a..3df753b 100644 --- a/drivers/staging/wlan-ng/p80211conv.c +++ b/drivers/staging/wlan-ng/p80211conv.c @@ -559,17 +559,17 @@ void p80211skb_rxmeta_detach(struct sk_buff *skb) /* Sanity checks */ if (skb == NULL) { /* bad skb */ pr_debug("Called w/ null skb.\n"); - goto exit; + return; } frmmeta = P80211SKB_FRMMETA(skb); if (frmmeta == NULL) { /* no magic */ pr_debug("Called w/ bad frmmeta magic.\n"); - goto exit; + return; } rxmeta = frmmeta->rx; if (rxmeta == NULL) { /* bad meta ptr */ pr_debug("Called w/ bad rxmeta ptr.\n"); - goto exit; + return; } /* Free rxmeta */ @@ -577,8 +577,6 @@ void p80211skb_rxmeta_detach(struct sk_buff *skb) /* Clear skb->cb */ memset(skb->cb, 0, sizeof(skb->cb)); -exit: - return; } /*---------------------------------------------------------------- @@ -660,5 +658,4 @@ void p80211skb_free(struct wlandevice *wlandev, struct sk_buff *skb) else printk(KERN_ERR "Freeing an skb (%p) w/ no frmmeta.\n", skb); dev_kfree_skb(skb); - return; } -- cgit v0.10.2 From 102db1fc4a87668d0021395e6f7af996cf0c78d5 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sun, 9 Sep 2012 18:41:00 +0530 Subject: staging:wlan-ng: cleanup prism2sta_commsqual_defer and hfa384x_drvr_getconfig the function prism2sta_commsqual_defer defines a goto done lable, which just jumps to end of function, which we can achieve with out it the hfa384x_drvr_getconfig doesn't need the result variable, we can remove and just return the function Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c b/drivers/staging/wlan-ng/hfa384x_usb.c index 25dd263..bdc63a6 100644 --- a/drivers/staging/wlan-ng/hfa384x_usb.c +++ b/drivers/staging/wlan-ng/hfa384x_usb.c @@ -2140,11 +2140,7 @@ exit_proc: ----------------------------------------------------------------*/ int hfa384x_drvr_getconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len) { - int result; - - result = hfa384x_dorrid_wait(hw, rid, buf, len); - - return result; + return hfa384x_dorrid_wait(hw, rid, buf, len); } /*---------------------------------------------------------------- diff --git a/drivers/staging/wlan-ng/prism2sta.c b/drivers/staging/wlan-ng/prism2sta.c index 1dfd9aa..32a2f66 100644 --- a/drivers/staging/wlan-ng/prism2sta.c +++ b/drivers/staging/wlan-ng/prism2sta.c @@ -1988,12 +1988,12 @@ void prism2sta_commsqual_defer(struct work_struct *data) int result = 0; if (hw->wlandev->hwremoved) - goto done; + return; /* we don't care if we're in AP mode */ if ((wlandev->macmode == WLAN_MACMODE_NONE) || (wlandev->macmode == WLAN_MACMODE_ESS_AP)) { - goto done; + return; } /* It only makes sense to poll these in non-IBSS */ @@ -2004,7 +2004,7 @@ void prism2sta_commsqual_defer(struct work_struct *data) if (result) { printk(KERN_ERR "error fetching commsqual\n"); - goto done; + return; } pr_debug("commsqual %d %d %d\n", @@ -2021,7 +2021,7 @@ void prism2sta_commsqual_defer(struct work_struct *data) if (result) { pr_debug("get signal rate failed, result = %d\n", result); - goto done; + return; } switch (mibitem->data) { @@ -2048,7 +2048,7 @@ void prism2sta_commsqual_defer(struct work_struct *data) if (result) { pr_debug("getconfig(0x%02x) failed, result = %d\n", HFA384x_RID_CURRENTBSSID, result); - goto done; + return; } result = hfa384x_drvr_getconfig(hw, @@ -2057,16 +2057,13 @@ void prism2sta_commsqual_defer(struct work_struct *data) if (result) { pr_debug("getconfig(0x%02x) failed, result = %d\n", HFA384x_RID_CURRENTSSID, result); - goto done; + return; } prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *) &ssid, (p80211pstrd_t *) &wlandev->ssid); /* Reschedule timer */ mod_timer(&hw->commsqual_timer, jiffies + HZ); - -done: - ; } void prism2sta_commsqual_timer(unsigned long data) -- cgit v0.10.2 From 50d6b9baa0f5fd3476fb1dacfd92da9e0348c3d6 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sun, 9 Sep 2012 18:41:01 +0530 Subject: staging:wlan-ng: clean register_wlandev function we dont need i to just return the status of register_netdev Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c index 0f51b4a..89b3e3b 100644 --- a/drivers/staging/wlan-ng/p80211netdev.c +++ b/drivers/staging/wlan-ng/p80211netdev.c @@ -852,13 +852,7 @@ int wlan_unsetup(wlandevice_t *wlandev) ----------------------------------------------------------------*/ int register_wlandev(wlandevice_t *wlandev) { - int i = 0; - - i = register_netdev(wlandev->netdev); - if (i) - return i; - - return 0; + return register_netdev(wlandev->netdev); } /*---------------------------------------------------------------- -- cgit v0.10.2 From 909ff71041262f1e9de465dd8c0fee6da17747fd Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sun, 9 Sep 2012 18:41:02 +0530 Subject: staging:wlan-ng: clean some more functions the function p80211netdev_rx doesnt' need a return at the end and also remove some new lines the function p80211knetdev_set_mac_address doesn't need the result variable assigned as it gets a return from p80211req_dorequest function Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c index 89b3e3b..8afb193 100644 --- a/drivers/staging/wlan-ng/p80211netdev.c +++ b/drivers/staging/wlan-ng/p80211netdev.c @@ -240,10 +240,7 @@ void p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb) { /* Enqueue for post-irq processing */ skb_queue_tail(&wlandev->nsd_rxq, skb); - tasklet_schedule(&wlandev->rx_bh); - - return; } /*---------------------------------------------------------------- @@ -644,7 +641,7 @@ static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr) p80211item_unk392_t *mibattr; p80211item_pstr6_t *macaddr; p80211item_uint32_t *resultcode; - int result = 0; + int result; /* If we're running, we don't allow MAC address changes */ if (netif_running(dev)) -- cgit v0.10.2 From 6690da5fdc2056b78376919944886c78defcba5f Mon Sep 17 00:00:00 2001 From: DanielC Date: Mon, 10 Sep 2012 19:41:51 -0700 Subject: Staging: silicom: Header-cleanup Staging: silicom: Header cleanup of WD_STEP_COUNT_GET Signed-off-by: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/bp_ioctl.h b/drivers/staging/silicom/bp_ioctl.h index 7621fe8..7d468a0 100644 --- a/drivers/staging/silicom/bp_ioctl.h +++ b/drivers/staging/silicom/bp_ioctl.h @@ -53,7 +53,7 @@ #define WDT_STEP_TIME 0x10 /* BIT_4 */ #define WD_MIN_TIME_GET(desc) (desc & 0xf) -#define WD_STEP_COUNT_GET(desc) (desc>>5) & 0xf +#define WD_STEP_COUNT_GET(desc) ((desc>>5) & 0xf) typedef enum { IF_SCAN, diff --git a/drivers/staging/silicom/libbp_sd.h b/drivers/staging/silicom/libbp_sd.h index 1ba8b84..d223a6cf 100644 --- a/drivers/staging/silicom/libbp_sd.h +++ b/drivers/staging/silicom/libbp_sd.h @@ -42,7 +42,6 @@ #define NIC_CAP_NEG 0x4000000 /* BIT 26 */ #define WD_MIN_TIME_GET(desc) (desc & 0xf) -#define WD_STEP_COUNT_GET(desc) (desc>>5) & 0xf #define WDT_STEP_TIME 0x10 struct bp_info { -- cgit v0.10.2 From 2fd002bc7b13eaa34c134325fbac3f893984ad1c Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 11 Sep 2012 00:15:12 +0300 Subject: staging: xgifb: document some LVDS data delay values Document some delay values based on the comments in XGI_XG21SetPanelDelay(). Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index 22c8eb9..e2fa1ff 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -137,10 +137,10 @@ struct XGI21_LVDSCapStruct { unsigned short LVDSVSYNC; unsigned char VCLKData1; unsigned char VCLKData2; - unsigned char PSC_S1; - unsigned char PSC_S2; - unsigned char PSC_S3; - unsigned char PSC_S4; + unsigned char PSC_S1; /* Duration between CPL on and signal on */ + unsigned char PSC_S2; /* Duration signal on and Vdd on */ + unsigned char PSC_S3; /* Duration between CPL off and signal off */ + unsigned char PSC_S4; /* Duration signal off and Vdd off */ unsigned char PSC_S5; }; -- cgit v0.10.2 From 886230c12d8fb2196daa9bea4ae83d82e6e03732 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 11 Sep 2012 00:15:13 +0300 Subject: staging: xgifb: replace XGI_XG21SetPanelDelay() with mdelay() Eliminate a trivial wrapper function. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index e81149f..6c1dd04 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -3122,33 +3122,6 @@ static void XGI_XG27BLSignalVDD(unsigned short tempbh, unsigned short tempbl, xgifb_reg_and_or(pVBInfo->P3d4, 0x48, ~tempbh, tempbl); } -/* --------------------------------------------------------------------- */ -/* Function : XGI_XG21SetPanelDelay */ -/* Input : */ -/* Output : */ -/* Description : */ -/* I/P : bl : 1 ; T1 : the duration between CPL on and signal on */ -/* : bl : 2 ; T2 : the duration signal on and Vdd on */ -/* : bl : 3 ; T3 : the duration between CPL off and signal off */ -/* : bl : 4 ; T4 : the duration signal off and Vdd off */ -/* --------------------------------------------------------------------- */ -static void XGI_XG21SetPanelDelay(struct xgifb_video_info *xgifb_info, - unsigned short tempbl, - struct vb_device_info *pVBInfo) -{ - if (tempbl == 1) - mdelay(xgifb_info->lvds_data.PSC_S1); - - if (tempbl == 2) - mdelay(xgifb_info->lvds_data.PSC_S2); - - if (tempbl == 3) - mdelay(xgifb_info->lvds_data.PSC_S3); - - if (tempbl == 4) - mdelay(xgifb_info->lvds_data.PSC_S4); -} - static void XGI_DisplayOn(struct xgifb_video_info *xgifb_info, struct xgi_hw_device_info *pXGIHWDE, struct vb_device_info *pVBInfo) @@ -3160,12 +3133,12 @@ static void XGI_DisplayOn(struct xgifb_video_info *xgifb_info, if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x1)) { /* LVDS VDD on */ XGI_XG21BLSignalVDD(0x01, 0x01, pVBInfo); - XGI_XG21SetPanelDelay(xgifb_info, 2, pVBInfo); + mdelay(xgifb_info->lvds_data.PSC_S2); } if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x20)) /* LVDS signal on */ XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo); - XGI_XG21SetPanelDelay(xgifb_info, 3, pVBInfo); + mdelay(xgifb_info->lvds_data.PSC_S3); /* LVDS backlight on */ XGI_XG21BLSignalVDD(0x02, 0x02, pVBInfo); } else { @@ -3180,12 +3153,12 @@ static void XGI_DisplayOn(struct xgifb_video_info *xgifb_info, if (!(XGI_XG27GetPSCValue(pVBInfo) & 0x1)) { /* LVDS VDD on */ XGI_XG27BLSignalVDD(0x01, 0x01, pVBInfo); - XGI_XG21SetPanelDelay(xgifb_info, 2, pVBInfo); + mdelay(xgifb_info->lvds_data.PSC_S2); } if (!(XGI_XG27GetPSCValue(pVBInfo) & 0x20)) /* LVDS signal on */ XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo); - XGI_XG21SetPanelDelay(xgifb_info, 3, pVBInfo); + mdelay(xgifb_info->lvds_data.PSC_S3); /* LVDS backlight on */ XGI_XG27BLSignalVDD(0x02, 0x02, pVBInfo); } else { @@ -3205,7 +3178,7 @@ void XGI_DisplayOff(struct xgifb_video_info *xgifb_info, if (pVBInfo->IF_DEF_LVDS == 1) { /* LVDS backlight off */ XGI_XG21BLSignalVDD(0x02, 0x00, pVBInfo); - XGI_XG21SetPanelDelay(xgifb_info, 3, pVBInfo); + mdelay(xgifb_info->lvds_data.PSC_S3); } else { /* DVO/DVI signal off */ XGI_XG21BLSignalVDD(0x20, 0x00, pVBInfo); @@ -3216,7 +3189,7 @@ void XGI_DisplayOff(struct xgifb_video_info *xgifb_info, if ((XGI_XG27GetPSCValue(pVBInfo) & 0x2)) { /* LVDS backlight off */ XGI_XG27BLSignalVDD(0x02, 0x00, pVBInfo); - XGI_XG21SetPanelDelay(xgifb_info, 3, pVBInfo); + mdelay(xgifb_info->lvds_data.PSC_S3); } if (pVBInfo->IF_DEF_LVDS == 0) -- cgit v0.10.2 From 6e90d0570d39cfef03913630dff3ca5c6598dbb8 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 11 Sep 2012 00:15:14 +0300 Subject: staging: xgifb: delete IF_DEF_ExpLink Delete a flag which is never set. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 6c1dd04..dc1e371 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -2960,20 +2960,6 @@ static unsigned char XGI_GetLCDInfo(unsigned short ModeNo, tempbx |= SetLCDtoNonExpanding; } - if (pVBInfo->IF_DEF_ExpLink == 1) { - if (modeflag & HalfDCLK) { - if (!(tempbx & SetLCDtoNonExpanding)) { - tempbx |= XGI_EnableLVDSDDA; - } else { - if (pVBInfo->LCDResInfo == Panel_1024x768) { - if (resinfo == 4) {/* 512x384 */ - tempbx |= XGI_EnableLVDSDDA; - } - } - } - } - } - if (pVBInfo->VBInfo & SetInSlaveMode) { if (pVBInfo->VBInfo & SetNotSimuMode) tempbx |= XGI_LCDVESATiming; diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index e2fa1ff..043d0fb 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -169,7 +169,6 @@ struct vb_device_info { unsigned short IF_DEF_LVDS, IF_DEF_TRUMPION, IF_DEF_DSTN; unsigned short IF_DEF_CRT2Monitor; unsigned short IF_DEF_LCDA, IF_DEF_YPbPr; - unsigned short IF_DEF_ExpLink; unsigned short IF_DEF_HiVision; unsigned short LCDResInfo, LCDTypeInfo, VBType;/*301b*/ unsigned short VBInfo, TVInfo, LCDInfo; -- cgit v0.10.2 From 31fb40fd13179bf05e6eb4f387dd80ecd6d71d2d Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 11 Sep 2012 00:15:15 +0300 Subject: staging: xgifb: delete IF_DEF_LCDA IF_DEF_LCDA is always true. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index dc1e371..3cba143 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -258,23 +258,13 @@ static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo, } if (pVBInfo->VBInfo & SetCRT2ToHiVision) { /* for HiTV */ - if ((pVBInfo->VBType & VB_SIS301LV) && - (pVBInfo->VBExtInfo == VB_YPbPr1080i)) { - tempax |= SupportYPbPr750p; - if ((pVBInfo->VBInfo & SetInSlaveMode) && - ((resinfo == 3) || - (resinfo == 4) || - (resinfo > 7))) + tempax |= SupportHiVision; + if ((pVBInfo->VBInfo & SetInSlaveMode) && + ((resinfo == 4) || + (resinfo == 3 && + (pVBInfo->SetFlag & TVSimuMode)) || + (resinfo > 7))) return 0; - } else { - tempax |= SupportHiVision; - if ((pVBInfo->VBInfo & SetInSlaveMode) && - ((resinfo == 4) || - (resinfo == 3 && - (pVBInfo->SetFlag & TVSimuMode)) || - (resinfo > 7))) - return 0; - } } else { if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO | SetCRT2ToSVIDEO | @@ -969,13 +959,8 @@ static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo, } /* 301lv */ - if ((pVBInfo->VBType & VB_SIS301LV) && - !(pVBInfo->VBExtInfo == VB_YPbPr1080i)) { - if (pVBInfo->VBExtInfo == YPbPr750p) - VCLKIndex = XGI_YPbPr750pVCLK; - else if (pVBInfo->VBExtInfo == YPbPr525p) - VCLKIndex = YPbPr525pVCLK; - else if (pVBInfo->SetFlag & RPLLDIV2XO) + if (pVBInfo->VBType & VB_SIS301LV) { + if (pVBInfo->SetFlag & RPLLDIV2XO) VCLKIndex = YPbPr525iVCLK_2; else VCLKIndex = YPbPr525iVCLK; @@ -2634,21 +2619,18 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, temp = xgifb_reg_get(pVBInfo->P3d4, 0x38); - if (pVBInfo->IF_DEF_LCDA == 1) { - - if (((HwDeviceExtension->jChipType >= XG20) || - (HwDeviceExtension->jChipType >= XG40)) && - (pVBInfo->IF_DEF_LVDS == 0)) { - if (pVBInfo->VBType & - (VB_SIS302B | - VB_SIS301LV | - VB_SIS302LV | - VB_XGI301C)) { - if (temp & EnableDualEdge) { - tempbx |= SetCRT2ToDualEdge; - if (temp & SetToLCDA) - tempbx |= XGI_SetCRT2ToLCDA; - } + if (((HwDeviceExtension->jChipType >= XG20) || + (HwDeviceExtension->jChipType >= XG40)) && + (pVBInfo->IF_DEF_LVDS == 0)) { + if (pVBInfo->VBType & + (VB_SIS302B | + VB_SIS301LV | + VB_SIS302LV | + VB_XGI301C)) { + if (temp & EnableDualEdge) { + tempbx |= SetCRT2ToDualEdge; + if (temp & SetToLCDA) + tempbx |= XGI_SetCRT2ToLCDA; } } } @@ -2702,19 +2684,17 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, tempbx = 0; } - if (pVBInfo->IF_DEF_LCDA == 1) { /* Select Display Device */ - if (!(pVBInfo->VBType & VB_NoLCD)) { - if (tempbx & XGI_SetCRT2ToLCDA) { - if (tempbx & SetSimuScanMode) - tempbx &= (~(SetCRT2ToLCD | - SetCRT2ToRAMDAC | - SwitchCRT2)); - else - tempbx &= (~(SetCRT2ToLCD | - SetCRT2ToRAMDAC | - SetCRT2ToTV | - SwitchCRT2)); - } + if (!(pVBInfo->VBType & VB_NoLCD)) { + if (tempbx & XGI_SetCRT2ToLCDA) { + if (tempbx & SetSimuScanMode) + tempbx &= (~(SetCRT2ToLCD | + SetCRT2ToRAMDAC | + SwitchCRT2)); + else + tempbx &= (~(SetCRT2ToLCD | + SetCRT2ToRAMDAC | + SetCRT2ToTV | + SwitchCRT2)); } } @@ -2777,11 +2757,9 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, if (!(tempbx & DisableCRT2Display)) { if ((!(tempbx & DriverMode)) || (!(modeflag & CRT2Mode))) { - if (pVBInfo->IF_DEF_LCDA == 1) { - if (!(tempbx & XGI_SetCRT2ToLCDA)) - tempbx |= (SetInSlaveMode | - SetSimuScanMode); - } + if (!(tempbx & XGI_SetCRT2ToLCDA)) + tempbx |= (SetInSlaveMode | + SetSimuScanMode); } /* LCD+TV can't support in slave mode @@ -3841,16 +3819,9 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, | VB_SIS302LV | VB_XGI301C))) temp += 2; - if (pVBInfo->VBInfo & SetCRT2ToHiVision) { - if (pVBInfo->VBType & VB_SIS301LV) { - if (pVBInfo->VBExtInfo == VB_YPbPr1080i) { - if (resinfo == 7) - temp -= 2; - } - } else if (resinfo == 7) { + if ((pVBInfo->VBInfo & SetCRT2ToHiVision) && + !(pVBInfo->VBType & VB_SIS301LV) && (resinfo == 7)) temp -= 2; - } - } } /* 0x05 Horizontal Display Start */ @@ -6566,7 +6537,6 @@ unsigned char XGISetModeNew(struct xgifb_video_info *xgifb_info, struct vb_device_info *pVBInfo = &VBINF; pVBInfo->BaseAddr = xgifb_info->vga_base; pVBInfo->IF_DEF_LVDS = 0; - pVBInfo->IF_DEF_LCDA = 1; if (HwDeviceExtension->jChipType >= XG20) { pVBInfo->IF_DEF_YPbPr = 0; diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index 043d0fb..ccb57ce 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -168,11 +168,10 @@ struct vb_device_info { unsigned short ModeType; unsigned short IF_DEF_LVDS, IF_DEF_TRUMPION, IF_DEF_DSTN; unsigned short IF_DEF_CRT2Monitor; - unsigned short IF_DEF_LCDA, IF_DEF_YPbPr; + unsigned short IF_DEF_YPbPr; unsigned short IF_DEF_HiVision; unsigned short LCDResInfo, LCDTypeInfo, VBType;/*301b*/ unsigned short VBInfo, TVInfo, LCDInfo; - unsigned short VBExtInfo;/*301lv*/ unsigned short SetFlag; unsigned short NewFlickerMode; unsigned short SelectCRT2Rate; -- cgit v0.10.2 From c62c517e51cc5e36e47cb7e6410a6c5edacb4e02 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 11 Sep 2012 00:15:16 +0300 Subject: staging: xgifb: delete some unused #defines Delete some unused #defines. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/vb_def.h b/drivers/staging/xgifb/vb_def.h index 69078d9..609ab70 100644 --- a/drivers/staging/xgifb/vb_def.h +++ b/drivers/staging/xgifb/vb_def.h @@ -3,9 +3,7 @@ #include "../../video/sis/initdef.h" #define VB_XGI301C 0x0020 /* for 301C */ -#define VB_YPbPr1080i 0x03 -#define LVDSCRT1Len 15 #define SupportCRT2in301C 0x0100 /* for 301C */ #define SetCHTVOverScan 0x8000 @@ -22,15 +20,6 @@ #define XGI_CRT2_PORT_00 (0x00 - 0x030) -/* ============================================================= - for 310 -============================================================== */ -#define ModeSoftSetting 0x04 - -/* ---------------- SetMode Stack */ -#define CRT1Len 15 -#define VCLKLen 4 - #define SupportAllCRT2 0x0078 #define NoSupportTV 0x0070 #define NoSupportHiVisionTV 0x0060 -- cgit v0.10.2 From 4d8f5ca7d2bb29e3721ca7396ae0207324dfccdb Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 11 Sep 2012 00:15:17 +0300 Subject: staging: xgifb: delete redundant chip type check All chip type values are covered by (chip >= XG20 || chip >= XG40). Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 3cba143..e300645 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -2619,9 +2619,7 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, temp = xgifb_reg_get(pVBInfo->P3d4, 0x38); - if (((HwDeviceExtension->jChipType >= XG20) || - (HwDeviceExtension->jChipType >= XG40)) && - (pVBInfo->IF_DEF_LVDS == 0)) { + if (pVBInfo->IF_DEF_LVDS == 0) { if (pVBInfo->VBType & (VB_SIS302B | VB_SIS301LV | -- cgit v0.10.2 From 4c047ac461324dd9c49d060a523257662650d478 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 11 Sep 2012 00:15:18 +0300 Subject: staging: xgifb: avoid copy-pasting LCD data Share the common data tables instead of having the same data in multiple tables. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index 1c16846..d823bb0 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -525,18 +525,7 @@ static struct SiS_LCDData XGI_StLCD1600x1200Data[] = { {1, 1, 2160, 1250, 2160, 1250} /* 09 (1600x1200) */ }; -static struct SiS_LCDData XGI_CetLCD1400x1050Data[] = { - {1, 1, 1688, 1066, 1688, 1066}, /* 00 (320x200,320x400, - 640x200,640x400) */ - {1, 1, 1688, 1066, 1688, 1066}, /* 01 (320x350,640x350) */ - {1, 1, 1688, 1066, 1688, 1066}, /* 02 (360x400,720x400) */ - {1, 1, 1688, 1066, 1688, 1066}, /* 03 (720x350) */ - {1, 1, 1688, 1066, 1688, 1066}, /* 04 (640x480x60Hz) */ - {1, 1, 1688, 1066, 1688, 1066}, /* 05 (800x600x60Hz) */ - {1, 1, 1688, 1066, 1688, 1066}, /* 06 (1024x768x60Hz) */ - {1, 1, 1688, 1066, 1688, 1066}, /* 07 (1280x1024x60Hz) */ - {1, 1, 1688, 1066, 1688, 1066} /* 08 (1400x1050x60Hz) */ -}; +#define XGI_CetLCD1400x1050Data XGI_CetLCD1280x1024Data static struct SiS_LCDData XGI_NoScalingData[] = { {1, 1, 800, 449, 800, 449}, @@ -583,17 +572,7 @@ static struct SiS_LCDData xgifb_lcd_1280x1024x75[] = { {1, 1, 1688, 1066, 1688, 1066} /* ; 07 (1280x1024x75Hz) */ }; -static struct SiS_LCDData XGI_CetLCD1280x1024x75Data[] = { - {1, 1, 1688, 1066, 1688, 1066}, /* ; 00 (320x200,320x400, - 640x200,640x400) */ - {1, 1, 1688, 1066, 1688, 1066}, /* ; 01 (320x350,640x350) */ - {1, 1, 1688, 1066, 1688, 1066}, /* ; 02 (360x400,720x400) */ - {1, 1, 1688, 1066, 1688, 1066}, /* ; 03 (720x350) */ - {1, 1, 1688, 1066, 1688, 1066}, /* ; 04 (640x480x75Hz) */ - {1, 1, 1688, 1066, 1688, 1066}, /* ; 05 (800x600x75Hz) */ - {1, 1, 1688, 1066, 1688, 1066}, /* ; 06 (1024x768x75Hz) */ - {1, 1, 1688, 1066, 1688, 1066} /* ; 07 (1280x1024x75Hz) */ -}; +#define XGI_CetLCD1280x1024x75Data XGI_CetLCD1280x1024Data static struct SiS_LCDData XGI_NoScalingDatax75[] = { {1, 1, 800, 449, 800, 449}, /* ; 00 (320x200, 320x400, @@ -1236,17 +1215,7 @@ static struct SiS_LVDSData XGI_LVDS1280x1024Data_1[] = { {1688, 1066, 1688, 1066} }; -static struct SiS_LVDSData XGI_LVDS1280x1024Data_2[] = { - {1344, 806, 1344, 806}, - {1344, 806, 1344, 806}, - {1344, 806, 1344, 806}, - {1344, 806, 1344, 806}, - {1344, 806, 1344, 806}, - {1344, 806, 1344, 806}, - {1344, 806, 1344, 806}, - {800, 449, 1280, 801}, - {800, 525, 1280, 813} -}; +#define XGI_LVDS1280x1024Data_2 XGI_LVDS1024x768Data_2 static struct SiS_LVDSData XGI_LVDS1400x1050Data_1[] = { {928, 416, 1688, 1066}, -- cgit v0.10.2 From 56d276cad49006e4c7f399895cbec68e4773fbee Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 11 Sep 2012 00:15:19 +0300 Subject: staging: xgifb: XGI_GetTVPtr: drop the table parameter Only one TV data table is used by the driver, delete unneeded complexity. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index e300645..7218804 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -1764,47 +1764,18 @@ static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo, return NULL; } -static void *XGI_GetTVPtr(unsigned short BX, unsigned short ModeNo, +static void *XGI_GetTVPtr(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) { - unsigned short i, tempdx, tempbx, tempal, modeflag, table; + unsigned short i, tempdx, tempal, modeflag; struct XGI330_TVDataTablStruct *tempdi = NULL; - tempbx = BX; modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; tempal = tempal & 0x3f; - table = tempbx; - - switch (tempbx) { - case 0: - tempdi = NULL; - break; - case 1: - tempdi = NULL; - break; - case 2: - case 6: - tempdi = xgifb_chrontel_tv; - break; - case 3: - tempdi = NULL; - break; - case 4: - tempdi = XGI_TVDataTable; - break; - case 5: - tempdi = NULL; - break; - default: - break; - } - - if (tempdi == NULL) /* OEMUtil */ - return NULL; - + tempdi = XGI_TVDataTable; tempdx = pVBInfo->TVInfo; if (pVBInfo->VBInfo & SetInSlaveMode) @@ -1821,70 +1792,51 @@ static void *XGI_GetTVPtr(unsigned short BX, unsigned short ModeNo, i++; } - if (table == 0x04) { - switch (tempdi[i].DATAPTR) { - case 0: - return &XGI_ExtPALData[tempal]; - break; - case 1: - return &XGI_ExtNTSCData[tempal]; - break; - case 2: - return &XGI_StPALData[tempal]; - break; - case 3: - return &XGI_StNTSCData[tempal]; - break; - case 4: - return &XGI_ExtHiTVData[tempal]; - break; - case 5: - return &XGI_St2HiTVData[tempal]; - break; - case 6: - return &XGI_ExtYPbPr525iData[tempal]; - break; - case 7: - return &XGI_ExtYPbPr525pData[tempal]; - break; - case 8: - return &XGI_ExtYPbPr750pData[tempal]; - break; - case 9: - return &XGI_StYPbPr525iData[tempal]; - break; - case 10: - return &XGI_StYPbPr525pData[tempal]; - break; - case 11: - return &XGI_StYPbPr750pData[tempal]; - break; - case 12: /* avoid system hang */ - return &XGI_ExtNTSCData[tempal]; - break; - case 13: - return &XGI_St1HiTVData[tempal]; - break; - default: - break; - } - } else if (table == 0x02) { - switch (tempdi[i].DATAPTR) { - case 0: - return &XGI_CHTVUNTSCData[tempal]; - break; - case 1: - return &XGI_CHTVONTSCData[tempal]; - break; - case 2: - return &XGI_CHTVUPALData[tempal]; - break; - case 3: - return &XGI_CHTVOPALData[tempal]; - break; - default: - break; - } + switch (tempdi[i].DATAPTR) { + case 0: + return &XGI_ExtPALData[tempal]; + break; + case 1: + return &XGI_ExtNTSCData[tempal]; + break; + case 2: + return &XGI_StPALData[tempal]; + break; + case 3: + return &XGI_StNTSCData[tempal]; + break; + case 4: + return &XGI_ExtHiTVData[tempal]; + break; + case 5: + return &XGI_St2HiTVData[tempal]; + break; + case 6: + return &XGI_ExtYPbPr525iData[tempal]; + break; + case 7: + return &XGI_ExtYPbPr525pData[tempal]; + break; + case 8: + return &XGI_ExtYPbPr750pData[tempal]; + break; + case 9: + return &XGI_StYPbPr525iData[tempal]; + break; + case 10: + return &XGI_StYPbPr525pData[tempal]; + break; + case 11: + return &XGI_StYPbPr750pData[tempal]; + break; + case 12: /* avoid system hang */ + return &XGI_ExtNTSCData[tempal]; + break; + case 13: + return &XGI_St1HiTVData[tempal]; + break; + default: + break; } return NULL; } @@ -3414,10 +3366,8 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, } if (pVBInfo->VBInfo & (SetCRT2ToTV)) { - tempbx = 4; - TVPtr = (struct SiS_TVData *) XGI_GetTVPtr(tempbx, - ModeNo, ModeIdIndex, RefreshRateTableIndex, - pVBInfo); + TVPtr = (struct SiS_TVData *) XGI_GetTVPtr(ModeNo, ModeIdIndex, + RefreshRateTableIndex, pVBInfo); pVBInfo->RVBHCMAX = TVPtr->RVBHCMAX; pVBInfo->RVBHCFACT = TVPtr->RVBHCFACT; -- cgit v0.10.2 From 6265ee4c0b7f3f8c02e44b5f52e43a095ef61420 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 11 Sep 2012 00:15:20 +0300 Subject: staging: xgifb: delete Chrontel TV data Delete unused Chrontel TV data. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 7218804..ae617c6 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -1770,12 +1770,10 @@ static void *XGI_GetTVPtr(unsigned short ModeNo, struct vb_device_info *pVBInfo) { unsigned short i, tempdx, tempal, modeflag; - struct XGI330_TVDataTablStruct *tempdi = NULL; modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; tempal = tempal & 0x3f; - tempdi = XGI_TVDataTable; tempdx = pVBInfo->TVInfo; if (pVBInfo->VBInfo & SetInSlaveMode) @@ -1786,13 +1784,14 @@ static void *XGI_GetTVPtr(unsigned short ModeNo, i = 0; - while (tempdi[i].MASK != 0xffff) { - if ((tempdx & tempdi[i].MASK) == tempdi[i].CAP) + while (XGI_TVDataTable[i].MASK != 0xffff) { + if ((tempdx & XGI_TVDataTable[i].MASK) == + XGI_TVDataTable[i].CAP) break; i++; } - switch (tempdi[i].DATAPTR) { + switch (XGI_TVDataTable[i].DATAPTR) { case 0: return &XGI_ExtPALData[tempal]; break; diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index d823bb0..34e538d 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -1501,42 +1501,6 @@ static struct XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesDatax75[] = { {0, 1328, 0, 771, 112, 6} /* ; 0A (1280x768x75Hz) */ }; -static struct SiS_LVDSData XGI_CHTVUNTSCData[] = { - { 840, 600, 840, 600}, - { 840, 600, 840, 600}, - { 840, 600, 840, 600}, - { 840, 600, 840, 600}, - { 784, 600, 784, 600}, - {1064, 750, 1064, 750} -}; - -static struct SiS_LVDSData XGI_CHTVONTSCData[] = { - { 840, 525, 840, 525}, - { 840, 525, 840, 525}, - { 840, 525, 840, 525}, - { 840, 525, 840, 525}, - { 784, 525, 784, 525}, - {1040, 700, 1040, 700} -}; - -static struct SiS_LVDSData XGI_CHTVUPALData[] = { - {1008, 625, 1008, 625}, - {1008, 625, 1008, 625}, - {1008, 625, 1008, 625}, - {1008, 625, 1008, 625}, - { 840, 750, 840, 750}, - { 936, 836, 936, 836} -}; - -static struct SiS_LVDSData XGI_CHTVOPALData[] = { - {1008, 625, 1008, 625}, - {1008, 625, 1008, 625}, - {1008, 625, 1008, 625}, - {1008, 625, 1008, 625}, - {840, 625, 840, 625}, - {960, 750, 960, 750} -}; - /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */ static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_1_H[] = { { {0x4B, 0x27, 0x8F, 0x32, 0x1B, 0x00, 0x45, 0x00} }, /* 00 (320x) */ @@ -1925,15 +1889,6 @@ static struct XGI330_TVDataTablStruct XGI_TVDataTable[] = { {0xffff, 0x0000, 12} /* END */ }; -/* Chrontel 7017 TV List */ -static struct XGI330_TVDataTablStruct xgifb_chrontel_tv[] = { - {0x0011, 0x0000, 0}, /* UNTSC */ - {0x0011, 0x0010, 1}, /* ONTSC */ - {0x0011, 0x0001, 2}, /* UPAL */ - {0x0011, 0x0011, 3}, /* OPAL */ - {0xFFFF, 0x0000, 4} -}; - static unsigned short LCDLenList[] = { LVDSCRT1Len_H, LVDSCRT1Len_V, -- cgit v0.10.2 From 245725456099586d9a403289e6b05bbd2891834b Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 11 Sep 2012 00:15:21 +0300 Subject: staging: xgifb: use proper typing for TV data There's a dangerous cast from XGI330_TVDataStruct to SiS_TVData. Use SiS_TVData everywhere, also the data can be made const. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index ae617c6..08879f4 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -1764,7 +1764,7 @@ static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo, return NULL; } -static void *XGI_GetTVPtr(unsigned short ModeNo, +static struct SiS_TVData const *XGI_GetTVPtr(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) @@ -3264,7 +3264,6 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short tempax = 0, tempbx, modeflag, resinfo; struct SiS_LCDData *LCDPtr = NULL; - struct SiS_TVData *TVPtr = NULL; /* si+Ext_ResInfo */ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; @@ -3365,8 +3364,10 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, } if (pVBInfo->VBInfo & (SetCRT2ToTV)) { - TVPtr = (struct SiS_TVData *) XGI_GetTVPtr(ModeNo, ModeIdIndex, - RefreshRateTableIndex, pVBInfo); + struct SiS_TVData const *TVPtr; + + TVPtr = XGI_GetTVPtr(ModeNo, ModeIdIndex, RefreshRateTableIndex, + pVBInfo); pVBInfo->RVBHCMAX = TVPtr->RVBHCMAX; pVBInfo->RVBHCFACT = TVPtr->RVBHCFACT; diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index ccb57ce..230c54f 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -59,19 +59,6 @@ struct XGI330_LCDDataDesStruct2 { unsigned short LCDVSync; }; - -struct XGI330_TVDataStruct { - unsigned short RVBHCMAX; - unsigned short RVBHCFACT; - unsigned short VGAHT; - unsigned short VGAVT; - unsigned short TVHDE; - unsigned short TVVDE; - unsigned short RVBHRS; - unsigned char FlickerMode; - unsigned short HALFRVBHRS; -}; - struct XGI330_LCDDataTablStruct { unsigned char PANELID; unsigned short MASK; diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index 34e538d..441cb39 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -882,7 +882,7 @@ static struct XGI330_LCDDataDesStruct2 XGI_NoScalingDesDatax75[] = { {9, 1337, 0, 771, 112, 6} /* ; 0A (1280x768x60Hz) */ }; -static struct XGI330_TVDataStruct XGI_StPALData[] = { +static const struct SiS_TVData XGI_StPALData[] = { {1, 1, 864, 525, 1270, 400, 100, 0, 760}, {1, 1, 864, 525, 1270, 350, 100, 0, 760}, {1, 1, 864, 525, 1270, 400, 0, 0, 720}, @@ -891,7 +891,7 @@ static struct XGI330_TVDataStruct XGI_StPALData[] = { {1, 1, 864, 525, 1270, 600, 50, 0, 0} }; -static struct XGI330_TVDataStruct XGI_ExtPALData[] = { +static const struct SiS_TVData XGI_ExtPALData[] = { {2, 1, 1080, 463, 1270, 500, 50, 0, 50}, {15, 7, 1152, 413, 1270, 500, 50, 0, 50}, {2, 1, 1080, 463, 1270, 500, 50, 0, 50}, @@ -902,7 +902,7 @@ static struct XGI330_TVDataStruct XGI_ExtPALData[] = { {3, 2, 1080, 619, 1270, 540, 438, 0, 438} }; -static struct XGI330_TVDataStruct XGI_StNTSCData[] = { +static const struct SiS_TVData XGI_StNTSCData[] = { {1, 1, 858, 525, 1270, 400, 50, 0, 760}, {1, 1, 858, 525, 1270, 350, 50, 0, 640}, {1, 1, 858, 525, 1270, 400, 0, 0, 720}, @@ -910,7 +910,7 @@ static struct XGI330_TVDataStruct XGI_StNTSCData[] = { {1, 1, 858, 525, 1270, 480, 0, 0, 760} }; -static struct XGI330_TVDataStruct XGI_ExtNTSCData[] = { +static const struct SiS_TVData XGI_ExtNTSCData[] = { {9, 5, 1001, 453, 1270, 420, 171, 0, 171}, {12, 5, 858, 403, 1270, 420, 171, 0, 171}, {9, 5, 1001, 453, 1270, 420, 171, 0, 171}, @@ -922,7 +922,7 @@ static struct XGI330_TVDataStruct XGI_ExtNTSCData[] = { {3, 2, 1001, 533, 1270, 420, 0, 0, 0} }; -static struct XGI330_TVDataStruct XGI_St1HiTVData[] = { +static const struct SiS_TVData XGI_St1HiTVData[] = { {1, 1, 892, 563, 690, 800, 0, 0, 0}, /* 00 (320x200,320x400, 640x200,640x400) */ {1, 1, 892, 563, 690, 700, 0, 0, 0}, /* 01 (320x350,640x350) */ @@ -932,7 +932,7 @@ static struct XGI330_TVDataStruct XGI_St1HiTVData[] = { {8, 5, 1050, 683, 1648, 960, 0x150, 1, 0} /* 05 (400x300,800x600) */ }; -static struct XGI330_TVDataStruct XGI_St2HiTVData[] = { +static const struct SiS_TVData XGI_St2HiTVData[] = { {3, 1, 840, 483, 1648, 960, 0x032, 0, 0}, /* 00 (320x200,320x400, 640x200,640x400) */ {1, 1, 892, 563, 690, 700, 0, 0, 0}, /* 01 (320x350,640x350) */ @@ -942,7 +942,7 @@ static struct XGI330_TVDataStruct XGI_St2HiTVData[] = { {8, 5, 1050, 683, 1648, 960, 0x17C, 1, 0} /* 05 (400x300,800x600) */ }; -static struct XGI330_TVDataStruct XGI_ExtHiTVData[] = { +static const struct SiS_TVData XGI_ExtHiTVData[] = { {6, 1, 840, 563, 1632, 960, 0, 0, 0}, /* 00 (320x200,320x400, 640x200,640x400) */ {3, 1, 960, 563, 1632, 960, 0, 0, 0}, /* 01 (320x350,640x350) */ @@ -957,7 +957,7 @@ static struct XGI330_TVDataStruct XGI_ExtHiTVData[] = { {8, 5, 1750, 803, 1648, 960, 0x128, 0, 0} /* 0A (1280x720) */ }; -static struct XGI330_TVDataStruct XGI_ExtYPbPr525iData[] = { +static const struct SiS_TVData XGI_ExtYPbPr525iData[] = { { 9, 5, 1001, 453, 1270, 420, 171, 0, 171}, { 12, 5, 858, 403, 1270, 420, 171, 0, 171}, { 9, 5, 1001, 453, 1270, 420, 171, 0, 171}, @@ -969,7 +969,7 @@ static struct XGI330_TVDataStruct XGI_ExtYPbPr525iData[] = { { 3, 2, 1001, 533, 1250, 420, 0, 0, 0} }; -static struct XGI330_TVDataStruct XGI_StYPbPr525iData[] = { +static const struct SiS_TVData XGI_StYPbPr525iData[] = { {1, 1, 858, 525, 1270, 400, 50, 0, 760}, {1, 1, 858, 525, 1270, 350, 50, 0, 640}, {1, 1, 858, 525, 1270, 400, 0, 0, 720}, @@ -977,7 +977,7 @@ static struct XGI330_TVDataStruct XGI_StYPbPr525iData[] = { {1, 1, 858, 525, 1270, 480, 0, 0, 760}, }; -static struct XGI330_TVDataStruct XGI_ExtYPbPr525pData[] = { +static const struct SiS_TVData XGI_ExtYPbPr525pData[] = { { 9, 5, 1001, 453, 1270, 420, 171, 0, 171}, { 12, 5, 858, 403, 1270, 420, 171, 0, 171}, { 9, 5, 1001, 453, 1270, 420, 171, 0, 171}, @@ -989,7 +989,7 @@ static struct XGI330_TVDataStruct XGI_ExtYPbPr525pData[] = { { 3, 2, 1001, 533, 1270, 420, 0, 0, 0} }; -static struct XGI330_TVDataStruct XGI_StYPbPr525pData[] = { +static const struct SiS_TVData XGI_StYPbPr525pData[] = { {1, 1, 1716, 525, 1270, 400, 50, 0, 760}, {1, 1, 1716, 525, 1270, 350, 50, 0, 640}, {1, 1, 1716, 525, 1270, 400, 0, 0, 720}, @@ -997,7 +997,7 @@ static struct XGI330_TVDataStruct XGI_StYPbPr525pData[] = { {1, 1, 1716, 525, 1270, 480, 0, 0, 760}, }; -static struct XGI330_TVDataStruct XGI_ExtYPbPr750pData[] = { +static const struct SiS_TVData XGI_ExtYPbPr750pData[] = { { 3, 1, 935, 470, 1130, 680, 50, 0, 0}, /* 00 (320x200,320x400, 640x200,640x400) */ {24, 7, 935, 420, 1130, 680, 50, 0, 0}, /* 01 (320x350,640x350) */ @@ -1012,7 +1012,7 @@ static struct XGI330_TVDataStruct XGI_ExtYPbPr750pData[] = { {10, 9, 1320, 830, 1130, 640, 50, 0, 0} }; -static struct XGI330_TVDataStruct XGI_StYPbPr750pData[] = { +static const struct SiS_TVData XGI_StYPbPr750pData[] = { {1, 1, 1650, 750, 1280, 400, 50, 0, 760}, {1, 1, 1650, 750, 1280, 350, 50, 0, 640}, {1, 1, 1650, 750, 1280, 400, 0, 0, 720}, -- cgit v0.10.2 From 18ba866bb4c2bf87842188aa0b66efadb402783f Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 11 Sep 2012 00:15:22 +0300 Subject: staging: xgifb: use a real pointer for TV DATAPTR Replace DATAPTR numbers with a real pointer to make code simpler. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 08879f4..cd40daf 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -1791,53 +1791,7 @@ static struct SiS_TVData const *XGI_GetTVPtr(unsigned short ModeNo, i++; } - switch (XGI_TVDataTable[i].DATAPTR) { - case 0: - return &XGI_ExtPALData[tempal]; - break; - case 1: - return &XGI_ExtNTSCData[tempal]; - break; - case 2: - return &XGI_StPALData[tempal]; - break; - case 3: - return &XGI_StNTSCData[tempal]; - break; - case 4: - return &XGI_ExtHiTVData[tempal]; - break; - case 5: - return &XGI_St2HiTVData[tempal]; - break; - case 6: - return &XGI_ExtYPbPr525iData[tempal]; - break; - case 7: - return &XGI_ExtYPbPr525pData[tempal]; - break; - case 8: - return &XGI_ExtYPbPr750pData[tempal]; - break; - case 9: - return &XGI_StYPbPr525iData[tempal]; - break; - case 10: - return &XGI_StYPbPr525pData[tempal]; - break; - case 11: - return &XGI_StYPbPr750pData[tempal]; - break; - case 12: /* avoid system hang */ - return &XGI_ExtNTSCData[tempal]; - break; - case 13: - return &XGI_St1HiTVData[tempal]; - break; - default: - break; - } - return NULL; + return &XGI_TVDataTable[i].DATAPTR[tempal]; } static void XGI_GetLVDSData(unsigned short ModeNo, unsigned short ModeIdIndex, diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index 230c54f..2eaeb26 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -69,7 +69,7 @@ struct XGI330_LCDDataTablStruct { struct XGI330_TVDataTablStruct { unsigned short MASK; unsigned short CAP; - unsigned short DATAPTR; + struct SiS_TVData const *DATAPTR; }; diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index 441cb39..05d9ab1 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -1872,21 +1872,21 @@ static struct XGI330_LCDDataTablStruct XGI_EPLCHLCDRegPtr[] = { {0xFF, 0x0000, 0x0000, 0} }; -static struct XGI330_TVDataTablStruct XGI_TVDataTable[] = { - {0x09E1, 0x0001, 0}, /* XGI_ExtPALData */ - {0x09E1, 0x0000, 1}, /* XGI_ExtNTSCData */ - {0x09E1, 0x0801, 2}, /* XGI_StPALData */ - {0x09E1, 0x0800, 3}, /* XGI_StNTSCData */ - {0x49E0, 0x0100, 4}, /* XGI_ExtHiTVData */ - {0x49E0, 0x4100, 5}, /* XGI_St2HiTVData */ - {0x49E0, 0x4900, 13}, /* XGI_St1HiTVData */ - {0x09E0, 0x0020, 6}, /* XGI_ExtYPbPr525iData */ - {0x09E0, 0x0040, 7}, /* XGI_ExtYPbPr525pData */ - {0x09E0, 0x0080, 8}, /* XGI_ExtYPbPr750pData */ - {0x09E0, 0x0820, 9}, /* XGI_StYPbPr525iData */ - {0x09E0, 0x0840, 10}, /* XGI_StYPbPr525pData */ - {0x09E0, 0x0880, 11}, /* XGI_StYPbPr750pData */ - {0xffff, 0x0000, 12} /* END */ +static const struct XGI330_TVDataTablStruct XGI_TVDataTable[] = { + {0x09E1, 0x0001, XGI_ExtPALData}, + {0x09E1, 0x0000, XGI_ExtNTSCData}, + {0x09E1, 0x0801, XGI_StPALData}, + {0x09E1, 0x0800, XGI_StNTSCData}, + {0x49E0, 0x0100, XGI_ExtHiTVData}, + {0x49E0, 0x4100, XGI_St2HiTVData}, + {0x49E0, 0x4900, XGI_St1HiTVData}, + {0x09E0, 0x0020, XGI_ExtYPbPr525iData}, + {0x09E0, 0x0040, XGI_ExtYPbPr525pData}, + {0x09E0, 0x0080, XGI_ExtYPbPr750pData}, + {0x09E0, 0x0820, XGI_StYPbPr525iData}, + {0x09E0, 0x0840, XGI_StYPbPr525pData}, + {0x09E0, 0x0880, XGI_StYPbPr750pData}, + {0xffff, 0x0000, XGI_ExtNTSCData}, }; static unsigned short LCDLenList[] = { -- cgit v0.10.2 From bc9ffcc2c6c08f8fe58d200afe482c59565f7e58 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 11 Sep 2012 00:15:23 +0300 Subject: staging: xgifb: delete Chrontel 7017 LCD data Delete unused Chrontel 7017 LCD data. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index cd40daf..a1ee4c1 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -1389,8 +1389,6 @@ static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo, tempdi = XGI_LCDDesDataTable; break; case 6: - tempdi = XGI_EPLCHLCDRegPtr; - break; case 7: case 8: case 9: @@ -1749,17 +1747,6 @@ static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo, default: break; } - } else if (table == 6) { - switch (tempdi[i].DATAPTR) { - case 0: - return &XGI_CH7017LV1024x768[tempal]; - break; - case 1: - return &XGI_CH7017LV1400x1050[tempal]; - break; - default: - break; - } } return NULL; } diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index 05d9ab1..14cabdb 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -403,13 +403,6 @@ static struct XGI_CRT1TableStruct XGI_CRT1Table[] = { 0x03, 0xDE, 0xC0, 0x84, 0xBF, 0x04, 0x90} } /* 0x47 */ }; -static unsigned char XGI_CH7017LV1024x768[] = { - 0x60, 0x02, 0x00, 0x07, 0x40, 0xED, - 0xA3, 0xC8, 0xC7, 0xAC, 0xE0, 0x02}; -static unsigned char XGI_CH7017LV1400x1050[] = { - 0x60, 0x03, 0x11, 0x00, 0x40, 0xE3, - 0xAD, 0xDB, 0xF6, 0xAC, 0xE0, 0x02}; - /*add for new UNIVGABIOS*/ static struct SiS_LCDData XGI_StLCD1024x768Data[] = { {62, 25, 800, 546, 1344, 806}, @@ -1866,12 +1859,6 @@ static struct XGI330_LCDDataTablStruct XGI_EPLLCDDesDataPtr[] = { {0xFF, 0x0000, 0x0000, 0} }; -static struct XGI330_LCDDataTablStruct XGI_EPLCHLCDRegPtr[] = { - {Panel_1024x768, 0x0000, 0x0000, 0}, /* XGI_CH7017LV1024x768 */ - {Panel_1400x1050, 0x0000, 0x0000, 1}, /* XGI_CH7017LV1400x1050 */ - {0xFF, 0x0000, 0x0000, 0} -}; - static const struct XGI330_TVDataTablStruct XGI_TVDataTable[] = { {0x09E1, 0x0001, XGI_ExtPALData}, {0x09E1, 0x0000, XGI_ExtNTSCData}, -- cgit v0.10.2 From 378fd8a582d85b18d66c79a251b17a53a627cf95 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 11 Sep 2012 00:15:24 +0300 Subject: staging: xgifb: XGI_GetLcdPtr: delete dead code Only table values 0..5 are ever used. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index a1ee4c1..c97e438 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -1365,9 +1365,9 @@ static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo, tempcx = LCDLenList[tempbx]; if (pVBInfo->LCDInfo & EnableScalingLCD) { /* ScaleLCD */ - if ((tempbx == 5) || (tempbx) == 7) + if (tempbx == 5) tempcx = LCDDesDataLen2; - else if ((tempbx == 3) || (tempbx == 8)) + else if (tempbx == 3) tempcx = LVDSDesDataLen2; } @@ -1388,12 +1388,6 @@ static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo, case 5: tempdi = XGI_LCDDesDataTable; break; - case 6: - case 7: - case 8: - case 9: - tempdi = NULL; - break; default: break; } -- cgit v0.10.2 From 898df164012eb8419940fde6040280328e1a5d1d Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 11 Sep 2012 00:15:25 +0300 Subject: staging: xgifb: delete LCDLenList LCDLenList is redundant. It's only used for modifying a write-only stack variable. Delete also related #defines. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/vb_def.h b/drivers/staging/xgifb/vb_def.h index 609ab70..77137e4 100644 --- a/drivers/staging/xgifb/vb_def.h +++ b/drivers/staging/xgifb/vb_def.h @@ -104,16 +104,6 @@ #define ActiveHiTV 0x08 #define ActiveYPbPr 0x10 -/* --------------------------------------------------------- */ -/* translated from asm code 301def.h */ -/* */ -/* --------------------------------------------------------- */ -#define LVDSCRT1Len_H 8 -#define LVDSCRT1Len_V 7 -#define LCDDesDataLen 6 -#define LVDSDesDataLen2 8 -#define LCDDesDataLen2 8 - #define NTSC1024x768HT 1908 #define YPbPrTV525iHT 1716 /* YPbPr */ diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index c97e438..6dd8650 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -1337,7 +1337,7 @@ static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) { - unsigned short i, tempdx, tempcx, tempbx, tempal, modeflag, table; + unsigned short i, tempdx, tempbx, tempal, modeflag, table; struct XGI330_LCDDataTablStruct *tempdi = NULL; @@ -1362,15 +1362,6 @@ static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo, tempal = (tempal & 0x0f); } - tempcx = LCDLenList[tempbx]; - - if (pVBInfo->LCDInfo & EnableScalingLCD) { /* ScaleLCD */ - if (tempbx == 5) - tempcx = LCDDesDataLen2; - else if (tempbx == 3) - tempcx = LVDSDesDataLen2; - } - switch (tempbx) { case 0: case 1: diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index 14cabdb..fd623f0 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -1876,19 +1876,6 @@ static const struct XGI330_TVDataTablStruct XGI_TVDataTable[] = { {0xffff, 0x0000, XGI_ExtNTSCData}, }; -static unsigned short LCDLenList[] = { - LVDSCRT1Len_H, - LVDSCRT1Len_V, - LVDSDataLen, - LCDDesDataLen, - LCDDataLen, - LCDDesDataLen, - 0, - LCDDesDataLen, - LCDDesDataLen, - 0 -}; - /* Dual link only */ static struct XGI330_LCDCapStruct XGI_LCDDLCapList[] = { /* LCDCap1024x768 */ -- cgit v0.10.2 From 14f7c11187ae5b128d5fc4d01b348cd6b44fc538 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 11 Sep 2012 00:15:26 +0300 Subject: staging: xgifb: delete XGI_LCDDataTablStruct Delete an unused structure. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index 2eaeb26..3780a42 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -43,13 +43,6 @@ struct XGI_LCDDesStruct { unsigned short LCDVRS; }; -struct XGI_LCDDataTablStruct { - unsigned char PANELID; - unsigned short MASK; - unsigned short CAP; - unsigned short DATAPTR; -}; - struct XGI330_LCDDataDesStruct2 { unsigned short LCDHDES; unsigned short LCDHRS; -- cgit v0.10.2 From d3ae5762c6f37f64f222c6a4027774c8077388f1 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 11 Sep 2012 00:15:27 +0300 Subject: staging: xgifb: use "else if" Use "else if" when possible to reduce nesting. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 0c859ae..7fc3049 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -1397,11 +1397,10 @@ static int XGIfb_pan_display(struct fb_var_screeninfo *var, if (var->yoffset < 0 || var->yoffset >= info->var.yres_virtual || var->xoffset) return -EINVAL; - } else { - if (var->xoffset + info->var.xres > info->var.xres_virtual + } else if (var->xoffset + info->var.xres > info->var.xres_virtual || var->yoffset + info->var.yres - > info->var.yres_virtual) - return -EINVAL; + > info->var.yres_virtual) { + return -EINVAL; } err = XGIfb_pan_var(var, info); if (err < 0) diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 6dd8650..504a9d9 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -116,11 +116,9 @@ static void XGI_SetSeqRegs(unsigned short ModeNo, i = XGI_SetCRT2ToLCDA; if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { tempah |= 0x01; - } else { - if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD)) { - if (pVBInfo->VBInfo & SetInSlaveMode) - tempah |= 0x01; - } + } else if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD)) { + if (pVBInfo->VBInfo & SetInSlaveMode) + tempah |= 0x01; } tempah |= 0x20; /* screen off */ @@ -165,10 +163,9 @@ static void XGI_SetATTRegs(unsigned short ModeNo, if ((modeflag & Charx8Dot) && i == 0x13) { /* ifndef Dot9 */ if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { ARdata = 0; - } else { - if ((pVBInfo->VBInfo & + } else if ((pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD)) && - (pVBInfo->VBInfo & SetInSlaveMode)) + (pVBInfo->VBInfo & SetInSlaveMode)) { ARdata = 0; } } @@ -265,42 +262,38 @@ static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo, (pVBInfo->SetFlag & TVSimuMode)) || (resinfo > 7))) return 0; - } else { - if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO | + } else if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO | SetCRT2ToSVIDEO | SetCRT2ToSCART | SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) { - tempax |= SupportTV; - - if (pVBInfo->VBType & (VB_SIS301B | - VB_SIS302B | - VB_SIS301LV | - VB_SIS302LV | - VB_XGI301C)) - tempax |= SupportTV1024; - - if (!(pVBInfo->VBInfo & TVSetPAL) && - (modeflag & NoSupportSimuTV) && - (pVBInfo->VBInfo & SetInSlaveMode) && - (!(pVBInfo->VBInfo & SetNotSimuMode))) - return 0; - } + tempax |= SupportTV; + + if (pVBInfo->VBType & (VB_SIS301B | + VB_SIS302B | + VB_SIS301LV | + VB_SIS302LV | + VB_XGI301C)) + tempax |= SupportTV1024; + + if (!(pVBInfo->VBInfo & TVSetPAL) && + (modeflag & NoSupportSimuTV) && + (pVBInfo->VBInfo & SetInSlaveMode) && + (!(pVBInfo->VBInfo & SetNotSimuMode))) + return 0; } - } else { /* for LVDS */ - if (pVBInfo->VBInfo & SetCRT2ToLCD) { - tempax |= SupportLCD; + } else if (pVBInfo->VBInfo & SetCRT2ToLCD) { /* for LVDS */ + tempax |= SupportLCD; - if (resinfo > 0x08) - return 0; /* 1024x768 */ + if (resinfo > 0x08) + return 0; /* 1024x768 */ - if (pVBInfo->LCDResInfo < Panel_1024x768) { - if (resinfo > 0x07) - return 0; /* 800x600 */ + if (pVBInfo->LCDResInfo < Panel_1024x768) { + if (resinfo > 0x07) + return 0; /* 800x600 */ - if (resinfo == 0x04) - return 0; /* 512x384 */ - } + if (resinfo == 0x04) + return 0; /* 512x384 */ } } @@ -976,13 +969,11 @@ static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo, Ext_CRTVCLK; VCLKIndex &= IndexMask; } - } else { /* LVDS */ - if ((pVBInfo->LCDResInfo == Panel_800x600) || - (pVBInfo->LCDResInfo == Panel_320x480)) - VCLKIndex = VCLK40; /* LVDSXlat1VCLK */ - else - VCLKIndex = VCLK65_315 + 2; /* LVDSXlat2VCLK, - LVDSXlat3VCLK */ + } else if ((pVBInfo->LCDResInfo == Panel_800x600) || + (pVBInfo->LCDResInfo == Panel_320x480)) { /* LVDS */ + VCLKIndex = VCLK40; /* LVDSXlat1VCLK */ + } else { + VCLKIndex = VCLK65_315 + 2; /* LVDSXlat2VCLK, LVDSXlat3VCLK */ } return VCLKIndex; @@ -2544,11 +2535,10 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, temp = 0x09FC; else temp = 0x097C; + } else if (pVBInfo->IF_DEF_HiVision == 1) { + temp = 0x01FC; } else { - if (pVBInfo->IF_DEF_HiVision == 1) - temp = 0x01FC; - else - temp = 0x017C; + temp = 0x017C; } } else { /* 3nd party chip */ temp = SetCRT2ToLCD; @@ -2720,19 +2710,17 @@ static void XGI_GetTVInfo(unsigned short ModeNo, unsigned short ModeIdIndex, if (pVBInfo->VBInfo & SetCRT2ToHiVision) { if (pVBInfo->VBInfo & SetInSlaveMode) tempbx &= (~RPLLDIV2XO); - } else { - if (tempbx & - (TVSetYPbPr525p | TVSetYPbPr750p)) + } else if (tempbx & + (TVSetYPbPr525p | TVSetYPbPr750p)) { tempbx &= (~RPLLDIV2XO); - else if (!(pVBInfo->VBType & + } else if (!(pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV | VB_SIS302LV | VB_XGI301C))) { - if (tempbx & TVSimuMode) - tempbx &= (~RPLLDIV2XO); - } + if (tempbx & TVSimuMode) + tempbx &= (~RPLLDIV2XO); } } } @@ -3865,18 +3853,16 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, } else { tempbx -= 10; } - } else { - if (pVBInfo->TVInfo & TVSimuMode) { - if (pVBInfo->TVInfo & TVSetPAL) { - if (pVBInfo->VBType & VB_SIS301LV) { - if (!(pVBInfo->TVInfo & - (TVSetYPbPr525p | - TVSetYPbPr750p | - TVSetHiVision))) - tempbx += 40; - } else { + } else if (pVBInfo->TVInfo & TVSimuMode) { + if (pVBInfo->TVInfo & TVSetPAL) { + if (pVBInfo->VBType & VB_SIS301LV) { + if (!(pVBInfo->TVInfo & + (TVSetYPbPr525p | + TVSetYPbPr750p | + TVSetHiVision))) tempbx += 40; - } + } else { + tempbx += 40; } } } @@ -4189,11 +4175,9 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, temp += 1; } } - } else { - if (pVBInfo->VBInfo & SetInSlaveMode) { - if (ModeNo == 0x2f) - temp += 1; - } + } else if (pVBInfo->VBInfo & SetInSlaveMode) { + if (ModeNo == 0x2f) + temp += 1; } } @@ -4858,13 +4842,11 @@ static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex, if (pVBInfo->VBInfo & SetCRT2ToLCD) { if (tempax > 800) tempax -= 800; - } else { - if (pVBInfo->VGAHDE > 800) { - if (pVBInfo->VGAHDE == 1024) - tempax = (tempax * 25 / 32) - 1; - else - tempax = (tempax * 20 / 32) - 1; - } + } else if (pVBInfo->VGAHDE > 800) { + if (pVBInfo->VGAHDE == 1024) + tempax = (tempax * 25 / 32) - 1; + else + tempax = (tempax * 20 / 32) - 1; } tempax -= 1; @@ -6218,12 +6200,10 @@ static void XGI_EnableBridge(struct xgifb_video_info *xgifb_info, if (pVBInfo->SetFlag & EnableChA) { /* Power on */ xgifb_reg_set(pVBInfo->Part1Port, 0x1E, 0x20); - } else { - if (pVBInfo->VBInfo & SetCRT2ToDualEdge) { - /* Power on */ - xgifb_reg_set(pVBInfo->Part1Port, - 0x1E, 0x20); - } + } else if (pVBInfo->VBInfo & SetCRT2ToDualEdge) { + /* Power on */ + xgifb_reg_set(pVBInfo->Part1Port, + 0x1E, 0x20); } } @@ -6481,16 +6461,14 @@ unsigned char XGISetModeNew(struct xgifb_video_info *xgifb_info, XGI_SetLCDAGroup(ModeNo, ModeIdIndex, HwDeviceExtension, pVBInfo); } - } else { - if (!(pVBInfo->VBInfo & SwitchCRT2)) { - XGI_SetCRT1Group(xgifb_info, - HwDeviceExtension, ModeNo, - ModeIdIndex, pVBInfo); - if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { - XGI_SetLCDAGroup(ModeNo, ModeIdIndex, - HwDeviceExtension, - pVBInfo); - } + } else if (!(pVBInfo->VBInfo & SwitchCRT2)) { + XGI_SetCRT1Group(xgifb_info, + HwDeviceExtension, ModeNo, + ModeIdIndex, pVBInfo); + if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { + XGI_SetLCDAGroup(ModeNo, ModeIdIndex, + HwDeviceExtension, + pVBInfo); } } -- cgit v0.10.2 From 073b61e8c1a2cca70712adbead5164b12d1527be Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 11 Sep 2012 00:15:28 +0300 Subject: staging: xgifb: access static data tables directly Access some data tables directly instead of using pointers. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 504a9d9..fb14f8d 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -56,21 +56,6 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) pVBInfo->SR21 = 0xa3; pVBInfo->SR22 = 0xfb; - pVBInfo->NTSCTiming = XGI330_NTSCTiming; - pVBInfo->PALTiming = XGI330_PALTiming; - pVBInfo->HiTVExtTiming = XGI330_HiTVExtTiming; - pVBInfo->HiTVSt1Timing = XGI330_HiTVSt1Timing; - pVBInfo->HiTVSt2Timing = XGI330_HiTVSt2Timing; - pVBInfo->HiTVTextTiming = XGI330_HiTVTextTiming; - pVBInfo->YPbPr750pTiming = XGI330_YPbPr750pTiming; - pVBInfo->YPbPr525pTiming = XGI330_YPbPr525pTiming; - pVBInfo->YPbPr525iTiming = XGI330_YPbPr525iTiming; - pVBInfo->HiTVGroup3Data = XGI330_HiTVGroup3Data; - pVBInfo->HiTVGroup3Simu = XGI330_HiTVGroup3Simu; - pVBInfo->HiTVGroup3Text = XGI330_HiTVGroup3Text; - pVBInfo->Ren525pGroup3 = XGI330_Ren525pGroup3; - pVBInfo->Ren750pGroup3 = XGI330_Ren750pGroup3; - pVBInfo->TimingH = (struct XGI_TimingHStruct *) XGI_TimingH; pVBInfo->TimingV = (struct XGI_TimingVStruct *) XGI_TimingV; pVBInfo->UpdateCRT1 = (struct XGI_XG21CRT1Struct *) XGI_UpdateCRT1Table; @@ -3976,33 +3961,33 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, tempax = (tempax & 0xff00) >> 8; xgifb_reg_set(pVBInfo->Part2Port, 0x0, tempax); - TimingPoint = pVBInfo->NTSCTiming; + TimingPoint = XGI330_NTSCTiming; if (pVBInfo->TVInfo & TVSetPAL) - TimingPoint = pVBInfo->PALTiming; + TimingPoint = XGI330_PALTiming; if (pVBInfo->VBInfo & SetCRT2ToHiVision) { - TimingPoint = pVBInfo->HiTVExtTiming; + TimingPoint = XGI330_HiTVExtTiming; if (pVBInfo->VBInfo & SetInSlaveMode) - TimingPoint = pVBInfo->HiTVSt2Timing; + TimingPoint = XGI330_HiTVSt2Timing; if (pVBInfo->SetFlag & TVSimuMode) - TimingPoint = pVBInfo->HiTVSt1Timing; + TimingPoint = XGI330_HiTVSt1Timing; if (!(modeflag & Charx8Dot)) - TimingPoint = pVBInfo->HiTVTextTiming; + TimingPoint = XGI330_HiTVTextTiming; } if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) { if (pVBInfo->TVInfo & TVSetYPbPr525i) - TimingPoint = pVBInfo->YPbPr525iTiming; + TimingPoint = XGI330_YPbPr525iTiming; if (pVBInfo->TVInfo & TVSetYPbPr525p) - TimingPoint = pVBInfo->YPbPr525pTiming; + TimingPoint = XGI330_YPbPr525pTiming; if (pVBInfo->TVInfo & TVSetYPbPr750p) - TimingPoint = pVBInfo->YPbPr750pTiming; + TimingPoint = XGI330_YPbPr750pTiming; } for (i = 0x01, j = 0; i <= 0x2D; i++, j++) @@ -4693,18 +4678,18 @@ static void XGI_SetGroup3(unsigned short ModeNo, unsigned short ModeIdIndex, if (pVBInfo->TVInfo & TVSetYPbPr525i) return; - tempdi = pVBInfo->HiTVGroup3Data; + tempdi = XGI330_HiTVGroup3Data; if (pVBInfo->SetFlag & TVSimuMode) { - tempdi = pVBInfo->HiTVGroup3Simu; + tempdi = XGI330_HiTVGroup3Simu; if (!(modeflag & Charx8Dot)) - tempdi = pVBInfo->HiTVGroup3Text; + tempdi = XGI330_HiTVGroup3Text; } if (pVBInfo->TVInfo & TVSetYPbPr525p) - tempdi = pVBInfo->Ren525pGroup3; + tempdi = XGI330_Ren525pGroup3; if (pVBInfo->TVInfo & TVSetYPbPr750p) - tempdi = pVBInfo->Ren750pGroup3; + tempdi = XGI330_Ren750pGroup3; for (i = 0; i <= 0x3E; i++) xgifb_reg_set(pVBInfo->Part3Port, i, tempdi[i]); diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index 3780a42..32eecf6 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -175,20 +175,6 @@ struct vb_device_info { struct SiS_MCLKData *MCLKData; struct XGI_ECLKDataStruct *ECLKData; - unsigned char *NTSCTiming; - unsigned char *PALTiming; - unsigned char *HiTVExtTiming; - unsigned char *HiTVSt1Timing; - unsigned char *HiTVSt2Timing; - unsigned char *HiTVTextTiming; - unsigned char *YPbPr750pTiming; - unsigned char *YPbPr525pTiming; - unsigned char *YPbPr525iTiming; - unsigned char *HiTVGroup3Data; - unsigned char *HiTVGroup3Simu; - unsigned char *HiTVGroup3Text; - unsigned char *Ren525pGroup3; - unsigned char *Ren750pGroup3; unsigned char *ScreenOffset; unsigned char *pXGINew_DRAMTypeDefinition; unsigned char XGINew_CR97; -- cgit v0.10.2 From d21222d186ffe347c91699ce1430d576c61af266 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 11 Sep 2012 00:15:29 +0300 Subject: staging: xgifb: mark constant data with const Mark some data tables as const. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index fb14f8d..76d3fe1 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -3929,7 +3929,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, { unsigned short i, j, tempax, tempbx, tempcx, temp, push1, push2, modeflag, resinfo, crt2crtc; - unsigned char *TimingPoint; + unsigned char const *TimingPoint; unsigned long longtemp, tempeax, tempebx, temp2, tempecx; @@ -4649,7 +4649,7 @@ static void XGI_SetGroup3(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { unsigned short i; - unsigned char *tempdi; + unsigned char const *tempdi; unsigned short modeflag; /* si+Ext_ResInfo */ diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index fd623f0..4f45d03b 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -1013,7 +1013,7 @@ static const struct SiS_TVData XGI_StYPbPr750pData[] = { {1, 1, 1650, 750, 1280, 480, 0, 0, 760}, }; -static unsigned char XGI330_NTSCTiming[] = { +static const unsigned char XGI330_NTSCTiming[] = { 0x17, 0x1d, 0x03, 0x09, 0x05, 0x06, 0x0c, 0x0c, 0x94, 0x49, 0x01, 0x0a, 0x06, 0x0d, 0x04, 0x0a, 0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x1b, @@ -1024,7 +1024,7 @@ static unsigned char XGI330_NTSCTiming[] = { 0x00, 0x40, 0x44, 0x00, 0xdb, 0x02, 0x3b, 0x00 }; -static unsigned char XGI330_PALTiming[] = { +static const unsigned char XGI330_PALTiming[] = { 0x21, 0x5A, 0x35, 0x6e, 0x04, 0x38, 0x3d, 0x70, 0x94, 0x49, 0x01, 0x12, 0x06, 0x3e, 0x35, 0x6d, 0x06, 0x14, 0x3e, 0x35, 0x6d, 0x00, 0x45, 0x2b, @@ -1035,7 +1035,7 @@ static unsigned char XGI330_PALTiming[] = { 0x00, 0x40, 0x3e, 0x00, 0xe1, 0x02, 0x28, 0x00 }; -static unsigned char XGI330_HiTVExtTiming[] = { +static const unsigned char XGI330_HiTVExtTiming[] = { 0x2D, 0x60, 0x2C, 0x5F, 0x08, 0x31, 0x3A, 0x64, 0x28, 0x02, 0x01, 0x3D, 0x06, 0x3E, 0x35, 0x6D, 0x06, 0x14, 0x3E, 0x35, 0x6D, 0x00, 0xC5, 0x3F, @@ -1047,7 +1047,7 @@ static unsigned char XGI330_HiTVExtTiming[] = { 0x27, 0x00, 0xfc, 0xff, 0x6a, 0x00 }; -static unsigned char XGI330_HiTVSt1Timing[] = { +static const unsigned char XGI330_HiTVSt1Timing[] = { 0x32, 0x65, 0x2C, 0x5F, 0x08, 0x31, 0x3A, 0x65, 0x28, 0x02, 0x01, 0x3D, 0x06, 0x3E, 0x35, 0x6D, 0x06, 0x14, 0x3E, 0x35, 0x6D, 0x00, 0xC5, 0x3F, @@ -1059,7 +1059,7 @@ static unsigned char XGI330_HiTVSt1Timing[] = { 0x0E, 0x00, 0xfc, 0xff, 0x2d, 0x00 }; -static unsigned char XGI330_HiTVSt2Timing[] = { +static const unsigned char XGI330_HiTVSt2Timing[] = { 0x32, 0x65, 0x2C, 0x5F, 0x08, 0x31, 0x3A, 0x64, 0x28, 0x02, 0x01, 0x3D, 0x06, 0x3E, 0x35, 0x6D, 0x06, 0x14, 0x3E, 0x35, 0x6D, 0x00, 0xC5, 0x3F, @@ -1071,7 +1071,7 @@ static unsigned char XGI330_HiTVSt2Timing[] = { 0x27, 0x00, 0xFC, 0xff, 0x6a, 0x00 }; -static unsigned char XGI330_HiTVTextTiming[] = { +static const unsigned char XGI330_HiTVTextTiming[] = { 0x32, 0x65, 0x2C, 0x5F, 0x08, 0x31, 0x3A, 0x65, 0x28, 0x02, 0x01, 0x3D, 0x06, 0x3E, 0x35, 0x6D, 0x06, 0x14, 0x3E, 0x35, 0x6D, 0x00, 0xC5, 0x3F, @@ -1083,7 +1083,7 @@ static unsigned char XGI330_HiTVTextTiming[] = { 0x11, 0x00, 0xFC, 0xFF, 0x32, 0x00 }; -static unsigned char XGI330_YPbPr750pTiming[] = { +static const unsigned char XGI330_YPbPr750pTiming[] = { 0x30, 0x1d, 0xe8, 0x09, 0x09, 0xed, 0x0c, 0x0c, 0x98, 0x0a, 0x01, 0x0c, 0x06, 0x0d, 0x04, 0x0a, 0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x3f, @@ -1095,7 +1095,7 @@ static unsigned char XGI330_YPbPr750pTiming[] = { 0x11, 0x00, 0xfc, 0xff, 0x32, 0x00 }; -static unsigned char XGI330_YPbPr525pTiming[] = { +static const unsigned char XGI330_YPbPr525pTiming[] = { 0x3E, 0x11, 0x06, 0x09, 0x0b, 0x0c, 0x0c, 0x0c, 0x98, 0x0a, 0x01, 0x0d, 0x06, 0x0d, 0x04, 0x0a, 0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x3f, @@ -1107,7 +1107,7 @@ static unsigned char XGI330_YPbPr525pTiming[] = { 0x11, 0x00, 0xFC, 0xFF, 0x32, 0x00 }; -static unsigned char XGI330_YPbPr525iTiming[] = { +static const unsigned char XGI330_YPbPr525iTiming[] = { 0x1B, 0x21, 0x03, 0x09, 0x05, 0x06, 0x0C, 0x0C, 0x94, 0x49, 0x01, 0x0A, 0x06, 0x0D, 0x04, 0x0A, 0x06, 0x14, 0x0D, 0x04, 0x0A, 0x00, 0x85, 0x1B, @@ -1119,7 +1119,7 @@ static unsigned char XGI330_YPbPr525iTiming[] = { 0x44, 0x00, 0xDB, 0x02, 0x3B, 0x00 }; -static unsigned char XGI330_HiTVGroup3Data[] = { +static const unsigned char XGI330_HiTVGroup3Data[] = { 0x00, 0x1A, 0x22, 0x63, 0x62, 0x22, 0x08, 0x5F, 0x05, 0x21, 0xB2, 0xB2, 0x55, 0x77, 0x2A, 0xA6, 0x25, 0x2F, 0x47, 0xFA, 0xC8, 0xFF, 0x8E, 0x20, @@ -1130,7 +1130,7 @@ static unsigned char XGI330_HiTVGroup3Data[] = { 0x18, 0x05, 0x18, 0x05, 0x4C, 0xA8, 0x01 }; -static unsigned char XGI330_HiTVGroup3Simu[] = { +static const unsigned char XGI330_HiTVGroup3Simu[] = { 0x00, 0x1A, 0x22, 0x63, 0x62, 0x22, 0x08, 0x95, 0xDB, 0x20, 0xB8, 0xB8, 0x55, 0x47, 0x2A, 0xA6, 0x25, 0x2F, 0x47, 0xFA, 0xC8, 0xFF, 0x8E, 0x20, @@ -1141,7 +1141,7 @@ static unsigned char XGI330_HiTVGroup3Simu[] = { 0x18, 0x05, 0x18, 0x05, 0x4C, 0xA8, 0x01 }; -static unsigned char XGI330_HiTVGroup3Text[] = { +static const unsigned char XGI330_HiTVGroup3Text[] = { 0x00, 0x1A, 0x22, 0x63, 0x62, 0x22, 0x08, 0xA7, 0xF5, 0x20, 0xCE, 0xCE, 0x55, 0x47, 0x2A, 0xA6, 0x25, 0x2F, 0x47, 0xFA, 0xC8, 0xFF, 0x8E, 0x20, @@ -1152,7 +1152,7 @@ static unsigned char XGI330_HiTVGroup3Text[] = { 0x18, 0x05, 0x18, 0x05, 0x4C, 0xA8, 0x01 }; -static unsigned char XGI330_Ren525pGroup3[] = { +static const unsigned char XGI330_Ren525pGroup3[] = { 0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x13, 0xB1, 0x41, 0x62, 0x62, 0xFF, 0xF4, 0x45, 0xa6, 0x25, 0x2F, 0x67, 0xF6, 0xbf, 0xFF, 0x8E, 0x20, @@ -1163,7 +1163,7 @@ static unsigned char XGI330_Ren525pGroup3[] = { 0x1a, 0x1F, 0x25, 0x2a, 0x4C, 0xAA, 0x01 }; -static unsigned char XGI330_Ren750pGroup3[] = { +static const unsigned char XGI330_Ren750pGroup3[] = { 0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x7a, 0x54, 0x41, 0xE7, 0xE7, 0xFF, 0xF4, 0x45, 0xa6, 0x25, 0x2F, 0x67, 0xF6, 0xbf, 0xFF, 0x8E, 0x20, -- cgit v0.10.2 From 8951dadc97aa51376611670d024f7418463a7bbd Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 11 Sep 2012 00:15:30 +0300 Subject: staging: xgifb: delete ISXPDOS Delete unneeded flag. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index fdb7d1a..0f6a529 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -1299,8 +1299,6 @@ unsigned char XGIInitNew(struct pci_dev *pdev) outb(0x67, (pVBInfo->BaseAddr + 0x12)); /* 3c2 <- 67 ,ynlai */ - pVBInfo->ISXPDOS = 0; - pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14; pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24; pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10; diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 76d3fe1..0ed8036 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -4872,9 +4872,7 @@ static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex, } /* end 301b */ - if (pVBInfo->ISXPDOS == 0) - XGI_SetCRT2VCLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, - pVBInfo); + XGI_SetCRT2VCLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo); } static void XGINew_EnableCRT2(struct vb_device_info *pVBInfo) diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index 32eecf6..70158c2 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -135,7 +135,6 @@ struct XGI301C_Tap4TimingStruct { }; struct vb_device_info { - unsigned char ISXPDOS; unsigned long P3c4, P3d4, P3c0, P3ce, P3c2, P3cc; unsigned long P3ca, P3c6, P3c7, P3c8, P3c9, P3da; unsigned long Part0Port, Part1Port, Part2Port; -- cgit v0.10.2 From e8cb03d422cc9a5afdc77e61232d9187d83c4c78 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 11 Sep 2012 00:15:31 +0300 Subject: staging: xgifb: use correct type for VBVCLKData Use correct type to eliminate casting. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 0ed8036..ef8775e 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -32,7 +32,7 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) pVBInfo->MCLKData = (struct SiS_MCLKData *) XGI340New_MCLKData; pVBInfo->ECLKData = (struct XGI_ECLKDataStruct *) XGI340_ECLKData; pVBInfo->VCLKData = (struct SiS_VCLKData *) XGI_VCLKData; - pVBInfo->VBVCLKData = (struct SiS_VBVCLKData *) XGI_VBVCLKData; + pVBInfo->VBVCLKData = XGI_VBVCLKData; pVBInfo->ScreenOffset = XGI330_ScreenOffset; pVBInfo->StResInfo = (struct SiS_StResInfo_S *) XGI330_StResInfo; pVBInfo->ModeResInfo @@ -2276,8 +2276,8 @@ static void XGI_GetVCLKLen(unsigned char tempal, unsigned char *di_0, | VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) { if ((!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) && (pVBInfo->SetFlag & ProgrammingCRT2)) { - *di_0 = (unsigned char) XGI_VBVCLKData[tempal].SR2B; - *di_1 = XGI_VBVCLKData[tempal].SR2C; + *di_0 = XGI_VBVCLKData[tempal].Part4_A; + *di_1 = XGI_VBVCLKData[tempal].Part4_C; } } else { *di_0 = XGI_VCLKData[tempal].SR2B; diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index 4f45d03b..180aae0 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -2234,7 +2234,7 @@ static struct SiS_VCLKData XGI_VCLKData[] = { {0xFF, 0x00, 0} /* End mark */ }; -static struct SiS_VCLKData XGI_VBVCLKData[] = { +static struct SiS_VBVCLKData XGI_VBVCLKData[] = { {0x1B, 0xE1, 25}, /* 00 (25.175MHz) */ {0x4E, 0xE4, 28}, /* 01 (28.322MHz) */ {0x57, 0xE4, 31}, /* 02 (31.500MHz) */ -- cgit v0.10.2 From a7e46d8b5cc29c48c4056f312a87a6c317c37ae7 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 11 Sep 2012 00:15:32 +0300 Subject: staging: xgifb: delete redundant casts Delete some redundant casts. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index ef8775e..e95a165 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -23,20 +23,18 @@ static const unsigned short XGINew_VGA_DAC[] = { void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) { - pVBInfo->StandTable = (struct SiS_StandTable_S *) &XGI330_StandTable; - pVBInfo->EModeIDTable = (struct XGI_ExtStruct *) XGI330_EModeIDTable; - pVBInfo->RefIndex = (struct XGI_Ext2Struct *) XGI330_RefIndex; - pVBInfo->XGINEWUB_CRT1Table - = (struct XGI_CRT1TableStruct *) XGI_CRT1Table; - - pVBInfo->MCLKData = (struct SiS_MCLKData *) XGI340New_MCLKData; - pVBInfo->ECLKData = (struct XGI_ECLKDataStruct *) XGI340_ECLKData; - pVBInfo->VCLKData = (struct SiS_VCLKData *) XGI_VCLKData; + pVBInfo->StandTable = &XGI330_StandTable; + pVBInfo->EModeIDTable = XGI330_EModeIDTable; + pVBInfo->RefIndex = XGI330_RefIndex; + pVBInfo->XGINEWUB_CRT1Table = XGI_CRT1Table; + + pVBInfo->MCLKData = XGI340New_MCLKData; + pVBInfo->ECLKData = XGI340_ECLKData; + pVBInfo->VCLKData = XGI_VCLKData; pVBInfo->VBVCLKData = XGI_VBVCLKData; pVBInfo->ScreenOffset = XGI330_ScreenOffset; - pVBInfo->StResInfo = (struct SiS_StResInfo_S *) XGI330_StResInfo; - pVBInfo->ModeResInfo - = (struct SiS_ModeResInfo_S *) XGI330_ModeResInfo; + pVBInfo->StResInfo = XGI330_StResInfo; + pVBInfo->ModeResInfo = XGI330_ModeResInfo; pVBInfo->LCDResInfo = 0; pVBInfo->LCDTypeInfo = 0; @@ -56,9 +54,9 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) pVBInfo->SR21 = 0xa3; pVBInfo->SR22 = 0xfb; - pVBInfo->TimingH = (struct XGI_TimingHStruct *) XGI_TimingH; - pVBInfo->TimingV = (struct XGI_TimingVStruct *) XGI_TimingV; - pVBInfo->UpdateCRT1 = (struct XGI_XG21CRT1Struct *) XGI_UpdateCRT1Table; + pVBInfo->TimingH = XGI_TimingH; + pVBInfo->TimingV = XGI_TimingV; + pVBInfo->UpdateCRT1 = XGI_UpdateCRT1Table; /* 310 customization related */ if ((pVBInfo->VBType & VB_SIS301LV) || (pVBInfo->VBType & VB_SIS302LV)) @@ -71,8 +69,7 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) if (ChipType == XG27) { unsigned char temp; - pVBInfo->MCLKData - = (struct SiS_MCLKData *) XGI27New_MCLKData; + pVBInfo->MCLKData = XGI27New_MCLKData; pVBInfo->CR40 = XGI27_cr41; pVBInfo->XGINew_CR97 = 0xc1; pVBInfo->SR15 = XG27_SR13; @@ -1752,9 +1749,8 @@ static void XGI_GetLVDSData(unsigned short ModeNo, unsigned short ModeIdIndex, tempbx = 2; if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { - LCDPtr = (struct SiS_LVDSData *)XGI_GetLcdPtr(tempbx, - ModeNo, ModeIdIndex, RefreshRateTableIndex, - pVBInfo); + LCDPtr = XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex, + RefreshRateTableIndex, pVBInfo); pVBInfo->VGAHT = LCDPtr->VGAHT; pVBInfo->VGAVT = LCDPtr->VGAVT; pVBInfo->HT = LCDPtr->LCDHT; @@ -1800,11 +1796,8 @@ static void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex, tempbx = 0; if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { - LCDPtr = (struct XGI_LVDSCRT1HDataStruct *) - XGI_GetLcdPtr(tempbx, ModeNo, - ModeIdIndex, - RefreshRateTableIndex, - pVBInfo); + LCDPtr = XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex, + RefreshRateTableIndex, pVBInfo); for (i = 0; i < 8; i++) pVBInfo->TimingH[0].data[i] = LCDPtr[0].Reg[i]; @@ -1815,13 +1808,8 @@ static void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex, tempbx = 1; if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { - LCDPtr1 = (struct XGI_LVDSCRT1VDataStruct *) - XGI_GetLcdPtr( - tempbx, - ModeNo, - ModeIdIndex, - RefreshRateTableIndex, - pVBInfo); + LCDPtr1 = XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex, + RefreshRateTableIndex, pVBInfo); for (i = 0; i < 7; i++) pVBInfo->TimingV[0].data[i] = LCDPtr1[0].Reg[i]; } @@ -1913,23 +1901,11 @@ static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex, modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; tempbx = 3; if (pVBInfo->LCDInfo & EnableScalingLCD) - LCDPtr1 = - (struct XGI330_LCDDataDesStruct2 *) - XGI_GetLcdPtr( - tempbx, - ModeNo, - ModeIdIndex, - RefreshRateTableIndex, - pVBInfo); + LCDPtr1 = XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex, + RefreshRateTableIndex, pVBInfo); else - LCDPtr = - (struct XGI_LCDDesStruct *) - XGI_GetLcdPtr( - tempbx, - ModeNo, - ModeIdIndex, - RefreshRateTableIndex, - pVBInfo); + LCDPtr = XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex, + RefreshRateTableIndex, pVBInfo); XGI_GetLCDSync(&tempax, &tempbx, pVBInfo); push1 = tempbx; @@ -2277,7 +2253,7 @@ static void XGI_GetVCLKLen(unsigned char tempal, unsigned char *di_0, if ((!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) && (pVBInfo->SetFlag & ProgrammingCRT2)) { *di_0 = XGI_VBVCLKData[tempal].Part4_A; - *di_1 = XGI_VBVCLKData[tempal].Part4_C; + *di_1 = XGI_VBVCLKData[tempal].Part4_B; } } else { *di_0 = XGI_VCLKData[tempal].SR2B; @@ -3179,9 +3155,8 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, tempbx = 4; if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { - LCDPtr = (struct SiS_LCDData *) XGI_GetLcdPtr(tempbx, - ModeNo, ModeIdIndex, RefreshRateTableIndex, - pVBInfo); + LCDPtr = XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex, + RefreshRateTableIndex, pVBInfo); pVBInfo->RVBHCMAX = LCDPtr->RVBHCMAX; pVBInfo->RVBHCFACT = LCDPtr->RVBHCFACT; @@ -4417,8 +4392,8 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, /* Customized LCDB Des no add */ tempbx = 5; - LCDBDesPtr = (struct XGI_LCDDesStruct *) XGI_GetLcdPtr(tempbx, ModeNo, - ModeIdIndex, RefreshRateTableIndex, pVBInfo); + LCDBDesPtr = XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex, + RefreshRateTableIndex, pVBInfo); tempah = pVBInfo->LCDResInfo; tempah &= PanelResInfo; -- cgit v0.10.2 From 119c08149ab5135eda67a1503484aacbf2164af3 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Tue, 4 Sep 2012 17:46:22 -0500 Subject: staging: drm/omap: hold a ref to the bo while waiting for flip Since the plane hasn't yet taken a reference, we need to hold a reference while waiting to ensure the backing GEM bo doesn't get freed from under us. Signed-off-by: Rob Clark Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/omapdrm/omap_crtc.c b/drivers/staging/omapdrm/omap_crtc.c index dade3de..732f2ad 100644 --- a/drivers/staging/omapdrm/omap_crtc.c +++ b/drivers/staging/omapdrm/omap_crtc.c @@ -155,6 +155,7 @@ static void page_flip_cb(void *arg) struct drm_crtc *crtc = arg; struct omap_crtc *omap_crtc = to_omap_crtc(crtc); struct drm_framebuffer *old_fb = omap_crtc->old_fb; + struct drm_gem_object *bo; omap_crtc->old_fb = NULL; @@ -165,6 +166,9 @@ static void page_flip_cb(void *arg) * cycle.. for now go for correctness and later figure out speed.. */ omap_plane_on_endwin(omap_crtc->plane, vblank_cb, crtc); + + bo = omap_framebuffer_bo(crtc->fb, 0); + drm_gem_object_unreference_unlocked(bo); } static int omap_crtc_page_flip_locked(struct drm_crtc *crtc, @@ -173,6 +177,7 @@ static int omap_crtc_page_flip_locked(struct drm_crtc *crtc, { struct drm_device *dev = crtc->dev; struct omap_crtc *omap_crtc = to_omap_crtc(crtc); + struct drm_gem_object *bo; DBG("%d -> %d", crtc->fb ? crtc->fb->base.id : -1, fb->base.id); @@ -185,8 +190,15 @@ static int omap_crtc_page_flip_locked(struct drm_crtc *crtc, omap_crtc->event = event; crtc->fb = fb; - omap_gem_op_async(omap_framebuffer_bo(fb, 0), OMAP_GEM_READ, - page_flip_cb, crtc); + /* + * Hold a reference temporarily until the crtc is updated + * and takes the reference to the bo. This avoids it + * getting freed from under us: + */ + bo = omap_framebuffer_bo(fb, 0); + drm_gem_object_reference(bo); + + omap_gem_op_async(bo, OMAP_GEM_READ, page_flip_cb, crtc); return 0; } -- cgit v0.10.2 From 98943079bfe0fcaca05410ea2fcfc00988ecc661 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 18:50:29 -0700 Subject: staging: comedi: adl_pci9111: remove dev_private macro This macro relies on a local variable having a specific name. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 63d55b0..cf3c43a 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -363,8 +363,6 @@ struct pci9111_private_data { short ai_bounce_buffer[2 * PCI9111_FIFO_HALF_SIZE]; }; -#define dev_private ((struct pci9111_private_data *)dev->private) - /* ------------------------------------------------------------------ */ /* PLX9050 SECTION */ /* ------------------------------------------------------------------ */ @@ -412,6 +410,8 @@ static void plx9050_interrupt_control(unsigned long io_base, static void pci9111_timer_set(struct comedi_device *dev) { + struct pci9111_private_data *dev_private = dev->private; + pci9111_8254_control_set(PCI9111_8254_COUNTER_0 | PCI9111_8254_READ_LOAD_LSB_MSB | PCI9111_8254_MODE_0 | @@ -525,6 +525,8 @@ static void pci9111_interrupt_source_set(struct comedi_device *dev, static int pci9111_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pci9111_private_data *dev_private = dev->private; + /* Disable interrupts */ plx9050_interrupt_control(dev_private->lcr_io_base, true, true, true, @@ -556,6 +558,7 @@ static int pci9111_ai_do_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { + struct pci9111_private_data *dev_private = dev->private; int tmp; int error = 0; int range, reference; @@ -756,6 +759,7 @@ pci9111_ai_do_cmd_test(struct comedi_device *dev, static int pci9111_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pci9111_private_data *dev_private = dev->private; struct comedi_cmd *async_cmd = &s->async->cmd; if (!dev->irq) { @@ -907,6 +911,7 @@ static void pci9111_ai_munge(struct comedi_device *dev, static irqreturn_t pci9111_interrupt(int irq, void *p_device) { struct comedi_device *dev = p_device; + struct pci9111_private_data *dev_private = dev->private; struct comedi_subdevice *s = dev->read_subdev; struct comedi_async *async; unsigned long irq_flags; @@ -1113,6 +1118,7 @@ pci9111_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pci9111_private_data *dev_private = dev->private; int i; for (i = 0; i < insn->n; i++) { @@ -1129,6 +1135,7 @@ static int pci9111_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pci9111_private_data *dev_private = dev->private; int i; for (i = 0; i < insn->n; i++) @@ -1189,6 +1196,8 @@ static int pci9111_do_insn_bits(struct comedi_device *dev, static int pci9111_reset(struct comedi_device *dev) { + struct pci9111_private_data *dev_private = dev->private; + /* Set trigger source to software */ plx9050_interrupt_control(dev_private->lcr_io_base, true, true, true, @@ -1246,14 +1255,18 @@ static struct pci_dev *pci9111_find_pci(struct comedi_device *dev, static int pci9111_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct pci9111_private_data *dev_private; struct pci_dev *pcidev; struct comedi_subdevice *s; unsigned long io_base, io_range, lcr_io_base, lcr_io_range; - int error; + int ret; const struct pci9111_board *board; - if (alloc_private(dev, sizeof(struct pci9111_private_data)) < 0) - return -ENOMEM; + ret = alloc_private(dev, sizeof(*dev_private)); + if (ret) + return ret; + dev_private = dev->private; + /* Probe the device to determine what device in the series it is. */ printk(KERN_ERR "comedi%d: " PCI9111_DRIVER_NAME " driver\n", @@ -1318,9 +1331,9 @@ static int pci9111_attach(struct comedi_device *dev, /* TODO: Add external multiplexer setup (according to option[2]). */ - error = comedi_alloc_subdevices(dev, 4); - if (error) - return error; + ret = comedi_alloc_subdevices(dev, 4); + if (ret) + return ret; s = &dev->subdevices[0]; dev->read_subdev = s; @@ -1376,8 +1389,9 @@ static int pci9111_attach(struct comedi_device *dev, static void pci9111_detach(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct pci9111_private_data *dev_private = dev->private; - if (dev->private != NULL) { + if (dev_private) { if (dev_private->is_valid) pci9111_reset(dev); } -- cgit v0.10.2 From 3faac285bbe190667798bc6aa20c51c91c6a165e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 18:50:49 -0700 Subject: staging: comedi: adl_pci9111: remove pci9111_board_nbr macro This macro is an open-coded version of the kernels ARRAY_SIZE macro. Use the kernel provided macro instead. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index cf3c43a..01a861d 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -332,9 +332,6 @@ static const struct pci9111_board pci9111_boards[] = { .ai_acquisition_period_min_ns = PCI9111_AI_ACQUISITION_PERIOD_MIN_NS} }; -#define pci9111_board_nbr \ - (sizeof(pci9111_boards)/sizeof(struct pci9111_board)) - /* Private data structure */ struct pci9111_private_data { @@ -1228,7 +1225,7 @@ static struct pci_dev *pci9111_find_pci(struct comedi_device *dev, for_each_pci_dev(pcidev) { if (pcidev->vendor != PCI_VENDOR_ID_ADLINK) continue; - for (i = 0; i < pci9111_board_nbr; i++) { + for (i = 0; i < ARRAY_SIZE(pci9111_boards); i++) { if (pcidev->device != pci9111_boards[i].device_id) continue; if (bus || slot) { -- cgit v0.10.2 From 886edb0caf2be7bbff443a4e272416b7d97d4c9f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 18:51:09 -0700 Subject: staging: comedi: adl_pci9111: remove PCI9111_IO_BASE macro This macro relies on a local variable having a specific name. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 01a861d..54a5e42 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -179,113 +179,111 @@ TODO: #define PCI9111_FIFO_FULL_MASK 0x40 #define PCI9111_AD_BUSY_MASK 0x80 -#define PCI9111_IO_BASE (dev->iobase) - /* * Define inlined function */ #define pci9111_trigger_and_autoscan_get() \ - (inb(PCI9111_IO_BASE+PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK)&0x0F) + (inb(dev->iobase + PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK)&0x0F) #define pci9111_trigger_and_autoscan_set(flags) \ - outb(flags, PCI9111_IO_BASE+PCI9111_REGISTER_TRIGGER_MODE_CONTROL) + outb(flags, dev->iobase + PCI9111_REGISTER_TRIGGER_MODE_CONTROL) #define pci9111_interrupt_and_fifo_get() \ - ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK) \ + ((inb(dev->iobase + PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK) \ >> 4) & 0x03) #define pci9111_interrupt_and_fifo_set(flags) \ - outb(flags, PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL) + outb(flags, dev->iobase + PCI9111_REGISTER_INTERRUPT_CONTROL) #define pci9111_interrupt_clear() \ - outb(0, PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CLEAR) + outb(0, dev->iobase + PCI9111_REGISTER_INTERRUPT_CLEAR) #define pci9111_software_trigger() \ - outb(0, PCI9111_IO_BASE+PCI9111_REGISTER_SOFTWARE_TRIGGER) + outb(0, dev->iobase + PCI9111_REGISTER_SOFTWARE_TRIGGER) #define pci9111_fifo_reset() do { \ outb(PCI9111_FFEN_SET_FIFO_ENABLE, \ - PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL); \ + dev->iobase + PCI9111_REGISTER_INTERRUPT_CONTROL); \ outb(PCI9111_FFEN_SET_FIFO_DISABLE, \ - PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL); \ + dev->iobase + PCI9111_REGISTER_INTERRUPT_CONTROL); \ outb(PCI9111_FFEN_SET_FIFO_ENABLE, \ - PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL); \ + dev->iobase + PCI9111_REGISTER_INTERRUPT_CONTROL); \ } while (0) #define pci9111_is_fifo_full() \ - ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)& \ + ((inb(dev->iobase + PCI9111_REGISTER_RANGE_STATUS_READBACK)& \ PCI9111_FIFO_FULL_MASK) == 0) #define pci9111_is_fifo_half_full() \ - ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)& \ + ((inb(dev->iobase + PCI9111_REGISTER_RANGE_STATUS_READBACK)& \ PCI9111_FIFO_HALF_FULL_MASK) == 0) #define pci9111_is_fifo_empty() \ - ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)& \ + ((inb(dev->iobase + PCI9111_REGISTER_RANGE_STATUS_READBACK)& \ PCI9111_FIFO_EMPTY_MASK) == 0) #define pci9111_ai_channel_set(channel) \ outb((channel)&PCI9111_CHANNEL_MASK, \ - PCI9111_IO_BASE+PCI9111_REGISTER_AD_CHANNEL_CONTROL) + dev->iobase + PCI9111_REGISTER_AD_CHANNEL_CONTROL) #define pci9111_ai_channel_get() \ - (inb(PCI9111_IO_BASE+PCI9111_REGISTER_AD_CHANNEL_READBACK) \ + (inb(dev->iobase + PCI9111_REGISTER_AD_CHANNEL_READBACK) \ &PCI9111_CHANNEL_MASK) #define pci9111_ai_range_set(range) \ outb((range)&PCI9111_RANGE_MASK, \ - PCI9111_IO_BASE+PCI9111_REGISTER_INPUT_SIGNAL_RANGE) + dev->iobase + PCI9111_REGISTER_INPUT_SIGNAL_RANGE) #define pci9111_ai_range_get() \ - (inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK) \ + (inb(dev->iobase + PCI9111_REGISTER_RANGE_STATUS_READBACK) \ &PCI9111_RANGE_MASK) #define pci9111_ai_get_data() \ - (((inw(PCI9111_IO_BASE+PCI9111_REGISTER_AD_FIFO_VALUE)>>4) \ + (((inw(dev->iobase + PCI9111_REGISTER_AD_FIFO_VALUE)>>4) \ &PCI9111_AI_RESOLUTION_MASK) \ ^ PCI9111_AI_RESOLUTION_2_CMP_BIT) #define pci9111_hr_ai_get_data() \ - ((inw(PCI9111_IO_BASE+PCI9111_REGISTER_AD_FIFO_VALUE) \ + ((inw(dev->iobase + PCI9111_REGISTER_AD_FIFO_VALUE) \ &PCI9111_HR_AI_RESOLUTION_MASK) \ ^ PCI9111_HR_AI_RESOLUTION_2_CMP_BIT) #define pci9111_ao_set_data(data) \ outw(data&PCI9111_AO_RESOLUTION_MASK, \ - PCI9111_IO_BASE+PCI9111_REGISTER_DA_OUTPUT) + dev->iobase + PCI9111_REGISTER_DA_OUTPUT) #define pci9111_di_get_bits() \ - inw(PCI9111_IO_BASE+PCI9111_REGISTER_DIGITAL_IO) + inw(dev->iobase + PCI9111_REGISTER_DIGITAL_IO) #define pci9111_do_set_bits(bits) \ - outw(bits, PCI9111_IO_BASE+PCI9111_REGISTER_DIGITAL_IO) + outw(bits, dev->iobase + PCI9111_REGISTER_DIGITAL_IO) #define pci9111_8254_control_set(flags) \ - outb(flags, PCI9111_IO_BASE+PCI9111_REGISTER_8254_CONTROL) + outb(flags, dev->iobase + PCI9111_REGISTER_8254_CONTROL) #define pci9111_8254_counter_0_set(data) \ do { \ outb(data & 0xFF, \ - PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_0); \ + dev->iobase + PCI9111_REGISTER_8254_COUNTER_0); \ outb((data >> 8) & 0xFF, \ - PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_0); \ + dev->iobase + PCI9111_REGISTER_8254_COUNTER_0); \ } while (0) #define pci9111_8254_counter_1_set(data) \ do { \ outb(data & 0xFF, \ - PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_1); \ + dev->iobase + PCI9111_REGISTER_8254_COUNTER_1); \ outb((data >> 8) & 0xFF, \ - PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_1); \ + dev->iobase + PCI9111_REGISTER_8254_COUNTER_1); \ } while (0) #define pci9111_8254_counter_2_set(data) \ do { \ outb(data & 0xFF, \ - PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_2); \ + dev->iobase + PCI9111_REGISTER_8254_COUNTER_2); \ outb((data >> 8) & 0xFF, \ - PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_2); \ + dev->iobase + PCI9111_REGISTER_8254_COUNTER_2); \ } while (0) static const struct comedi_lrange pci9111_hr_ai_range = { @@ -967,7 +965,7 @@ static irqreturn_t pci9111_interrupt(int irq, void *p_device) && !dev_private-> stop_is_none ? dev_private->stop_counter : PCI9111_FIFO_HALF_SIZE; - insw(PCI9111_IO_BASE + PCI9111_REGISTER_AD_FIFO_VALUE, + insw(dev->iobase + PCI9111_REGISTER_AD_FIFO_VALUE, dev_private->ai_bounce_buffer, num_samples); if (dev_private->scan_delay < 1) { -- cgit v0.10.2 From d3ceb27c70efbe7d1f4e086370e5e0ba76fef5d8 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 18:51:30 -0700 Subject: staging: comedi: adl_pci9111: remove pci9111_8254_* i/o macros These macros rely on a local variable having a specific name. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 54a5e42..a8d9584 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -259,33 +259,6 @@ TODO: #define pci9111_do_set_bits(bits) \ outw(bits, dev->iobase + PCI9111_REGISTER_DIGITAL_IO) -#define pci9111_8254_control_set(flags) \ - outb(flags, dev->iobase + PCI9111_REGISTER_8254_CONTROL) - -#define pci9111_8254_counter_0_set(data) \ - do { \ - outb(data & 0xFF, \ - dev->iobase + PCI9111_REGISTER_8254_COUNTER_0); \ - outb((data >> 8) & 0xFF, \ - dev->iobase + PCI9111_REGISTER_8254_COUNTER_0); \ - } while (0) - -#define pci9111_8254_counter_1_set(data) \ - do { \ - outb(data & 0xFF, \ - dev->iobase + PCI9111_REGISTER_8254_COUNTER_1); \ - outb((data >> 8) & 0xFF, \ - dev->iobase + PCI9111_REGISTER_8254_COUNTER_1); \ - } while (0) - -#define pci9111_8254_counter_2_set(data) \ - do { \ - outb(data & 0xFF, \ - dev->iobase + PCI9111_REGISTER_8254_COUNTER_2); \ - outb((data >> 8) & 0xFF, \ - dev->iobase + PCI9111_REGISTER_8254_COUNTER_2); \ - } while (0) - static const struct comedi_lrange pci9111_hr_ai_range = { 5, { @@ -407,25 +380,35 @@ static void pci9111_timer_set(struct comedi_device *dev) { struct pci9111_private_data *dev_private = dev->private; - pci9111_8254_control_set(PCI9111_8254_COUNTER_0 | - PCI9111_8254_READ_LOAD_LSB_MSB | - PCI9111_8254_MODE_0 | - PCI9111_8254_BINARY_COUNTER); + outb(PCI9111_8254_COUNTER_0 | + PCI9111_8254_READ_LOAD_LSB_MSB | + PCI9111_8254_MODE_0 | + PCI9111_8254_BINARY_COUNTER, + dev->iobase + PCI9111_REGISTER_8254_CONTROL); - pci9111_8254_control_set(PCI9111_8254_COUNTER_1 | - PCI9111_8254_READ_LOAD_LSB_MSB | - PCI9111_8254_MODE_2 | - PCI9111_8254_BINARY_COUNTER); + outb(PCI9111_8254_COUNTER_1 | + PCI9111_8254_READ_LOAD_LSB_MSB | + PCI9111_8254_MODE_2 | + PCI9111_8254_BINARY_COUNTER, + dev->iobase + PCI9111_REGISTER_8254_CONTROL); - pci9111_8254_control_set(PCI9111_8254_COUNTER_2 | - PCI9111_8254_READ_LOAD_LSB_MSB | - PCI9111_8254_MODE_2 | - PCI9111_8254_BINARY_COUNTER); + outb(PCI9111_8254_COUNTER_2 | + PCI9111_8254_READ_LOAD_LSB_MSB | + PCI9111_8254_MODE_2 | + PCI9111_8254_BINARY_COUNTER, + dev->iobase + PCI9111_REGISTER_8254_CONTROL); udelay(1); - pci9111_8254_counter_2_set(dev_private->timer_divisor_2); - pci9111_8254_counter_1_set(dev_private->timer_divisor_1); + outb(dev_private->timer_divisor_2 & 0xff, + dev->iobase + PCI9111_REGISTER_8254_COUNTER_2); + outb((dev_private->timer_divisor_2 >> 8) & 0xff, + dev->iobase + PCI9111_REGISTER_8254_COUNTER_2); + + outb(dev_private->timer_divisor_1 & 0xff, + dev->iobase + PCI9111_REGISTER_8254_COUNTER_1); + outb((dev_private->timer_divisor_1 >> 8) & 0xff, + dev->iobase + PCI9111_REGISTER_8254_COUNTER_1); } enum pci9111_trigger_sources { -- cgit v0.10.2 From 9d09315113192b127d79b79cc2cf1b2bb52f2337 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 18:51:49 -0700 Subject: staging: comedi: adl_pci9111: use 8253 helper functions The timer on this board is a standard 8254 compatible counter/timer. Instead of open-coding the 8254 timer io, use the helper functions provided by 8253.h. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index a8d9584..2ac81c1 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -116,22 +116,6 @@ TODO: #define PCI9111_8254_CLOCK_PERIOD_NS 500 -#define PCI9111_8254_COUNTER_0 0x00 -#define PCI9111_8254_COUNTER_1 0x40 -#define PCI9111_8254_COUNTER_2 0x80 -#define PCI9111_8254_COUNTER_LATCH 0x00 -#define PCI9111_8254_READ_LOAD_LSB_ONLY 0x10 -#define PCI9111_8254_READ_LOAD_MSB_ONLY 0x20 -#define PCI9111_8254_READ_LOAD_LSB_MSB 0x30 -#define PCI9111_8254_MODE_0 0x00 -#define PCI9111_8254_MODE_1 0x02 -#define PCI9111_8254_MODE_2 0x04 -#define PCI9111_8254_MODE_3 0x06 -#define PCI9111_8254_MODE_4 0x08 -#define PCI9111_8254_MODE_5 0x0A -#define PCI9111_8254_BINARY_COUNTER 0x00 -#define PCI9111_8254_BCD_COUNTER 0x01 - /* IO address map */ #define PCI9111_REGISTER_AD_FIFO_VALUE 0x00 /* AD Data stored @@ -148,10 +132,7 @@ TODO: #define PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK 0x0A #define PCI9111_REGISTER_SOFTWARE_TRIGGER 0x0E #define PCI9111_REGISTER_INTERRUPT_CONTROL 0x0C -#define PCI9111_REGISTER_8254_COUNTER_0 0x40 -#define PCI9111_REGISTER_8254_COUNTER_1 0x42 -#define PCI9111_REGISTER_8254_COUNTER_2 0X44 -#define PCI9111_REGISTER_8254_CONTROL 0x46 +#define PCI9111_8254_BASE_REG 0x40 #define PCI9111_REGISTER_INTERRUPT_CLEAR 0x48 #define PCI9111_TRIGGER_MASK 0x0F @@ -379,36 +360,16 @@ static void plx9050_interrupt_control(unsigned long io_base, static void pci9111_timer_set(struct comedi_device *dev) { struct pci9111_private_data *dev_private = dev->private; + unsigned long timer_base = dev->iobase + PCI9111_8254_BASE_REG; - outb(PCI9111_8254_COUNTER_0 | - PCI9111_8254_READ_LOAD_LSB_MSB | - PCI9111_8254_MODE_0 | - PCI9111_8254_BINARY_COUNTER, - dev->iobase + PCI9111_REGISTER_8254_CONTROL); - - outb(PCI9111_8254_COUNTER_1 | - PCI9111_8254_READ_LOAD_LSB_MSB | - PCI9111_8254_MODE_2 | - PCI9111_8254_BINARY_COUNTER, - dev->iobase + PCI9111_REGISTER_8254_CONTROL); - - outb(PCI9111_8254_COUNTER_2 | - PCI9111_8254_READ_LOAD_LSB_MSB | - PCI9111_8254_MODE_2 | - PCI9111_8254_BINARY_COUNTER, - dev->iobase + PCI9111_REGISTER_8254_CONTROL); + i8254_set_mode(timer_base, 1, 0, I8254_MODE0 | I8254_BINARY); + i8254_set_mode(timer_base, 1, 1, I8254_MODE2 | I8254_BINARY); + i8254_set_mode(timer_base, 1, 2, I8254_MODE2 | I8254_BINARY); udelay(1); - outb(dev_private->timer_divisor_2 & 0xff, - dev->iobase + PCI9111_REGISTER_8254_COUNTER_2); - outb((dev_private->timer_divisor_2 >> 8) & 0xff, - dev->iobase + PCI9111_REGISTER_8254_COUNTER_2); - - outb(dev_private->timer_divisor_1 & 0xff, - dev->iobase + PCI9111_REGISTER_8254_COUNTER_1); - outb((dev_private->timer_divisor_1 >> 8) & 0xff, - dev->iobase + PCI9111_REGISTER_8254_COUNTER_1); + i8254_write(timer_base, 1, 2, dev_private->timer_divisor_2); + i8254_write(timer_base, 1, 1, dev_private->timer_divisor_1); } enum pci9111_trigger_sources { -- cgit v0.10.2 From 101e490a2a2a81f41c9e82acba80a537824aa499 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 18:52:07 -0700 Subject: staging: comedi: adl_pci9111: remove pci9111_d[io]_* i/o macros These macros rely on a local variable having a specific name. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 2ac81c1..3c0b8c1 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -121,7 +121,7 @@ TODO: #define PCI9111_REGISTER_AD_FIFO_VALUE 0x00 /* AD Data stored in FIFO */ #define PCI9111_REGISTER_DA_OUTPUT 0x00 -#define PCI9111_REGISTER_DIGITAL_IO 0x02 +#define PCI9111_DIO_REG 0x02 #define PCI9111_REGISTER_EXTENDED_IO_PORTS 0x04 #define PCI9111_REGISTER_AD_CHANNEL_CONTROL 0x06 /* Channel selection */ @@ -234,11 +234,6 @@ TODO: outw(data&PCI9111_AO_RESOLUTION_MASK, \ dev->iobase + PCI9111_REGISTER_DA_OUTPUT) -#define pci9111_di_get_bits() \ - inw(dev->iobase + PCI9111_REGISTER_DIGITAL_IO) - -#define pci9111_do_set_bits(bits) \ - outw(bits, dev->iobase + PCI9111_REGISTER_DIGITAL_IO) static const struct comedi_lrange pci9111_hr_ai_range = { 5, @@ -1095,7 +1090,7 @@ static int pci9111_di_insn_bits(struct comedi_device *dev, { unsigned int bits; - bits = pci9111_di_get_bits(); + bits = inw(dev->iobase + PCI9111_DIO_REG); data[1] = bits; return insn->n; @@ -1120,7 +1115,7 @@ static int pci9111_do_insn_bits(struct comedi_device *dev, bits |= data[0] & data[1]; s->state = bits; - pci9111_do_set_bits(bits); + outw(bits, dev->iobase + PCI9111_DIO_REG); data[1] = bits; -- cgit v0.10.2 From bfa6d3b80fe578d6f930107f75b600920d7e74e0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 18:52:34 -0700 Subject: staging: comedi: adl_pci9111: cleanup pci9111_di_insn_bits() Remove the unnecessary comments and remove the unneeded local variable. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 3c0b8c1..71eebe5 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -1078,20 +1078,12 @@ static int pci9111_ao_insn_read(struct comedi_device *dev, return i; } -/* ------------------------------------------------------------------ */ -/* DIGITAL INPUT OUTPUT SECTION */ -/* ------------------------------------------------------------------ */ - -/* Digital inputs */ - static int pci9111_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_insn *insn, + unsigned int *data) { - unsigned int bits; - - bits = inw(dev->iobase + PCI9111_DIO_REG); - data[1] = bits; + data[1] = inw(dev->iobase + PCI9111_DIO_REG); return insn->n; } -- cgit v0.10.2 From 83dcfee0f2b29e689f79f259bde1c1dc34772b13 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 18:52:58 -0700 Subject: staging: comedi: adl_pci9111: cleanup pci9111_do_insn_bits() Remove the unnecessary comments. Cleanup the function to follow the comedi standard for digital outputs. The 'mask' does not need to be checked, the comedi core will make sure that it is valid based on the subdevice data. The outputs only need to be updated if the 'mask' indicates something is changing, otherwise we just need to return the current "state" of the outputs. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 71eebe5..477aa2b 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -108,7 +108,6 @@ TODO: #define PCI9111_AO_RESOLUTION_MASK 0x0FFF #define PCI9111_DI_CHANNEL_NBR 16 #define PCI9111_DO_CHANNEL_NBR 16 -#define PCI9111_DO_MASK 0xFFFF #define PCI9111_RANGE_SETTING_DELAY 10 #define PCI9111_AI_INSTANT_READ_UDELAY_US 2 @@ -1088,28 +1087,22 @@ static int pci9111_di_insn_bits(struct comedi_device *dev, return insn->n; } -/* Digital outputs */ - static int pci9111_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_insn *insn, + unsigned int *data) { - unsigned int bits; + unsigned int mask = data[0]; + unsigned int bits = data[1]; - /* Only set bits that have been masked */ - /* data[0] = mask */ - /* data[1] = bit state */ + if (mask) { + s->state &= ~mask; + s->state |= (bits & mask); - data[0] &= PCI9111_DO_MASK; - - bits = s->state; - bits &= ~data[0]; - bits |= data[0] & data[1]; - s->state = bits; - - outw(bits, dev->iobase + PCI9111_DIO_REG); + outw(s->state, dev->iobase + PCI9111_DIO_REG); + } - data[1] = bits; + data[1] = s->state; return insn->n; } -- cgit v0.10.2 From dc79022aefaba02ab85edf7df70cd35164888523 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 18:53:16 -0700 Subject: staging: comedi: adl_pci9111: remove pci9111_ao_set_data macro This macro relies on a local variable having a specific name. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 477aa2b..7d1737a 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -119,7 +119,7 @@ TODO: #define PCI9111_REGISTER_AD_FIFO_VALUE 0x00 /* AD Data stored in FIFO */ -#define PCI9111_REGISTER_DA_OUTPUT 0x00 +#define PCI9111_AO_REG 0x00 #define PCI9111_DIO_REG 0x02 #define PCI9111_REGISTER_EXTENDED_IO_PORTS 0x04 #define PCI9111_REGISTER_AD_CHANNEL_CONTROL 0x06 /* Channel @@ -229,11 +229,6 @@ TODO: &PCI9111_HR_AI_RESOLUTION_MASK) \ ^ PCI9111_HR_AI_RESOLUTION_2_CMP_BIT) -#define pci9111_ao_set_data(data) \ - outw(data&PCI9111_AO_RESOLUTION_MASK, \ - dev->iobase + PCI9111_REGISTER_DA_OUTPUT) - - static const struct comedi_lrange pci9111_hr_ai_range = { 5, { @@ -1055,7 +1050,8 @@ pci9111_ao_insn_write(struct comedi_device *dev, int i; for (i = 0; i < insn->n; i++) { - pci9111_ao_set_data(data[i]); + outw(data[i] & PCI9111_AO_RESOLUTION_MASK, + dev->iobase + PCI9111_AO_REG); dev_private->ao_readback = data[i]; } -- cgit v0.10.2 From b3450faf38294faea229fb9353498ae05b6e2075 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 18:53:33 -0700 Subject: staging: comedi: adl_pci9111: cleanup pci9111_ao_insn_read() Remove the unnecessary comments. The readback value does not need to be masked. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 7d1737a..98fb86b 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -1058,19 +1058,18 @@ pci9111_ao_insn_write(struct comedi_device *dev, return i; } -/* Analog output readback */ - static int pci9111_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_insn *insn, + unsigned int *data) { struct pci9111_private_data *dev_private = dev->private; int i; for (i = 0; i < insn->n; i++) - data[i] = dev_private->ao_readback & PCI9111_AO_RESOLUTION_MASK; + data[i] = dev_private->ao_readback; - return i; + return insn->n; } static int pci9111_di_insn_bits(struct comedi_device *dev, -- cgit v0.10.2 From 6b7044dcfc1c1df1b8858ead6456158f0d925725 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 18:53:49 -0700 Subject: staging: comedi: adl_pci9111: cleanup ao resolution The 'ao_resolution' in the boardinfo is not used. Remove it. Rename the 'ao_resolution_mask' to 'ao_maxdata', this information is copied to the ao subdevice 'maxdata'. Remove the PCI9111_AO_RESOLUTION* defines and just open-code the maxdata in the boardinfo. Remove the mask of the output data in pci9111_ao_insn_write(), the comedi core insures that the data is valid. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 98fb86b..d5226a8 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -104,8 +104,6 @@ TODO: #define PCI9111_AI_ACQUISITION_PERIOD_MIN_NS 10000 #define PCI9111_AO_CHANNEL_NBR 1 -#define PCI9111_AO_RESOLUTION 12 -#define PCI9111_AO_RESOLUTION_MASK 0x0FFF #define PCI9111_DI_CHANNEL_NBR 16 #define PCI9111_DO_CHANNEL_NBR 16 @@ -251,8 +249,7 @@ struct pci9111_board { int ao_channel_nbr; /* num of D/A chans */ int ai_resolution; /* resolution of A/D */ int ai_resolution_mask; - int ao_resolution; /* resolution of D/A */ - int ao_resolution_mask; + int ao_maxdata; const struct comedi_lrange *ai_range_list; /* rangelist for A/D */ const struct comedi_lrange *ao_range_list; /* rangelist for D/A */ unsigned int ai_acquisition_period_min_ns; @@ -266,8 +263,7 @@ static const struct pci9111_board pci9111_boards[] = { .ao_channel_nbr = PCI9111_AO_CHANNEL_NBR, .ai_resolution = PCI9111_HR_AI_RESOLUTION, .ai_resolution_mask = PCI9111_HR_AI_RESOLUTION_MASK, - .ao_resolution = PCI9111_AO_RESOLUTION, - .ao_resolution_mask = PCI9111_AO_RESOLUTION_MASK, + .ao_maxdata = 0x0fff, .ai_range_list = &pci9111_hr_ai_range, .ao_range_list = &range_bipolar10, .ai_acquisition_period_min_ns = PCI9111_AI_ACQUISITION_PERIOD_MIN_NS} @@ -1050,8 +1046,7 @@ pci9111_ao_insn_write(struct comedi_device *dev, int i; for (i = 0; i < insn->n; i++) { - outw(data[i] & PCI9111_AO_RESOLUTION_MASK, - dev->iobase + PCI9111_AO_REG); + outw(data[i], dev->iobase + PCI9111_AO_REG); dev_private->ao_readback = data[i]; } @@ -1273,7 +1268,7 @@ static int pci9111_attach(struct comedi_device *dev, s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE | SDF_COMMON; s->n_chan = board->ao_channel_nbr; - s->maxdata = board->ao_resolution_mask; + s->maxdata = board->ao_maxdata; s->len_chanlist = board->ao_channel_nbr; s->range_table = board->ao_range_list; s->insn_write = pci9111_ao_insn_write; -- cgit v0.10.2 From 2084fd19f8dbe5c47f36364e725c58eca910dcc4 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 18:54:08 -0700 Subject: staging: comedi: adl_pci9111: cleanup pci9111_ao_insn_write() Remove the unnecessary comment. Only the last data value written needs to be cached for readback. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index d5226a8..10f1b87 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -1035,22 +1035,22 @@ conversion_done: return i; } -/* Analog instant output */ - -static int -pci9111_ao_insn_write(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data) +static int pci9111_ao_insn_write(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct pci9111_private_data *dev_private = dev->private; + unsigned int val = 0; int i; for (i = 0; i < insn->n; i++) { - outw(data[i], dev->iobase + PCI9111_AO_REG); - dev_private->ao_readback = data[i]; + val = data[i]; + outw(val, dev->iobase + PCI9111_AO_REG); } + dev_private->ao_readback = val; - return i; + return insn->n; } static int pci9111_ao_insn_read(struct comedi_device *dev, -- cgit v0.10.2 From 2873ea8154b220c11f5e17222a3879925d7db506 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 18:54:26 -0700 Subject: staging: comedi: adl_pci9111: remove AI_INSN_DEBUG code This debug output should be removed in the final driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 10f1b87..1f32a26 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -979,8 +979,6 @@ static irqreturn_t pci9111_interrupt(int irq, void *p_device) /* analog instant input */ -#undef AI_INSN_DEBUG - static int pci9111_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -990,12 +988,6 @@ static int pci9111_ai_insn_read(struct comedi_device *dev, int timeout, i; -#ifdef AI_INSN_DEBUG - printk(PCI9111_DRIVER_NAME ": ai_insn set c/r/n = %2x/%2x/%2x\n", - CR_CHAN((&insn->chanspec)[0]), - CR_RANGE((&insn->chanspec)[0]), insn->n); -#endif - pci9111_ai_channel_set(CR_CHAN((&insn->chanspec)[0])); if ((pci9111_ai_range_get()) != CR_RANGE((&insn->chanspec)[0])) @@ -1026,12 +1018,6 @@ conversion_done: data[i] = pci9111_ai_get_data(); } -#ifdef AI_INSN_DEBUG - printk(PCI9111_DRIVER_NAME ": ai_insn get c/r/t = %2x/%2x/%2x\n", - pci9111_ai_channel_get(), - pci9111_ai_range_get(), pci9111_trigger_and_autoscan_get()); -#endif - return i; } -- cgit v0.10.2 From af031edf3f377b946c1d2b0d163fcf32b1041434 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 18:54:42 -0700 Subject: staging: comedi: adl_pci9111: cleanup pci9111_ai_munge() The shift, maxdata, and invert values, used to handle the 12-/16-bit analog input differences, can be calculated based on the subdevice maxdata value. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 1f32a26..3d7e720 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -809,21 +809,15 @@ static void pci9111_ai_munge(struct comedi_device *dev, unsigned int num_bytes, unsigned int start_chan_index) { - unsigned int i, num_samples = num_bytes / sizeof(short); short *array = data; - int resolution = - ((struct pci9111_board *)dev->board_ptr)->ai_resolution; - - for (i = 0; i < num_samples; i++) { - if (resolution == PCI9111_HR_AI_RESOLUTION) - array[i] = - (array[i] & PCI9111_HR_AI_RESOLUTION_MASK) ^ - PCI9111_HR_AI_RESOLUTION_2_CMP_BIT; - else - array[i] = - ((array[i] >> 4) & PCI9111_AI_RESOLUTION_MASK) ^ - PCI9111_AI_RESOLUTION_2_CMP_BIT; - } + unsigned int maxdata = s->maxdata; + unsigned int invert = (maxdata + 1) >> 1; + unsigned int shift = (maxdata == 0xffff) ? 0 : 4; + unsigned int num_samples = num_bytes / sizeof(short); + unsigned int i; + + for (i = 0; i < num_samples; i++) + array[i] = ((array[i] >> shift) & maxdata) ^ invert; } /* ------------------------------------------------------------------ */ -- cgit v0.10.2 From b5d8d11931f3b772487381e7ca89dfd6e5b4f0fd Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 18:55:04 -0700 Subject: staging: comedi: adl_pci9111: remove pci9111_{hr_, )ai* macros These macros rely on a local variable having a specific name. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 3d7e720..b009c7b 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -115,8 +115,7 @@ TODO: /* IO address map */ -#define PCI9111_REGISTER_AD_FIFO_VALUE 0x00 /* AD Data stored - in FIFO */ +#define PCI9111_AI_FIFO_REG 0x00 #define PCI9111_AO_REG 0x00 #define PCI9111_DIO_REG 0x02 #define PCI9111_REGISTER_EXTENDED_IO_PORTS 0x04 @@ -217,16 +216,6 @@ TODO: (inb(dev->iobase + PCI9111_REGISTER_RANGE_STATUS_READBACK) \ &PCI9111_RANGE_MASK) -#define pci9111_ai_get_data() \ - (((inw(dev->iobase + PCI9111_REGISTER_AD_FIFO_VALUE)>>4) \ - &PCI9111_AI_RESOLUTION_MASK) \ - ^ PCI9111_AI_RESOLUTION_2_CMP_BIT) - -#define pci9111_hr_ai_get_data() \ - ((inw(dev->iobase + PCI9111_REGISTER_AD_FIFO_VALUE) \ - &PCI9111_HR_AI_RESOLUTION_MASK) \ - ^ PCI9111_HR_AI_RESOLUTION_2_CMP_BIT) - static const struct comedi_lrange pci9111_hr_ai_range = { 5, { @@ -888,7 +877,7 @@ static irqreturn_t pci9111_interrupt(int irq, void *p_device) && !dev_private-> stop_is_none ? dev_private->stop_counter : PCI9111_FIFO_HALF_SIZE; - insw(dev->iobase + PCI9111_REGISTER_AD_FIFO_VALUE, + insw(dev->iobase + PCI9111_AI_FIFO_REG, dev_private->ai_bounce_buffer, num_samples); if (dev_private->scan_delay < 1) { @@ -1007,9 +996,13 @@ static int pci9111_ai_insn_read(struct comedi_device *dev, conversion_done: if (resolution == PCI9111_HR_AI_RESOLUTION) - data[i] = pci9111_hr_ai_get_data(); + data[i] = (inw(dev->iobase + PCI9111_AI_FIFO_REG) + & PCI9111_HR_AI_RESOLUTION_MASK) + ^ PCI9111_HR_AI_RESOLUTION_2_CMP_BIT; else - data[i] = pci9111_ai_get_data(); + data[i] = ((inw(dev->iobase + PCI9111_AI_FIFO_REG) >> 4) + & PCI9111_AI_RESOLUTION_MASK) + ^ PCI9111_AI_RESOLUTION_2_CMP_BIT; } return i; -- cgit v0.10.2 From 2f002cc9b8c5e59d3e67a184d7b1520fed9e3094 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 18:55:54 -0700 Subject: staging: comedi: adl_pci9111: cleanup ai read in pci9111_ai_insn_read() The shift, maxdata, and invert values, used to handle the 12-/16-bit analog input differences, can be calculated based on the subdevice maxdata value. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index b009c7b..0093a40 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -966,10 +966,11 @@ static int pci9111_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - int resolution = - ((struct pci9111_board *)dev->board_ptr)->ai_resolution; - - int timeout, i; + unsigned int maxdata = s->maxdata; + unsigned int invert = (maxdata + 1) >> 1; + unsigned int shift = (maxdata == 0xffff) ? 0 : 4; + int timeout; + int i; pci9111_ai_channel_set(CR_CHAN((&insn->chanspec)[0])); @@ -995,14 +996,8 @@ static int pci9111_ai_insn_read(struct comedi_device *dev, conversion_done: - if (resolution == PCI9111_HR_AI_RESOLUTION) - data[i] = (inw(dev->iobase + PCI9111_AI_FIFO_REG) - & PCI9111_HR_AI_RESOLUTION_MASK) - ^ PCI9111_HR_AI_RESOLUTION_2_CMP_BIT; - else - data[i] = ((inw(dev->iobase + PCI9111_AI_FIFO_REG) >> 4) - & PCI9111_AI_RESOLUTION_MASK) - ^ PCI9111_AI_RESOLUTION_2_CMP_BIT; + data[i] = inw(dev->iobase + PCI9111_AI_FIFO_REG); + data[i] = ((data[i] >> shift) & maxdata) ^ invert; } return i; -- cgit v0.10.2 From 05841b3638715a32daeb2ba9fe543974f2f10bd1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 18:57:42 -0700 Subject: staging: comedi: adl_pci9111: analog output subdevice is fixed The analog output subdevice is the same for all boards supported by this driver. Remove the boardinfo for it and just open-code the values in the attach function. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 0093a40..08f7e67 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -103,7 +103,6 @@ TODO: #define PCI9111_HR_AI_RESOLUTION_2_CMP_BIT 0x8000 #define PCI9111_AI_ACQUISITION_PERIOD_MIN_NS 10000 -#define PCI9111_AO_CHANNEL_NBR 1 #define PCI9111_DI_CHANNEL_NBR 16 #define PCI9111_DO_CHANNEL_NBR 16 @@ -235,12 +234,9 @@ struct pci9111_board { const char *name; /* driver name */ int device_id; int ai_channel_nbr; /* num of A/D chans */ - int ao_channel_nbr; /* num of D/A chans */ int ai_resolution; /* resolution of A/D */ int ai_resolution_mask; - int ao_maxdata; const struct comedi_lrange *ai_range_list; /* rangelist for A/D */ - const struct comedi_lrange *ao_range_list; /* rangelist for D/A */ unsigned int ai_acquisition_period_min_ns; }; @@ -249,12 +245,9 @@ static const struct pci9111_board pci9111_boards[] = { .name = "pci9111_hr", .device_id = PCI9111_HR_DEVICE_ID, .ai_channel_nbr = PCI9111_AI_CHANNEL_NBR, - .ao_channel_nbr = PCI9111_AO_CHANNEL_NBR, .ai_resolution = PCI9111_HR_AI_RESOLUTION, .ai_resolution_mask = PCI9111_HR_AI_RESOLUTION_MASK, - .ao_maxdata = 0x0fff, .ai_range_list = &pci9111_hr_ai_range, - .ao_range_list = &range_bipolar10, .ai_acquisition_period_min_ns = PCI9111_AI_ACQUISITION_PERIOD_MIN_NS} }; @@ -1233,14 +1226,14 @@ static int pci9111_attach(struct comedi_device *dev, s->munge = pci9111_ai_munge; s = &dev->subdevices[1]; - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITABLE | SDF_COMMON; - s->n_chan = board->ao_channel_nbr; - s->maxdata = board->ao_maxdata; - s->len_chanlist = board->ao_channel_nbr; - s->range_table = board->ao_range_list; - s->insn_write = pci9111_ao_insn_write; - s->insn_read = pci9111_ao_insn_read; + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITABLE | SDF_COMMON; + s->n_chan = 1; + s->maxdata = 0x0fff; + s->len_chanlist = 1; + s->range_table = &range_bipolar10; + s->insn_write = pci9111_ao_insn_write; + s->insn_read = pci9111_ao_insn_read; s = &dev->subdevices[2]; s->type = COMEDI_SUBD_DI; -- cgit v0.10.2 From 3acf31763f3e499b6ba9a1eaabb98a1922883e55 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 18:58:00 -0700 Subject: staging: comedi: adl_pci9111: digital input/output subdevices are fixed The digital input and output subdevices are the same for all boards supported by this driver. Remove the defines just open-code the values in the attach function. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 08f7e67..349ca0e 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -103,8 +103,6 @@ TODO: #define PCI9111_HR_AI_RESOLUTION_2_CMP_BIT 0x8000 #define PCI9111_AI_ACQUISITION_PERIOD_MIN_NS 10000 -#define PCI9111_DI_CHANNEL_NBR 16 -#define PCI9111_DO_CHANNEL_NBR 16 #define PCI9111_RANGE_SETTING_DELAY 10 #define PCI9111_AI_INSTANT_READ_UDELAY_US 2 @@ -1236,20 +1234,20 @@ static int pci9111_attach(struct comedi_device *dev, s->insn_read = pci9111_ao_insn_read; s = &dev->subdevices[2]; - s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE; - s->n_chan = PCI9111_DI_CHANNEL_NBR; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = pci9111_di_insn_bits; + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE; + s->n_chan = 16; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = pci9111_di_insn_bits; s = &dev->subdevices[3]; - s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = PCI9111_DO_CHANNEL_NBR; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = pci9111_do_insn_bits; + s->type = COMEDI_SUBD_DO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 16; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = pci9111_do_insn_bits; dev_private->is_valid = 1; -- cgit v0.10.2 From e6e69aa1306c5daa3f4a5e7b88b784b68b5cb00c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 18:58:29 -0700 Subject: staging: comedi: adl_pci9111: remove chanlist_len checks The chanlist_len is validated by the comedi core before calling the do_cmdtest function. Remove these redundant checks. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 349ca0e..ba8d794 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -514,16 +514,6 @@ pci9111_ai_do_cmd_test(struct comedi_device *dev, /* Step 3 : make sure arguments are trivialy compatible */ - if (cmd->chanlist_len < 1) { - cmd->chanlist_len = 1; - error++; - } - - if (cmd->chanlist_len > board->ai_channel_nbr) { - cmd->chanlist_len = board->ai_channel_nbr; - error++; - } - if ((cmd->start_src == TRIG_NOW) && (cmd->start_arg != 0)) { cmd->start_arg = 0; error++; -- cgit v0.10.2 From f212a372c2e57fa1157eebdf5b81028426bc527c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 18:58:46 -0700 Subject: staging: comedi: adl_pci9111: remove 'single' channel list check The comedi core verifies that the chanlist elements are inrange for the subdevice. Remove the redundant check in thie driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index ba8d794..98b4f5d 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -630,14 +630,6 @@ pci9111_ai_do_cmd_test(struct comedi_device *dev, error++; } } - } else { - if ((CR_CHAN(cmd->chanlist[0]) > - (board->ai_channel_nbr - 1)) - || (CR_CHAN(cmd->chanlist[0]) < 0)) { - comedi_error(dev, - "channel number is out of limits\n"); - error++; - } } } -- cgit v0.10.2 From 02baee8cd8a0465d33231c4ee01f0a572bd1e0ae Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 18:59:02 -0700 Subject: staging: comedi: adl_pci9111: analog input subdevice is fixed The analog input subdevice is the same for all boards supported by this driver. Remove the boardinfo just open-code the values in the attach function. Note: the only other board that could be supported by this driver is the ADLink PCI-9111DG board. This board has 12-bit analog inputs instead of the 16-bit inputs of the PCI-9111HR board. Unfortunately these boards share the same PCI vendor/device id. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 98b4f5d..38faa46 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -92,16 +92,6 @@ TODO: #define PCI9111_FIFO_HALF_SIZE 512 -#define PCI9111_AI_CHANNEL_NBR 16 - -#define PCI9111_AI_RESOLUTION 12 -#define PCI9111_AI_RESOLUTION_MASK 0x0FFF -#define PCI9111_AI_RESOLUTION_2_CMP_BIT 0x0800 - -#define PCI9111_HR_AI_RESOLUTION 16 -#define PCI9111_HR_AI_RESOLUTION_MASK 0xFFFF -#define PCI9111_HR_AI_RESOLUTION_2_CMP_BIT 0x8000 - #define PCI9111_AI_ACQUISITION_PERIOD_MIN_NS 10000 #define PCI9111_RANGE_SETTING_DELAY 10 @@ -231,22 +221,13 @@ static const struct comedi_lrange pci9111_hr_ai_range = { struct pci9111_board { const char *name; /* driver name */ int device_id; - int ai_channel_nbr; /* num of A/D chans */ - int ai_resolution; /* resolution of A/D */ - int ai_resolution_mask; - const struct comedi_lrange *ai_range_list; /* rangelist for A/D */ - unsigned int ai_acquisition_period_min_ns; }; static const struct pci9111_board pci9111_boards[] = { { .name = "pci9111_hr", .device_id = PCI9111_HR_DEVICE_ID, - .ai_channel_nbr = PCI9111_AI_CHANNEL_NBR, - .ai_resolution = PCI9111_HR_AI_RESOLUTION, - .ai_resolution_mask = PCI9111_HR_AI_RESOLUTION_MASK, - .ai_range_list = &pci9111_hr_ai_range, - .ai_acquisition_period_min_ns = PCI9111_AI_ACQUISITION_PERIOD_MIN_NS} + }, }; /* Private data structure */ @@ -467,7 +448,6 @@ pci9111_ai_do_cmd_test(struct comedi_device *dev, int error = 0; int range, reference; int i; - struct pci9111_board *board = (struct pci9111_board *)dev->board_ptr; /* Step 1 : check if trigger are trivialy valid */ @@ -520,8 +500,8 @@ pci9111_ai_do_cmd_test(struct comedi_device *dev, } if ((cmd->convert_src == TRIG_TIMER) && - (cmd->convert_arg < board->ai_acquisition_period_min_ns)) { - cmd->convert_arg = board->ai_acquisition_period_min_ns; + (cmd->convert_arg < PCI9111_AI_ACQUISITION_PERIOD_MIN_NS)) { + cmd->convert_arg = PCI9111_AI_ACQUISITION_PERIOD_MIN_NS; error++; } if ((cmd->convert_src == TRIG_EXT) && (cmd->convert_arg != 0)) { @@ -530,8 +510,8 @@ pci9111_ai_do_cmd_test(struct comedi_device *dev, } if ((cmd->scan_begin_src == TRIG_TIMER) && - (cmd->scan_begin_arg < board->ai_acquisition_period_min_ns)) { - cmd->scan_begin_arg = board->ai_acquisition_period_min_ns; + (cmd->scan_begin_arg < PCI9111_AI_ACQUISITION_PERIOD_MIN_NS)) { + cmd->scan_begin_arg = PCI9111_AI_ACQUISITION_PERIOD_MIN_NS; error++; } if ((cmd->scan_begin_src == TRIG_FOLLOW) @@ -1187,23 +1167,17 @@ static int pci9111_attach(struct comedi_device *dev, s = &dev->subdevices[0]; dev->read_subdev = s; - - s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_CMD_READ; - - /* TODO: Add external multiplexer data */ - /* if (devpriv->usemux) { s->n_chan = devpriv->usemux; } */ - /* else { s->n_chan = this_board->n_aichan; } */ - - s->n_chan = board->ai_channel_nbr; - s->maxdata = board->ai_resolution_mask; - s->len_chanlist = board->ai_channel_nbr; - s->range_table = board->ai_range_list; - s->cancel = pci9111_ai_cancel; - s->insn_read = pci9111_ai_insn_read; - s->do_cmdtest = pci9111_ai_do_cmd_test; - s->do_cmd = pci9111_ai_do_cmd; - s->munge = pci9111_ai_munge; + s->type = COMEDI_SUBD_AI; + s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_CMD_READ; + s->n_chan = 16; + s->maxdata = 0xffff; + s->len_chanlist = 16; + s->range_table = &pci9111_hr_ai_range; + s->cancel = pci9111_ai_cancel; + s->insn_read = pci9111_ai_insn_read; + s->do_cmdtest = pci9111_ai_do_cmd_test; + s->do_cmd = pci9111_ai_do_cmd; + s->munge = pci9111_ai_munge; s = &dev->subdevices[1]; s->type = COMEDI_SUBD_AO; -- cgit v0.10.2 From 034f8734599d87648b50195978f5f871301d2867 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 18:59:21 -0700 Subject: staging: comedi: adl_pci9111: remove the board attach noise Remove the kernel messages about the io base/range for the pci resources. Move the board attach messages to the end of the attach and use a simple/clean dev_info message for it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 38faa46..f30bcb7 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -1098,10 +1098,6 @@ static int pci9111_attach(struct comedi_device *dev, dev_private = dev->private; /* Probe the device to determine what device in the series it is. */ - - printk(KERN_ERR "comedi%d: " PCI9111_DRIVER_NAME " driver\n", - dev->minor); - pcidev = pci9111_find_pci(dev, it); if (!pcidev) return -EIO; @@ -1116,10 +1112,6 @@ static int pci9111_attach(struct comedi_device *dev, lcr_io_base = pci_resource_start(pcidev, 1); lcr_io_range = pci_resource_len(pcidev, 1); - printk - ("comedi%d: local configuration registers at address 0x%4lx [0x%4lx]\n", - dev->minor, lcr_io_base, lcr_io_range); - /* Enable PCI device and request regions */ if (comedi_pci_enable(pcidev, PCI9111_DRIVER_NAME) < 0) { printk @@ -1132,9 +1124,6 @@ static int pci9111_attach(struct comedi_device *dev, io_base = pci_resource_start(pcidev, 2); io_range = pci_resource_len(pcidev, 2); - printk(KERN_ERR "comedi%d: 6503 registers at address 0x%4lx [0x%4lx]\n", - dev->minor, io_base, io_range); - dev->iobase = io_base; dev->board_name = board->name; dev_private->io_range = io_range; @@ -1207,6 +1196,8 @@ static int pci9111_attach(struct comedi_device *dev, dev_private->is_valid = 1; + dev_info(dev->class_dev, "%s attached\n", dev->board_name); + return 0; } -- cgit v0.10.2 From f2bed9b4cbc6fa34db4e9b788c5f631fb7358ecc Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 18:59:38 -0700 Subject: staging: comedi: adl_pci9111: remove the io_range values from the private data These values are not used by the driver. Remove them. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index f30bcb7..650aa98 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -233,11 +233,8 @@ static const struct pci9111_board pci9111_boards[] = { /* Private data structure */ struct pci9111_private_data { - unsigned long io_range; /* PCI6503 io range */ - unsigned long lcr_io_base; /* Local configuration register base * address */ - unsigned long lcr_io_range; int stop_counter; int stop_is_none; @@ -1088,7 +1085,7 @@ static int pci9111_attach(struct comedi_device *dev, struct pci9111_private_data *dev_private; struct pci_dev *pcidev; struct comedi_subdevice *s; - unsigned long io_base, io_range, lcr_io_base, lcr_io_range; + unsigned long io_base, lcr_io_base; int ret; const struct pci9111_board *board; @@ -1110,7 +1107,6 @@ static int pci9111_attach(struct comedi_device *dev, * [PCI_BASE_ADDRESS #1]. */ lcr_io_base = pci_resource_start(pcidev, 1); - lcr_io_range = pci_resource_len(pcidev, 1); /* Enable PCI device and request regions */ if (comedi_pci_enable(pcidev, PCI9111_DRIVER_NAME) < 0) { @@ -1122,14 +1118,11 @@ static int pci9111_attach(struct comedi_device *dev, /* Read PCI6308 register base address [PCI_BASE_ADDRESS #2]. */ io_base = pci_resource_start(pcidev, 2); - io_range = pci_resource_len(pcidev, 2); dev->iobase = io_base; dev->board_name = board->name; - dev_private->io_range = io_range; dev_private->is_valid = 0; dev_private->lcr_io_base = lcr_io_base; - dev_private->lcr_io_range = lcr_io_range; pci9111_reset(dev); -- cgit v0.10.2 From 3e5a0ba03e2f0d7402e47620ce0fae71b44e4723 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 18:59:54 -0700 Subject: staging: comedi: adl_pci9111: use attach_pci callback Convert this PCI driver to use the comedi PCI auto config attach mechanism by adding an 'attach_pci' callback function. Since the driver does not require any external configuration options, and the legacy 'attach' callback is now optional, remove it. The boardinfo is also not needed now so remove it also. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 650aa98..0c20c8d 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -47,14 +47,7 @@ Supports: The scanned channels must be consecutive and start from 0. They must all have the same range and aref. -Configuration options: - - [0] - PCI bus number (optional) - [1] - PCI slot number (optional) - -If bus/slot is not specified, the first available PCI -device will be used. - +Configuration options: not applicable, uses PCI auto config */ /* @@ -86,10 +79,6 @@ TODO: #define PCI9111_DRIVER_NAME "adl_pci9111" #define PCI9111_HR_DEVICE_ID 0x9111 -/* TODO: Add other pci9111 board id */ - -#define PCI9111_IO_RANGE 0x0100 - #define PCI9111_FIFO_HALF_SIZE 512 #define PCI9111_AI_ACQUISITION_PERIOD_MIN_NS 10000 @@ -214,22 +203,6 @@ static const struct comedi_lrange pci9111_hr_ai_range = { } }; -/* */ -/* Board specification structure */ -/* */ - -struct pci9111_board { - const char *name; /* driver name */ - int device_id; -}; - -static const struct pci9111_board pci9111_boards[] = { - { - .name = "pci9111_hr", - .device_id = PCI9111_HR_DEVICE_ID, - }, -}; - /* Private data structure */ struct pci9111_private_data { @@ -1044,105 +1017,37 @@ static int pci9111_reset(struct comedi_device *dev) return 0; } -static struct pci_dev *pci9111_find_pci(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - struct pci_dev *pcidev = NULL; - int bus = it->options[0]; - int slot = it->options[1]; - int i; - - for_each_pci_dev(pcidev) { - if (pcidev->vendor != PCI_VENDOR_ID_ADLINK) - continue; - for (i = 0; i < ARRAY_SIZE(pci9111_boards); i++) { - if (pcidev->device != pci9111_boards[i].device_id) - continue; - if (bus || slot) { - /* requested particular bus/slot */ - if (pcidev->bus->number != bus || - PCI_SLOT(pcidev->devfn) != slot) - continue; - } - dev->board_ptr = pci9111_boards + i; - printk(KERN_ERR - "comedi%d: found %s (b:s:f=%d:%d:%d), irq=%d\n", - dev->minor, pci9111_boards[i].name, - pcidev->bus->number, PCI_SLOT(pcidev->devfn), - PCI_FUNC(pcidev->devfn), pcidev->irq); - return pcidev; - } - } - printk(KERN_ERR - "comedi%d: no supported board found! (req. bus/slot : %d/%d)\n", - dev->minor, bus, slot); - return NULL; -} - -static int pci9111_attach(struct comedi_device *dev, - struct comedi_devconfig *it) +static int pci9111_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) { struct pci9111_private_data *dev_private; - struct pci_dev *pcidev; struct comedi_subdevice *s; - unsigned long io_base, lcr_io_base; int ret; - const struct pci9111_board *board; + + comedi_set_hw_dev(dev, &pcidev->dev); + dev->board_name = dev->driver->driver_name; ret = alloc_private(dev, sizeof(*dev_private)); if (ret) return ret; dev_private = dev->private; - /* Probe the device to determine what device in the series it is. */ - pcidev = pci9111_find_pci(dev, it); - if (!pcidev) - return -EIO; - comedi_set_hw_dev(dev, &pcidev->dev); - board = (struct pci9111_board *)dev->board_ptr; - - /* TODO: Warn about non-tested boards. */ - - /* Read local configuration register base address - * [PCI_BASE_ADDRESS #1]. */ - - lcr_io_base = pci_resource_start(pcidev, 1); - - /* Enable PCI device and request regions */ - if (comedi_pci_enable(pcidev, PCI9111_DRIVER_NAME) < 0) { - printk - ("comedi%d: Failed to enable PCI device and request regions\n", - dev->minor); - return -EIO; - } - /* Read PCI6308 register base address [PCI_BASE_ADDRESS #2]. */ - - io_base = pci_resource_start(pcidev, 2); - - dev->iobase = io_base; - dev->board_name = board->name; - dev_private->is_valid = 0; - dev_private->lcr_io_base = lcr_io_base; + ret = comedi_pci_enable(pcidev, dev->board_name); + if (ret) + return ret; + dev_private->lcr_io_base = pci_resource_start(pcidev, 1); + dev->iobase = pci_resource_start(pcidev, 2); pci9111_reset(dev); - /* Irq setup */ - - dev->irq = 0; if (pcidev->irq > 0) { + ret = request_irq(dev->irq, pci9111_interrupt, + IRQF_SHARED, dev->board_name, dev); + if (ret) + return ret; dev->irq = pcidev->irq; - - if (request_irq(dev->irq, pci9111_interrupt, - IRQF_SHARED, PCI9111_DRIVER_NAME, dev) != 0) { - printk(KERN_ERR - "comedi%d: unable to allocate irq %u\n", - dev->minor, dev->irq); - return -EINVAL; - } } - /* TODO: Add external multiplexer setup (according to option[2]). */ - ret = comedi_alloc_subdevices(dev, 4); if (ret) return ret; @@ -1215,7 +1120,7 @@ static void pci9111_detach(struct comedi_device *dev) static struct comedi_driver adl_pci9111_driver = { .driver_name = "adl_pci9111", .module = THIS_MODULE, - .attach = pci9111_attach, + .attach_pci = pci9111_attach_pci, .detach = pci9111_detach, }; -- cgit v0.10.2 From 1fbc937b240db5e54be3cfa147d7efb4d72b6a1d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 19:00:11 -0700 Subject: staging: comedi: adl_pci9111: remove AI_DO_CMD_DEBUG code This debug output should be removed in the final driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 0c20c8d..f9d874b 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -375,8 +375,6 @@ static void pci9111_interrupt_source_set(struct comedi_device *dev, /* Cancel analog input autoscan */ -#undef AI_DO_CMD_DEBUG - static int pci9111_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { @@ -393,10 +391,6 @@ static int pci9111_ai_cancel(struct comedi_device *dev, pci9111_fifo_reset(); -#ifdef AI_DO_CMD_DEBUG - printk(PCI9111_DRIVER_NAME ": ai_cancel\n"); -#endif - return 0; } @@ -650,11 +644,6 @@ static int pci9111_ai_do_cmd(struct comedi_device *dev, &(async_cmd->convert_arg), async_cmd-> flags & TRIG_ROUND_MASK); -#ifdef AI_DO_CMD_DEBUG - printk(PCI9111_DRIVER_NAME ": divisors = %d, %d\n", - dev_private->timer_divisor_1, - dev_private->timer_divisor_2); -#endif pci9111_trigger_source_set(dev, software); pci9111_timer_set(dev); @@ -696,23 +685,6 @@ static int pci9111_ai_do_cmd(struct comedi_device *dev, dev_private->chunk_num_samples = dev_private->chanlist_len * (1 + dev_private->scan_delay); -#ifdef AI_DO_CMD_DEBUG - printk(PCI9111_DRIVER_NAME ": start interruptions!\n"); - printk(PCI9111_DRIVER_NAME ": trigger source = %2x\n", - pci9111_trigger_and_autoscan_get()); - printk(PCI9111_DRIVER_NAME ": irq source = %2x\n", - pci9111_interrupt_and_fifo_get()); - printk(PCI9111_DRIVER_NAME ": ai_do_cmd\n"); - printk(PCI9111_DRIVER_NAME ": stop counter = %d\n", - dev_private->stop_counter); - printk(PCI9111_DRIVER_NAME ": scan delay = %d\n", - dev_private->scan_delay); - printk(PCI9111_DRIVER_NAME ": chanlist_len = %d\n", - dev_private->chanlist_len); - printk(PCI9111_DRIVER_NAME ": chunk num samples = %d\n", - dev_private->chunk_num_samples); -#endif - return 0; } -- cgit v0.10.2 From 9852d13745bef4158e152c3b00f0678ca1b5ccb7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 19:00:29 -0700 Subject: staging: comedi: adl_pci9111: remove INTERRUPT_DEBUG code This debug output should be removed in the final driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index f9d874b..6d20e59 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -708,8 +708,6 @@ static void pci9111_ai_munge(struct comedi_device *dev, /* INTERRUPT SECTION */ /* ------------------------------------------------------------------ */ -#undef INTERRUPT_DEBUG - static irqreturn_t pci9111_interrupt(int irq, void *p_device) { struct comedi_device *dev = p_device; @@ -762,10 +760,6 @@ static irqreturn_t pci9111_interrupt(int irq, void *p_device) unsigned int num_samples; unsigned int bytes_written = 0; -#ifdef INTERRUPT_DEBUG - printk(PCI9111_DRIVER_NAME ": fifo is half full\n"); -#endif - num_samples = PCI9111_FIFO_HALF_SIZE > dev_private->stop_counter -- cgit v0.10.2 From ae479ee562cf3d7d33eebbb30e6c3105475ed5b8 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 19:00:46 -0700 Subject: staging: comedi: adl_pci9111: use local variables for the chan/range Simplify the chan/range in pci9111_ai_insn_read() by using local variables for hold the values and by just passing insn->chanspec to the CR_* macros instead of using (&insn->chanspec)[0]. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 6d20e59..0103e44 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -855,16 +855,18 @@ static int pci9111_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + unsigned int chan = CR_CHAN(insn->chanspec); + unsigned int range = CR_RANGE(insn->chanspec); unsigned int maxdata = s->maxdata; unsigned int invert = (maxdata + 1) >> 1; unsigned int shift = (maxdata == 0xffff) ? 0 : 4; int timeout; int i; - pci9111_ai_channel_set(CR_CHAN((&insn->chanspec)[0])); + pci9111_ai_channel_set(chan); - if ((pci9111_ai_range_get()) != CR_RANGE((&insn->chanspec)[0])) - pci9111_ai_range_set(CR_RANGE((&insn->chanspec)[0])); + if ((pci9111_ai_range_get()) != range) + pci9111_ai_range_set(range); pci9111_fifo_reset(); -- cgit v0.10.2 From c514bab7cc74a2235ea342a83bb643aee69a62de Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 19:01:12 -0700 Subject: staging: comedi: adl_pci9111: remove pci9111_ai_range_[gs]et macros These macros rely on a local variable having a specific name. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 0103e44..1eef86d 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -98,8 +98,8 @@ TODO: #define PCI9111_REGISTER_AD_CHANNEL_CONTROL 0x06 /* Channel selection */ #define PCI9111_REGISTER_AD_CHANNEL_READBACK 0x06 -#define PCI9111_REGISTER_INPUT_SIGNAL_RANGE 0x08 -#define PCI9111_REGISTER_RANGE_STATUS_READBACK 0x08 +#define PCI9111_AI_RANGE_REG 0x08 +#define PCI9111_RANGE_STATUS_REG 0x08 #define PCI9111_REGISTER_TRIGGER_MODE_CONTROL 0x0A #define PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK 0x0A #define PCI9111_REGISTER_SOFTWARE_TRIGGER 0x0E @@ -165,15 +165,15 @@ TODO: } while (0) #define pci9111_is_fifo_full() \ - ((inb(dev->iobase + PCI9111_REGISTER_RANGE_STATUS_READBACK)& \ + ((inb(dev->iobase + PCI9111_RANGE_STATUS_REG)& \ PCI9111_FIFO_FULL_MASK) == 0) #define pci9111_is_fifo_half_full() \ - ((inb(dev->iobase + PCI9111_REGISTER_RANGE_STATUS_READBACK)& \ + ((inb(dev->iobase + PCI9111_RANGE_STATUS_REG)& \ PCI9111_FIFO_HALF_FULL_MASK) == 0) #define pci9111_is_fifo_empty() \ - ((inb(dev->iobase + PCI9111_REGISTER_RANGE_STATUS_READBACK)& \ + ((inb(dev->iobase + PCI9111_RANGE_STATUS_REG)& \ PCI9111_FIFO_EMPTY_MASK) == 0) #define pci9111_ai_channel_set(channel) \ @@ -184,14 +184,6 @@ TODO: (inb(dev->iobase + PCI9111_REGISTER_AD_CHANNEL_READBACK) \ &PCI9111_CHANNEL_MASK) -#define pci9111_ai_range_set(range) \ - outb((range)&PCI9111_RANGE_MASK, \ - dev->iobase + PCI9111_REGISTER_INPUT_SIGNAL_RANGE) - -#define pci9111_ai_range_get() \ - (inb(dev->iobase + PCI9111_REGISTER_RANGE_STATUS_READBACK) \ - &PCI9111_RANGE_MASK) - static const struct comedi_lrange pci9111_hr_ai_range = { 5, { @@ -612,7 +604,8 @@ static int pci9111_ai_do_cmd(struct comedi_device *dev, /* Set gain */ /* This is the same gain on every channel */ - pci9111_ai_range_set(CR_RANGE(async_cmd->chanlist[0])); + outb(CR_RANGE(async_cmd->chanlist[0]) & PCI9111_RANGE_MASK, + dev->iobase + PCI9111_AI_RANGE_REG); /* Set counter */ @@ -860,13 +853,17 @@ static int pci9111_ai_insn_read(struct comedi_device *dev, unsigned int maxdata = s->maxdata; unsigned int invert = (maxdata + 1) >> 1; unsigned int shift = (maxdata == 0xffff) ? 0 : 4; + unsigned int current_range; int timeout; int i; pci9111_ai_channel_set(chan); - if ((pci9111_ai_range_get()) != range) - pci9111_ai_range_set(range); + current_range = inb(dev->iobase + PCI9111_RANGE_STATUS_REG); + if ((current_range & PCI9111_RANGE_MASK) != range) { + outb(range & PCI9111_RANGE_MASK, + dev->iobase + PCI9111_AI_RANGE_REG); + } pci9111_fifo_reset(); -- cgit v0.10.2 From 0f0bde920c3ba7333800b874260a917cc408832d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 19:01:31 -0700 Subject: staging: comedi: adl_pci9111: remove pci9111_ai_channel_[gs]et macros These macros rely on a local variable having a specific name. The comedi code makes sure the channel number is valid so the mask of PCI9111_CHANNEL_MASK can be remove. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 1eef86d..7131179 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -95,8 +95,7 @@ TODO: #define PCI9111_AO_REG 0x00 #define PCI9111_DIO_REG 0x02 #define PCI9111_REGISTER_EXTENDED_IO_PORTS 0x04 -#define PCI9111_REGISTER_AD_CHANNEL_CONTROL 0x06 /* Channel - selection */ +#define PCI9111_AI_CHANNEL_REG 0x06 #define PCI9111_REGISTER_AD_CHANNEL_READBACK 0x06 #define PCI9111_AI_RANGE_REG 0x08 #define PCI9111_RANGE_STATUS_REG 0x08 @@ -124,8 +123,6 @@ TODO: #define PCI9111_FFEN_SET_FIFO_ENABLE (0 << 2) #define PCI9111_FFEN_SET_FIFO_DISABLE (1 << 2) -#define PCI9111_CHANNEL_MASK 0x0F - #define PCI9111_RANGE_MASK 0x07 #define PCI9111_FIFO_EMPTY_MASK 0x10 #define PCI9111_FIFO_HALF_FULL_MASK 0x20 @@ -176,14 +173,6 @@ TODO: ((inb(dev->iobase + PCI9111_RANGE_STATUS_REG)& \ PCI9111_FIFO_EMPTY_MASK) == 0) -#define pci9111_ai_channel_set(channel) \ - outb((channel)&PCI9111_CHANNEL_MASK, \ - dev->iobase + PCI9111_REGISTER_AD_CHANNEL_CONTROL) - -#define pci9111_ai_channel_get() \ - (inb(dev->iobase + PCI9111_REGISTER_AD_CHANNEL_READBACK) \ - &PCI9111_CHANNEL_MASK) - static const struct comedi_lrange pci9111_hr_ai_range = { 5, { @@ -594,10 +583,12 @@ static int pci9111_ai_do_cmd(struct comedi_device *dev, /* TODO: handle the case of an external multiplexer */ if (async_cmd->chanlist_len > 1) { - pci9111_ai_channel_set((async_cmd->chanlist_len) - 1); + outb(async_cmd->chanlist_len - 1, + dev->iobase + PCI9111_AI_CHANNEL_REG); pci9111_autoscan_set(dev, true); } else { - pci9111_ai_channel_set(CR_CHAN(async_cmd->chanlist[0])); + outb(CR_CHAN(async_cmd->chanlist[0]), + dev->iobase + PCI9111_AI_CHANNEL_REG); pci9111_autoscan_set(dev, false); } @@ -857,7 +848,7 @@ static int pci9111_ai_insn_read(struct comedi_device *dev, int timeout; int i; - pci9111_ai_channel_set(chan); + outb(chan, dev->iobase + PCI9111_AI_CHANNEL_REG); current_range = inb(dev->iobase + PCI9111_RANGE_STATUS_REG); if ((current_range & PCI9111_RANGE_MASK) != range) { -- cgit v0.10.2 From 967643734582396275efd6183c2b95786993231c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 19:01:50 -0700 Subject: staging: comedi: adl_pci9111: remove pci9111_is_fifo_* macros These macros rely on a local variable having a specific name. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 7131179..ad683a7 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -161,17 +161,6 @@ TODO: dev->iobase + PCI9111_REGISTER_INTERRUPT_CONTROL); \ } while (0) -#define pci9111_is_fifo_full() \ - ((inb(dev->iobase + PCI9111_RANGE_STATUS_REG)& \ - PCI9111_FIFO_FULL_MASK) == 0) - -#define pci9111_is_fifo_half_full() \ - ((inb(dev->iobase + PCI9111_RANGE_STATUS_REG)& \ - PCI9111_FIFO_HALF_FULL_MASK) == 0) - -#define pci9111_is_fifo_empty() \ - ((inb(dev->iobase + PCI9111_RANGE_STATUS_REG)& \ - PCI9111_FIFO_EMPTY_MASK) == 0) static const struct comedi_lrange pci9111_hr_ai_range = { 5, @@ -698,6 +687,7 @@ static irqreturn_t pci9111_interrupt(int irq, void *p_device) struct pci9111_private_data *dev_private = dev->private; struct comedi_subdevice *s = dev->read_subdev; struct comedi_async *async; + unsigned int status; unsigned long irq_flags; unsigned char intcsr; @@ -729,7 +719,10 @@ static irqreturn_t pci9111_interrupt(int irq, void *p_device) (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) { /* Interrupt comes from fifo_half-full signal */ - if (pci9111_is_fifo_full()) { + status = inb(dev->iobase + PCI9111_RANGE_STATUS_REG); + + /* '0' means FIFO is full, data may have been lost */ + if (!(status & PCI9111_FIFO_FULL_MASK)) { spin_unlock_irqrestore(&dev->spinlock, irq_flags); comedi_error(dev, PCI9111_DRIVER_NAME " fifo overflow"); pci9111_interrupt_clear(); @@ -740,7 +733,8 @@ static irqreturn_t pci9111_interrupt(int irq, void *p_device) return IRQ_HANDLED; } - if (pci9111_is_fifo_half_full()) { + /* '0' means FIFO is half-full */ + if (!(status & PCI9111_FIFO_HALF_FULL_MASK)) { unsigned int num_samples; unsigned int bytes_written = 0; @@ -844,14 +838,14 @@ static int pci9111_ai_insn_read(struct comedi_device *dev, unsigned int maxdata = s->maxdata; unsigned int invert = (maxdata + 1) >> 1; unsigned int shift = (maxdata == 0xffff) ? 0 : 4; - unsigned int current_range; + unsigned int status; int timeout; int i; outb(chan, dev->iobase + PCI9111_AI_CHANNEL_REG); - current_range = inb(dev->iobase + PCI9111_RANGE_STATUS_REG); - if ((current_range & PCI9111_RANGE_MASK) != range) { + status = inb(dev->iobase + PCI9111_RANGE_STATUS_REG); + if ((status & PCI9111_RANGE_MASK) != range) { outb(range & PCI9111_RANGE_MASK, dev->iobase + PCI9111_AI_RANGE_REG); } @@ -864,7 +858,9 @@ static int pci9111_ai_insn_read(struct comedi_device *dev, timeout = PCI9111_AI_INSTANT_READ_TIMEOUT; while (timeout--) { - if (!pci9111_is_fifo_empty()) + status = inb(dev->iobase + PCI9111_RANGE_STATUS_REG); + /* '1' means FIFO is not empty */ + if (status & PCI9111_FIFO_EMPTY_MASK) goto conversion_done; } -- cgit v0.10.2 From 3eb60d7309043831d8d345bd7fc32459598ade8c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten dev Date: Mon, 10 Sep 2012 19:02:20 -0700 Subject: staging: comedi: adl_pci9111: remove pci9111_software_trigger macro This macro relies on a local variable having a specific name. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index ad683a7..78c3a89 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -101,7 +101,7 @@ TODO: #define PCI9111_RANGE_STATUS_REG 0x08 #define PCI9111_REGISTER_TRIGGER_MODE_CONTROL 0x0A #define PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK 0x0A -#define PCI9111_REGISTER_SOFTWARE_TRIGGER 0x0E +#define PCI9111_SOFTWARE_TRIGGER_REG 0x0E #define PCI9111_REGISTER_INTERRUPT_CONTROL 0x0C #define PCI9111_8254_BASE_REG 0x40 #define PCI9111_REGISTER_INTERRUPT_CLEAR 0x48 @@ -149,9 +149,6 @@ TODO: #define pci9111_interrupt_clear() \ outb(0, dev->iobase + PCI9111_REGISTER_INTERRUPT_CLEAR) -#define pci9111_software_trigger() \ - outb(0, dev->iobase + PCI9111_REGISTER_SOFTWARE_TRIGGER) - #define pci9111_fifo_reset() do { \ outb(PCI9111_FFEN_SET_FIFO_ENABLE, \ dev->iobase + PCI9111_REGISTER_INTERRUPT_CONTROL); \ @@ -853,7 +850,8 @@ static int pci9111_ai_insn_read(struct comedi_device *dev, pci9111_fifo_reset(); for (i = 0; i < insn->n; i++) { - pci9111_software_trigger(); + /* Generate a software trigger */ + outb(0, dev->iobase + PCI9111_SOFTWARE_TRIGGER_REG); timeout = PCI9111_AI_INSTANT_READ_TIMEOUT; -- cgit v0.10.2 From f123f287e03ed19a2eb6a4fd6a15908f76c9f086 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 19:02:40 -0700 Subject: staging: comedi: adl_pci9111: remove pci9111_interrupt_clear macro This macro relies on a local variable having a specific name. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 78c3a89..6e93b9e 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -104,7 +104,7 @@ TODO: #define PCI9111_SOFTWARE_TRIGGER_REG 0x0E #define PCI9111_REGISTER_INTERRUPT_CONTROL 0x0C #define PCI9111_8254_BASE_REG 0x40 -#define PCI9111_REGISTER_INTERRUPT_CLEAR 0x48 +#define PCI9111_INT_CLR_REG 0x48 #define PCI9111_TRIGGER_MASK 0x0F #define PCI9111_PTRG_OFF (0 << 3) @@ -146,9 +146,6 @@ TODO: #define pci9111_interrupt_and_fifo_set(flags) \ outb(flags, dev->iobase + PCI9111_REGISTER_INTERRUPT_CONTROL) -#define pci9111_interrupt_clear() \ - outb(0, dev->iobase + PCI9111_REGISTER_INTERRUPT_CLEAR) - #define pci9111_fifo_reset() do { \ outb(PCI9111_FFEN_SET_FIFO_ENABLE, \ dev->iobase + PCI9111_REGISTER_INTERRUPT_CONTROL); \ @@ -722,7 +719,7 @@ static irqreturn_t pci9111_interrupt(int irq, void *p_device) if (!(status & PCI9111_FIFO_FULL_MASK)) { spin_unlock_irqrestore(&dev->spinlock, irq_flags); comedi_error(dev, PCI9111_DRIVER_NAME " fifo overflow"); - pci9111_interrupt_clear(); + outb(0, dev->iobase + PCI9111_INT_CLR_REG); pci9111_ai_cancel(dev, s); async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; comedi_event(dev, s); @@ -808,10 +805,7 @@ static irqreturn_t pci9111_interrupt(int irq, void *p_device) pci9111_ai_cancel(dev, s); } - /* Very important, otherwise another interrupt request will be inserted - * and will cause driver hangs on processing interrupt event. */ - - pci9111_interrupt_clear(); + outb(0, dev->iobase + PCI9111_INT_CLR_REG); spin_unlock_irqrestore(&dev->spinlock, irq_flags); -- cgit v0.10.2 From 2959bc21ba38e9b711cd5ebf581272d3d7455444 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 19:03:00 -0700 Subject: staging: comedi: adl_pci9111: remove pci9111_interrupt_and_fifo_[sg]et macros These macros rely on a local variable having a specific name. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 6e93b9e..e2c327c 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -100,9 +100,9 @@ TODO: #define PCI9111_AI_RANGE_REG 0x08 #define PCI9111_RANGE_STATUS_REG 0x08 #define PCI9111_REGISTER_TRIGGER_MODE_CONTROL 0x0A -#define PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK 0x0A +#define PCI9111_AI_MODE_INT_RB_REG 0x0A #define PCI9111_SOFTWARE_TRIGGER_REG 0x0E -#define PCI9111_REGISTER_INTERRUPT_CONTROL 0x0C +#define PCI9111_INT_CTRL_REG 0x0C #define PCI9111_8254_BASE_REG 0x40 #define PCI9111_INT_CLR_REG 0x48 @@ -134,25 +134,18 @@ TODO: */ #define pci9111_trigger_and_autoscan_get() \ - (inb(dev->iobase + PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK)&0x0F) + (inb(dev->iobase + PCI9111_AI_MODE_INT_RB_REG)&0x0F) #define pci9111_trigger_and_autoscan_set(flags) \ outb(flags, dev->iobase + PCI9111_REGISTER_TRIGGER_MODE_CONTROL) -#define pci9111_interrupt_and_fifo_get() \ - ((inb(dev->iobase + PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK) \ - >> 4) & 0x03) - -#define pci9111_interrupt_and_fifo_set(flags) \ - outb(flags, dev->iobase + PCI9111_REGISTER_INTERRUPT_CONTROL) - #define pci9111_fifo_reset() do { \ outb(PCI9111_FFEN_SET_FIFO_ENABLE, \ - dev->iobase + PCI9111_REGISTER_INTERRUPT_CONTROL); \ + dev->iobase + PCI9111_INT_CTRL_REG); \ outb(PCI9111_FFEN_SET_FIFO_DISABLE, \ - dev->iobase + PCI9111_REGISTER_INTERRUPT_CONTROL); \ + dev->iobase + PCI9111_INT_CTRL_REG); \ outb(PCI9111_FFEN_SET_FIFO_ENABLE, \ - dev->iobase + PCI9111_REGISTER_INTERRUPT_CONTROL); \ + dev->iobase + PCI9111_INT_CTRL_REG); \ } while (0) @@ -322,15 +315,21 @@ static void pci9111_interrupt_source_set(struct comedi_device *dev, { int flags; - flags = pci9111_interrupt_and_fifo_get() & 0x04; + /* Read the current interrupt control bits */ + flags = inb(dev->iobase + PCI9111_AI_MODE_INT_RB_REG); + /* Shift the bits so they are compatible with the write register */ + flags >>= 4; + /* Mask off the ISCx bits */ + flags &= 0xc0; + /* Now set the new ISCx bits */ if (irq_0_source == irq_on_fifo_half_full) flags |= PCI9111_ISC0_SET_IRQ_ON_FIFO_HALF_FULL; if (irq_1_source == irq_on_external_trigger) flags |= PCI9111_ISC1_SET_IRQ_ON_EXT_TRG; - pci9111_interrupt_and_fifo_set(flags); + outb(flags, dev->iobase + PCI9111_INT_CTRL_REG); } /* ------------------------------------------------------------------ */ -- cgit v0.10.2 From 20614d96f0b2e0d3acd07212afdf82919ae88a94 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 19:03:19 -0700 Subject: staging: comedi: adl_pci9111: remove pci9111_trigger_and_autoscan_[sg]et macros These macros rely on a local variable having a specific name. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index e2c327c..dc37570 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -99,7 +99,7 @@ TODO: #define PCI9111_REGISTER_AD_CHANNEL_READBACK 0x06 #define PCI9111_AI_RANGE_REG 0x08 #define PCI9111_RANGE_STATUS_REG 0x08 -#define PCI9111_REGISTER_TRIGGER_MODE_CONTROL 0x0A +#define PCI9111_AI_MODE_CTRL_REG 0x0A #define PCI9111_AI_MODE_INT_RB_REG 0x0A #define PCI9111_SOFTWARE_TRIGGER_REG 0x0E #define PCI9111_INT_CTRL_REG 0x0C @@ -133,12 +133,6 @@ TODO: * Define inlined function */ -#define pci9111_trigger_and_autoscan_get() \ - (inb(dev->iobase + PCI9111_AI_MODE_INT_RB_REG)&0x0F) - -#define pci9111_trigger_and_autoscan_set(flags) \ - outb(flags, dev->iobase + PCI9111_REGISTER_TRIGGER_MODE_CONTROL) - #define pci9111_fifo_reset() do { \ outb(PCI9111_FFEN_SET_FIFO_ENABLE, \ dev->iobase + PCI9111_INT_CTRL_REG); \ @@ -256,7 +250,10 @@ static void pci9111_trigger_source_set(struct comedi_device *dev, { int flags; - flags = pci9111_trigger_and_autoscan_get() & 0x09; + /* Read the current trigger mode control bits */ + flags = inb(dev->iobase + PCI9111_AI_MODE_INT_RB_REG); + /* Mask off the EITS and TPST bits */ + flags &= 0x9; switch (source) { case software: @@ -272,31 +269,37 @@ static void pci9111_trigger_source_set(struct comedi_device *dev, break; } - pci9111_trigger_and_autoscan_set(flags); + outb(flags, dev->iobase + PCI9111_AI_MODE_CTRL_REG); } static void pci9111_pretrigger_set(struct comedi_device *dev, bool pretrigger) { int flags; - flags = pci9111_trigger_and_autoscan_get() & 0x07; + /* Read the current trigger mode control bits */ + flags = inb(dev->iobase + PCI9111_AI_MODE_INT_RB_REG); + /* Mask off the PTRG bit */ + flags &= 0x7; if (pretrigger) flags |= PCI9111_PTRG_ON; - pci9111_trigger_and_autoscan_set(flags); + outb(flags, dev->iobase + PCI9111_AI_MODE_CTRL_REG); } static void pci9111_autoscan_set(struct comedi_device *dev, bool autoscan) { int flags; - flags = pci9111_trigger_and_autoscan_get() & 0x0e; + /* Read the current trigger mode control bits */ + flags = inb(dev->iobase + PCI9111_AI_MODE_INT_RB_REG); + /* Mask off the ASCAN bit */ + flags &= 0xe; if (autoscan) flags |= PCI9111_ASCAN_ON; - pci9111_trigger_and_autoscan_set(flags); + outb(flags, dev->iobase + PCI9111_AI_MODE_CTRL_REG); } enum pci9111_ISC0_sources { -- cgit v0.10.2 From 6b228d8a23515571cba52f16df7ac2630c45fd83 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 19:03:39 -0700 Subject: staging: comedi: adl_pci9111: change pci9111_fifo_reset into a function This macro relies on a local variable having a specific name. It's used multiple places so change it into a function. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index dc37570..209e9d0 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -129,20 +129,6 @@ TODO: #define PCI9111_FIFO_FULL_MASK 0x40 #define PCI9111_AD_BUSY_MASK 0x80 -/* - * Define inlined function - */ - -#define pci9111_fifo_reset() do { \ - outb(PCI9111_FFEN_SET_FIFO_ENABLE, \ - dev->iobase + PCI9111_INT_CTRL_REG); \ - outb(PCI9111_FFEN_SET_FIFO_DISABLE, \ - dev->iobase + PCI9111_INT_CTRL_REG); \ - outb(PCI9111_FFEN_SET_FIFO_ENABLE, \ - dev->iobase + PCI9111_INT_CTRL_REG); \ - } while (0) - - static const struct comedi_lrange pci9111_hr_ai_range = { 5, { @@ -335,6 +321,16 @@ static void pci9111_interrupt_source_set(struct comedi_device *dev, outb(flags, dev->iobase + PCI9111_INT_CTRL_REG); } +static void pci9111_fifo_reset(struct comedi_device *dev) +{ + unsigned long int_ctrl_reg = dev->iobase + PCI9111_INT_CTRL_REG; + + /* To reset the FIFO, set FFEN sequence as 0 -> 1 -> 0 */ + outb(PCI9111_FFEN_SET_FIFO_ENABLE, int_ctrl_reg); + outb(PCI9111_FFEN_SET_FIFO_DISABLE, int_ctrl_reg); + outb(PCI9111_FFEN_SET_FIFO_ENABLE, int_ctrl_reg); +} + /* ------------------------------------------------------------------ */ /* HARDWARE TRIGGERED ANALOG INPUT SECTION */ /* ------------------------------------------------------------------ */ @@ -355,7 +351,7 @@ static int pci9111_ai_cancel(struct comedi_device *dev, pci9111_autoscan_set(dev, false); - pci9111_fifo_reset(); + pci9111_fifo_reset(dev); return 0; } @@ -616,7 +612,7 @@ static int pci9111_ai_do_cmd(struct comedi_device *dev, pci9111_trigger_source_set(dev, software); pci9111_timer_set(dev); - pci9111_fifo_reset(); + pci9111_fifo_reset(dev); pci9111_interrupt_source_set(dev, irq_on_fifo_half_full, irq_on_timer_tick); pci9111_trigger_source_set(dev, timer_pacer); @@ -635,7 +631,7 @@ static int pci9111_ai_do_cmd(struct comedi_device *dev, case TRIG_EXT: pci9111_trigger_source_set(dev, external); - pci9111_fifo_reset(); + pci9111_fifo_reset(dev); pci9111_interrupt_source_set(dev, irq_on_fifo_half_full, irq_on_timer_tick); plx9050_interrupt_control(dev_private->lcr_io_base, true, true, @@ -843,7 +839,7 @@ static int pci9111_ai_insn_read(struct comedi_device *dev, dev->iobase + PCI9111_AI_RANGE_REG); } - pci9111_fifo_reset(); + pci9111_fifo_reset(dev); for (i = 0; i < insn->n; i++) { /* Generate a software trigger */ @@ -860,7 +856,7 @@ static int pci9111_ai_insn_read(struct comedi_device *dev, comedi_error(dev, "A/D read timeout"); data[i] = 0; - pci9111_fifo_reset(); + pci9111_fifo_reset(dev); return -ETIME; conversion_done: -- cgit v0.10.2 From 8c7524e6f0b7d3ca70b957e032ee4f761c7deddf Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 19:04:00 -0700 Subject: staging: comedi: adl_pci9111: cleanup the io register map Finish renaming the defines for the register map. Move the bit defines so that they are associated with the register. Remove the unneeded '0' bit defines. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 209e9d0..721aaa2 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -89,45 +89,35 @@ TODO: #define PCI9111_8254_CLOCK_PERIOD_NS 500 -/* IO address map */ - -#define PCI9111_AI_FIFO_REG 0x00 -#define PCI9111_AO_REG 0x00 -#define PCI9111_DIO_REG 0x02 -#define PCI9111_REGISTER_EXTENDED_IO_PORTS 0x04 -#define PCI9111_AI_CHANNEL_REG 0x06 -#define PCI9111_REGISTER_AD_CHANNEL_READBACK 0x06 -#define PCI9111_AI_RANGE_REG 0x08 -#define PCI9111_RANGE_STATUS_REG 0x08 -#define PCI9111_AI_MODE_CTRL_REG 0x0A -#define PCI9111_AI_MODE_INT_RB_REG 0x0A -#define PCI9111_SOFTWARE_TRIGGER_REG 0x0E -#define PCI9111_INT_CTRL_REG 0x0C -#define PCI9111_8254_BASE_REG 0x40 -#define PCI9111_INT_CLR_REG 0x48 - -#define PCI9111_TRIGGER_MASK 0x0F -#define PCI9111_PTRG_OFF (0 << 3) -#define PCI9111_PTRG_ON (1 << 3) -#define PCI9111_EITS_EXTERNAL (1 << 2) -#define PCI9111_EITS_INTERNAL (0 << 2) -#define PCI9111_TPST_SOFTWARE_TRIGGER (0 << 1) -#define PCI9111_TPST_TIMER_PACER (1 << 1) -#define PCI9111_ASCAN_ON (1 << 0) -#define PCI9111_ASCAN_OFF (0 << 0) - -#define PCI9111_ISC0_SET_IRQ_ON_ENDING_OF_AD_CONVERSION (0 << 0) -#define PCI9111_ISC0_SET_IRQ_ON_FIFO_HALF_FULL (1 << 0) -#define PCI9111_ISC1_SET_IRQ_ON_TIMER_TICK (0 << 1) -#define PCI9111_ISC1_SET_IRQ_ON_EXT_TRG (1 << 1) -#define PCI9111_FFEN_SET_FIFO_ENABLE (0 << 2) -#define PCI9111_FFEN_SET_FIFO_DISABLE (1 << 2) - -#define PCI9111_RANGE_MASK 0x07 -#define PCI9111_FIFO_EMPTY_MASK 0x10 -#define PCI9111_FIFO_HALF_FULL_MASK 0x20 -#define PCI9111_FIFO_FULL_MASK 0x40 -#define PCI9111_AD_BUSY_MASK 0x80 +/* + * IO address map and bit defines + */ +#define PCI9111_AI_FIFO_REG 0x00 +#define PCI9111_AO_REG 0x00 +#define PCI9111_DIO_REG 0x02 +#define PCI9111_EDIO_REG 0x04 +#define PCI9111_AI_CHANNEL_REG 0x06 +#define PCI9111_AI_RANGE_STAT_REG 0x08 +#define PCI9111_AI_STAT_AD_BUSY (1 << 7) +#define PCI9111_AI_STAT_FF_FF (1 << 6) +#define PCI9111_AI_STAT_FF_HF (1 << 5) +#define PCI9111_AI_STAT_FF_EF (1 << 4) +#define PCI9111_AI_RANGE_MASK (7 << 0) +#define PCI9111_AI_TRIG_CTRL_REG 0x0a +#define PCI9111_AI_TRIG_CTRL_TRGEVENT (1 << 5) +#define PCI9111_AI_TRIG_CTRL_POTRG (1 << 4) +#define PCI9111_AI_TRIG_CTRL_PTRG (1 << 3) +#define PCI9111_AI_TRIG_CTRL_ETIS (1 << 2) +#define PCI9111_AI_TRIG_CTRL_TPST (1 << 1) +#define PCI9111_AI_TRIG_CTRL_ASCAN (1 << 0) +#define PCI9111_INT_CTRL_REG 0x0c +#define PCI9111_INT_CTRL_ISC2 (1 << 3) +#define PCI9111_INT_CTRL_FFEN (1 << 2) +#define PCI9111_INT_CTRL_ISC1 (1 << 1) +#define PCI9111_INT_CTRL_ISC0 (1 << 0) +#define PCI9111_SOFT_TRIG_REG 0x0e +#define PCI9111_8254_BASE_REG 0x40 +#define PCI9111_INT_CLR_REG 0x48 static const struct comedi_lrange pci9111_hr_ai_range = { 5, @@ -237,25 +227,24 @@ static void pci9111_trigger_source_set(struct comedi_device *dev, int flags; /* Read the current trigger mode control bits */ - flags = inb(dev->iobase + PCI9111_AI_MODE_INT_RB_REG); + flags = inb(dev->iobase + PCI9111_AI_TRIG_CTRL_REG); /* Mask off the EITS and TPST bits */ flags &= 0x9; switch (source) { case software: - flags |= PCI9111_EITS_INTERNAL | PCI9111_TPST_SOFTWARE_TRIGGER; break; case timer_pacer: - flags |= PCI9111_EITS_INTERNAL | PCI9111_TPST_TIMER_PACER; + flags |= PCI9111_AI_TRIG_CTRL_TPST; break; case external: - flags |= PCI9111_EITS_EXTERNAL; + flags |= PCI9111_AI_TRIG_CTRL_ETIS; break; } - outb(flags, dev->iobase + PCI9111_AI_MODE_CTRL_REG); + outb(flags, dev->iobase + PCI9111_AI_TRIG_CTRL_REG); } static void pci9111_pretrigger_set(struct comedi_device *dev, bool pretrigger) @@ -263,14 +252,14 @@ static void pci9111_pretrigger_set(struct comedi_device *dev, bool pretrigger) int flags; /* Read the current trigger mode control bits */ - flags = inb(dev->iobase + PCI9111_AI_MODE_INT_RB_REG); + flags = inb(dev->iobase + PCI9111_AI_TRIG_CTRL_REG); /* Mask off the PTRG bit */ flags &= 0x7; if (pretrigger) - flags |= PCI9111_PTRG_ON; + flags |= PCI9111_AI_TRIG_CTRL_PTRG; - outb(flags, dev->iobase + PCI9111_AI_MODE_CTRL_REG); + outb(flags, dev->iobase + PCI9111_AI_TRIG_CTRL_REG); } static void pci9111_autoscan_set(struct comedi_device *dev, bool autoscan) @@ -278,14 +267,14 @@ static void pci9111_autoscan_set(struct comedi_device *dev, bool autoscan) int flags; /* Read the current trigger mode control bits */ - flags = inb(dev->iobase + PCI9111_AI_MODE_INT_RB_REG); + flags = inb(dev->iobase + PCI9111_AI_TRIG_CTRL_REG); /* Mask off the ASCAN bit */ flags &= 0xe; if (autoscan) - flags |= PCI9111_ASCAN_ON; + flags |= PCI9111_AI_TRIG_CTRL_ASCAN; - outb(flags, dev->iobase + PCI9111_AI_MODE_CTRL_REG); + outb(flags, dev->iobase + PCI9111_AI_TRIG_CTRL_REG); } enum pci9111_ISC0_sources { @@ -305,7 +294,7 @@ static void pci9111_interrupt_source_set(struct comedi_device *dev, int flags; /* Read the current interrupt control bits */ - flags = inb(dev->iobase + PCI9111_AI_MODE_INT_RB_REG); + flags = inb(dev->iobase + PCI9111_AI_TRIG_CTRL_REG); /* Shift the bits so they are compatible with the write register */ flags >>= 4; /* Mask off the ISCx bits */ @@ -313,10 +302,10 @@ static void pci9111_interrupt_source_set(struct comedi_device *dev, /* Now set the new ISCx bits */ if (irq_0_source == irq_on_fifo_half_full) - flags |= PCI9111_ISC0_SET_IRQ_ON_FIFO_HALF_FULL; + flags |= PCI9111_INT_CTRL_ISC0; if (irq_1_source == irq_on_external_trigger) - flags |= PCI9111_ISC1_SET_IRQ_ON_EXT_TRG; + flags |= PCI9111_INT_CTRL_ISC1; outb(flags, dev->iobase + PCI9111_INT_CTRL_REG); } @@ -326,9 +315,9 @@ static void pci9111_fifo_reset(struct comedi_device *dev) unsigned long int_ctrl_reg = dev->iobase + PCI9111_INT_CTRL_REG; /* To reset the FIFO, set FFEN sequence as 0 -> 1 -> 0 */ - outb(PCI9111_FFEN_SET_FIFO_ENABLE, int_ctrl_reg); - outb(PCI9111_FFEN_SET_FIFO_DISABLE, int_ctrl_reg); - outb(PCI9111_FFEN_SET_FIFO_ENABLE, int_ctrl_reg); + outb(0, int_ctrl_reg); + outb(PCI9111_INT_CTRL_FFEN, int_ctrl_reg); + outb(0, int_ctrl_reg); } /* ------------------------------------------------------------------ */ @@ -576,8 +565,8 @@ static int pci9111_ai_do_cmd(struct comedi_device *dev, /* Set gain */ /* This is the same gain on every channel */ - outb(CR_RANGE(async_cmd->chanlist[0]) & PCI9111_RANGE_MASK, - dev->iobase + PCI9111_AI_RANGE_REG); + outb(CR_RANGE(async_cmd->chanlist[0]) & PCI9111_AI_RANGE_MASK, + dev->iobase + PCI9111_AI_RANGE_STAT_REG); /* Set counter */ @@ -711,10 +700,10 @@ static irqreturn_t pci9111_interrupt(int irq, void *p_device) (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) { /* Interrupt comes from fifo_half-full signal */ - status = inb(dev->iobase + PCI9111_RANGE_STATUS_REG); + status = inb(dev->iobase + PCI9111_AI_RANGE_STAT_REG); /* '0' means FIFO is full, data may have been lost */ - if (!(status & PCI9111_FIFO_FULL_MASK)) { + if (!(status & PCI9111_AI_STAT_FF_FF)) { spin_unlock_irqrestore(&dev->spinlock, irq_flags); comedi_error(dev, PCI9111_DRIVER_NAME " fifo overflow"); outb(0, dev->iobase + PCI9111_INT_CLR_REG); @@ -726,7 +715,7 @@ static irqreturn_t pci9111_interrupt(int irq, void *p_device) } /* '0' means FIFO is half-full */ - if (!(status & PCI9111_FIFO_HALF_FULL_MASK)) { + if (!(status & PCI9111_AI_STAT_FF_HF)) { unsigned int num_samples; unsigned int bytes_written = 0; @@ -833,24 +822,24 @@ static int pci9111_ai_insn_read(struct comedi_device *dev, outb(chan, dev->iobase + PCI9111_AI_CHANNEL_REG); - status = inb(dev->iobase + PCI9111_RANGE_STATUS_REG); - if ((status & PCI9111_RANGE_MASK) != range) { - outb(range & PCI9111_RANGE_MASK, - dev->iobase + PCI9111_AI_RANGE_REG); + status = inb(dev->iobase + PCI9111_AI_RANGE_STAT_REG); + if ((status & PCI9111_AI_RANGE_MASK) != range) { + outb(range & PCI9111_AI_RANGE_MASK, + dev->iobase + PCI9111_AI_RANGE_STAT_REG); } pci9111_fifo_reset(dev); for (i = 0; i < insn->n; i++) { /* Generate a software trigger */ - outb(0, dev->iobase + PCI9111_SOFTWARE_TRIGGER_REG); + outb(0, dev->iobase + PCI9111_SOFT_TRIG_REG); timeout = PCI9111_AI_INSTANT_READ_TIMEOUT; while (timeout--) { - status = inb(dev->iobase + PCI9111_RANGE_STATUS_REG); + status = inb(dev->iobase + PCI9111_AI_RANGE_STAT_REG); /* '1' means FIFO is not empty */ - if (status & PCI9111_FIFO_EMPTY_MASK) + if (status & PCI9111_AI_STAT_FF_EF) goto conversion_done; } -- cgit v0.10.2 From afa6ac4aa59e0255cf380d561a7c4e5ac9f33f52 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 19:04:18 -0700 Subject: staging: comedi: adl_pci9111: cleanup pci9111_hr_ai_range For aesthetic reasons, rename the symbol and fix the whitespace. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 721aaa2..b6f6c5c 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -119,15 +119,15 @@ TODO: #define PCI9111_8254_BASE_REG 0x40 #define PCI9111_INT_CLR_REG 0x48 -static const struct comedi_lrange pci9111_hr_ai_range = { +static const struct comedi_lrange pci9111_ai_range = { 5, { - BIP_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(2.5), - BIP_RANGE(1.25), - BIP_RANGE(0.625) - } + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2.5), + BIP_RANGE(1.25), + BIP_RANGE(0.625) + } }; /* Private data structure */ @@ -990,7 +990,7 @@ static int pci9111_attach_pci(struct comedi_device *dev, s->n_chan = 16; s->maxdata = 0xffff; s->len_chanlist = 16; - s->range_table = &pci9111_hr_ai_range; + s->range_table = &pci9111_ai_range; s->cancel = pci9111_ai_cancel; s->insn_read = pci9111_ai_insn_read; s->do_cmdtest = pci9111_ai_do_cmd_test; -- cgit v0.10.2 From eba16272d1e5b17788bacfb64194b79e3a6b25a3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 19:04:37 -0700 Subject: staging: comedi: adl_pci9111: cleanup timer_divisor_[12] For aesthetic reasons, rename the symbols. Remove the unnecessary () around the symbols in the calls to i8253_cascade_ns_to_timer_2div(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index b6f6c5c..fe55029 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -146,9 +146,8 @@ struct pci9111_private_data { int ao_readback; /* Last written analog output data */ - unsigned int timer_divisor_1; /* Divisor values for the 8254 timer - * pacer */ - unsigned int timer_divisor_2; + unsigned int div1; + unsigned int div2; int is_valid; /* Is device valid */ @@ -211,8 +210,8 @@ static void pci9111_timer_set(struct comedi_device *dev) udelay(1); - i8254_write(timer_base, 1, 2, dev_private->timer_divisor_2); - i8254_write(timer_base, 1, 1, dev_private->timer_divisor_1); + i8254_write(timer_base, 1, 2, dev_private->div2); + i8254_write(timer_base, 1, 1, dev_private->div1); } enum pci9111_trigger_sources { @@ -462,8 +461,8 @@ pci9111_ai_do_cmd_test(struct comedi_device *dev, if (cmd->convert_src == TRIG_TIMER) { tmp = cmd->convert_arg; i8253_cascade_ns_to_timer_2div(PCI9111_8254_CLOCK_PERIOD_NS, - &(dev_private->timer_divisor_1), - &(dev_private->timer_divisor_2), + &dev_private->div1, + &dev_private->div2, &(cmd->convert_arg), cmd->flags & TRIG_ROUND_MASK); if (tmp != cmd->convert_arg) @@ -593,8 +592,8 @@ static int pci9111_ai_do_cmd(struct comedi_device *dev, switch (async_cmd->convert_src) { case TRIG_TIMER: i8253_cascade_ns_to_timer_2div(PCI9111_8254_CLOCK_PERIOD_NS, - &(dev_private->timer_divisor_1), - &(dev_private->timer_divisor_2), + &dev_private->div1, + &dev_private->div2, &(async_cmd->convert_arg), async_cmd-> flags & TRIG_ROUND_MASK); @@ -938,11 +937,9 @@ static int pci9111_reset(struct comedi_device *dev) pci9111_pretrigger_set(dev, false); pci9111_autoscan_set(dev, false); - /* Reset 8254 chip */ - - dev_private->timer_divisor_1 = 0; - dev_private->timer_divisor_2 = 0; - + /* Reset 8254 chip */ + dev_private->div1 = 0; + dev_private->div2 = 0; pci9111_timer_set(dev); return 0; -- cgit v0.10.2 From 893be483434a364f3a01127bdbfbdab8c5331501 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Sep 2012 19:04:57 -0700 Subject: staging: comedi: adl_pci9111: remove unnecessary 'is_valid' The 'is_valid' variable in the private data is only used in the detach of the board to determine if the pci9111_reset() function can be called. That function only requires a valid dev->iobase to work. Use that for the check instead and remove the unneeded variable from the private data. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index fe55029..7cf015e 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -149,8 +149,6 @@ struct pci9111_private_data { unsigned int div1; unsigned int div2; - int is_valid; /* Is device valid */ - short ai_bounce_buffer[2 * PCI9111_FIFO_HALF_SIZE]; }; @@ -1020,8 +1018,6 @@ static int pci9111_attach_pci(struct comedi_device *dev, s->range_table = &range_digital; s->insn_bits = pci9111_do_insn_bits; - dev_private->is_valid = 1; - dev_info(dev->class_dev, "%s attached\n", dev->board_name); return 0; @@ -1030,12 +1026,9 @@ static int pci9111_attach_pci(struct comedi_device *dev, static void pci9111_detach(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - struct pci9111_private_data *dev_private = dev->private; - if (dev_private) { - if (dev_private->is_valid) - pci9111_reset(dev); - } + if (dev->iobase) + pci9111_reset(dev); if (dev->irq != 0) free_irq(dev->irq, dev); if (pcidev) { -- cgit v0.10.2 From 86f9150c90cf75448341cee69e74cbfca56e252e Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 10 Sep 2012 16:01:27 -0700 Subject: staging: "wlags49_h2" Fix typos. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlags49_h2/README.ubuntu b/drivers/staging/wlags49_h2/README.ubuntu index f1483c4..bfad7dc 100644 --- a/drivers/staging/wlags49_h2/README.ubuntu +++ b/drivers/staging/wlags49_h2/README.ubuntu @@ -46,12 +46,12 @@ If you have a card using the HERMES II.5 chip you have to make changes to the Makefile and uncomment -DHERMES25. This will build driver wlags49_h25_cs. -Note: You can detemine the type with command "pccardctrl info" +Note: You can determine the type with command "pccardctrl info" MANIFID: 0156,0002 = HERMES - not supported by this driver MANIFID: 0156,0003 = HERMES II (Wireless B) MANIFID: 0156,0004 = HERMES II.5 (Wireless B/G) -After succesfull compile type command +After successful compile type command sudo make install @@ -93,7 +93,7 @@ have to "open" the device first to get a handle and after "close" no changed; the former ioctl functions are now called before "open" and after "close", which was not expected. One of the problems was enable/ disable of interrupts in the HCF. Interrupt handling starts at "open" -so if a former "ioctl" routinge is called before "open" or after "close" +so if a former "ioctl" routine is called before "open" or after "close" then nothing should be done with interrupt switching in the HCF. Once this was solved most HCF_ASSERTS went away. @@ -120,8 +120,8 @@ include the man page. Even though setting parameters on the module does not work anymore but it provides some information about all the settings. -I have not have personal contact with Agere, but others have. Agere -agreed to make their software available under the BSD licence. +I have no personal contact with Agere, but others have. Agere +agreed to make their software available under the BSD license. This driver is based on the 7.22 version. The following was mailed by Agere to Andrey Borzenkov about this: diff --git a/drivers/staging/wlags49_h2/TODO b/drivers/staging/wlags49_h2/TODO index 94032b6..f1a4561 100644 --- a/drivers/staging/wlags49_h2/TODO +++ b/drivers/staging/wlags49_h2/TODO @@ -1,4 +1,4 @@ -First of all, the best thing would be that this driver becomes obsolte by +First of all, the best thing would be that this driver becomes obsolete by adding support for Hermes II and Hermes II.5 cards to the existing orinoco driver. The orinoco driver currently only supports Hermes I based cards. Since this will not happen by magic and has not happened until now this @@ -10,11 +10,11 @@ list. TODO: - verify against a Hermes II.5 card - - verify with WPA encription (both with H2 and H2.5 cards) + - verify with WPA encryption (both with H2 and H2.5 cards) - sometimes the card does not initialize correctly, retry mechanisms - are build in to catch most cases but not all + are built in to catch most cases but not all - once the driver runs it is very stable, but I have the impression - some the crittical sections take to long + that some of the critical sections take some time. - the driver is split into a Hermes II and a Hermes II.5 part, it would be nice to handle both with one module instead of two - review by the wireless developer community @@ -25,7 +25,7 @@ TODO: DONE: - verified against a Hermes II card (Thomson Speedtouch 110 PCMCIA card) - - verified with WEP encription + - verified with WEP encryption Please send any patches or complaints about this driver to Greg Kroah-Hartman and Cc: Henk de Groot diff --git a/drivers/staging/wlags49_h2/hcf.c b/drivers/staging/wlags49_h2/hcf.c index 4235446..4aac26d 100644 --- a/drivers/staging/wlags49_h2/hcf.c +++ b/drivers/staging/wlags49_h2/hcf.c @@ -508,7 +508,7 @@ HCF_STATIC hcf_16* BASED xxxx[ ] = { * - HCF_ACT_INT_FORCE_ON enable interrupt generation by WaveLAN NIC * - HCF_ACT_INT_OFF disable interrupt generation by WaveLAN NIC * - HCF_ACT_INT_ON compensate 1 HCF_ACT_INT_OFF, enable interrupt generation if balance reached - * - HCF_ACT_PRS_SCAN Hermes Probe Respons Scan (F102) command + * - HCF_ACT_PRS_SCAN Hermes Probe Response Scan (F102) command * - HCF_ACT_RX_ACK acknowledge non-DMA receiver to Hermes * - HCF_ACT_SCAN Hermes Inquire Scan (F101) command (non-WARP only) * - HCF_ACT_SLEEP DDS Sleep request @@ -571,7 +571,7 @@ HCF_STATIC hcf_16* BASED xxxx[ ] = { * The F/W is wokenup by the HCF when the NIC Interrupts mode are disabled, i.e. at the first HCF_ACT_INT_OFF * after going into sleep. * - * The following Miscellanuous actions are defined: + * The following Miscellaneous actions are defined: * * o HCF_ACT_RX_ACK: Receiver Acknowledgement (non-DMA, non-USB mode only) * Acking the receiver, frees the NIC memory used to hold the Rx frame and allows the F/W to @@ -579,7 +579,7 @@ HCF_STATIC hcf_16* BASED xxxx[ ] = { * If the MSF does not need access (any longer) to the current frame, e.g. because it is rejected based on the * look ahead or copied to another buffer, the receiver may be acked. Acking earlier is assumed to have the * potential of improving the performance. - * If the MSF does not explitly ack te receiver, the acking is done implicitly if: + * If the MSF does not explicitly ack the receiver, the acking is done implicitly if: * - the received frame fits in the look ahead buffer, by the hcf_service_nic call that reported the Rx frame * - if not in the above step, by hcf_rcv_msg (assuming hcf_rcv_msg is called) * - if neither of the above implicit acks nor an explicit ack by the MSF, by the first hcf_service_nic after @@ -591,9 +591,9 @@ HCF_STATIC hcf_16* BASED xxxx[ ] = { * The Inquire Tallies command requests the F/W to provide its current set of tallies. * See also hcf_get_info with CFG_TALLIES as parameter. * - * o HCF_ACT_PRS_SCAN: Inquire Probe Respons Scan command + * o HCF_ACT_PRS_SCAN: Inquire Probe Response Scan command * This command is only operational if the F/W is enabled. - * The Probe Respons Scan command starts a scan sequence. + * The Probe Response Scan command starts a scan sequence. * The HCF puts the result of this action in an MSF defined buffer (see CFG_RID_LOG_STRCT). * * o HCF_ACT_SCAN: Inquire Scan command @@ -606,7 +606,7 @@ HCF_STATIC hcf_16* BASED xxxx[ ] = { * - NIC interrupts are not disabled while required by parameter action. * - an invalid code is specified in parameter action. * - HCF_ACT_INT_ON commands outnumber the HCF_ACT_INT_OFF commands. - * - reentrancy, may be caused by calling hcf_functions without adequate protection against NIC interrupts or + * - reentrancy, may be caused by calling hcf_functions without adequate protection against NIC interrupts or * multi-threading * * - Since the HCF does not maintain status information relative to the F/W enabled state, it is not asserted @@ -625,7 +625,7 @@ HCF_STATIC hcf_16* BASED xxxx[ ] = { * change in HREG_EV_STAT matching a bit in HREG_INT_EN, i.e. not if invoked as result of another device * generating an interrupt on the shared interrupt line. * Note 1: it has been observed that under certain adverse conditions on certain platforms the writing of - * HREG_INT_EN can apparently fail, therefor it is paramount that HREG_INT_EN is written again with 0 for + * HREG_INT_EN can apparently fail, therefore it is paramount that HREG_INT_EN is written again with 0 for * each and every call to HCF_ACT_INT_OFF. * Note 2: it has been observed that under certain H/W & S/W architectures this logic is called when there is * no NIC at all. To cater for this, the value of HREG_INT_EN is validated. If the unused bit 0x0100 is set, @@ -902,7 +902,7 @@ hcf_action( IFBP ifbp, hcf_16 action ) * - A command other than Continue, Enable, Disable, Connect or Disconnect is given. * - An invalid combination of the subfields is given or a bit outside the subfields is given. * - any return code besides HCF_SUCCESS. - * - reentrancy, may be caused by calling a hcf_function without adequate protection against NIC interrupts or + * - reentrancy, may be caused by calling a hcf_function without adequate protection against NIC interrupts or * multi-threading * *.DIAGRAM @@ -1030,7 +1030,7 @@ hcf_cntl( IFBP ifbp, hcf_16 cmd ) * hcf_connect passes the MSF-defined location of the IFB to the HCF and grants or revokes access right for the * HCF to the IFB. Revoking is done by specifying HCF_DISCONNECT rather than an I/O address for the parameter * io_base. Every call of hcf_connect in "connect" mode, must eventually be followed by a call of hcf_connect - * in "disconnect" mode. Clalling hcf_connect in "connect"/"disconnect" mode can not be nested. + * in "disconnect" mode. Calling hcf_connect in "connect"/"disconnect" mode can not be nested. * The IFB address must be used as a handle with all subsequent HCF-function calls and the HCF uses the IFB * address as a handle when it performs a call(back) of an MSF-function (i.e. msf_assert). * @@ -1058,7 +1058,7 @@ hcf_cntl( IFBP ifbp, hcf_16 cmd ) * specification for S/W reset * Note 2: it turns out that on some H/W constellations, the clock to access the EEProm is not lowered * to an appropriate frequency by HREG_IO_SRESET. By giving an HCMD_INI first, this problem is worked around. - *2b: Experimentally it is determined over a wide range of F/W versions that waiting for the for Cmd bit in + *2b: Experimentally it is determined over a wide range of F/W versions that are waiting for the for Cmd bit in * Ev register gives a workable strategy. The available documentation does not give much clues. *4: clear and initialize the IFB * The HCF house keeping info is designed such that zero is the appropriate initial value for as much as diff --git a/drivers/staging/wlags49_h2/mdd.h b/drivers/staging/wlags49_h2/mdd.h index 48aa108..0c91497 100644 --- a/drivers/staging/wlags49_h2/mdd.h +++ b/drivers/staging/wlags49_h2/mdd.h @@ -652,7 +652,7 @@ XX1( CFG_SCAN, SCAN_RS_STRCT, scan_result[32] ) /*Scan results * #define CFG_CNF_WDS_ADDR6 0xFC16 //[AP] Port 6 MAC Adrs of corresponding WDS Link node #define CFG_CNF_PM_MCAST_BUF 0xFC17 //[AP] Switch for PM buffereing of Multicast Messages #define CFG_CNF_MCAST_PM_BUF CFG_CNF_PM_MCAST_BUF //name does not match H-II spec -#define CFG_CNF_REJECT_ANY 0xFC18 //[AP] Switch for PM buffereing of Multicast Messages +#define CFG_CNF_REJECT_ANY 0xFC18 //[AP] Switch for PM buffering of Multicast Messages #define CFG_CNF_ENCRYPTION 0xFC20 //select en/de-cryption of Tx/Rx messages #define CFG_CNF_AUTHENTICATION 0xFC21 //[STA] selects Authentication algorithm @@ -1004,7 +1004,7 @@ XX1( CFG_SCAN, SCAN_RS_STRCT, scan_result[32] ) /*Scan results * #define CFG_CURRENT_LINK_STATUS 0x090B //Latest link status got through 0xF200 LinkEvent /*============================================================ INFORMATION FRAMES =========================*/ -#define CFG_INFO_FRAME_MIN 0xF000 //lowest value representing an Informatio Frame +#define CFG_INFO_FRAME_MIN 0xF000 //lowest value representing an Information Frame #define CFG_TALLIES 0xF100 //Communications Tallies #define CFG_SCAN 0xF101 //Scan results diff --git a/drivers/staging/wlags49_h2/sta_h2.c b/drivers/staging/wlags49_h2/sta_h2.c index f9a3852..00dffe2 100644 --- a/drivers/staging/wlags49_h2/sta_h2.c +++ b/drivers/staging/wlags49_h2/sta_h2.c @@ -26,7 +26,7 @@ #include "hcfcfg.h" // to get hcf_16 etc defined as well as - // possible settings which inluence mdd.h or dhf.h + // possible settings which influence mdd.h or dhf.h #include "mdd.h" //to get COMP_ID_STA etc defined #include "dhf.h" //used to be "fhfmem.h", to get memblock,plugrecord, diff --git a/drivers/staging/wlags49_h2/sta_h25.c b/drivers/staging/wlags49_h2/sta_h25.c index 86ca1cd..5b6f670 100644 --- a/drivers/staging/wlags49_h2/sta_h25.c +++ b/drivers/staging/wlags49_h2/sta_h25.c @@ -25,7 +25,7 @@ #include "hcfcfg.h" // to get hcf_16 etc defined as well as - // possible settings which inluence mdd.h or dhf.h + // possible settings which influence mdd.h or dhf.h #include "mdd.h" //to get COMP_ID_STA etc defined #include "dhf.h" //used to be "fhfmem.h", to get memblock,plugrecord, diff --git a/drivers/staging/wlags49_h2/wl_enc.h b/drivers/staging/wlags49_h2/wl_enc.h index 46629f3..1804611 100644 --- a/drivers/staging/wlags49_h2/wl_enc.h +++ b/drivers/staging/wlags49_h2/wl_enc.h @@ -106,7 +106,7 @@ ENCSTRCT, *PENCSTRCT; /******************************************************************************* - * function prrottypes + * function prototypes ******************************************************************************/ int wl_wep_code( char *szCrypt, char *szDest, void *Data, int nLen ); diff --git a/drivers/staging/wlags49_h2/wl_internal.h b/drivers/staging/wlags49_h2/wl_internal.h index 480814e..b230781 100644 --- a/drivers/staging/wlags49_h2/wl_internal.h +++ b/drivers/staging/wlags49_h2/wl_internal.h @@ -838,7 +838,7 @@ typedef struct dma_strct DESC_STRCT *rx_packet[NUM_RX_DESC]; DESC_STRCT *rx_reclaim_desc, *tx_reclaim_desc; // Descriptors for host-reclaim purposes (see HCF) int tx_rsc_ind; // DMA Tx resource indicator is maintained in the MSF, not in the HCF - int rx_rsc_ind; // Also added rx rsource indicator so that cleanup can be performed if alloc fails + int rx_rsc_ind; // Also added rx resource indicator so that cleanup can be performed if alloc fails int status; } DMA_STRCT; diff --git a/drivers/staging/wlags49_h2/wl_main.c b/drivers/staging/wlags49_h2/wl_main.c index bb3733f..f5f120a 100644 --- a/drivers/staging/wlags49_h2/wl_main.c +++ b/drivers/staging/wlags49_h2/wl_main.c @@ -63,7 +63,7 @@ * constant definitions ******************************************************************************/ -/* Allow support for calling system fcns to access F/W iamge file */ +/* Allow support for calling system fcns to access F/W image file */ #define __KERNEL_SYSCALLS__ /******************************************************************************* @@ -1163,7 +1163,7 @@ int rc; CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.version_major ), CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.version_minor )); - /* now we wil get the MAC address of the card */ + /* now we will get the MAC address of the card */ lp->ltvRecord.len = 4; if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) { lp->ltvRecord.typ = CFG_NIC_MAC_ADDR; @@ -1374,7 +1374,7 @@ int wl_put_ltv_init( struct wl_private *lp ) lp->ltvRecord.len = 2; lp->ltvRecord.typ = CFG_CNTL_OPT; - /* The Card Services build must ALWAYS configure for 16-bit I/O. PCI or + /* The Card Services build must ALWAYS be configured for 16-bit I/O. PCI or CardBus can be set to either 16/32 bit I/O, or Bus Master DMA, but only for Hermes-2.5 */ #ifdef BUS_PCMCIA @@ -2474,7 +2474,7 @@ void wl_resume(struct net_device *dev) * * DESCRIPTION: * - * This function perfroms a check on the device and calls wl_remove() if + * This function performs a check on the device and calls wl_remove() if * necessary. This function can be used for all bus types, but exists mostly * for the benefit of the Card Services driver, as there are times when * wl_remove() does not get called. @@ -2596,7 +2596,7 @@ int wl_enable( struct wl_private *lp ) lp->portState = WVLAN_PORT_STATE_ENABLED; //;?bad mnemonic, NIC iso PORT #ifdef ENABLE_DMA if ( lp->use_dma ) { - wl_pci_dma_hcf_supply( lp ); //;?always succes? + wl_pci_dma_hcf_supply( lp ); //;?always successful? } #endif } @@ -2874,7 +2874,7 @@ int wl_mbx( struct wl_private *lp ) * DESCRIPTION: * * This function will perform the tedious task of endian translating all - * fields withtin a mailbox message which need translating. + * fields within a mailbox message which need translating. * * PARAMETERS: * @@ -2989,7 +2989,7 @@ void wl_endian_translate_mailbox( ltv_t *ltv ) * * DESCRIPTION: * - * This function will process the mailbox data. + * This function processes the mailbox data. * * PARAMETERS: * diff --git a/drivers/staging/wlags49_h2/wl_netdev.c b/drivers/staging/wlags49_h2/wl_netdev.c index cc56141..fb42140 100644 --- a/drivers/staging/wlags49_h2/wl_netdev.c +++ b/drivers/staging/wlags49_h2/wl_netdev.c @@ -1599,7 +1599,7 @@ void wl_wds_device_dealloc( struct wl_private *lp ) * DESCRIPTION: * * Used to start the netif queues of all the "virtual" network devices - * which repesent the WDS ports. + * which represent the WDS ports. * * PARAMETERS: * @@ -1634,7 +1634,7 @@ void wl_wds_netif_start_queue( struct wl_private *lp ) * DESCRIPTION: * * Used to stop the netif queues of all the "virtual" network devices - * which repesent the WDS ports. + * which represent the WDS ports. * * PARAMETERS: * @@ -1669,7 +1669,7 @@ void wl_wds_netif_stop_queue( struct wl_private *lp ) * DESCRIPTION: * * Used to wake the netif queues of all the "virtual" network devices - * which repesent the WDS ports. + * which represent the WDS ports. * * PARAMETERS: * @@ -1704,7 +1704,7 @@ void wl_wds_netif_wake_queue( struct wl_private *lp ) * DESCRIPTION: * * Used to signal the network layer that carrier is present on all of the - * "virtual" network devices which repesent the WDS ports. + * "virtual" network devices which represent the WDS ports. * * PARAMETERS: * @@ -1737,7 +1737,7 @@ void wl_wds_netif_carrier_on( struct wl_private *lp ) * DESCRIPTION: * * Used to signal the network layer that carrier is NOT present on all of - * the "virtual" network devices which repesent the WDS ports. + * the "virtual" network devices which represent the WDS ports. * * PARAMETERS: * diff --git a/drivers/staging/wlags49_h2/wl_pci.c b/drivers/staging/wlags49_h2/wl_pci.c index 457c7ed..a09c3ac 100644 --- a/drivers/staging/wlags49_h2/wl_pci.c +++ b/drivers/staging/wlags49_h2/wl_pci.c @@ -223,7 +223,7 @@ int wl_adapter_init_module( void ) ******************************************************************************/ void wl_adapter_cleanup_module( void ) { - //;?how comes wl_adapter_cleanup_module is located in a seemingly pci specific module + //;?how come wl_adapter_cleanup_module is located in a seemingly pci specific module DBG_FUNC( "wl_adapter_cleanup_module" ); DBG_ENTER( DbgInfo ); @@ -899,7 +899,7 @@ int wl_pci_dma_free_tx_packet( struct pci_dev *pdev, struct wl_private *lp, * DESCRIPTION: * * Allocates a single Rx packet, consisting of two descriptors and one - * contiguous buffer. THe buffer starts with the hermes-specific header. + * contiguous buffer. The buffer starts with the hermes-specific header. * One descriptor points at the start, the other at offset 0x3a of the * buffer. * diff --git a/drivers/staging/wlags49_h2/wl_wext.c b/drivers/staging/wlags49_h2/wl_wext.c index cef12f7..f553366 100644 --- a/drivers/staging/wlags49_h2/wl_wext.c +++ b/drivers/staging/wlags49_h2/wl_wext.c @@ -606,7 +606,7 @@ retry: if (retries < 10) { retries++; - /* Holding the lock too long, make a gap to allow other processes */ + /* Holding the lock too long, makes a gap to allow other processes */ wl_unlock(lp, &flags); wl_lock( lp, &flags ); @@ -618,7 +618,7 @@ retry: goto out_unlock; } - /* Holding the lock too long, make a gap to allow other processes */ + /* Holding the lock too long, makes a gap to allow other processes */ wl_unlock(lp, &flags); wl_lock( lp, &flags ); @@ -631,7 +631,7 @@ retry: } } - /* Holding the lock too long, make a gap to allow other processes */ + /* Holding the lock too long, makes a gap to allow other processes */ wl_unlock(lp, &flags); wl_lock( lp, &flags ); @@ -694,7 +694,7 @@ retry: /* Encryption */ - /* Holding the lock too long, make a gap to allow other processes */ + /* Holding the lock too long, makes a gap to allow other processes */ wl_unlock(lp, &flags); wl_lock( lp, &flags ); @@ -721,7 +721,7 @@ retry: // Retry Limits and Lifetime - NOT SUPPORTED - /* Holding the lock too long, make a gap to allow other processes */ + /* Holding the lock too long, makes a gap to allow other processes */ wl_unlock(lp, &flags); wl_lock( lp, &flags ); @@ -2646,7 +2646,7 @@ retry: DBG_TRACE( DbgInfo, "CFG_SCAN_CHANNEL result : 0x%x\n", status ); - // Holding the lock too long, make a gap to allow other processes + // Holding the lock too long, makes a gap to allow other processes wl_unlock(lp, &flags); wl_lock( lp, &flags ); @@ -2657,7 +2657,7 @@ retry: DBG_TRACE( DbgInfo, "Reset card to recover, attempt: %d\n", retries ); wl_reset( dev ); - // Holding the lock too long, make a gap to allow other processes + // Holding the lock too long, makes a gap to allow other processes wl_unlock(lp, &flags); wl_lock( lp, &flags ); @@ -2674,7 +2674,7 @@ retry: status = hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord )); - // Holding the lock too long, make a gap to allow other processes + // Holding the lock too long, makes a gap to allow other processes wl_unlock(lp, &flags); wl_lock( lp, &flags ); @@ -2682,7 +2682,7 @@ retry: /* Initiate the scan */ /* NOTE: Using HCF_ACT_SCAN has been removed, as using HCF_ACT_ACS_SCAN to - retrieve probe responses must always be used to support WPA */ + retrieve probe response must always be used to support WPA */ status = hcf_action( &( lp->hcfCtx ), HCF_ACT_ACS_SCAN ); if( status == HCF_SUCCESS ) { @@ -3055,7 +3055,7 @@ static void flush_tx(struct wl_private *lp) * Make sure that there is no data queued up in the firmware * before setting the TKIP keys. If this check is not * performed, some data may be sent out with incorrect MIC - * and cause synchronizarion errors with the AP + * and cause synchronization errors with the AP */ /* Check every 1ms for 100ms */ for (count = 0; count < 100; count++) { @@ -3655,7 +3655,7 @@ void wl_wext_event_ap( struct net_device *dev ) this event BEFORE sending the association event, as there are timing issues with the hostap supplicant. The supplicant will attempt to process an EAPOL-Key frame from an AP before receiving this information, which - is required properly process the said frame. */ + is required for a proper processed frame. */ wl_wext_event_assoc_ie( dev ); /* Get the BSSID */ -- cgit v0.10.2 From c37a1747acbfc83641338a29952fff99bff6deb0 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 10 Sep 2012 22:31:06 -0700 Subject: staging: tidspbridge: Prepare for irqs.h removal Let's define some things locally to avoid breaking build when irqs.h is removed. This is needed for the ARM common zImage support. Cc: Omar Ramirez Luna Cc: Greg Kroah-Hartman Signed-off-by: Tony Lindgren Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/tidspbridge/core/dsp-clock.c b/drivers/staging/tidspbridge/core/dsp-clock.c index c7df34e..7eac01e 100644 --- a/drivers/staging/tidspbridge/core/dsp-clock.c +++ b/drivers/staging/tidspbridge/core/dsp-clock.c @@ -16,6 +16,8 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ +#define L4_34XX_BASE 0x48000000 + #include /* ----------------------------------- Host OS */ diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index a19bf5c..012c5a0 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c @@ -415,10 +415,10 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, /* Assert RST1 i.e only the RST only for DSP megacell */ if (!status) { /* - * XXX: ioremapping MUST be removed once ctrl + * XXX: OMAP343X_CTRL_BASE ioremapping MUST be removed once ctrl * function is made available. */ - void __iomem *ctrl = ioremap(OMAP343X_CTRL_BASE, SZ_4K); + void __iomem *ctrl = ioremap(0x48002000, SZ_4K); if (!ctrl) return -ENOMEM; diff --git a/drivers/staging/tidspbridge/core/wdt.c b/drivers/staging/tidspbridge/core/wdt.c index 870f934..1ed1474 100644 --- a/drivers/staging/tidspbridge/core/wdt.c +++ b/drivers/staging/tidspbridge/core/wdt.c @@ -25,7 +25,8 @@ #include -#define OMAP34XX_WDT3_BASE (L4_PER_34XX_BASE + 0x30000) +#define OMAP34XX_WDT3_BASE (0x49000000 + 0x30000) +#define INT_34XX_WDT3_IRQ 36 static struct dsp_wdt_setting dsp_wdt; -- cgit v0.10.2 From 13b2663c95f6f30f835ef92ef51c9aff0b3f09d6 Mon Sep 17 00:00:00 2001 From: Macpaul Lin Date: Tue, 11 Sep 2012 15:55:31 +0800 Subject: staging/gdm72xx: remove camel-case vars in gdm_qos Remove camel-case variables in gdm_qos.h and gdm_qos.c Signed-off-by: Macpaul Lin Cc: Paul Stewart Cc: Ben Chan Cc: Sage Ahn Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/gdm72xx/gdm_qos.c b/drivers/staging/gdm72xx/gdm_qos.c index 80bde05..e26c6a8 100644 --- a/drivers/staging/gdm72xx/gdm_qos.c +++ b/drivers/staging/gdm72xx/gdm_qos.c @@ -106,8 +106,8 @@ void gdm_qos_init(void *nic_ptr) for (i = 0 ; i < QOS_MAX; i++) { INIT_LIST_HEAD(&qcb->qos_list[i]); - qcb->csr[i].QoSBufCount = 0; - qcb->csr[i].Enabled = 0; + qcb->csr[i].qos_buf_count = 0; + qcb->csr[i].enabled = 0; } qcb->qos_list_cnt = 0; @@ -133,8 +133,8 @@ void gdm_qos_release_list(void *nic_ptr) spin_lock_irqsave(&qcb->qos_lock, flags); for (i = 0; i < QOS_MAX; i++) { - qcb->csr[i].QoSBufCount = 0; - qcb->csr[i].Enabled = 0; + qcb->csr[i].qos_buf_count = 0; + qcb->csr[i].enabled = 0; } qcb->qos_list_cnt = 0; @@ -153,42 +153,42 @@ static u32 chk_ipv4_rule(struct gdm_wimax_csr_s *csr, u8 *Stream, u8 *port) { int i; - if (csr->ClassifierRuleEnable&IPTYPEOFSERVICE) { - if (((Stream[1] & csr->IPToSMask) < csr->IPToSLow) || - ((Stream[1] & csr->IPToSMask) > csr->IPToSHigh)) + if (csr->classifier_rule_en&IPTYPEOFSERVICE) { + if (((Stream[1] & csr->ip2s_mask) < csr->ip2s_lo) || + ((Stream[1] & csr->ip2s_mask) > csr->ip2s_hi)) return 1; } - if (csr->ClassifierRuleEnable&PROTOCOL) { - if (Stream[9] != csr->Protocol) + if (csr->classifier_rule_en&PROTOCOL) { + if (Stream[9] != csr->protocol) return 1; } - if (csr->ClassifierRuleEnable&IPMASKEDSRCADDRESS) { + if (csr->classifier_rule_en&IPMASKEDSRCADDRESS) { for (i = 0; i < 4; i++) { - if ((Stream[12 + i] & csr->IPSrcAddrMask[i]) != - (csr->IPSrcAddr[i] & csr->IPSrcAddrMask[i])) + if ((Stream[12 + i] & csr->ipsrc_addrmask[i]) != + (csr->ipsrc_addr[i] & csr->ipsrc_addrmask[i])) return 1; } } - if (csr->ClassifierRuleEnable&IPMASKEDDSTADDRESS) { + if (csr->classifier_rule_en&IPMASKEDDSTADDRESS) { for (i = 0; i < 4; i++) { - if ((Stream[16 + i] & csr->IPDstAddrMask[i]) != - (csr->IPDstAddr[i] & csr->IPDstAddrMask[i])) + if ((Stream[16 + i] & csr->ipdst_addrmask[i]) != + (csr->ipdst_addr[i] & csr->ipdst_addrmask[i])) return 1; } } - if (csr->ClassifierRuleEnable&PROTOCOLSRCPORTRANGE) { + if (csr->classifier_rule_en&PROTOCOLSRCPORTRANGE) { i = ((port[0]<<8)&0xff00)+port[1]; - if ((i < csr->SrcPortLow) || (i > csr->SrcPortHigh)) + if ((i < csr->srcport_lo) || (i > csr->srcport_hi)) return 1; } - if (csr->ClassifierRuleEnable&PROTOCOLDSTPORTRANGE) { + if (csr->classifier_rule_en&PROTOCOLDSTPORTRANGE) { i = ((port[2]<<8)&0xff00)+port[3]; - if ((i < csr->DstPortLow) || (i > csr->DstPortHigh)) + if ((i < csr->dstport_lo) || (i > csr->dstport_hi)) return 1; } @@ -208,8 +208,8 @@ static u32 get_qos_index(struct nic *nic, u8 *iph, u8 *tcpudph) if (IP_Ver == 4) { for (i = 0; i < QOS_MAX; i++) { - if (qcb->csr[i].Enabled) { - if (qcb->csr[i].ClassifierRuleEnable) { + if (qcb->csr[i].enabled) { + if (qcb->csr[i].classifier_rule_en) { if (chk_ipv4_rule(&qcb->csr[i], iph, tcpudph) == 0) return i; @@ -230,14 +230,14 @@ static u32 extract_qos_list(struct nic *nic, struct list_head *head) INIT_LIST_HEAD(head); for (i = 0; i < QOS_MAX; i++) { - if (qcb->csr[i].Enabled) { - if (qcb->csr[i].QoSBufCount < qcb->qos_limit_size) { + if (qcb->csr[i].enabled) { + if (qcb->csr[i].qos_buf_count < qcb->qos_limit_size) { if (!list_empty(&qcb->qos_list[i])) { entry = list_entry( qcb->qos_list[i].prev, struct qos_entry_s, list); list_move_tail(&entry->list, head); - qcb->csr[i].QoSBufCount++; + qcb->csr[i].qos_buf_count++; if (!list_empty(&qcb->qos_list[i])) wprintk("QoS Index(%d) is piled!!\n", i); @@ -322,8 +322,8 @@ static u32 get_csr(struct qos_cb_s *qcb, u32 SFID, int mode) if (mode) { for (i = 0; i < QOS_MAX; i++) { - if (qcb->csr[i].Enabled == 0) { - qcb->csr[i].Enabled = 1; + if (qcb->csr[i].enabled == 0) { + qcb->csr[i].enabled = 1; qcb->qos_list_cnt++; return i; } @@ -365,7 +365,7 @@ void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size) eprintk("QoS ERROR: No SF\n"); return; } - qcb->csr[index].QoSBufCount = buf[(i*5)+10]; + qcb->csr[index].qos_buf_count = buf[(i*5)+10]; } extract_qos_list(nic, &send_list); @@ -391,38 +391,38 @@ void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size) spin_lock_irqsave(&qcb->qos_lock, flags); qcb->csr[index].SFID = SFID; - qcb->csr[index].ClassifierRuleEnable = ((buf[pos++]<<8)&0xff00); - qcb->csr[index].ClassifierRuleEnable += buf[pos++]; - if (qcb->csr[index].ClassifierRuleEnable == 0) + qcb->csr[index].classifier_rule_en = ((buf[pos++]<<8)&0xff00); + qcb->csr[index].classifier_rule_en += buf[pos++]; + if (qcb->csr[index].classifier_rule_en == 0) qcb->qos_null_idx = index; - qcb->csr[index].IPToSMask = buf[pos++]; - qcb->csr[index].IPToSLow = buf[pos++]; - qcb->csr[index].IPToSHigh = buf[pos++]; - qcb->csr[index].Protocol = buf[pos++]; - qcb->csr[index].IPSrcAddrMask[0] = buf[pos++]; - qcb->csr[index].IPSrcAddrMask[1] = buf[pos++]; - qcb->csr[index].IPSrcAddrMask[2] = buf[pos++]; - qcb->csr[index].IPSrcAddrMask[3] = buf[pos++]; - qcb->csr[index].IPSrcAddr[0] = buf[pos++]; - qcb->csr[index].IPSrcAddr[1] = buf[pos++]; - qcb->csr[index].IPSrcAddr[2] = buf[pos++]; - qcb->csr[index].IPSrcAddr[3] = buf[pos++]; - qcb->csr[index].IPDstAddrMask[0] = buf[pos++]; - qcb->csr[index].IPDstAddrMask[1] = buf[pos++]; - qcb->csr[index].IPDstAddrMask[2] = buf[pos++]; - qcb->csr[index].IPDstAddrMask[3] = buf[pos++]; - qcb->csr[index].IPDstAddr[0] = buf[pos++]; - qcb->csr[index].IPDstAddr[1] = buf[pos++]; - qcb->csr[index].IPDstAddr[2] = buf[pos++]; - qcb->csr[index].IPDstAddr[3] = buf[pos++]; - qcb->csr[index].SrcPortLow = ((buf[pos++]<<8)&0xff00); - qcb->csr[index].SrcPortLow += buf[pos++]; - qcb->csr[index].SrcPortHigh = ((buf[pos++]<<8)&0xff00); - qcb->csr[index].SrcPortHigh += buf[pos++]; - qcb->csr[index].DstPortLow = ((buf[pos++]<<8)&0xff00); - qcb->csr[index].DstPortLow += buf[pos++]; - qcb->csr[index].DstPortHigh = ((buf[pos++]<<8)&0xff00); - qcb->csr[index].DstPortHigh += buf[pos++]; + qcb->csr[index].ip2s_mask = buf[pos++]; + qcb->csr[index].ip2s_lo = buf[pos++]; + qcb->csr[index].ip2s_hi = buf[pos++]; + qcb->csr[index].protocol = buf[pos++]; + qcb->csr[index].ipsrc_addrmask[0] = buf[pos++]; + qcb->csr[index].ipsrc_addrmask[1] = buf[pos++]; + qcb->csr[index].ipsrc_addrmask[2] = buf[pos++]; + qcb->csr[index].ipsrc_addrmask[3] = buf[pos++]; + qcb->csr[index].ipsrc_addr[0] = buf[pos++]; + qcb->csr[index].ipsrc_addr[1] = buf[pos++]; + qcb->csr[index].ipsrc_addr[2] = buf[pos++]; + qcb->csr[index].ipsrc_addr[3] = buf[pos++]; + qcb->csr[index].ipdst_addrmask[0] = buf[pos++]; + qcb->csr[index].ipdst_addrmask[1] = buf[pos++]; + qcb->csr[index].ipdst_addrmask[2] = buf[pos++]; + qcb->csr[index].ipdst_addrmask[3] = buf[pos++]; + qcb->csr[index].ipdst_addr[0] = buf[pos++]; + qcb->csr[index].ipdst_addr[1] = buf[pos++]; + qcb->csr[index].ipdst_addr[2] = buf[pos++]; + qcb->csr[index].ipdst_addr[3] = buf[pos++]; + qcb->csr[index].srcport_lo = ((buf[pos++]<<8)&0xff00); + qcb->csr[index].srcport_lo += buf[pos++]; + qcb->csr[index].srcport_hi = ((buf[pos++]<<8)&0xff00); + qcb->csr[index].srcport_hi += buf[pos++]; + qcb->csr[index].dstport_lo = ((buf[pos++]<<8)&0xff00); + qcb->csr[index].dstport_lo += buf[pos++]; + qcb->csr[index].dstport_hi = ((buf[pos++]<<8)&0xff00); + qcb->csr[index].dstport_hi += buf[pos++]; qcb->qos_limit_size = 254/qcb->qos_list_cnt; spin_unlock_irqrestore(&qcb->qos_lock, flags); @@ -444,7 +444,7 @@ void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size) INIT_LIST_HEAD(&free_list); spin_lock_irqsave(&qcb->qos_lock, flags); - qcb->csr[index].Enabled = 0; + qcb->csr[index].enabled = 0; qcb->qos_list_cnt--; qcb->qos_limit_size = 254/qcb->qos_list_cnt; diff --git a/drivers/staging/gdm72xx/gdm_qos.h b/drivers/staging/gdm72xx/gdm_qos.h index 33f2bd4..8f18119 100644 --- a/drivers/staging/gdm72xx/gdm_qos.h +++ b/drivers/staging/gdm72xx/gdm_qos.h @@ -20,18 +20,18 @@ #define BOOLEAN u8 -#define QOS_MAX 16 -#define IPTYPEOFSERVICE 0x8000 -#define PROTOCOL 0x4000 -#define IPMASKEDSRCADDRESS 0x2000 -#define IPMASKEDDSTADDRESS 0x1000 +#define QOS_MAX 16 +#define IPTYPEOFSERVICE 0x8000 +#define PROTOCOL 0x4000 +#define IPMASKEDSRCADDRESS 0x2000 +#define IPMASKEDDSTADDRESS 0x1000 #define PROTOCOLSRCPORTRANGE 0x800 #define PROTOCOLDSTPORTRANGE 0x400 -#define DSTMACADDR 0x200 -#define SRCMACADDR 0x100 -#define ETHERTYPE 0x80 +#define DSTMACADDR 0x200 +#define SRCMACADDR 0x100 +#define ETHERTYPE 0x80 #define IEEE802_1DUSERPRIORITY 0x40 -#define IEEE802_1QVLANID 0x10 +#define IEEE802_1QVLANID 0x10 struct gdm_wimax_csr_s { /* union{ @@ -51,28 +51,28 @@ struct gdm_wimax_csr_s { Reserved:5; } fields; } */ - BOOLEAN Enabled; - u32 SFID; - u8 QoSBufCount; - u16 ClassifierRuleEnable; - u8 IPToSLow; - u8 IPToSHigh; - u8 IPToSMask; - u8 Protocol; - u8 IPSrcAddr[16]; - u8 IPSrcAddrMask[16]; - u8 IPDstAddr[16]; - u8 IPDstAddrMask[16]; - u16 SrcPortLow; - u16 SrcPortHigh; - u16 DstPortLow; - u16 DstPortHigh; + BOOLEAN enabled; + u32 SFID; + u8 qos_buf_count; + u16 classifier_rule_en; + u8 ip2s_lo; + u8 ip2s_hi; + u8 ip2s_mask; + u8 protocol; + u8 ipsrc_addr[16]; + u8 ipsrc_addrmask[16]; + u8 ipdst_addr[16]; + u8 ipdst_addrmask[16]; + u16 srcport_lo; + u16 srcport_hi; + u16 dstport_lo; + u16 dstport_hi; }; struct qos_entry_s { - struct list_head list; - struct sk_buff *skb; - struct net_device *dev; + struct list_head list; + struct sk_buff *skb; + struct net_device *dev; }; @@ -81,7 +81,7 @@ struct qos_cb_s { u32 qos_list_cnt; u32 qos_null_idx; struct gdm_wimax_csr_s csr[QOS_MAX]; - spinlock_t qos_lock; + spinlock_t qos_lock; u32 qos_limit_size; }; -- cgit v0.10.2 From 43b9778eeb789fbfad3ce66da3bbb3440440fbb8 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 10:47:08 -0700 Subject: staging: comedi: comedi_fc: introduce cfc_check_trigger_src All of the comedi drivers that support the 'cmd' callback also require a 'do_cmdtest' callback. The do_cmdtest validates the comedi_cmd before it is executed. "Step 1" of each do_cmdtest does a trivial validation of the trigger sources by doing something like this for each trigger: int err = 0; unsigned int tmp; tmp = cmd->start_src; src &= TRIG_NOW; if (!src || tmp != src) err++; /* Test the remaining triggers similarly */ if (err) return 1; Introduce a helper function in comedi_fc to handle this boilerplate. The drivers can then just do: err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); /* Test the remaining triggers similarly */ if (err) return 1; Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/comedi_fc.h b/drivers/staging/comedi/drivers/comedi_fc.h index 4b2cfd3..1f08391 100644 --- a/drivers/staging/comedi/drivers/comedi_fc.h +++ b/drivers/staging/comedi/drivers/comedi_fc.h @@ -73,4 +73,24 @@ static inline unsigned int cfc_bytes_per_scan(struct comedi_subdevice *subd) return num_samples * bytes_per_sample(subd); } +/** + * cfc_check_trigger_src() - trivially validate a comedi_cmd trigger source + * @src: pointer to the trigger source to validate + * @flags: bitmask of valid TRIG_* for the trigger + * + * This is used in "step 1" of the do_cmdtest functions of comedi drivers + * to vaildate the comedi_cmd triggers. The mask of the @src against the + * @flags allows the userspace comedilib to pass all the comedi_cmd + * triggers as TRIG_ANY and get back a bitmask of the valid trigger sources. + */ +static inline int cfc_check_trigger_src(unsigned int *src, unsigned int flags) +{ + unsigned int orig_src = *src; + + *src = orig_src & flags; + if (*src == TRIG_INVALID || *src != orig_src) + return -EINVAL; + return 0; +} + #endif /* _COMEDI_FC_H */ -- cgit v0.10.2 From 97e01bb10a193b1d8592303d8858192ee9ea32f7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 10:47:33 -0700 Subject: staging: comedi: adl_pci9111: use cfc_check_trigger_src Remove the pci9111_check_trigger_src macro and use the helper function cfc_check_trigger_src instead. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 7cf015e..ebd819e 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -342,18 +342,9 @@ static int pci9111_ai_cancel(struct comedi_device *dev, return 0; } -/* Test analog input command */ - -#define pci9111_check_trigger_src(src, flags) do { \ - tmp = src; \ - src &= flags; \ - if (!src || tmp != src) \ - error++; \ - } while (false); - -static int -pci9111_ai_do_cmd_test(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_cmd *cmd) +static int pci9111_ai_do_cmd_test(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_cmd *cmd) { struct pci9111_private_data *dev_private = dev->private; int tmp; @@ -361,14 +352,16 @@ pci9111_ai_do_cmd_test(struct comedi_device *dev, int range, reference; int i; - /* Step 1 : check if trigger are trivialy valid */ + /* Step 1 : check if trigger are trivialy valid */ - pci9111_check_trigger_src(cmd->start_src, TRIG_NOW); - pci9111_check_trigger_src(cmd->scan_begin_src, - TRIG_TIMER | TRIG_FOLLOW | TRIG_EXT); - pci9111_check_trigger_src(cmd->convert_src, TRIG_TIMER | TRIG_EXT); - pci9111_check_trigger_src(cmd->scan_end_src, TRIG_COUNT); - pci9111_check_trigger_src(cmd->stop_src, TRIG_COUNT | TRIG_NONE); + error |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); + error |= cfc_check_trigger_src(&cmd->scan_begin_src, + TRIG_TIMER | TRIG_FOLLOW | TRIG_EXT); + error |= cfc_check_trigger_src(&cmd->convert_src, + TRIG_TIMER | TRIG_EXT); + error |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + error |= cfc_check_trigger_src(&cmd->stop_src, + TRIG_COUNT | TRIG_NONE); if (error) return 1; -- cgit v0.10.2 From 6be4173b02f85fa3d2f8610b79ea276eea86c3ac Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 10:47:52 -0700 Subject: staging: comedi: adl_pci9111: single source triggers are unique If a single source trigger passes "step 1" of the do_cmdtest function they are already unique. There is no need to recheck them. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index ebd819e..152d682 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -369,9 +369,6 @@ static int pci9111_ai_do_cmd_test(struct comedi_device *dev, /* step 2 : make sure trigger sources are unique and mutually * compatible */ - if (cmd->start_src != TRIG_NOW) - error++; - if ((cmd->scan_begin_src != TRIG_TIMER) && (cmd->scan_begin_src != TRIG_FOLLOW) && (cmd->scan_begin_src != TRIG_EXT)) @@ -388,9 +385,6 @@ static int pci9111_ai_do_cmd_test(struct comedi_device *dev, (cmd->scan_begin_src == TRIG_FOLLOW))) error++; - - if (cmd->scan_end_src != TRIG_COUNT) - error++; if ((cmd->stop_src != TRIG_COUNT) && (cmd->stop_src != TRIG_NONE)) error++; -- cgit v0.10.2 From 6c39eed00cb28d4997ddf3a7aa96a1aff48c8828 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 10:48:10 -0700 Subject: staging: comedi: comedi_fc: introduce cfc_check_trigger_is_unique "Step 2" of each do_cmdtest checks that the trigger sources are unique by doing something like this for each trigger: if (cmd->start_src != TRIG_TIMER && cmd->start_src != TRIG_FOLLOW && cmd->start_src != TRIG_EXT) err++; /* Test the remaining triggers similarly */ if (err) return 2; Introduce a helper function in comedi_fc to handle this boilerplate. The drivers can then just do: err |= cfc_check_trigger_is_unique(cmd->start_src); /* Test the remaining triggers similarly */ if (err) return 2; Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/comedi_fc.h b/drivers/staging/comedi/drivers/comedi_fc.h index 1f08391..94481c6 100644 --- a/drivers/staging/comedi/drivers/comedi_fc.h +++ b/drivers/staging/comedi/drivers/comedi_fc.h @@ -93,4 +93,16 @@ static inline int cfc_check_trigger_src(unsigned int *src, unsigned int flags) return 0; } +/** + * cfc_check_trigger_is_unique() - make sure a trigger source is unique + * @src: the trigger source to check + */ +static inline int cfc_check_trigger_is_unique(unsigned int src) +{ + /* this test is true if more than one _src bit is set */ + if ((src & (src - 1)) != 0) + return -EINVAL; + return 0; +} + #endif /* _COMEDI_FC_H */ -- cgit v0.10.2 From e990333d11d8d37d802c8c2f22acf1b0461bd7c9 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 10:48:28 -0700 Subject: staging: comedi: adl_pci9111: use cfc_check_trigger_is_unique Use the helper function cfc_check_trigger_is_unique. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 152d682..7f7efe1 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -366,27 +366,22 @@ static int pci9111_ai_do_cmd_test(struct comedi_device *dev, if (error) return 1; - /* step 2 : make sure trigger sources are unique and mutually - * compatible */ + /* Step 2a : make sure trigger sources are unique */ - if ((cmd->scan_begin_src != TRIG_TIMER) && - (cmd->scan_begin_src != TRIG_FOLLOW) && - (cmd->scan_begin_src != TRIG_EXT)) - error++; + error |= cfc_check_trigger_is_unique(cmd->scan_begin_src); + error |= cfc_check_trigger_is_unique(cmd->convert_src); + error |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ - if ((cmd->convert_src != TRIG_TIMER) && (cmd->convert_src != TRIG_EXT)) - error++; if ((cmd->convert_src == TRIG_TIMER) && !((cmd->scan_begin_src == TRIG_TIMER) || (cmd->scan_begin_src == TRIG_FOLLOW))) - error++; + error |= -EINVAL; if ((cmd->convert_src == TRIG_EXT) && !((cmd->scan_begin_src == TRIG_EXT) || (cmd->scan_begin_src == TRIG_FOLLOW))) - error++; - - if ((cmd->stop_src != TRIG_COUNT) && (cmd->stop_src != TRIG_NONE)) - error++; + error |= -EINVAL; if (error) return 2; -- cgit v0.10.2 From 499a76dc830d32fa8a0c56360b89d4596789f85e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 10:48:47 -0700 Subject: staging: comedi: adl_pci9111: remove extra i8253_cascade_ns_to_timer_2div() The comedi core always calls the 'do_cmdtest' function before it calls the 'do_cmd' function. The 'do_cmdtest' for this driver calls i8253_cascade_ns_to_timer_2div() to validate the cmd->convert_arg. This call sets the dev_private 'div1' and 'div2' values needed to program the 8254 timer. There is no need to call the i8253 function a second time in the do_cmd function. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 7f7efe1..44b01f4 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -443,7 +443,7 @@ static int pci9111_ai_do_cmd_test(struct comedi_device *dev, i8253_cascade_ns_to_timer_2div(PCI9111_8254_CLOCK_PERIOD_NS, &dev_private->div1, &dev_private->div2, - &(cmd->convert_arg), + &cmd->convert_arg, cmd->flags & TRIG_ROUND_MASK); if (tmp != cmd->convert_arg) error++; @@ -571,13 +571,6 @@ static int pci9111_ai_do_cmd(struct comedi_device *dev, dev_private->scan_delay = 0; switch (async_cmd->convert_src) { case TRIG_TIMER: - i8253_cascade_ns_to_timer_2div(PCI9111_8254_CLOCK_PERIOD_NS, - &dev_private->div1, - &dev_private->div2, - &(async_cmd->convert_arg), - async_cmd-> - flags & TRIG_ROUND_MASK); - pci9111_trigger_source_set(dev, software); pci9111_timer_set(dev); pci9111_fifo_reset(dev); -- cgit v0.10.2 From 293b048a1677162a1c23cdaa441525c2602705f2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 10:49:04 -0700 Subject: staging: comedi: adl_pci9111: remove unnecessary comments Remove some obvious comments. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 44b01f4..d2d072e 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -130,11 +130,8 @@ static const struct comedi_lrange pci9111_ai_range = { } }; -/* Private data structure */ - struct pci9111_private_data { - unsigned long lcr_io_base; /* Local configuration register base - * address */ + unsigned long lcr_io_base; int stop_counter; int stop_is_none; @@ -144,7 +141,7 @@ struct pci9111_private_data { unsigned int chunk_counter; unsigned int chunk_num_samples; - int ao_readback; /* Last written analog output data */ + int ao_readback; unsigned int div1; unsigned int div2; @@ -152,10 +149,6 @@ struct pci9111_private_data { short ai_bounce_buffer[2 * PCI9111_FIFO_HALF_SIZE]; }; -/* ------------------------------------------------------------------ */ -/* PLX9050 SECTION */ -/* ------------------------------------------------------------------ */ - #define PLX9050_REGISTER_INTERRUPT_CONTROL 0x4c #define PLX9050_LINTI1_ENABLE (1 << 0) @@ -191,12 +184,6 @@ static void plx9050_interrupt_control(unsigned long io_base, outb(flags, io_base + PLX9050_REGISTER_INTERRUPT_CONTROL); } -/* ------------------------------------------------------------------ */ -/* MISCELLANEOUS SECTION */ -/* ------------------------------------------------------------------ */ - -/* 8254 timer */ - static void pci9111_timer_set(struct comedi_device *dev) { struct pci9111_private_data *dev_private = dev->private; @@ -317,19 +304,12 @@ static void pci9111_fifo_reset(struct comedi_device *dev) outb(0, int_ctrl_reg); } -/* ------------------------------------------------------------------ */ -/* HARDWARE TRIGGERED ANALOG INPUT SECTION */ -/* ------------------------------------------------------------------ */ - -/* Cancel analog input autoscan */ - static int pci9111_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { struct pci9111_private_data *dev_private = dev->private; /* Disable interrupts */ - plx9050_interrupt_control(dev_private->lcr_io_base, true, true, true, true, false); @@ -514,8 +494,6 @@ static int pci9111_ai_do_cmd_test(struct comedi_device *dev, } -/* Analog input command */ - static int pci9111_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { @@ -630,10 +608,6 @@ static void pci9111_ai_munge(struct comedi_device *dev, array[i] = ((array[i] >> shift) & maxdata) ^ invert; } -/* ------------------------------------------------------------------ */ -/* INTERRUPT SECTION */ -/* ------------------------------------------------------------------ */ - static irqreturn_t pci9111_interrupt(int irq, void *p_device) { struct comedi_device *dev = p_device; @@ -773,12 +747,6 @@ static irqreturn_t pci9111_interrupt(int irq, void *p_device) return IRQ_HANDLED; } -/* ------------------------------------------------------------------ */ -/* INSTANT ANALOG INPUT OUTPUT SECTION */ -/* ------------------------------------------------------------------ */ - -/* analog instant input */ - static int pci9111_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -891,18 +859,11 @@ static int pci9111_do_insn_bits(struct comedi_device *dev, return insn->n; } -/* ------------------------------------------------------------------ */ -/* INITIALISATION SECTION */ -/* ------------------------------------------------------------------ */ - -/* Reset device */ - static int pci9111_reset(struct comedi_device *dev) { struct pci9111_private_data *dev_private = dev->private; /* Set trigger source to software */ - plx9050_interrupt_control(dev_private->lcr_io_base, true, true, true, true, false); -- cgit v0.10.2 From 559e9a6899cd3056764e4272681b64eb326df3f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCng=C3=B6r=20Erseymen?= Date: Tue, 11 Sep 2012 17:56:42 +0300 Subject: staging: comedi: fix brace coding style issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix coding style issues by removing unnecessary braces. Signed-off-by: Güngör Erseymen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 5e91444..2c21dbd 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -159,9 +159,8 @@ int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it) return -EBUSY; for (driv = comedi_drivers; driv; driv = driv->next) { - if (!try_module_get(driv->module)) { + if (!try_module_get(driv->module)) continue; - } if (driv->num_names) { dev->board_ptr = comedi_recognize(driv, it->board_name); if (dev->board_ptr) @@ -174,9 +173,8 @@ int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* recognize has failed if we get here */ /* report valid board names before returning error */ for (driv = comedi_drivers; driv; driv = driv->next) { - if (!try_module_get(driv->module)) { + if (!try_module_get(driv->module)) continue; - } comedi_report_boards(driv); module_put(driv->module); } -- cgit v0.10.2 From 76d2cd30b5abf1dbca274d13d14260252b5898fb Mon Sep 17 00:00:00 2001 From: J Keerthy Date: Tue, 11 Sep 2012 19:06:52 +0300 Subject: staging: omap-thermal: Correct checkpatch.pl warnings Removes checkpatch warnings on omap-bandgap.c. Signed-off-by: J Keerthy Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index c556abb..9ef44ea 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -1037,20 +1037,20 @@ static int omap_bandgap_save_ctxt(struct omap_bandgap *bg_ptr) if (OMAP_BANDGAP_HAS(bg_ptr, MODE_CONFIG)) rval->bg_mode_ctrl = omap_bandgap_readl(bg_ptr, - tsr->bgap_mode_ctrl); + tsr->bgap_mode_ctrl); if (OMAP_BANDGAP_HAS(bg_ptr, COUNTER)) rval->bg_counter = omap_bandgap_readl(bg_ptr, - tsr->bgap_counter); + tsr->bgap_counter); if (OMAP_BANDGAP_HAS(bg_ptr, TALERT)) { rval->bg_threshold = omap_bandgap_readl(bg_ptr, - tsr->bgap_threshold); + tsr->bgap_threshold); rval->bg_ctrl = omap_bandgap_readl(bg_ptr, - tsr->bgap_mask_ctrl); + tsr->bgap_mask_ctrl); } if (OMAP_BANDGAP_HAS(bg_ptr, TSHUT_CONFIG)) rval->tshut_threshold = omap_bandgap_readl(bg_ptr, - tsr->tshut_threshold); + tsr->tshut_threshold); } return 0; @@ -1074,8 +1074,9 @@ static int omap_bandgap_restore_ctxt(struct omap_bandgap *bg_ptr) if (val == 0) { if (OMAP_BANDGAP_HAS(bg_ptr, TSHUT_CONFIG)) - omap_bandgap_writel(bg_ptr, rval->tshut_threshold, - tsr->tshut_threshold); + omap_bandgap_writel(bg_ptr, + rval->tshut_threshold, + tsr->tshut_threshold); /* Force immediate temperature measurement and update * of the DTEMP field */ -- cgit v0.10.2 From cff860f5faa318bfb4a1549e0fa03d2c3c6cbe57 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Tue, 11 Sep 2012 19:06:53 +0300 Subject: staging: omap-thermal: remove checkpatch.pl warnings on data files Simple checkpatch.pl clean ups. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/omap-thermal/omap4-thermal.c b/drivers/staging/omap-thermal/omap4-thermal.c index fa9dbcd..04c02b6 100644 --- a/drivers/staging/omap-thermal/omap4-thermal.c +++ b/drivers/staging/omap-thermal/omap4-thermal.c @@ -77,15 +77,15 @@ const struct omap_bandgap_data omap4430_data = { .remove_sensor = omap_thermal_remove_sensor, .sensors = { { - .registers = &omap4430_mpu_temp_sensor_registers, - .ts_data = &omap4430_mpu_temp_sensor_data, - .domain = "cpu", - .slope = 0, - .constant = 20000, - .slope_pcb = 0, - .constant_pcb = 20000, - .register_cooling = omap_thermal_register_cpu_cooling, - .unregister_cooling = omap_thermal_unregister_cpu_cooling, + .registers = &omap4430_mpu_temp_sensor_registers, + .ts_data = &omap4430_mpu_temp_sensor_data, + .domain = "cpu", + .slope = 0, + .constant = 20000, + .slope_pcb = 0, + .constant_pcb = 20000, + .register_cooling = omap_thermal_register_cpu_cooling, + .unregister_cooling = omap_thermal_unregister_cpu_cooling, }, }, .sensor_count = 1, @@ -215,15 +215,15 @@ const struct omap_bandgap_data omap4460_data = { .remove_sensor = omap_thermal_remove_sensor, .sensors = { { - .registers = &omap4460_mpu_temp_sensor_registers, - .ts_data = &omap4460_mpu_temp_sensor_data, - .domain = "cpu", - .slope = OMAP_GRADIENT_SLOPE_4460, - .constant = OMAP_GRADIENT_CONST_4460, - .slope_pcb = OMAP_GRADIENT_SLOPE_W_PCB_4460, - .constant_pcb = OMAP_GRADIENT_CONST_W_PCB_4460, - .register_cooling = omap_thermal_register_cpu_cooling, - .unregister_cooling = omap_thermal_unregister_cpu_cooling, + .registers = &omap4460_mpu_temp_sensor_registers, + .ts_data = &omap4460_mpu_temp_sensor_data, + .domain = "cpu", + .slope = OMAP_GRADIENT_SLOPE_4460, + .constant = OMAP_GRADIENT_CONST_4460, + .slope_pcb = OMAP_GRADIENT_SLOPE_W_PCB_4460, + .constant_pcb = OMAP_GRADIENT_CONST_W_PCB_4460, + .register_cooling = omap_thermal_register_cpu_cooling, + .unregister_cooling = omap_thermal_unregister_cpu_cooling, }, }, .sensor_count = 1, @@ -244,15 +244,15 @@ const struct omap_bandgap_data omap4470_data = { .remove_sensor = omap_thermal_remove_sensor, .sensors = { { - .registers = &omap4460_mpu_temp_sensor_registers, - .ts_data = &omap4460_mpu_temp_sensor_data, - .domain = "cpu", - .slope = OMAP_GRADIENT_SLOPE_4470, - .constant = OMAP_GRADIENT_CONST_4470, - .slope_pcb = OMAP_GRADIENT_SLOPE_W_PCB_4470, - .constant_pcb = OMAP_GRADIENT_CONST_W_PCB_4470, - .register_cooling = omap_thermal_register_cpu_cooling, - .unregister_cooling = omap_thermal_unregister_cpu_cooling, + .registers = &omap4460_mpu_temp_sensor_registers, + .ts_data = &omap4460_mpu_temp_sensor_data, + .domain = "cpu", + .slope = OMAP_GRADIENT_SLOPE_4470, + .constant = OMAP_GRADIENT_CONST_4470, + .slope_pcb = OMAP_GRADIENT_SLOPE_W_PCB_4470, + .constant_pcb = OMAP_GRADIENT_CONST_W_PCB_4470, + .register_cooling = omap_thermal_register_cpu_cooling, + .unregister_cooling = omap_thermal_unregister_cpu_cooling, }, }, .sensor_count = 1, diff --git a/drivers/staging/omap-thermal/omap5-thermal.c b/drivers/staging/omap-thermal/omap5-thermal.c index 0658af2..2f3a498 100644 --- a/drivers/staging/omap-thermal/omap5-thermal.c +++ b/drivers/staging/omap-thermal/omap5-thermal.c @@ -268,29 +268,29 @@ const struct omap_bandgap_data omap5430_data = { .remove_sensor = omap_thermal_remove_sensor, .sensors = { { - .registers = &omap5430_mpu_temp_sensor_registers, - .ts_data = &omap5430_mpu_temp_sensor_data, - .domain = "cpu", - .register_cooling = omap_thermal_register_cpu_cooling, - .unregister_cooling = omap_thermal_unregister_cpu_cooling, - .slope = OMAP_GRADIENT_SLOPE_5430_CPU, - .constant = OMAP_GRADIENT_CONST_5430_CPU, - .slope_pcb = OMAP_GRADIENT_SLOPE_W_PCB_5430_CPU, - .constant_pcb = OMAP_GRADIENT_CONST_W_PCB_5430_CPU, + .registers = &omap5430_mpu_temp_sensor_registers, + .ts_data = &omap5430_mpu_temp_sensor_data, + .domain = "cpu", + .register_cooling = omap_thermal_register_cpu_cooling, + .unregister_cooling = omap_thermal_unregister_cpu_cooling, + .slope = OMAP_GRADIENT_SLOPE_5430_CPU, + .constant = OMAP_GRADIENT_CONST_5430_CPU, + .slope_pcb = OMAP_GRADIENT_SLOPE_W_PCB_5430_CPU, + .constant_pcb = OMAP_GRADIENT_CONST_W_PCB_5430_CPU, }, { - .registers = &omap5430_gpu_temp_sensor_registers, - .ts_data = &omap5430_gpu_temp_sensor_data, - .domain = "gpu", - .slope = OMAP_GRADIENT_SLOPE_5430_GPU, - .constant = OMAP_GRADIENT_CONST_5430_GPU, - .slope_pcb = OMAP_GRADIENT_SLOPE_W_PCB_5430_GPU, - .constant_pcb = OMAP_GRADIENT_CONST_W_PCB_5430_GPU, + .registers = &omap5430_gpu_temp_sensor_registers, + .ts_data = &omap5430_gpu_temp_sensor_data, + .domain = "gpu", + .slope = OMAP_GRADIENT_SLOPE_5430_GPU, + .constant = OMAP_GRADIENT_CONST_5430_GPU, + .slope_pcb = OMAP_GRADIENT_SLOPE_W_PCB_5430_GPU, + .constant_pcb = OMAP_GRADIENT_CONST_W_PCB_5430_GPU, }, { - .registers = &omap5430_core_temp_sensor_registers, - .ts_data = &omap5430_core_temp_sensor_data, - .domain = "core", + .registers = &omap5430_core_temp_sensor_registers, + .ts_data = &omap5430_core_temp_sensor_data, + .domain = "core", }, }, .sensor_count = 3, -- cgit v0.10.2 From 765a1939a364d121e70b452c3df34c2af446f47a Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Tue, 11 Sep 2012 19:06:54 +0300 Subject: staging: omap-thermal: fix polling period settings While registering the omap thermal zones we need to properly specify TC1 and TC2, as long as the proper passive polling period and monitor period. This patch fixes the parameters passed while registering the thermal zone. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/omap-thermal/omap-thermal-common.c b/drivers/staging/omap-thermal/omap-thermal-common.c index 0675a5e..d156424 100644 --- a/drivers/staging/omap-thermal/omap-thermal-common.c +++ b/drivers/staging/omap-thermal/omap-thermal-common.c @@ -246,7 +246,9 @@ int omap_thermal_expose_sensor(struct omap_bandgap *bg_ptr, int id, /* Create thermal zone */ data->omap_thermal = thermal_zone_device_register(domain, OMAP_TRIP_NUMBER, 0, data, &omap_thermal_ops, - 0, FAST_TEMP_MONITORING_RATE, 0, 0); + 1, 2, /*TODO: remove this when FW allows */ + FAST_TEMP_MONITORING_RATE, + FAST_TEMP_MONITORING_RATE); if (IS_ERR_OR_NULL(data->omap_thermal)) { dev_err(bg_ptr->dev, "thermal zone device is NULL\n"); return PTR_ERR(data->omap_thermal); -- cgit v0.10.2 From 04a4d10d07b1017eadef721fcd5a3937e2e1be53 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Tue, 11 Sep 2012 19:06:55 +0300 Subject: staging: omap-thermal: improve conf data handling and initialization While registering the thermal zone, it is required to have the cooling devices already setup, so that the .bind callback can succeed. Due to that, the driver code needs to be reorganized so that we first setup the cooling devices then the zones. This way we cope with the right thermal framework initialization sequence. This patch changes the order of the thermal zone initialization, so that we create it only when the cooling devices are available. It also adds some defensive checks for the config data, so that the callbacks are ready for calls when the data is still not initialized. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index 9ef44ea..ff93c15 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -953,12 +953,12 @@ int __devinit omap_bandgap_probe(struct platform_device *pdev) for (i = 0; i < bg_ptr->conf->sensor_count; i++) { char *domain; + if (bg_ptr->conf->sensors[i].register_cooling) + bg_ptr->conf->sensors[i].register_cooling(bg_ptr, i); + domain = bg_ptr->conf->sensors[i].domain; if (bg_ptr->conf->expose_sensor) bg_ptr->conf->expose_sensor(bg_ptr, i, domain); - - if (bg_ptr->conf->sensors[i].register_cooling) - bg_ptr->conf->sensors[i].register_cooling(bg_ptr, i); } /* diff --git a/drivers/staging/omap-thermal/omap-thermal-common.c b/drivers/staging/omap-thermal/omap-thermal-common.c index d156424..46ee0a9 100644 --- a/drivers/staging/omap-thermal/omap-thermal-common.c +++ b/drivers/staging/omap-thermal/omap-thermal-common.c @@ -77,10 +77,16 @@ static inline int omap_thermal_get_temp(struct thermal_zone_device *thermal, unsigned long *temp) { struct omap_thermal_data *data = thermal->devdata; - struct omap_bandgap *bg_ptr = data->bg_ptr; - struct omap_temp_sensor *s = &bg_ptr->conf->sensors[data->sensor_id]; + struct omap_bandgap *bg_ptr; + struct omap_temp_sensor *s; int ret, tmp, pcb_temp, slope, constant; + if (!data) + return 0; + + bg_ptr = data->bg_ptr; + s = &bg_ptr->conf->sensors[data->sensor_id]; + ret = omap_bandgap_read_temperature(bg_ptr, data->sensor_id, &tmp); if (ret) return ret; @@ -227,21 +233,37 @@ static struct thermal_zone_device_ops omap_thermal_ops = { .get_crit_temp = omap_thermal_get_crit_temp, }; -int omap_thermal_expose_sensor(struct omap_bandgap *bg_ptr, int id, - char *domain) +static struct omap_thermal_data +*omap_thermal_build_data(struct omap_bandgap *bg_ptr, int id) { struct omap_thermal_data *data; data = devm_kzalloc(bg_ptr->dev, sizeof(*data), GFP_KERNEL); if (!data) { dev_err(bg_ptr->dev, "kzalloc fail\n"); - return -ENOMEM; + return NULL; } data->sensor_id = id; data->bg_ptr = bg_ptr; data->mode = THERMAL_DEVICE_ENABLED; INIT_WORK(&data->thermal_wq, omap_thermal_work); + return data; +} + +int omap_thermal_expose_sensor(struct omap_bandgap *bg_ptr, int id, + char *domain) +{ + struct omap_thermal_pdata pdata; + + data = omap_bandgap_get_sensor_data(bg_ptr, id); + + if (!data) + data = omap_thermal_build_pdata(bg_ptr, id); + + if (!data) + return -EINVAL; + /* TODO: remove TC1 TC2 */ /* Create thermal zone */ data->omap_thermal = thermal_zone_device_register(domain, @@ -335,6 +357,11 @@ int omap_thermal_register_cpu_cooling(struct omap_bandgap *bg_ptr, int id) int tab_size, ret; data = omap_bandgap_get_sensor_data(bg_ptr, id); + if (!data) + data = omap_thermal_build_pdata(bg_ptr, id); + + if (!data) + return -EINVAL; ret = omap_thermal_build_cpufreq_clip(bg_ptr, &tab_ptr, &tab_size); if (ret < 0) { @@ -351,6 +378,7 @@ int omap_thermal_register_cpu_cooling(struct omap_bandgap *bg_ptr, int id) return PTR_ERR(data->cool_dev); } bg_ptr->conf->sensors[id].cooling_data.freq_clip_count = tab_size; + omap_bandgap_set_sensor_data(bg_ptr, id, data); return 0; } -- cgit v0.10.2 From 28086cbdadc6ef7fc3600b8478e5d5b9bfe483b8 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Tue, 11 Sep 2012 13:34:54 +0200 Subject: Staging: ipack/bridges/tpci200: Put the TPCI200 control registers into a struct. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This saves us from a little pointer arithmetic and cleans up the code a bit. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 302fc21..c88166d 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -14,14 +14,6 @@ #include #include "tpci200.h" -/* TPCI200 controls registers */ -static const int control_reg[] = { - TPCI200_CONTROL_A_REG, - TPCI200_CONTROL_B_REG, - TPCI200_CONTROL_C_REG, - TPCI200_CONTROL_D_REG -}; - static int tpci200_slot_unregister(struct ipack_device *dev); static struct tpci200_board *check_slot(struct ipack_device *dev) @@ -85,8 +77,7 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id) irqreturn_t ret = IRQ_NONE; /* Read status register */ - status_reg = readw(tpci200->info->interface_regs + - TPCI200_STATUS_REG); + status_reg = readw(&tpci200->info->interface_regs->status); if (status_reg & TPCI200_SLOT_INT_MASK) { unhandled_ints = status_reg & TPCI200_SLOT_INT_MASK; @@ -107,7 +98,7 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id) } } } - /* Interrupt not handled are disabled */ + /* Interrupts not handled are disabled */ if (unhandled_ints) { for (i = 0; i < TPCI200_NB_SLOT; i++) { if (unhandled_ints & ((TPCI200_INT0_EN | TPCI200_INT1_EN) << (2*i))) { @@ -115,13 +106,11 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id) "No registered ISR for slot [%d:%d]!. IRQ will be disabled.\n", tpci200->number, i); reg_value = readw( - tpci200->info->interface_regs + - control_reg[i]); + &tpci200->info->interface_regs->control[i]); reg_value &= ~(TPCI200_INT0_EN | TPCI200_INT1_EN); writew(reg_value, - (tpci200->info->interface_regs + - control_reg[i])); + &tpci200->info->interface_regs->control[i]); } } } @@ -219,8 +208,7 @@ static int tpci200_register(struct tpci200_board *tpci200) (void __iomem *)mem_base + TPCI200_MEM8_GAP*i; tpci200->slots[i].mem_phys.size = TPCI200_MEM8_SIZE; - writew(slot_ctrl, (tpci200->info->interface_regs + - control_reg[i])); + writew(slot_ctrl, &tpci200->info->interface_regs->control[i]); } res = request_irq(tpci200->info->pdev->irq, @@ -259,8 +247,7 @@ static int __tpci200_request_irq(struct tpci200_board *tpci200, * clock rate 8 MHz */ slot_ctrl = TPCI200_INT0_EN | TPCI200_INT1_EN; - writew(slot_ctrl, (tpci200->info->interface_regs + - control_reg[dev->slot])); + writew(slot_ctrl, &tpci200->info->interface_regs->control[dev->slot]); return 0; } @@ -279,8 +266,7 @@ static void __tpci200_free_irq(struct tpci200_board *tpci200, * clock rate 8 MHz */ slot_ctrl = 0; - writew(slot_ctrl, (tpci200->info->interface_regs + - control_reg[dev->slot])); + writew(slot_ctrl, &tpci200->info->interface_regs->control[dev->slot]); } static int tpci200_free_irq(struct ipack_device *dev) diff --git a/drivers/staging/ipack/bridges/tpci200.h b/drivers/staging/ipack/bridges/tpci200.h index 38acba1..867d696 100644 --- a/drivers/staging/ipack/bridges/tpci200.h +++ b/drivers/staging/ipack/bridges/tpci200.h @@ -37,13 +37,15 @@ #define TPCI200_MEM16_SPACE_BAR 4 #define TPCI200_MEM8_SPACE_BAR 5 -#define TPCI200_REVISION_REG 0x00 -#define TPCI200_CONTROL_A_REG 0x02 -#define TPCI200_CONTROL_B_REG 0x04 -#define TPCI200_CONTROL_C_REG 0x06 -#define TPCI200_CONTROL_D_REG 0x08 -#define TPCI200_RESET_REG 0x0A -#define TPCI200_STATUS_REG 0x0C +struct tpci200_regs { + u16 revision; + /* writes to control should occur with the mutex held to protect + * read-modify-write operations */ + u16 control[4]; + u16 reset; + u16 status; + u8 reserved[242]; +} __packed; #define TPCI200_IFACE_SIZE 0x100 @@ -63,6 +65,7 @@ #define TPCI200_MEM16_GAP 0x00800000 #define TPCI200_MEM16_SIZE 0x00800000 +/* control field in tpci200_regs */ #define TPCI200_INT0_EN 0x0040 #define TPCI200_INT1_EN 0x0080 #define TPCI200_INT0_EDGE 0x0010 @@ -72,11 +75,13 @@ #define TPCI200_RECOVER_EN 0x0002 #define TPCI200_CLK32 0x0001 +/* reset field in tpci200_regs */ #define TPCI200_A_RESET 0x0001 #define TPCI200_B_RESET 0x0002 #define TPCI200_C_RESET 0x0004 #define TPCI200_D_RESET 0x0008 +/* status field in tpci200_regs */ #define TPCI200_A_TIMEOUT 0x1000 #define TPCI200_B_TIMEOUT 0x2000 #define TPCI200_C_TIMEOUT 0x4000 @@ -149,7 +154,7 @@ struct tpci200_slot { struct tpci200_infos { struct pci_dev *pdev; struct pci_device_id *id_table; - void __iomem *interface_regs; + struct tpci200_regs __iomem *interface_regs; void __iomem *ioidint_space; void __iomem *mem8_space; void __iomem *cfg_regs; -- cgit v0.10.2 From 7b6ab33c28980ae26de09654a0d5db6080c76921 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Tue, 11 Sep 2012 13:34:55 +0200 Subject: Staging: ipack: Provide several carrier callbacks. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We provide callbacks to: - set/get the clockrate a module is accessed at, - get the error state of a slot, - get/reset the timeout state of a slot. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h index 4d73f75..a133304 100644 --- a/drivers/staging/ipack/ipack.h +++ b/drivers/staging/ipack/ipack.h @@ -113,6 +113,15 @@ struct ipack_driver { * @request_irq: request IRQ * @free_irq: free IRQ * @remove_device: tell the bridge module that the device has been removed + * @get_clockrate: Returns the clockrate the carrier is currently + * communicating with the device at. + * @set_clockrate: Sets the clock-rate for carrier / module communication. + * Should return -EINVAL if the requested speed is not supported. + * @get_error: Returns the error state for the slot the device is attached + * to. + * @get_timeout: Returns 1 if the communication with the device has + * previously timed out. + * @reset_timeout: Resets the state returned by get_timeout. */ struct ipack_bus_ops { int (*map_space) (struct ipack_device *dev, unsigned int memory_size, int space); @@ -120,6 +129,12 @@ struct ipack_bus_ops { int (*request_irq) (struct ipack_device *dev, int vector, int (*handler)(void *), void *arg); int (*free_irq) (struct ipack_device *dev); int (*remove_device) (struct ipack_device *dev); + + int (*get_clockrate) (struct ipack_device *dev); + int (*set_clockrate) (struct ipack_device *dev, int mherz); + int (*get_error) (struct ipack_device *dev); + int (*get_timeout) (struct ipack_device *dev); + int (*reset_timeout) (struct ipack_device *dev); }; /** -- cgit v0.10.2 From eb12d88bf5f07a5aac77bebdfcb8a77ade48964e Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Tue, 11 Sep 2012 13:34:56 +0200 Subject: Staging: ipack/bridges/tpci200: provide new callbacks to tpci200 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Provide get_clockrate, set_clockrate, get_error, get_timeout and reset_timeout callbacks. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index c88166d..22e3da1 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -14,6 +14,20 @@ #include #include "tpci200.h" +static u16 tpci200_status_timeout[] = { + TPCI200_A_TIMEOUT, + TPCI200_B_TIMEOUT, + TPCI200_C_TIMEOUT, + TPCI200_D_TIMEOUT, +}; + +static u16 tpci200_status_error[] = { + TPCI200_A_ERROR, + TPCI200_B_ERROR, + TPCI200_C_ERROR, + TPCI200_D_ERROR, +}; + static int tpci200_slot_unregister(struct ipack_device *dev); static struct tpci200_board *check_slot(struct ipack_device *dev) @@ -505,6 +519,94 @@ out_unlock: return res; } +static int tpci200_get_clockrate(struct ipack_device *dev) +{ + struct tpci200_board *tpci200 = check_slot(dev); + u16 __iomem *addr; + + if (!tpci200) + return -ENODEV; + + addr = &tpci200->info->interface_regs->control[dev->slot]; + return (ioread16(addr) & TPCI200_CLK32) ? 32 : 8; +} + +static int tpci200_set_clockrate(struct ipack_device *dev, int mherz) +{ + struct tpci200_board *tpci200 = check_slot(dev); + u16 __iomem *addr; + u16 reg; + + if (!tpci200) + return -ENODEV; + + addr = &tpci200->info->interface_regs->control[dev->slot]; + + /* Ensure the control register is not changed by another task after we + * have read it. */ + mutex_lock(&tpci200->mutex); + reg = ioread16(addr); + switch (mherz) { + case 8: + reg &= ~(TPCI200_CLK32); + break; + case 32: + reg |= TPCI200_CLK32; + break; + default: + mutex_unlock(&tpci200->mutex); + return -EINVAL; + } + iowrite16(reg, addr); + mutex_unlock(&tpci200->mutex); + return 0; +} + +static int tpci200_get_error(struct ipack_device *dev) +{ + struct tpci200_board *tpci200 = check_slot(dev); + u16 __iomem *addr; + u16 mask; + + if (!tpci200) + return -ENODEV; + + addr = &tpci200->info->interface_regs->status; + mask = tpci200_status_error[dev->slot]; + return (ioread16(addr) & mask) ? 1 : 0; +} + +static int tpci200_get_timeout(struct ipack_device *dev) +{ + struct tpci200_board *tpci200 = check_slot(dev); + u16 __iomem *addr; + u16 mask; + + if (!tpci200) + return -ENODEV; + + addr = &tpci200->info->interface_regs->status; + mask = tpci200_status_timeout[dev->slot]; + + return (ioread16(addr) & mask) ? 1 : 0; +} + +static int tpci200_reset_timeout(struct ipack_device *dev) +{ + struct tpci200_board *tpci200 = check_slot(dev); + u16 __iomem *addr; + u16 mask; + + if (!tpci200) + return -ENODEV; + + addr = &tpci200->info->interface_regs->status; + mask = tpci200_status_timeout[dev->slot]; + + iowrite16(mask, addr); + return 0; +} + static void tpci200_uninstall(struct tpci200_board *tpci200) { int i; @@ -522,6 +624,11 @@ static const struct ipack_bus_ops tpci200_bus_ops = { .request_irq = tpci200_request_irq, .free_irq = tpci200_free_irq, .remove_device = tpci200_slot_unregister, + .get_clockrate = tpci200_get_clockrate, + .set_clockrate = tpci200_set_clockrate, + .get_error = tpci200_get_error, + .get_timeout = tpci200_get_timeout, + .reset_timeout = tpci200_reset_timeout, }; static int tpci200_install(struct tpci200_board *tpci200) @@ -549,7 +656,7 @@ static int tpci200_pci_probe(struct pci_dev *pdev, { int ret, i; struct tpci200_board *tpci200; - __le32 reg32; + u32 reg32; tpci200 = kzalloc(sizeof(struct tpci200_board), GFP_KERNEL); if (!tpci200) -- cgit v0.10.2 From 0b0f3a1bee7f321b92ffc37d8b32d1ce412a285c Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Tue, 11 Sep 2012 13:34:57 +0200 Subject: Staging: ipack: Obtain supported speeds from ID ROM. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c index af47772..c36ba9e 100644 --- a/drivers/staging/ipack/ipack.c +++ b/drivers/staging/ipack/ipack.c @@ -262,15 +262,21 @@ static void ipack_parse_id1(struct ipack_device *dev) dev->id_vendor = id[4]; dev->id_device = id[5]; + dev->speed_8mhz = 1; + dev->speed_32mhz = (id[7] == 'H'); } static void ipack_parse_id2(struct ipack_device *dev) { __be16 *id = (__be16 *) dev->id; + u16 flags; dev->id_vendor = ((be16_to_cpu(id[3]) & 0xff) << 16) + be16_to_cpu(id[4]); dev->id_device = be16_to_cpu(id[5]); + flags = be16_to_cpu(id[10]); + dev->speed_8mhz = !!(flags & 2); + dev->speed_32mhz = !!(flags & 4); } static int ipack_device_read_id(struct ipack_device *dev) diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h index a133304..89af9e4 100644 --- a/drivers/staging/ipack/ipack.h +++ b/drivers/staging/ipack/ipack.h @@ -79,6 +79,8 @@ struct ipack_device { u32 id_vendor; u32 id_device; u8 id_format; + unsigned int speed_8mhz:1; + unsigned int speed_32mhz:1; }; /** -- cgit v0.10.2 From 90cb61948fad898f7ac7452c68f2bec56b0e85f0 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Tue, 11 Sep 2012 13:34:58 +0200 Subject: Staging: ipack: Choose the optimum bus speed by default. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c index c36ba9e..1ad73e5 100644 --- a/drivers/staging/ipack/ipack.c +++ b/drivers/staging/ipack/ipack.c @@ -387,6 +387,11 @@ struct ipack_device *ipack_device_register(struct ipack_bus_device *bus, return NULL; } + /* if the device supports 32 MHz operation, use it. */ + ret = bus->ops->set_clockrate(dev, dev->speed_32mhz ? 32 : 8); + if (ret < 0) + dev_err(&dev->dev, "failed to perform set_clock_rate operation.\n"); + ret = device_register(&dev->dev); if (ret < 0) { kfree(dev->id); -- cgit v0.10.2 From 3bea7fcb797eed256f461e14e1992f4e71932704 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Tue, 11 Sep 2012 13:34:59 +0200 Subject: Staging: ipack: remove field driver from struct ipack_device. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After a successful match is found the driver field in struct device is set by the core device code. We can use this field. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c index 1ad73e5..6895426 100644 --- a/drivers/staging/ipack/ipack.c +++ b/drivers/staging/ipack/ipack.c @@ -59,32 +59,29 @@ static int ipack_bus_match(struct device *dev, struct device_driver *drv) const struct ipack_device_id *found_id; found_id = ipack_match_id(idrv->id_table, idev); - if (found_id) { - idev->driver = idrv; - return 1; - } - - return 0; + return found_id ? 1 : 0; } static int ipack_bus_probe(struct device *device) { struct ipack_device *dev = to_ipack_dev(device); + struct ipack_driver *drv = to_ipack_driver(device->driver); - if (!dev->driver->ops->probe) + if (!drv->ops->probe) return -EINVAL; - return dev->driver->ops->probe(dev); + return drv->ops->probe(dev); } static int ipack_bus_remove(struct device *device) { struct ipack_device *dev = to_ipack_dev(device); + struct ipack_driver *drv = to_ipack_driver(device->driver); - if (!dev->driver->ops->remove) + if (!drv->ops->remove) return -EINVAL; - dev->driver->ops->remove(dev); + drv->ops->remove(dev); return 0; } diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h index 89af9e4..ad4c3bf 100644 --- a/drivers/staging/ipack/ipack.h +++ b/drivers/staging/ipack/ipack.h @@ -53,7 +53,6 @@ struct ipack_addr_space { * @bus_nr: IP bus number where the device is plugged * @slot: Slot where the device is plugged in the carrier board * @irq: IRQ vector - * @driver: Pointer to the ipack_driver that manages the device * @bus: ipack_bus_device where the device is plugged to. * @id_space: Virtual address to ID space. * @io_space: Virtual address to IO space. @@ -68,7 +67,6 @@ struct ipack_device { unsigned int bus_nr; unsigned int slot; unsigned int irq; - struct ipack_driver *driver; struct ipack_bus_device *bus; struct ipack_addr_space id_space; struct ipack_addr_space io_space; -- cgit v0.10.2 From 939c37a3c9da8bc23edbbfc01674c1c472a3ad1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20Iglesias=20Gons=C3=A1lvez?= Date: Tue, 11 Sep 2012 13:35:00 +0200 Subject: Staging: ipack/bridges/tpci200: remove struct list_head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As the linked list was removed before, delete the useless struct list_head Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/bridges/tpci200.h b/drivers/staging/ipack/bridges/tpci200.h index 867d696..fc90a94 100644 --- a/drivers/staging/ipack/bridges/tpci200.h +++ b/drivers/staging/ipack/bridges/tpci200.h @@ -161,7 +161,6 @@ struct tpci200_infos { struct ipack_bus_device *ipack_bus; }; struct tpci200_board { - struct list_head list; unsigned int number; struct mutex mutex; struct tpci200_slot *slots; -- cgit v0.10.2 From 07766ab0256c0870746dae2362625e64e8968fc7 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Tue, 11 Sep 2012 13:35:01 +0200 Subject: Staging: ipack: Switch to 8MHz operation before reading ID. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reading the ID space at 8 MHz is always supported. Most carriers will boot up in 8MHz mode. Still, play it safe and ensure we are operating at 8Mhz. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c index 6895426..e2f819ca 100644 --- a/drivers/staging/ipack/ipack.c +++ b/drivers/staging/ipack/ipack.c @@ -377,6 +377,9 @@ struct ipack_device *ipack_device_register(struct ipack_bus_device *bus, dev_set_name(&dev->dev, "ipack-dev.%u.%u", dev->bus_nr, dev->slot); + if (bus->ops->set_clockrate(dev, 8)) + dev_warn(&dev->dev, "failed to switch to 8 MHz operation for reading of device ID.\n"); + ret = ipack_device_read_id(dev); if (ret < 0) { dev_err(&dev->dev, "error reading device id section.\n"); @@ -385,9 +388,11 @@ struct ipack_device *ipack_device_register(struct ipack_bus_device *bus, } /* if the device supports 32 MHz operation, use it. */ - ret = bus->ops->set_clockrate(dev, dev->speed_32mhz ? 32 : 8); - if (ret < 0) - dev_err(&dev->dev, "failed to perform set_clock_rate operation.\n"); + if (dev->speed_32mhz) { + ret = bus->ops->set_clockrate(dev, 32); + if (ret < 0) + dev_err(&dev->dev, "failed to switch to 32 MHz operation.\n"); + } ret = device_register(&dev->dev); if (ret < 0) { -- cgit v0.10.2 From 8a3ae16e60fb78e0bf062c243ffba5575b64a412 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Tue, 11 Sep 2012 13:35:02 +0200 Subject: Staging: ipack: reset previous timeouts during device registration. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resetting the previous timeout we avoid to read the timeout status register and see timeout errors that don't correspond to the present state of the device. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c index e2f819ca..08b122d 100644 --- a/drivers/staging/ipack/ipack.c +++ b/drivers/staging/ipack/ipack.c @@ -379,6 +379,8 @@ struct ipack_device *ipack_device_register(struct ipack_bus_device *bus, if (bus->ops->set_clockrate(dev, 8)) dev_warn(&dev->dev, "failed to switch to 8 MHz operation for reading of device ID.\n"); + if (bus->ops->reset_timeout(dev)) + dev_warn(&dev->dev, "failed to reset potential timeout."); ret = ipack_device_read_id(dev); if (ret < 0) { -- cgit v0.10.2 From a92caeb8e1189f190ac13bb5e745446b25b09ae5 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Tue, 11 Sep 2012 13:35:03 +0200 Subject: Staging: ipack: check the device ID space CRC. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We check the CRC and store the result of the check in struct ipac_device. A warning is emitted if the check fails. However we leave it to the IPack module device to refuse to initialize due to a bad CRC. I have seen otherwise good modules with bad CRCs. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c index 08b122d..26dc976 100644 --- a/drivers/staging/ipack/ipack.c +++ b/drivers/staging/ipack/ipack.c @@ -253,20 +253,71 @@ void ipack_driver_unregister(struct ipack_driver *edrv) } EXPORT_SYMBOL_GPL(ipack_driver_unregister); +static u16 ipack_crc_byte(u16 crc, u8 c) +{ + int i; + + crc ^= c << 8; + for (i = 0; i < 8; i++) + crc = (crc << 1) ^ ((crc & 0x8000) ? 0x1021 : 0); + return crc; +} + +/* + * The algorithm in lib/crc-ccitt.c does not seem to apply since it uses the + * opposite bit ordering. + */ +static u8 ipack_calc_crc1(struct ipack_device *dev) +{ + u8 c; + u16 crc; + unsigned int i; + + crc = 0xffff; + for (i = 0; i < dev->id_avail; i++) { + c = (i != 11) ? dev->id[i] : 0; + crc = ipack_crc_byte(crc, c); + } + crc = ~crc; + return crc & 0xff; +} + +static u16 ipack_calc_crc2(struct ipack_device *dev) +{ + u8 c; + u16 crc; + unsigned int i; + + crc = 0xffff; + for (i = 0; i < dev->id_avail; i++) { + c = ((i != 0x18) && (i != 0x19)) ? dev->id[i] : 0; + crc = ipack_crc_byte(crc, c); + } + crc = ~crc; + return crc; +} + static void ipack_parse_id1(struct ipack_device *dev) { u8 *id = dev->id; + u8 crc; dev->id_vendor = id[4]; dev->id_device = id[5]; dev->speed_8mhz = 1; dev->speed_32mhz = (id[7] == 'H'); + crc = ipack_calc_crc1(dev); + dev->id_crc_correct = (crc == id[11]); + if (!dev->id_crc_correct) { + dev_warn(&dev->dev, "ID CRC invalid found 0x%x, expected 0x%x.\n", + id[11], crc); + } } static void ipack_parse_id2(struct ipack_device *dev) { __be16 *id = (__be16 *) dev->id; - u16 flags; + u16 flags, crc; dev->id_vendor = ((be16_to_cpu(id[3]) & 0xff) << 16) + be16_to_cpu(id[4]); @@ -274,6 +325,12 @@ static void ipack_parse_id2(struct ipack_device *dev) flags = be16_to_cpu(id[10]); dev->speed_8mhz = !!(flags & 2); dev->speed_32mhz = !!(flags & 4); + crc = ipack_calc_crc2(dev); + dev->id_crc_correct = (crc == be16_to_cpu(id[12])); + if (!dev->id_crc_correct) { + dev_warn(&dev->dev, "ID CRC invalid found 0x%x, expected 0x%x.\n", + id[11], crc); + } } static int ipack_device_read_id(struct ipack_device *dev) diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h index ad4c3bf..77d8075 100644 --- a/drivers/staging/ipack/ipack.h +++ b/drivers/staging/ipack/ipack.h @@ -77,6 +77,7 @@ struct ipack_device { u32 id_vendor; u32 id_device; u8 id_format; + unsigned int id_crc_correct:1; unsigned int speed_8mhz:1; unsigned int speed_32mhz:1; }; -- cgit v0.10.2 From 7987812295cd734a3ba55c9cd02f16fbaec64ace Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20Iglesias=20Gons=C3=A1lvez?= Date: Tue, 11 Sep 2012 13:35:04 +0200 Subject: Staging: ipack/bridges/tpci200: reorder the iounmap and pci_release_region MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move iounmap and pci_release_region to tpci200_unregister(), as it is the place where the clean-up of the device is done. Also, renamed iounmap() to pci_iounmap() as the mapped region was requested from PCI bus. Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 22e3da1..383571c 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -64,10 +64,12 @@ static void tpci200_unregister(struct tpci200_board *tpci200) pci_iounmap(tpci200->info->pdev, tpci200->info->interface_regs); pci_iounmap(tpci200->info->pdev, tpci200->info->ioidint_space); pci_iounmap(tpci200->info->pdev, tpci200->info->mem8_space); + pci_iounmap(tpci200->info->pdev, tpci200->info->cfg_regs); pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR); pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR); pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR); + pci_release_region(tpci200->info->pdev, TPCI200_CFG_MEM_BAR); pci_disable_device(tpci200->info->pdev); pci_dev_put(tpci200->info->pdev); @@ -750,9 +752,6 @@ static void __tpci200_pci_remove(struct tpci200_board *tpci200) tpci200_uninstall(tpci200); ipack_bus_unregister(tpci200->info->ipack_bus); - iounmap(tpci200->info->cfg_regs); - pci_release_region(tpci200->info->pdev, TPCI200_CFG_MEM_BAR); - kfree(tpci200->info); kfree(tpci200); } -- cgit v0.10.2 From b442bf738454d5eeaf695e45051e9fa7242bb9a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20Iglesias=20Gons=C3=A1lvez?= Date: Tue, 11 Sep 2012 13:35:05 +0200 Subject: Staging: ipack/bridges/tpci200: increment the reference counter of the pci_dev MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As indicated in the documentation of pci_dev_get. Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 383571c..b928140 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -670,6 +670,8 @@ static int tpci200_pci_probe(struct pci_dev *pdev, goto out_err_info; } + pci_dev_get(pdev); + /* Obtain a mapping of the carrier's PCI configuration registers */ ret = pci_request_region(pdev, TPCI200_CFG_MEM_BAR, KBUILD_MODNAME " Configuration Memory"); @@ -741,6 +743,7 @@ out_err_install: out_err_ioremap: pci_release_region(pdev, TPCI200_CFG_MEM_BAR); out_err_pci_request: + pci_dev_put(pdev); kfree(tpci200->info); out_err_info: kfree(tpci200); -- cgit v0.10.2 From 7273b88ebfc1b3ea5387e37fae8b1d77e59e169f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20Iglesias=20Gons=C3=A1lvez?= Date: Tue, 11 Sep 2012 13:35:06 +0200 Subject: Staging: ipack/bridges/tpci200: fix the uninstall the ipack device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using the call to the ipack_device_unregister() function to avoid the strange way it was doing, as the device model will take care of calling the bus's .remove function when a device is being unregistered. Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index b928140..77e6392 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -385,7 +385,6 @@ static int tpci200_slot_unregister(struct ipack_device *dev) return -ERESTARTSYS; tpci200->slots[dev->slot].dev = NULL; - ipack_device_unregister(dev); mutex_unlock(&tpci200->mutex); return 0; @@ -614,7 +613,7 @@ static void tpci200_uninstall(struct tpci200_board *tpci200) int i; for (i = 0; i < TPCI200_NB_SLOT; i++) - tpci200_slot_unregister(tpci200->slots[i].dev); + ipack_device_unregister(tpci200->slots[i].dev); tpci200_unregister(tpci200); kfree(tpci200->slots); -- cgit v0.10.2 From ca8481c23cc841aeded46a1ad6964c93e8167dd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20Iglesias=20Gons=C3=A1lvez?= Date: Tue, 11 Sep 2012 13:35:07 +0200 Subject: Staging: ipack/devices/ipoctal: change exiting procedure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ipoctal devices can be uninstalled from the ipack_driver_unregister() call as the device model calles the bus's .remove() function for each device registered by the driver and it will execute the .remove() function of the ipoctal driver. Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index c94a9df..272832f 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -853,11 +853,6 @@ static int __init ipoctal_init(void) static void __exit ipoctal_exit(void) { - struct ipoctal *p, *next; - - list_for_each_entry_safe(p, next, &ipoctal_list, list) - p->dev->bus->ops->remove_device(p->dev); - ipack_driver_unregister(&driver); } -- cgit v0.10.2 From 690949e7faaed39300cc618c10a56dec3d1180c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20Iglesias=20Gons=C3=A1lvez?= Date: Tue, 11 Sep 2012 13:35:08 +0200 Subject: Staging: ipack/devices/ipoctal: free the IRQ. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As the IRQ was requested by the driver, it should free it also. Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index 272832f..35513d9 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -803,6 +803,8 @@ static void __ipoctal_remove(struct ipoctal *ipoctal) { int i; + ipoctal->dev->bus->ops->free_irq(ipoctal->dev); + for (i = 0; i < NR_CHANNELS; i++) { tty_unregister_device(ipoctal->tty_drv, i); tty_port_free_xmit_buf(&ipoctal->tty_port[i]); -- cgit v0.10.2 From bffe0fd02198fb13586ad4f572c1a028b8547ecd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20Iglesias=20Gons=C3=A1lvez?= Date: Tue, 11 Sep 2012 13:35:09 +0200 Subject: Staging: ipack: unregister devices when uninstall the carrier device. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Find the IP modules that are plugged to the carrier and unregister them. Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c index 26dc976..c83f015 100644 --- a/drivers/staging/ipack/ipack.c +++ b/drivers/staging/ipack/ipack.c @@ -229,8 +229,20 @@ struct ipack_bus_device *ipack_bus_register(struct device *parent, int slots, } EXPORT_SYMBOL_GPL(ipack_bus_register); +static int ipack_unregister_bus_member(struct device *dev, void *data) +{ + struct ipack_device *idev = to_ipack_dev(dev); + struct ipack_bus_device *bus = data; + + if (idev->bus_nr == bus->bus_nr) + ipack_device_unregister(idev); + + return 1; +} + int ipack_bus_unregister(struct ipack_bus_device *bus) { + bus_for_each_dev(&ipack_bus_type, NULL, bus, ipack_unregister_bus_member); ida_simple_remove(&ipack_ida, bus->bus_nr); kfree(bus); return 0; -- cgit v0.10.2 From 9c0d169e8fd9637eebe98e1ad4e61c0de9edc43e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20Iglesias=20Gons=C3=A1lvez?= Date: Tue, 11 Sep 2012 13:35:10 +0200 Subject: Staging: ipack/bridges/tpci200: delete ipack_device_unregister calls when exiting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As the ipack_bus_unregister() takes care of unregistering the devices plugged in the carrier, it is not needed to do it in the carrier driver. Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 77e6392..8de74c9 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -610,11 +610,6 @@ static int tpci200_reset_timeout(struct ipack_device *dev) static void tpci200_uninstall(struct tpci200_board *tpci200) { - int i; - - for (i = 0; i < TPCI200_NB_SLOT; i++) - ipack_device_unregister(tpci200->slots[i].dev); - tpci200_unregister(tpci200); kfree(tpci200->slots); } @@ -751,8 +746,8 @@ out_err_info: static void __tpci200_pci_remove(struct tpci200_board *tpci200) { - tpci200_uninstall(tpci200); ipack_bus_unregister(tpci200->info->ipack_bus); + tpci200_uninstall(tpci200); kfree(tpci200->info); kfree(tpci200); -- cgit v0.10.2 From daf8007c02558a61a27ba035844787269406274e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20Iglesias=20Gons=C3=A1lvez?= Date: Tue, 11 Sep 2012 13:35:11 +0200 Subject: Staging: ipack/bridges/tpci200: remove tpci200_slot_unregister MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is not needed as the IP module should free its IRQ using tpci200_free_irq callback. Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 8de74c9..0823cdb 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -28,8 +28,6 @@ static u16 tpci200_status_error[] = { TPCI200_D_ERROR, }; -static int tpci200_slot_unregister(struct ipack_device *dev); - static struct tpci200_board *check_slot(struct ipack_device *dev) { struct tpci200_board *tpci200; @@ -368,28 +366,6 @@ out_unlock: return 0; } -static int tpci200_slot_unregister(struct ipack_device *dev) -{ - struct tpci200_board *tpci200; - - if (dev == NULL) - return -ENODEV; - - tpci200 = check_slot(dev); - if (tpci200 == NULL) - return -EINVAL; - - tpci200_free_irq(dev); - - if (mutex_lock_interruptible(&tpci200->mutex)) - return -ERESTARTSYS; - - tpci200->slots[dev->slot].dev = NULL; - mutex_unlock(&tpci200->mutex); - - return 0; -} - static int tpci200_slot_map_space(struct ipack_device *dev, unsigned int memory_size, int space) { @@ -619,7 +595,7 @@ static const struct ipack_bus_ops tpci200_bus_ops = { .unmap_space = tpci200_slot_unmap_space, .request_irq = tpci200_request_irq, .free_irq = tpci200_free_irq, - .remove_device = tpci200_slot_unregister, + .remove_device = NULL, .get_clockrate = tpci200_get_clockrate, .set_clockrate = tpci200_set_clockrate, .get_error = tpci200_get_error, -- cgit v0.10.2 From 4a589c54eeecfab774bbdb11ff2e658ef1a076bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20Iglesias=20Gons=C3=A1lvez?= Date: Tue, 11 Sep 2012 13:35:12 +0200 Subject: Staging: ipack: delete .remove_device() callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As the IP module driver takes care of freeing its resources. Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 0823cdb..5aff0d0 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -595,7 +595,6 @@ static const struct ipack_bus_ops tpci200_bus_ops = { .unmap_space = tpci200_slot_unmap_space, .request_irq = tpci200_request_irq, .free_irq = tpci200_free_irq, - .remove_device = NULL, .get_clockrate = tpci200_get_clockrate, .set_clockrate = tpci200_set_clockrate, .get_error = tpci200_get_error, diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h index 77d8075..0ea9d84 100644 --- a/drivers/staging/ipack/ipack.h +++ b/drivers/staging/ipack/ipack.h @@ -113,7 +113,6 @@ struct ipack_driver { * @unmap_space: unmap IP address space * @request_irq: request IRQ * @free_irq: free IRQ - * @remove_device: tell the bridge module that the device has been removed * @get_clockrate: Returns the clockrate the carrier is currently * communicating with the device at. * @set_clockrate: Sets the clock-rate for carrier / module communication. @@ -129,8 +128,6 @@ struct ipack_bus_ops { int (*unmap_space) (struct ipack_device *dev, int space); int (*request_irq) (struct ipack_device *dev, int vector, int (*handler)(void *), void *arg); int (*free_irq) (struct ipack_device *dev); - int (*remove_device) (struct ipack_device *dev); - int (*get_clockrate) (struct ipack_device *dev); int (*set_clockrate) (struct ipack_device *dev, int mherz); int (*get_error) (struct ipack_device *dev); -- cgit v0.10.2 From 6f2c12ae422addc0f04cb6380fe2b18cfac97781 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Tue, 11 Sep 2012 13:35:13 +0200 Subject: Staging: ipack/bridges/tpci200: Store the irq holder in slot_irq. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This way we do no longer need to keep a dangling pointer to struct ipack_device in tpci200_slot after the device has been removed. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsálvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 5aff0d0..9d886b7 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -89,6 +89,7 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id) unsigned short status_reg, reg_value; unsigned short unhandled_ints = 0; irqreturn_t ret = IRQ_NONE; + struct slot_irq *slot_irq; /* Read status register */ status_reg = readw(&tpci200->info->interface_regs->status); @@ -97,15 +98,17 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id) unhandled_ints = status_reg & TPCI200_SLOT_INT_MASK; /* callback to the IRQ handler for the corresponding slot */ for (i = 0; i < TPCI200_NB_SLOT; i++) { - if ((tpci200->slots[i].irq != NULL) && + slot_irq = tpci200->slots[i].irq; + + if ((slot_irq != NULL) && (status_reg & ((TPCI200_A_INT0 | TPCI200_A_INT1) << (2*i)))) { - ret = tpci200->slots[i].irq->handler(tpci200->slots[i].irq->arg); + ret = slot_irq->handler(slot_irq->arg); /* Dummy reads */ - readw(tpci200->slots[i].dev->io_space.address + + readw(slot_irq->holder->io_space.address + 0xC0); - readw(tpci200->slots[i].dev->io_space.address + + readw(slot_irq->holder->io_space.address + 0xC2); unhandled_ints &= ~(((TPCI200_A_INT0 | TPCI200_A_INT1) << (2*i))); @@ -115,8 +118,10 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id) /* Interrupts not handled are disabled */ if (unhandled_ints) { for (i = 0; i < TPCI200_NB_SLOT; i++) { + slot_irq = tpci200->slots[i].irq; + if (unhandled_ints & ((TPCI200_INT0_EN | TPCI200_INT1_EN) << (2*i))) { - dev_info(&tpci200->slots[i].dev->dev, + dev_info(&slot_irq->holder->dev, "No registered ISR for slot [%d:%d]!. IRQ will be disabled.\n", tpci200->number, i); reg_value = readw( @@ -487,6 +492,7 @@ static int tpci200_request_irq(struct ipack_device *dev, int vector, slot_irq->vector = vector; slot_irq->handler = handler; slot_irq->arg = arg; + slot_irq->holder = dev; tpci200->slots[dev->slot].irq = slot_irq; res = __tpci200_request_irq(tpci200, dev); @@ -701,8 +707,7 @@ static int tpci200_pci_probe(struct pci_dev *pdev, * The TPCI200 has assigned his own two IRQ by PCI bus driver */ for (i = 0; i < TPCI200_NB_SLOT; i++) - tpci200->slots[i].dev = - ipack_device_register(tpci200->info->ipack_bus, i, i); + ipack_device_register(tpci200->info->ipack_bus, i, i); return 0; out_err_bus_register: diff --git a/drivers/staging/ipack/bridges/tpci200.h b/drivers/staging/ipack/bridges/tpci200.h index fc90a94..75a5dcc 100644 --- a/drivers/staging/ipack/bridges/tpci200.h +++ b/drivers/staging/ipack/bridges/tpci200.h @@ -121,6 +121,7 @@ struct tpci200_regs { * */ struct slot_irq { + struct ipack_device *holder; int vector; int (*handler)(void *); void *arg; @@ -136,7 +137,6 @@ struct slot_irq { * */ struct tpci200_slot { - struct ipack_device *dev; struct slot_irq *irq; struct ipack_addr_space io_phys; struct ipack_addr_space id_phys; -- cgit v0.10.2 From 554e02c92468dc4958a528a953e590fd3ccd8f84 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 13:44:59 -0700 Subject: staging: comedi: icp_multi: convert to a pci_driver This driver is for a PCI device not a legacy device. Convert it from a module_comedi_driver to a module_comedi_pci_driver. This will allow using the comedi_pci_auto_config mechanism to attach to the device. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index 73fe8a3..e0aac68 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -58,7 +58,7 @@ Options: #include "icp_multi.h" -#define DEVICE_ID 0x8000 /* Device ID */ +#define PCI_DEVICE_ID_ICP_MULTI 0x8000 #define ICP_MULTI_EXTDEBUG @@ -1025,7 +1025,7 @@ static void icp_multi_detach(struct comedi_device *dev) static const struct boardtype boardtypes[] = { { .name = "icp_multi", - .device_id = DEVICE_ID, + .device_id = PCI_DEVICE_ID_ICP_MULTI, .iorange = IORANGE_ICP_MULTI, .have_irq = 1, .cardtype = TYPE_ICP_MULTI, @@ -1052,7 +1052,31 @@ static struct comedi_driver icp_multi_driver = { .board_name = &boardtypes[0].name, .offset = sizeof(struct boardtype), }; -module_comedi_driver(icp_multi_driver); + +static int __devinit icp_multi_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &icp_multi_driver); +} + +static void __devexit icp_multi_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(icp_multi_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_ICP, PCI_DEVICE_ID_ICP_MULTI) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, icp_multi_pci_table); + +static struct pci_driver icp_multi_pci_driver = { + .name = "icp_multi", + .id_table = icp_multi_pci_table, + .probe = icp_multi_pci_probe, + .remove = __devexit_p(icp_multi_pci_remove), +}; +module_comedi_pci_driver(icp_multi_driver, icp_multi_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); -- cgit v0.10.2 From 888866625c089f949d810639d62d85ab3d276c05 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 13:45:16 -0700 Subject: staging: comedi: icp_multi: remove ICP_MULTI_EXTDEBUG This define enables a bunch of function trace messages. These should be removed in the final driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index e0aac68..3567a48 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -60,8 +60,6 @@ Options: #define PCI_DEVICE_ID_ICP_MULTI 0x8000 -#define ICP_MULTI_EXTDEBUG - /* Hardware types of the cards */ #define TYPE_ICP_MULTI 0 @@ -194,10 +192,6 @@ static void setup_channel_list(struct comedi_device *dev, unsigned int i, range, chanprog; unsigned int diff; -#ifdef ICP_MULTI_EXTDEBUG - printk(KERN_DEBUG - "icp multi EDBG: setup_channel_list(...,%d)\n", n_chan); -#endif devpriv->act_chanlist_len = n_chan; devpriv->act_chanlist_pos = 0; @@ -235,14 +229,7 @@ static void setup_channel_list(struct comedi_device *dev, /* Output channel, range, mode to ICP Multi */ writew(devpriv->AdcCmdStatus, devpriv->io_addr + ICP_MULTI_ADC_CSR); - -#ifdef ICP_MULTI_EXTDEBUG - printk(KERN_DEBUG - "GS: %2d. [%4x]=%4x %4x\n", i, chanprog, range, - devpriv->act_chanlist[i]); -#endif } - } /* @@ -269,9 +256,6 @@ static int icp_multi_insn_read_ai(struct comedi_device *dev, { int n, timeout; -#ifdef ICP_MULTI_EXTDEBUG - printk(KERN_DEBUG "icp multi EDBG: BGN: icp_multi_insn_read_ai(...)\n"); -#endif /* Disable A/D conversion ready interrupt */ devpriv->IntEnable &= ~ADC_READY; writew(devpriv->IntEnable, devpriv->io_addr + ICP_MULTI_INT_EN); @@ -283,12 +267,6 @@ static int icp_multi_insn_read_ai(struct comedi_device *dev, /* Set up appropriate channel, mode and range data, for specified ch */ setup_channel_list(dev, s, &insn->chanspec, 1); -#ifdef ICP_MULTI_EXTDEBUG - printk(KERN_DEBUG "icp_multi A ST=%4x IO=%p\n", - readw(devpriv->io_addr + ICP_MULTI_ADC_CSR), - devpriv->io_addr + ICP_MULTI_ADC_CSR); -#endif - for (n = 0; n < insn->n; n++) { /* Set start ADC bit */ devpriv->AdcCmdStatus |= ADC_ST; @@ -296,18 +274,8 @@ static int icp_multi_insn_read_ai(struct comedi_device *dev, devpriv->io_addr + ICP_MULTI_ADC_CSR); devpriv->AdcCmdStatus &= ~ADC_ST; -#ifdef ICP_MULTI_EXTDEBUG - printk(KERN_DEBUG "icp multi B n=%d ST=%4x\n", n, - readw(devpriv->io_addr + ICP_MULTI_ADC_CSR)); -#endif - udelay(1); -#ifdef ICP_MULTI_EXTDEBUG - printk(KERN_DEBUG "icp multi C n=%d ST=%4x\n", n, - readw(devpriv->io_addr + ICP_MULTI_ADC_CSR)); -#endif - /* Wait for conversion to complete, or get fed up waiting */ timeout = 100; while (timeout--) { @@ -315,15 +283,6 @@ static int icp_multi_insn_read_ai(struct comedi_device *dev, ICP_MULTI_ADC_CSR) & ADC_BSY)) goto conv_finish; -#ifdef ICP_MULTI_EXTDEBUG - if (!(timeout % 10)) - printk(KERN_DEBUG - "icp multi D n=%d tm=%d ST=%4x\n", n, - timeout, - readw(devpriv->io_addr + - ICP_MULTI_ADC_CSR)); -#endif - udelay(1); } @@ -342,11 +301,6 @@ static int icp_multi_insn_read_ai(struct comedi_device *dev, /* Clear data received */ data[n] = 0; -#ifdef ICP_MULTI_EXTDEBUG - printk(KERN_DEBUG - "icp multi EDBG: END: icp_multi_insn_read_ai(...) n=%d\n", - n); -#endif return -ETIME; conv_finish: @@ -362,10 +316,6 @@ conv_finish: devpriv->IntStatus |= ADC_READY; writew(devpriv->IntStatus, devpriv->io_addr + ICP_MULTI_INT_STAT); -#ifdef ICP_MULTI_EXTDEBUG - printk(KERN_DEBUG - "icp multi EDBG: END: icp_multi_insn_read_ai(...) n=%d\n", n); -#endif return n; } @@ -393,10 +343,6 @@ static int icp_multi_insn_write_ao(struct comedi_device *dev, { int n, chan, range, timeout; -#ifdef ICP_MULTI_EXTDEBUG - printk(KERN_DEBUG - "icp multi EDBG: BGN: icp_multi_insn_write_ao(...)\n"); -#endif /* Disable D/A conversion ready interrupt */ devpriv->IntEnable &= ~DAC_READY; writew(devpriv->IntEnable, devpriv->io_addr + ICP_MULTI_INT_EN); @@ -429,15 +375,6 @@ static int icp_multi_insn_write_ao(struct comedi_device *dev, ICP_MULTI_DAC_CSR) & DAC_BSY)) goto dac_ready; -#ifdef ICP_MULTI_EXTDEBUG - if (!(timeout % 10)) - printk(KERN_DEBUG - "icp multi A n=%d tm=%d ST=%4x\n", n, - timeout, - readw(devpriv->io_addr + - ICP_MULTI_DAC_CSR)); -#endif - udelay(1); } @@ -456,11 +393,6 @@ static int icp_multi_insn_write_ao(struct comedi_device *dev, /* Clear data received */ devpriv->ao_data[chan] = 0; -#ifdef ICP_MULTI_EXTDEBUG - printk(KERN_DEBUG - "icp multi EDBG: END: icp_multi_insn_write_ao(...) n=%d\n", - n); -#endif return -ETIME; dac_ready: @@ -477,10 +409,6 @@ dac_ready: devpriv->ao_data[chan] = data[n]; } -#ifdef ICP_MULTI_EXTDEBUG - printk(KERN_DEBUG - "icp multi EDBG: END: icp_multi_insn_write_ao(...) n=%d\n", n); -#endif return n; } @@ -567,10 +495,6 @@ static int icp_multi_insn_bits_do(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { -#ifdef ICP_MULTI_EXTDEBUG - printk(KERN_DEBUG "icp multi EDBG: BGN: icp_multi_insn_bits_do(...)\n"); -#endif - if (data[0]) { s->state &= ~data[0]; s->state |= (data[0] & data[1]); @@ -582,9 +506,6 @@ static int icp_multi_insn_bits_do(struct comedi_device *dev, data[1] = readw(devpriv->io_addr + ICP_MULTI_DI); -#ifdef ICP_MULTI_EXTDEBUG - printk(KERN_DEBUG "icp multi EDBG: END: icp_multi_insn_bits_do(...)\n"); -#endif return insn->n; } @@ -659,24 +580,12 @@ static irqreturn_t interrupt_service_icp_multi(int irq, void *d) struct comedi_device *dev = d; int int_no; -#ifdef ICP_MULTI_EXTDEBUG - printk(KERN_DEBUG - "icp multi EDBG: BGN: interrupt_service_icp_multi(%d,...)\n", - irq); -#endif - /* Is this interrupt from our board? */ int_no = readw(devpriv->io_addr + ICP_MULTI_INT_STAT) & Status_IRQ; if (!int_no) /* No, exit */ return IRQ_NONE; -#ifdef ICP_MULTI_EXTDEBUG - printk(KERN_DEBUG - "icp multi EDBG: interrupt_service_icp_multi() ST: %4x\n", - readw(devpriv->io_addr + ICP_MULTI_INT_STAT)); -#endif - /* Determine which interrupt is active & handle it */ switch (int_no) { case ADC_READY: @@ -700,10 +609,6 @@ static irqreturn_t interrupt_service_icp_multi(int irq, void *d) } -#ifdef ICP_MULTI_EXTDEBUG - printk(KERN_DEBUG - "icp multi EDBG: END: interrupt_service_icp_multi(...)\n"); -#endif return IRQ_HANDLED; } @@ -734,10 +639,6 @@ static int check_channel_list(struct comedi_device *dev, { unsigned int i; -#ifdef ICP_MULTI_EXTDEBUG - printk(KERN_DEBUG - "icp multi EDBG: check_channel_list(...,%d)\n", n_chan); -#endif /* Check that we at least have one channel to check */ if (n_chan < 1) { comedi_error(dev, "range/channel list is empty!"); @@ -783,10 +684,6 @@ static int icp_multi_reset(struct comedi_device *dev) { unsigned int i; -#ifdef ICP_MULTI_EXTDEBUG - printk(KERN_DEBUG - "icp_multi EDBG: BGN: icp_multi_reset(...)\n"); -#endif /* Clear INT enables and requests */ writew(0, devpriv->io_addr + ICP_MULTI_INT_EN); writew(0x00ff, devpriv->io_addr + ICP_MULTI_INT_STAT); @@ -815,10 +712,6 @@ static int icp_multi_reset(struct comedi_device *dev) /* Digital outputs to 0 */ writew(0, devpriv->io_addr + ICP_MULTI_DO); -#ifdef ICP_MULTI_EXTDEBUG - printk(KERN_DEBUG - "icp multi EDBG: END: icp_multi_reset(...)\n"); -#endif return 0; } @@ -841,15 +734,8 @@ static int icp_multi_attach(struct comedi_device *dev, return ret; /* Initialise list of PCI cards in system, if not already done so */ - if (pci_list_builded++ == 0) { - pci_card_list_init(PCI_VENDOR_ID_ICP, -#ifdef ICP_MULTI_EXTDEBUG - 1 -#else - 0 -#endif - ); - } + if (pci_list_builded++ == 0) + pci_card_list_init(PCI_VENDOR_ID_ICP, 0); printk(KERN_WARNING "Anne's comedi%d: icp_multi: board=%s", dev->minor, @@ -883,11 +769,6 @@ static int icp_multi_attach(struct comedi_device *dev, printk(KERN_WARNING "ioremap failed.\n"); return -ENOMEM; } -#ifdef ICP_MULTI_EXTDEBUG - printk(KERN_DEBUG - "0x%08llx mapped to %p, ", (unsigned long long)iobase, - devpriv->io_addr); -#endif dev->board_name = this_board->name; @@ -952,7 +833,7 @@ static int icp_multi_attach(struct comedi_device *dev, s->n_chan = this_board->n_aochan; s->maxdata = this_board->ao_maxdata; s->len_chanlist = this_board->n_aochan; - s->range_table = this_board->rangelist_ao; + s->range_table = &range_analog; s->insn_write = icp_multi_insn_write_ao; s->insn_read = icp_multi_insn_read_ao; subdev++; @@ -1000,10 +881,6 @@ static int icp_multi_attach(struct comedi_device *dev, devpriv->valid = 1; -#ifdef ICP_MULTI_EXTDEBUG - printk(KERN_DEBUG "icp multi EDBG: END: icp_multi_attach(...)\n"); -#endif - return 0; } -- cgit v0.10.2 From 5b93da54bf0a55fd53b96cfb1ac0ce0f8905d1e0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 13:45:31 -0700 Subject: staging: comedi: icp_multi: remove n_ctrs from boardinfo There is only one board type supported by this driver and the number of counter channels is constant. Remove the boardinfo for it and just open-code the value. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index 3567a48..6924b1d 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -135,7 +135,6 @@ struct boardtype { int n_aochan; /* num of D/A chans */ int n_dichan; /* num of DI chans */ int n_dochan; /* num of DO chans */ - int n_ctrs; /* num of counters */ int ai_maxdata; /* resolution of A/D */ int ao_maxdata; /* resolution of D/A */ const struct comedi_lrange *rangelist_ai; /* rangelist for A/D */ @@ -781,8 +780,7 @@ static int icp_multi_attach(struct comedi_device *dev, n_subdevices++; if (this_board->n_dochan) n_subdevices++; - if (this_board->n_ctrs) - n_subdevices++; + n_subdevices++; ret = comedi_alloc_subdevices(dev, n_subdevices); if (ret) @@ -866,18 +864,16 @@ static int icp_multi_attach(struct comedi_device *dev, subdev++; } - if (this_board->n_ctrs) { - s = &dev->subdevices[subdev]; - s->type = COMEDI_SUBD_COUNTER; - s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = this_board->n_ctrs; - s->maxdata = 0xffff; - s->len_chanlist = this_board->n_ctrs; - s->state = 0; - s->insn_read = icp_multi_insn_read_ctr; - s->insn_write = icp_multi_insn_write_ctr; - subdev++; - } + s = &dev->subdevices[subdev]; + s->type = COMEDI_SUBD_COUNTER; + s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = 4; + s->maxdata = 0xffff; + s->len_chanlist = 4; + s->state = 0; + s->insn_read = icp_multi_insn_read_ctr; + s->insn_write = icp_multi_insn_write_ctr; + subdev++; devpriv->valid = 1; @@ -911,7 +907,6 @@ static const struct boardtype boardtypes[] = { .n_aochan = 4, .n_dichan = 16, .n_dochan = 8, - .n_ctrs = 4, .ai_maxdata = 0x0fff, .ao_maxdata = 0x0fff, .rangelist_ai = &range_analog, -- cgit v0.10.2 From 2aa707058ffa3c31abf8b7480c7773400cc87d01 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 13:45:46 -0700 Subject: staging: comedi: icp_multi: remove n_dochan from boardinfo There is only one board type supported by this driver and the number of digital output channels is constant. Remove the boardinfo for it and just open-code the value. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index 6924b1d..a80dec8 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -134,7 +134,6 @@ struct boardtype { int n_aichand; /* num of A/D chans in diff mode */ int n_aochan; /* num of D/A chans */ int n_dichan; /* num of DI chans */ - int n_dochan; /* num of DO chans */ int ai_maxdata; /* resolution of A/D */ int ao_maxdata; /* resolution of D/A */ const struct comedi_lrange *rangelist_ai; /* rangelist for A/D */ @@ -778,8 +777,7 @@ static int icp_multi_attach(struct comedi_device *dev, n_subdevices++; if (this_board->n_dichan) n_subdevices++; - if (this_board->n_dochan) - n_subdevices++; + n_subdevices++; n_subdevices++; ret = comedi_alloc_subdevices(dev, n_subdevices); @@ -850,19 +848,17 @@ static int icp_multi_attach(struct comedi_device *dev, subdev++; } - if (this_board->n_dochan) { - s = &dev->subdevices[subdev]; - s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE; - s->n_chan = this_board->n_dochan; - s->maxdata = 1; - s->len_chanlist = this_board->n_dochan; - s->range_table = &range_digital; - s->io_bits = (1 << this_board->n_dochan) - 1; - s->state = 0; - s->insn_bits = icp_multi_insn_bits_do; - subdev++; - } + s = &dev->subdevices[subdev]; + s->type = COMEDI_SUBD_DO; + s->subdev_flags = SDF_WRITABLE | SDF_READABLE; + s->n_chan = 8; + s->maxdata = 1; + s->len_chanlist = 8; + s->range_table = &range_digital; + s->io_bits = 0xff; + s->state = 0; + s->insn_bits = icp_multi_insn_bits_do; + subdev++; s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_COUNTER; @@ -906,7 +902,6 @@ static const struct boardtype boardtypes[] = { .n_aichand = 8, .n_aochan = 4, .n_dichan = 16, - .n_dochan = 8, .ai_maxdata = 0x0fff, .ao_maxdata = 0x0fff, .rangelist_ai = &range_analog, -- cgit v0.10.2 From 48f31251264c3cabcec274da184ad669c195a627 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 13:46:02 -0700 Subject: staging: comedi: icp_multi: remove n_dichan from boardinfo There is only one board type supported by this driver and the number of digital input channels is constant. Remove the boardinfo for it and just open-code the value. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index a80dec8..7ad58e3 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -133,7 +133,6 @@ struct boardtype { int n_aichan; /* num of A/D chans */ int n_aichand; /* num of A/D chans in diff mode */ int n_aochan; /* num of D/A chans */ - int n_dichan; /* num of DI chans */ int ai_maxdata; /* resolution of A/D */ int ao_maxdata; /* resolution of D/A */ const struct comedi_lrange *rangelist_ai; /* rangelist for A/D */ @@ -775,8 +774,7 @@ static int icp_multi_attach(struct comedi_device *dev, n_subdevices++; if (this_board->n_aochan) n_subdevices++; - if (this_board->n_dichan) - n_subdevices++; + n_subdevices++; n_subdevices++; n_subdevices++; @@ -835,18 +833,16 @@ static int icp_multi_attach(struct comedi_device *dev, subdev++; } - if (this_board->n_dichan) { - s = &dev->subdevices[subdev]; - s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE; - s->n_chan = this_board->n_dichan; - s->maxdata = 1; - s->len_chanlist = this_board->n_dichan; - s->range_table = &range_digital; - s->io_bits = 0; - s->insn_bits = icp_multi_insn_bits_di; - subdev++; - } + s = &dev->subdevices[subdev]; + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE; + s->n_chan = 16; + s->maxdata = 1; + s->len_chanlist = 16; + s->range_table = &range_digital; + s->io_bits = 0; + s->insn_bits = icp_multi_insn_bits_di; + subdev++; s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_DO; @@ -901,7 +897,6 @@ static const struct boardtype boardtypes[] = { .n_aichan = 16, .n_aichand = 8, .n_aochan = 4, - .n_dichan = 16, .ai_maxdata = 0x0fff, .ao_maxdata = 0x0fff, .rangelist_ai = &range_analog, -- cgit v0.10.2 From fafe91a8b2ea372b76e0cbad995cea8afd77b5da Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 13:46:17 -0700 Subject: staging: comedi: icp_multi: remove n_aochan from boardinfo There is only one board type supported by this driver and the number of analog output channels is constant. Remove the boardinfo for it and just open-code the value. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index 7ad58e3..a4c6af9 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -132,7 +132,6 @@ struct boardtype { char cardtype; /* 0=ICP Multi */ int n_aichan; /* num of A/D chans */ int n_aichand; /* num of A/D chans in diff mode */ - int n_aochan; /* num of D/A chans */ int ai_maxdata; /* resolution of A/D */ int ao_maxdata; /* resolution of D/A */ const struct comedi_lrange *rangelist_ai; /* rangelist for A/D */ @@ -685,28 +684,28 @@ static int icp_multi_reset(struct comedi_device *dev) writew(0, devpriv->io_addr + ICP_MULTI_INT_EN); writew(0x00ff, devpriv->io_addr + ICP_MULTI_INT_STAT); - if (this_board->n_aochan) - /* Set DACs to 0..5V range and 0V output */ - for (i = 0; i < this_board->n_aochan; i++) { - devpriv->DacCmdStatus &= 0xfcce; + /* Set DACs to 0..5V range and 0V output */ + for (i = 0; i < 4; i++) { + devpriv->DacCmdStatus &= 0xfcce; - /* Set channel number */ - devpriv->DacCmdStatus |= (i << 8); + /* Set channel number */ + devpriv->DacCmdStatus |= (i << 8); - /* Output 0V */ - writew(0, devpriv->io_addr + ICP_MULTI_AO); + /* Output 0V */ + writew(0, devpriv->io_addr + ICP_MULTI_AO); - /* Set start conversion bit */ - devpriv->DacCmdStatus |= DAC_ST; + /* Set start conversion bit */ + devpriv->DacCmdStatus |= DAC_ST; - /* Output to command / status register */ - writew(devpriv->DacCmdStatus, - devpriv->io_addr + ICP_MULTI_DAC_CSR); + /* Output to command / status register */ + writew(devpriv->DacCmdStatus, + devpriv->io_addr + ICP_MULTI_DAC_CSR); - /* Delay to allow DAC time to recover */ - udelay(1); - } - /* Digital outputs to 0 */ + /* Delay to allow DAC time to recover */ + udelay(1); + } + + /* Digital outputs to 0 */ writew(0, devpriv->io_addr + ICP_MULTI_DO); return 0; @@ -772,8 +771,7 @@ static int icp_multi_attach(struct comedi_device *dev, n_subdevices = 0; if (this_board->n_aichan) n_subdevices++; - if (this_board->n_aochan) - n_subdevices++; + n_subdevices++; n_subdevices++; n_subdevices++; n_subdevices++; @@ -820,18 +818,16 @@ static int icp_multi_attach(struct comedi_device *dev, subdev++; } - if (this_board->n_aochan) { - s = &dev->subdevices[subdev]; - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = this_board->n_aochan; - s->maxdata = this_board->ao_maxdata; - s->len_chanlist = this_board->n_aochan; - s->range_table = &range_analog; - s->insn_write = icp_multi_insn_write_ao; - s->insn_read = icp_multi_insn_read_ao; - subdev++; - } + s = &dev->subdevices[subdev]; + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = 4; + s->maxdata = this_board->ao_maxdata; + s->len_chanlist = 4; + s->range_table = &range_analog; + s->insn_write = icp_multi_insn_write_ao; + s->insn_read = icp_multi_insn_read_ao; + subdev++; s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_DI; @@ -896,7 +892,6 @@ static const struct boardtype boardtypes[] = { .cardtype = TYPE_ICP_MULTI, .n_aichan = 16, .n_aichand = 8, - .n_aochan = 4, .ai_maxdata = 0x0fff, .ao_maxdata = 0x0fff, .rangelist_ai = &range_analog, -- cgit v0.10.2 From 281ecb066de68938ce551a7a22d139bc103251a4 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 13:46:34 -0700 Subject: staging: comedi: icp_multi: remove n_aichan from boardinfo There is only one board type supported by this driver and the number of analog input channels is constant. Remove the boardinfo for it and just open-code the value. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index a4c6af9..88f033c 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -130,7 +130,6 @@ struct boardtype { int iorange; /* I/O range len */ char have_irq; /* 1=card support IRQ */ char cardtype; /* 0=ICP Multi */ - int n_aichan; /* num of A/D chans */ int n_aichand; /* num of A/D chans in diff mode */ int ai_maxdata; /* resolution of A/D */ int ao_maxdata; /* resolution of D/A */ @@ -650,7 +649,7 @@ static int check_channel_list(struct comedi_device *dev, return 0; } } else { - if (CR_CHAN(chanlist[i]) > this_board->n_aichan) { + if (CR_CHAN(chanlist[i]) > s->n_chan) { comedi_error(dev, "Incorrect ai channel number"); return 0; @@ -769,8 +768,7 @@ static int icp_multi_attach(struct comedi_device *dev, dev->board_name = this_board->name; n_subdevices = 0; - if (this_board->n_aichan) - n_subdevices++; + n_subdevices++; n_subdevices++; n_subdevices++; n_subdevices++; @@ -803,20 +801,18 @@ static int icp_multi_attach(struct comedi_device *dev, subdev = 0; - if (this_board->n_aichan) { - s = &dev->subdevices[subdev]; - dev->read_subdev = s; - s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND; - if (this_board->n_aichand) - s->subdev_flags |= SDF_DIFF; - s->n_chan = this_board->n_aichan; - s->maxdata = this_board->ai_maxdata; - s->len_chanlist = this_board->n_aichan; - s->range_table = this_board->rangelist_ai; - s->insn_read = icp_multi_insn_read_ai; - subdev++; - } + s = &dev->subdevices[subdev]; + dev->read_subdev = s; + s->type = COMEDI_SUBD_AI; + s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND; + if (this_board->n_aichand) + s->subdev_flags |= SDF_DIFF; + s->n_chan = 16; + s->maxdata = this_board->ai_maxdata; + s->len_chanlist = 16; + s->range_table = this_board->rangelist_ai; + s->insn_read = icp_multi_insn_read_ai; + subdev++; s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_AO; @@ -890,7 +886,6 @@ static const struct boardtype boardtypes[] = { .iorange = IORANGE_ICP_MULTI, .have_irq = 1, .cardtype = TYPE_ICP_MULTI, - .n_aichan = 16, .n_aichand = 8, .ai_maxdata = 0x0fff, .ao_maxdata = 0x0fff, -- cgit v0.10.2 From 08567ce9b6b6235897d0895630b88d4cb84f9784 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 13:47:03 -0700 Subject: staging: comedi: icp_multi: remove n_aichand from boardinfo The analog inputs for this board always support differential inputs and the number of channels is half the normal analog input number. Remove the n_aichand field from the boardinfo and fix the code accordingly. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index 88f033c..35f5f31 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -130,7 +130,6 @@ struct boardtype { int iorange; /* I/O range len */ char have_irq; /* 1=card support IRQ */ char cardtype; /* 0=ICP Multi */ - int n_aichand; /* num of A/D chans in diff mode */ int ai_maxdata; /* resolution of A/D */ int ao_maxdata; /* resolution of D/A */ const struct comedi_lrange *rangelist_ai; /* rangelist for A/D */ @@ -643,7 +642,7 @@ static int check_channel_list(struct comedi_device *dev, for (i = 0; i < n_chan; i++) { /* Check that channel number is < maximum */ if (CR_AREF(chanlist[i]) == AREF_DIFF) { - if (CR_CHAN(chanlist[i]) > this_board->n_aichand) { + if (CR_CHAN(chanlist[i]) > (s->nchan / 2)) { comedi_error(dev, "Incorrect differential ai ch-nr"); return 0; @@ -804,9 +803,7 @@ static int icp_multi_attach(struct comedi_device *dev, s = &dev->subdevices[subdev]; dev->read_subdev = s; s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND; - if (this_board->n_aichand) - s->subdev_flags |= SDF_DIFF; + s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF; s->n_chan = 16; s->maxdata = this_board->ai_maxdata; s->len_chanlist = 16; @@ -886,7 +883,6 @@ static const struct boardtype boardtypes[] = { .iorange = IORANGE_ICP_MULTI, .have_irq = 1, .cardtype = TYPE_ICP_MULTI, - .n_aichand = 8, .ai_maxdata = 0x0fff, .ao_maxdata = 0x0fff, .rangelist_ai = &range_analog, -- cgit v0.10.2 From 68b82e0954c3a80b230722f5315f7d41eca3d0a2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 13:47:20 -0700 Subject: staging: comedi: icp_multi: remove ao_maxdata from boardinfo The analog outputs of this board always have 12-bit resolution. Remove the boardinfo and just open-code the value. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index 35f5f31..3a28f91 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -131,7 +131,6 @@ struct boardtype { char have_irq; /* 1=card support IRQ */ char cardtype; /* 0=ICP Multi */ int ai_maxdata; /* resolution of A/D */ - int ao_maxdata; /* resolution of D/A */ const struct comedi_lrange *rangelist_ai; /* rangelist for A/D */ const char *rangecode; /* range codes for programming */ const struct comedi_lrange *rangelist_ao; /* rangelist for D/A */ @@ -815,7 +814,7 @@ static int icp_multi_attach(struct comedi_device *dev, s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; s->n_chan = 4; - s->maxdata = this_board->ao_maxdata; + s->maxdata = 0x0fff; s->len_chanlist = 4; s->range_table = &range_analog; s->insn_write = icp_multi_insn_write_ao; @@ -884,7 +883,6 @@ static const struct boardtype boardtypes[] = { .have_irq = 1, .cardtype = TYPE_ICP_MULTI, .ai_maxdata = 0x0fff, - .ao_maxdata = 0x0fff, .rangelist_ai = &range_analog, .rangecode = range_codes_analog, .rangelist_ao = &range_analog, -- cgit v0.10.2 From efac035ca6eaaf6ca353e730055022cdf03ae7bb Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 13:47:36 -0700 Subject: staging: comedi: icp_multi: remove ai_maxdata from boardinfo The analog inputs of this board always have 12-bit resolution. Remove the boardinfo and just open-code the value. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index 3a28f91..ef2359f 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -130,7 +130,6 @@ struct boardtype { int iorange; /* I/O range len */ char have_irq; /* 1=card support IRQ */ char cardtype; /* 0=ICP Multi */ - int ai_maxdata; /* resolution of A/D */ const struct comedi_lrange *rangelist_ai; /* rangelist for A/D */ const char *rangecode; /* range codes for programming */ const struct comedi_lrange *rangelist_ao; /* rangelist for D/A */ @@ -804,7 +803,7 @@ static int icp_multi_attach(struct comedi_device *dev, s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF; s->n_chan = 16; - s->maxdata = this_board->ai_maxdata; + s->maxdata = 0x0fff; s->len_chanlist = 16; s->range_table = this_board->rangelist_ai; s->insn_read = icp_multi_insn_read_ai; @@ -882,7 +881,6 @@ static const struct boardtype boardtypes[] = { .iorange = IORANGE_ICP_MULTI, .have_irq = 1, .cardtype = TYPE_ICP_MULTI, - .ai_maxdata = 0x0fff, .rangelist_ai = &range_analog, .rangecode = range_codes_analog, .rangelist_ao = &range_analog, -- cgit v0.10.2 From d4fb0f256028f16de8e33da7007fcf711c817929 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 13:47:52 -0700 Subject: staging: comedi: icp_multi: remove ranglist_ao from boardinfo This variable is not used by the driver. Remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index ef2359f..e749622 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -132,7 +132,6 @@ struct boardtype { char cardtype; /* 0=ICP Multi */ const struct comedi_lrange *rangelist_ai; /* rangelist for A/D */ const char *rangecode; /* range codes for programming */ - const struct comedi_lrange *rangelist_ao; /* rangelist for D/A */ }; struct icp_multi_private { @@ -883,7 +882,6 @@ static const struct boardtype boardtypes[] = { .cardtype = TYPE_ICP_MULTI, .rangelist_ai = &range_analog, .rangecode = range_codes_analog, - .rangelist_ao = &range_analog, }, }; -- cgit v0.10.2 From abdeac3fd65534dd9b8f46a0fa3ce5c9d545a8f7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 13:48:09 -0700 Subject: staging: comedi: icp_multi: remove rangelist_ai from boardinfo There is only one board type supported by this driver and the analog input ranges are constant. Remove the boardinfo for it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index e749622..3a2fc74 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -130,7 +130,6 @@ struct boardtype { int iorange; /* I/O range len */ char have_irq; /* 1=card support IRQ */ char cardtype; /* 0=ICP Multi */ - const struct comedi_lrange *rangelist_ai; /* rangelist for A/D */ const char *rangecode; /* range codes for programming */ }; @@ -804,7 +803,7 @@ static int icp_multi_attach(struct comedi_device *dev, s->n_chan = 16; s->maxdata = 0x0fff; s->len_chanlist = 16; - s->range_table = this_board->rangelist_ai; + s->range_table = &range_analog; s->insn_read = icp_multi_insn_read_ai; subdev++; @@ -880,7 +879,6 @@ static const struct boardtype boardtypes[] = { .iorange = IORANGE_ICP_MULTI, .have_irq = 1, .cardtype = TYPE_ICP_MULTI, - .rangelist_ai = &range_analog, .rangecode = range_codes_analog, }, }; -- cgit v0.10.2 From d68a8635c5b706e3c037d89fd130e62ddce5c823 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 13:48:27 -0700 Subject: staging: comedi: icp_multi: remove rangecode from boardinfo The analog inputs and outputs for this driver use the same table to set the analog range. Remove the boardinfo for it and just reference the table directly. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index 3a2fc74..95262c7 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -130,7 +130,6 @@ struct boardtype { int iorange; /* I/O range len */ char have_irq; /* 1=card support IRQ */ char cardtype; /* 0=ICP Multi */ - const char *rangecode; /* range codes for programming */ }; struct icp_multi_private { @@ -212,7 +211,7 @@ static void setup_channel_list(struct comedi_device *dev, devpriv->AdcCmdStatus |= (chanprog << 8); /* Get range for current channel */ - range = this_board->rangecode[CR_RANGE(chanlist[i])]; + range = range_codes_analog[CR_RANGE(chanlist[i])]; /* Set range. bits 4-5 */ devpriv->AdcCmdStatus |= range; @@ -351,7 +350,7 @@ static int icp_multi_insn_write_ao(struct comedi_device *dev, /* Bit 5 = 1 : 10V */ /* Bits 8-9 : Channel number */ devpriv->DacCmdStatus &= 0xfccf; - devpriv->DacCmdStatus |= this_board->rangecode[range]; + devpriv->DacCmdStatus |= range_codes_analog[range]; devpriv->DacCmdStatus |= (chan << 8); writew(devpriv->DacCmdStatus, devpriv->io_addr + ICP_MULTI_DAC_CSR); @@ -879,7 +878,6 @@ static const struct boardtype boardtypes[] = { .iorange = IORANGE_ICP_MULTI, .have_irq = 1, .cardtype = TYPE_ICP_MULTI, - .rangecode = range_codes_analog, }, }; -- cgit v0.10.2 From 4ba47b8f88b6893e79e704d37bad7044c376fc4f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 13:48:50 -0700 Subject: staging: comedi: icp_multi: remove cardtype from boardinfo This variable is not used in the driver. Remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index 95262c7..e40c8f0 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -60,9 +60,6 @@ Options: #define PCI_DEVICE_ID_ICP_MULTI 0x8000 -/* Hardware types of the cards */ -#define TYPE_ICP_MULTI 0 - #define IORANGE_ICP_MULTI 32 #define ICP_MULTI_ADC_CSR 0 /* R/W: ADC command/status register */ @@ -129,7 +126,6 @@ struct boardtype { int device_id; int iorange; /* I/O range len */ char have_irq; /* 1=card support IRQ */ - char cardtype; /* 0=ICP Multi */ }; struct icp_multi_private { @@ -877,7 +873,6 @@ static const struct boardtype boardtypes[] = { .device_id = PCI_DEVICE_ID_ICP_MULTI, .iorange = IORANGE_ICP_MULTI, .have_irq = 1, - .cardtype = TYPE_ICP_MULTI, }, }; -- cgit v0.10.2 From 22d5ab0201f2621ebe834f309cb94d712427e62c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 13:49:10 -0700 Subject: staging: comedi: icp_multi: remove iorange from boardinfo This variable is not used in the driver. Remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index e40c8f0..0fdab8d 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -60,8 +60,6 @@ Options: #define PCI_DEVICE_ID_ICP_MULTI 0x8000 -#define IORANGE_ICP_MULTI 32 - #define ICP_MULTI_ADC_CSR 0 /* R/W: ADC command/status register */ #define ICP_MULTI_AI 2 /* R: Analogue input data */ #define ICP_MULTI_DAC_CSR 4 /* R/W: DAC command/status register */ @@ -124,7 +122,6 @@ static unsigned short pci_list_builded; /*>0 list of card is known */ struct boardtype { const char *name; /* driver name */ int device_id; - int iorange; /* I/O range len */ char have_irq; /* 1=card support IRQ */ }; @@ -871,7 +868,6 @@ static const struct boardtype boardtypes[] = { { .name = "icp_multi", .device_id = PCI_DEVICE_ID_ICP_MULTI, - .iorange = IORANGE_ICP_MULTI, .have_irq = 1, }, }; -- cgit v0.10.2 From aa1b2cb3c5930bb332d756bd566771dcc83f251b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 13:49:26 -0700 Subject: staging: comedi: icp_multi: remove have_irq from boardinfo The board supported by this driver always supports interrupts. Remove the boardinfo. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index 0fdab8d..36336c1 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -122,7 +122,6 @@ static unsigned short pci_list_builded; /*>0 list of card is known */ struct boardtype { const char *name; /* driver name */ int device_id; - char have_irq; /* 1=card support IRQ */ }; struct icp_multi_private { @@ -767,20 +766,17 @@ static int icp_multi_attach(struct comedi_device *dev, icp_multi_reset(dev); - if (this_board->have_irq) { - if (irq) { - if (request_irq(irq, interrupt_service_icp_multi, - IRQF_SHARED, "Inova Icp Multi", dev)) { - printk(KERN_WARNING - "unable to allocate IRQ %u, DISABLING IT", - irq); - irq = 0; /* Can't use IRQ */ - } else - printk(KERN_WARNING ", irq=%u", irq); + if (irq) { + if (request_irq(irq, interrupt_service_icp_multi, + IRQF_SHARED, "Inova Icp Multi", dev)) { + printk(KERN_WARNING + "unable to allocate IRQ %u, DISABLING IT", + irq); + irq = 0; /* Can't use IRQ */ } else - printk(KERN_WARNING ", IRQ disabled"); + printk(KERN_WARNING ", irq=%u", irq); } else - irq = 0; + printk(KERN_WARNING ", IRQ disabled"); dev->irq = irq; @@ -868,7 +864,6 @@ static const struct boardtype boardtypes[] = { { .name = "icp_multi", .device_id = PCI_DEVICE_ID_ICP_MULTI, - .have_irq = 1, }, }; -- cgit v0.10.2 From 12b4a097b6fd6d7c7e18dbb40d2ed62cdc26cd3b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 13:49:43 -0700 Subject: staging: comedi: icp_multi: the number of subdevices is fixed This board always has 5 subdevices. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index 36336c1..4d2952e 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -700,7 +700,7 @@ static int icp_multi_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct comedi_subdevice *s; - int ret, subdev, n_subdevices; + int ret; unsigned int irq; struct pcilst_struct *card = NULL; resource_size_t io_addr[5], iobase; @@ -753,14 +753,7 @@ static int icp_multi_attach(struct comedi_device *dev, dev->board_name = this_board->name; - n_subdevices = 0; - n_subdevices++; - n_subdevices++; - n_subdevices++; - n_subdevices++; - n_subdevices++; - - ret = comedi_alloc_subdevices(dev, n_subdevices); + ret = comedi_alloc_subdevices(dev, 5); if (ret) return ret; @@ -782,9 +775,7 @@ static int icp_multi_attach(struct comedi_device *dev, printk(KERN_WARNING ".\n"); - subdev = 0; - - s = &dev->subdevices[subdev]; + s = &dev->subdevices[0]; dev->read_subdev = s; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF; @@ -793,9 +784,8 @@ static int icp_multi_attach(struct comedi_device *dev, s->len_chanlist = 16; s->range_table = &range_analog; s->insn_read = icp_multi_insn_read_ai; - subdev++; - s = &dev->subdevices[subdev]; + s = &dev->subdevices[1]; s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; s->n_chan = 4; @@ -804,9 +794,8 @@ static int icp_multi_attach(struct comedi_device *dev, s->range_table = &range_analog; s->insn_write = icp_multi_insn_write_ao; s->insn_read = icp_multi_insn_read_ao; - subdev++; - s = &dev->subdevices[subdev]; + s = &dev->subdevices[2]; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; s->n_chan = 16; @@ -815,9 +804,8 @@ static int icp_multi_attach(struct comedi_device *dev, s->range_table = &range_digital; s->io_bits = 0; s->insn_bits = icp_multi_insn_bits_di; - subdev++; - s = &dev->subdevices[subdev]; + s = &dev->subdevices[3]; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE | SDF_READABLE; s->n_chan = 8; @@ -827,9 +815,8 @@ static int icp_multi_attach(struct comedi_device *dev, s->io_bits = 0xff; s->state = 0; s->insn_bits = icp_multi_insn_bits_do; - subdev++; - s = &dev->subdevices[subdev]; + s = &dev->subdevices[4]; s->type = COMEDI_SUBD_COUNTER; s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; s->n_chan = 4; @@ -838,7 +825,6 @@ static int icp_multi_attach(struct comedi_device *dev, s->state = 0; s->insn_read = icp_multi_insn_read_ctr; s->insn_write = icp_multi_insn_write_ctr; - subdev++; devpriv->valid = 1; -- cgit v0.10.2 From 798cdd05e00f2ffb2aa763f5bc2605cd9c08a265 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 13:50:06 -0700 Subject: staging: comedi: icp_multi: remove board attach noise Remove the kernel message noise during the attach of the board. Use a simple/clean dev_info at the end of the attach. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index 4d2952e..4673a89 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -706,10 +706,6 @@ static int icp_multi_attach(struct comedi_device *dev, resource_size_t io_addr[5], iobase; unsigned char pci_bus, pci_slot, pci_func; - printk(KERN_WARNING - "icp_multi EDBG: BGN: icp_multi_attach(...)\n"); - - /* Allocate private data storage space */ ret = alloc_private(dev, sizeof(struct icp_multi_private)); if (ret < 0) return ret; @@ -718,10 +714,6 @@ static int icp_multi_attach(struct comedi_device *dev, if (pci_list_builded++ == 0) pci_card_list_init(PCI_VENDOR_ID_ICP, 0); - printk(KERN_WARNING - "Anne's comedi%d: icp_multi: board=%s", dev->minor, - this_board->name); - card = select_and_alloc_pci_card(PCI_VENDOR_ID_ICP, this_board->device_id, it->options[0], it->options[1]); @@ -732,24 +724,14 @@ static int icp_multi_attach(struct comedi_device *dev, devpriv->card = card; if ((pci_card_data(card, &pci_bus, &pci_slot, &pci_func, &io_addr[0], - &irq)) < 0) { - printk(KERN_WARNING " - Can't get configuration data!\n"); + &irq)) < 0) return -EIO; - } iobase = io_addr[2]; devpriv->phys_iobase = iobase; - - printk(KERN_WARNING - ", b:s:f=%d:%d:%d, io=0x%8llx \n", pci_bus, pci_slot, pci_func, - (unsigned long long)iobase); - devpriv->io_addr = ioremap(iobase, ICP_MULTI_SIZE); - - if (devpriv->io_addr == NULL) { - printk(KERN_WARNING "ioremap failed.\n"); + if (devpriv->io_addr == NULL) return -ENOMEM; - } dev->board_name = this_board->name; @@ -762,19 +744,12 @@ static int icp_multi_attach(struct comedi_device *dev, if (irq) { if (request_irq(irq, interrupt_service_icp_multi, IRQF_SHARED, "Inova Icp Multi", dev)) { - printk(KERN_WARNING - "unable to allocate IRQ %u, DISABLING IT", - irq); irq = 0; /* Can't use IRQ */ - } else - printk(KERN_WARNING ", irq=%u", irq); - } else - printk(KERN_WARNING ", IRQ disabled"); + } + } dev->irq = irq; - printk(KERN_WARNING ".\n"); - s = &dev->subdevices[0]; dev->read_subdev = s; s->type = COMEDI_SUBD_AI; @@ -828,6 +803,9 @@ static int icp_multi_attach(struct comedi_device *dev, devpriv->valid = 1; + dev_info(dev->class_dev, "%s attached, irq %sabled\n", + dev->board_name, dev->irq ? "en" : "dis"); + return 0; } -- cgit v0.10.2 From 194b9e3cf49319231e8b47125dc5d043350f4406 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 13:50:41 -0700 Subject: staging: comedi: icp_multi: use attach_pci callback Convert this PCI driver to use the comedi PCI auto config attach mechanism by adding an 'attach_pci' callback function. Since the driver does not require any external configuration options, and the legacy 'attach' callback is now optional, remove it. The boardinfo is also not needed now so remove it also. This also allows removing the icp_multi.h header completely. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index 4673a89..14b4ce5 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -44,10 +44,7 @@ There are 4 x 12-bit Analogue Outputs. Ranges : 5V, 10V, +/-5V, +/-10V 4 x 16-bit counters -Options: - [0] - PCI bus number - if bus number and slot number are 0, - then driver search for first unused card - [1] - PCI slot number +Configuration options: not applicable, uses PCI auto config */ #include @@ -56,8 +53,6 @@ Options: #include #include -#include "icp_multi.h" - #define PCI_DEVICE_ID_ICP_MULTI 0x8000 #define ICP_MULTI_ADC_CSR 0 /* R/W: ADC command/status register */ @@ -117,18 +112,10 @@ static const char range_codes_analog[] = { 0x00, 0x20, 0x10, 0x30 }; Data & Structure declarations ============================================================================== */ -static unsigned short pci_list_builded; /*>0 list of card is known */ - -struct boardtype { - const char *name; /* driver name */ - int device_id; -}; struct icp_multi_private { - struct pcilst_struct *card; /* pointer to card */ char valid; /* card is usable */ void __iomem *io_addr; /* Pointer to mapped io address */ - resource_size_t phys_iobase; /* Physical io address */ unsigned int AdcCmdStatus; /* ADC Command/Status register */ unsigned int DacCmdStatus; /* DAC Command/Status register */ unsigned int IntEnable; /* Interrupt Enable register */ @@ -144,7 +131,6 @@ struct icp_multi_private { }; #define devpriv ((struct icp_multi_private *)dev->private) -#define this_board ((const struct boardtype *)dev->board_ptr) /* ============================================================================== @@ -696,60 +682,43 @@ static int icp_multi_reset(struct comedi_device *dev) return 0; } -static int icp_multi_attach(struct comedi_device *dev, - struct comedi_devconfig *it) +static int icp_multi_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) { struct comedi_subdevice *s; + resource_size_t iobase; int ret; - unsigned int irq; - struct pcilst_struct *card = NULL; - resource_size_t io_addr[5], iobase; - unsigned char pci_bus, pci_slot, pci_func; + + comedi_set_hw_dev(dev, &pcidev->dev); + dev->board_name = dev->driver->driver_name; ret = alloc_private(dev, sizeof(struct icp_multi_private)); if (ret < 0) return ret; - /* Initialise list of PCI cards in system, if not already done so */ - if (pci_list_builded++ == 0) - pci_card_list_init(PCI_VENDOR_ID_ICP, 0); - - card = select_and_alloc_pci_card(PCI_VENDOR_ID_ICP, - this_board->device_id, it->options[0], - it->options[1]); - - if (card == NULL) - return -EIO; - - devpriv->card = card; - - if ((pci_card_data(card, &pci_bus, &pci_slot, &pci_func, &io_addr[0], - &irq)) < 0) - return -EIO; + ret = comedi_pci_enable(pcidev, dev->board_name); + if (ret) + return ret; + iobase = pci_resource_start(pcidev, 2); + dev->iobase = iobase; - iobase = io_addr[2]; - devpriv->phys_iobase = iobase; devpriv->io_addr = ioremap(iobase, ICP_MULTI_SIZE); - if (devpriv->io_addr == NULL) + if (!devpriv->io_addr) return -ENOMEM; - dev->board_name = this_board->name; - ret = comedi_alloc_subdevices(dev, 5); if (ret) return ret; icp_multi_reset(dev); - if (irq) { - if (request_irq(irq, interrupt_service_icp_multi, - IRQF_SHARED, "Inova Icp Multi", dev)) { - irq = 0; /* Can't use IRQ */ - } + if (pcidev->irq) { + ret = request_irq(pcidev->irq, interrupt_service_icp_multi, + IRQF_SHARED, dev->board_name, dev); + if (ret == 0) + dev->irq = pcidev->irq; } - dev->irq = irq; - s = &dev->subdevices[0]; dev->read_subdev = s; s->type = COMEDI_SUBD_AI; @@ -811,6 +780,8 @@ static int icp_multi_attach(struct comedi_device *dev, static void icp_multi_detach(struct comedi_device *dev) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + if (dev->private) if (devpriv->valid) icp_multi_reset(dev); @@ -818,27 +789,17 @@ static void icp_multi_detach(struct comedi_device *dev) free_irq(dev->irq, dev); if (dev->private && devpriv->io_addr) iounmap(devpriv->io_addr); - if (dev->private && devpriv->card) - pci_card_free(devpriv->card); - if (--pci_list_builded == 0) - pci_card_list_cleanup(PCI_VENDOR_ID_ICP); + if (pcidev) { + if (dev->iobase) + comedi_pci_disable(pcidev); + } } -static const struct boardtype boardtypes[] = { - { - .name = "icp_multi", - .device_id = PCI_DEVICE_ID_ICP_MULTI, - }, -}; - static struct comedi_driver icp_multi_driver = { .driver_name = "icp_multi", .module = THIS_MODULE, - .attach = icp_multi_attach, + .attach_pci = icp_multi_attach_pci, .detach = icp_multi_detach, - .num_names = ARRAY_SIZE(boardtypes), - .board_name = &boardtypes[0].name, - .offset = sizeof(struct boardtype), }; static int __devinit icp_multi_pci_probe(struct pci_dev *dev, diff --git a/drivers/staging/comedi/drivers/icp_multi.h b/drivers/staging/comedi/drivers/icp_multi.h deleted file mode 100644 index dbf9908..0000000 --- a/drivers/staging/comedi/drivers/icp_multi.h +++ /dev/null @@ -1,297 +0,0 @@ -/* - comedi/drivers/icp_multi.h - - Stuff for ICP Multi - - Author: Anne Smorthit - -*/ - -#ifndef _ICP_MULTI_H_ -#define _ICP_MULTI_H_ - -#include "../comedidev.h" - -/****************************************************************************/ - -struct pcilst_struct { - struct pcilst_struct *next; - int used; - struct pci_dev *pcidev; - unsigned short vendor; - unsigned short device; - unsigned char pci_bus; - unsigned char pci_slot; - unsigned char pci_func; - resource_size_t io_addr[5]; - unsigned int irq; -}; - -struct pcilst_struct *inova_devices; -/* ptr to root list of all Inova devices */ - -/****************************************************************************/ - -static void pci_card_list_init(unsigned short pci_vendor, char display); -static void pci_card_list_cleanup(unsigned short pci_vendor); -static struct pcilst_struct *find_free_pci_card_by_device(unsigned short - vendor_id, - unsigned short - device_id); -static int find_free_pci_card_by_position(unsigned short vendor_id, - unsigned short device_id, - unsigned short pci_bus, - unsigned short pci_slot, - struct pcilst_struct **card); -static struct pcilst_struct *select_and_alloc_pci_card(unsigned short vendor_id, - unsigned short device_id, - unsigned short pci_bus, - unsigned short pci_slot); - -static int pci_card_alloc(struct pcilst_struct *amcc); -static int pci_card_free(struct pcilst_struct *amcc); -static void pci_card_list_display(void); -static int pci_card_data(struct pcilst_struct *amcc, - unsigned char *pci_bus, unsigned char *pci_slot, - unsigned char *pci_func, resource_size_t * io_addr, - unsigned int *irq); - -/****************************************************************************/ - -/* build list of Inova cards in this system */ -static void pci_card_list_init(unsigned short pci_vendor, char display) -{ - struct pci_dev *pcidev = NULL; - struct pcilst_struct *inova, *last; - int i; - - inova_devices = NULL; - last = NULL; - - for_each_pci_dev(pcidev) { - if (pcidev->vendor == pci_vendor) { - inova = kzalloc(sizeof(*inova), GFP_KERNEL); - if (!inova) { - printk - ("icp_multi: pci_card_list_init: allocation failed\n"); - pci_dev_put(pcidev); - break; - } - - inova->pcidev = pci_dev_get(pcidev); - if (last) { - last->next = inova; - } else { - inova_devices = inova; - } - last = inova; - - inova->vendor = pcidev->vendor; - inova->device = pcidev->device; - inova->pci_bus = pcidev->bus->number; - inova->pci_slot = PCI_SLOT(pcidev->devfn); - inova->pci_func = PCI_FUNC(pcidev->devfn); - /* Note: resources may be invalid if PCI device - * not enabled, but they are corrected in - * pci_card_alloc. */ - for (i = 0; i < 5; i++) - inova->io_addr[i] = - pci_resource_start(pcidev, i); - inova->irq = pcidev->irq; - } - } - - if (display) - pci_card_list_display(); -} - -/****************************************************************************/ -/* free up list of amcc cards in this system */ -static void pci_card_list_cleanup(unsigned short pci_vendor) -{ - struct pcilst_struct *inova, *next; - - for (inova = inova_devices; inova; inova = next) { - next = inova->next; - pci_dev_put(inova->pcidev); - kfree(inova); - } - - inova_devices = NULL; -} - -/****************************************************************************/ -/* find first unused card with this device_id */ -static struct pcilst_struct *find_free_pci_card_by_device(unsigned short - vendor_id, - unsigned short - device_id) -{ - struct pcilst_struct *inova, *next; - - for (inova = inova_devices; inova; inova = next) { - next = inova->next; - if ((!inova->used) && (inova->device == device_id) - && (inova->vendor == vendor_id)) - return inova; - - } - - return NULL; -} - -/****************************************************************************/ -/* find card on requested position */ -static int find_free_pci_card_by_position(unsigned short vendor_id, - unsigned short device_id, - unsigned short pci_bus, - unsigned short pci_slot, - struct pcilst_struct **card) -{ - struct pcilst_struct *inova, *next; - - *card = NULL; - for (inova = inova_devices; inova; inova = next) { - next = inova->next; - if ((inova->vendor == vendor_id) && (inova->device == device_id) - && (inova->pci_bus == pci_bus) - && (inova->pci_slot == pci_slot)) { - if (!(inova->used)) { - *card = inova; - return 0; /* ok, card is found */ - } else { - return 2; /* card exist but is used */ - } - } - } - - return 1; /* no card found */ -} - -/****************************************************************************/ -/* mark card as used */ -static int pci_card_alloc(struct pcilst_struct *inova) -{ - int i; - - if (!inova) { - printk(" - BUG!! inova is NULL!\n"); - return -1; - } - - if (inova->used) - return 1; - if (comedi_pci_enable(inova->pcidev, "icp_multi")) { - printk(" - Can't enable PCI device and request regions!\n"); - return -1; - } - /* Resources will be accurate now. */ - for (i = 0; i < 5; i++) - inova->io_addr[i] = pci_resource_start(inova->pcidev, i); - inova->irq = inova->pcidev->irq; - inova->used = 1; - return 0; -} - -/****************************************************************************/ -/* mark card as free */ -static int pci_card_free(struct pcilst_struct *inova) -{ - if (!inova) - return -1; - - if (!inova->used) - return 1; - inova->used = 0; - comedi_pci_disable(inova->pcidev); - return 0; -} - -/****************************************************************************/ -/* display list of found cards */ -static void pci_card_list_display(void) -{ - struct pcilst_struct *inova, *next; - - printk("Anne's List of pci cards\n"); - printk("bus:slot:func vendor device io_inova io_daq irq used\n"); - - for (inova = inova_devices; inova; inova = next) { - next = inova->next; - printk - ("%2d %2d %2d 0x%4x 0x%4x 0x%8llx 0x%8llx %2u %2d\n", - inova->pci_bus, inova->pci_slot, inova->pci_func, - inova->vendor, inova->device, - (unsigned long long)inova->io_addr[0], - (unsigned long long)inova->io_addr[2], inova->irq, - inova->used); - - } -} - -/****************************************************************************/ -/* return all card information for driver */ -static int pci_card_data(struct pcilst_struct *inova, - unsigned char *pci_bus, unsigned char *pci_slot, - unsigned char *pci_func, resource_size_t * io_addr, - unsigned int *irq) -{ - int i; - - if (!inova) - return -1; - *pci_bus = inova->pci_bus; - *pci_slot = inova->pci_slot; - *pci_func = inova->pci_func; - for (i = 0; i < 5; i++) - io_addr[i] = inova->io_addr[i]; - *irq = inova->irq; - return 0; -} - -/****************************************************************************/ -/* select and alloc card */ -static struct pcilst_struct *select_and_alloc_pci_card(unsigned short vendor_id, - unsigned short device_id, - unsigned short pci_bus, - unsigned short pci_slot) -{ - struct pcilst_struct *card; - int err; - - if ((pci_bus < 1) & (pci_slot < 1)) { /* use autodetection */ - - card = find_free_pci_card_by_device(vendor_id, device_id); - if (card == NULL) { - printk(" - Unused card not found in system!\n"); - return NULL; - } - } else { - switch (find_free_pci_card_by_position(vendor_id, device_id, - pci_bus, pci_slot, - &card)) { - case 1: - printk - (" - Card not found on requested position b:s %d:%d!\n", - pci_bus, pci_slot); - return NULL; - case 2: - printk - (" - Card on requested position is used b:s %d:%d!\n", - pci_bus, pci_slot); - return NULL; - } - } - - err = pci_card_alloc(card); - if (err != 0) { - if (err > 0) - printk(" - Can't allocate card!\n"); - /* else: error already printed. */ - return NULL; - } - - return card; -} - -#endif -- cgit v0.10.2 From 65e9e2dc2cca5590affcc299454a783578c9457b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 13:50:56 -0700 Subject: staging: comedi: icp_multi: remove devpriv macro This macro relies on a local variable having a specific name. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index 14b4ce5..c340855 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -130,8 +130,6 @@ struct icp_multi_private { unsigned int do_data; /* Remember digital output data */ }; -#define devpriv ((struct icp_multi_private *)dev->private) - /* ============================================================================== @@ -156,6 +154,7 @@ static void setup_channel_list(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int *chanlist, unsigned int n_chan) { + struct icp_multi_private *devpriv = dev->private; unsigned int i, range, chanprog; unsigned int diff; @@ -221,6 +220,7 @@ static int icp_multi_insn_read_ai(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct icp_multi_private *devpriv = dev->private; int n, timeout; /* Disable A/D conversion ready interrupt */ @@ -308,6 +308,7 @@ static int icp_multi_insn_write_ao(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct icp_multi_private *devpriv = dev->private; int n, chan, range, timeout; /* Disable D/A conversion ready interrupt */ @@ -401,6 +402,7 @@ static int icp_multi_insn_read_ao(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct icp_multi_private *devpriv = dev->private; int n, chan; /* Get channel number */ @@ -435,6 +437,8 @@ static int icp_multi_insn_bits_di(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct icp_multi_private *devpriv = dev->private; + data[1] = readw(devpriv->io_addr + ICP_MULTI_DI); return insn->n; @@ -462,6 +466,8 @@ static int icp_multi_insn_bits_do(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct icp_multi_private *devpriv = dev->private; + if (data[0]) { s->state &= ~data[0]; s->state |= (data[0] & data[1]); @@ -545,6 +551,7 @@ Parameters: static irqreturn_t interrupt_service_icp_multi(int irq, void *d) { struct comedi_device *dev = d; + struct icp_multi_private *devpriv = dev->private; int int_no; /* Is this interrupt from our board? */ @@ -649,6 +656,7 @@ Returns:int 0 = success */ static int icp_multi_reset(struct comedi_device *dev) { + struct icp_multi_private *devpriv = dev->private; unsigned int i; /* Clear INT enables and requests */ @@ -685,6 +693,7 @@ static int icp_multi_reset(struct comedi_device *dev) static int icp_multi_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) { + struct icp_multi_private *devpriv; struct comedi_subdevice *s; resource_size_t iobase; int ret; @@ -692,9 +701,10 @@ static int icp_multi_attach_pci(struct comedi_device *dev, comedi_set_hw_dev(dev, &pcidev->dev); dev->board_name = dev->driver->driver_name; - ret = alloc_private(dev, sizeof(struct icp_multi_private)); + ret = alloc_private(dev, sizeof(*devpriv)); if (ret < 0) return ret; + devpriv = dev->private; ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) @@ -781,13 +791,14 @@ static int icp_multi_attach_pci(struct comedi_device *dev, static void icp_multi_detach(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct icp_multi_private *devpriv = dev->private; - if (dev->private) + if (devpriv) if (devpriv->valid) icp_multi_reset(dev); if (dev->irq) free_irq(dev->irq, dev); - if (dev->private && devpriv->io_addr) + if (devpriv && devpriv->io_addr) iounmap(devpriv->io_addr); if (pcidev) { if (dev->iobase) -- cgit v0.10.2 From 4e4fd689ad9648202a9723658c115cc7e066df9a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 13:51:16 -0700 Subject: staging: comedi: icp_multi: remove the function description comments These comments are pretty obvious. Remove them. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index c340855..d696d4d 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -130,26 +130,6 @@ struct icp_multi_private { unsigned int do_data; /* Remember digital output data */ }; -/* -============================================================================== - -Name: setup_channel_list - -Description: - This function sets the appropriate channel selection, - differential input mode and range bits in the ADC Command/ - Status register. - -Parameters: - struct comedi_device *dev Pointer to current service structure - struct comedi_subdevice *s Pointer to current subdevice structure - unsigned int *chanlist Pointer to packed channel list - unsigned int n_chan Number of channels to scan - -Returns:Void - -============================================================================== -*/ static void setup_channel_list(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int *chanlist, unsigned int n_chan) @@ -198,24 +178,6 @@ static void setup_channel_list(struct comedi_device *dev, } } -/* -============================================================================== - -Name: icp_multi_insn_read_ai - -Description: - This function reads a single analogue input. - -Parameters: - struct comedi_device *dev Pointer to current device structure - struct comedi_subdevice *s Pointer to current subdevice structure - struct comedi_insn *insn Pointer to current comedi instruction - unsigned int *data Pointer to analogue input data - -Returns:int Nmuber of instructions executed - -============================================================================== -*/ static int icp_multi_insn_read_ai(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -286,24 +248,6 @@ conv_finish: return n; } -/* -============================================================================== - -Name: icp_multi_insn_write_ao - -Description: - This function writes a single analogue output. - -Parameters: - struct comedi_device *dev Pointer to current device structure - struct comedi_subdevice *s Pointer to current subdevice structure - struct comedi_insn *insn Pointer to current comedi instruction - unsigned int *data Pointer to analogue output data - -Returns:int Nmuber of instructions executed - -============================================================================== -*/ static int icp_multi_insn_write_ao(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -380,24 +324,6 @@ dac_ready: return n; } -/* -============================================================================== - -Name: icp_multi_insn_read_ao - -Description: - This function reads a single analogue output. - -Parameters: - struct comedi_device *dev Pointer to current device structure - struct comedi_subdevice *s Pointer to current subdevice structure - struct comedi_insn *insn Pointer to current comedi instruction - unsigned int *data Pointer to analogue output data - -Returns:int Nmuber of instructions executed - -============================================================================== -*/ static int icp_multi_insn_read_ao(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -415,24 +341,6 @@ static int icp_multi_insn_read_ao(struct comedi_device *dev, return n; } -/* -============================================================================== - -Name: icp_multi_insn_bits_di - -Description: - This function reads the digital inputs. - -Parameters: - struct comedi_device *dev Pointer to current device structure - struct comedi_subdevice *s Pointer to current subdevice structure - struct comedi_insn *insn Pointer to current comedi instruction - unsigned int *data Pointer to analogue output data - -Returns:int Nmuber of instructions executed - -============================================================================== -*/ static int icp_multi_insn_bits_di(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -444,24 +352,6 @@ static int icp_multi_insn_bits_di(struct comedi_device *dev, return insn->n; } -/* -============================================================================== - -Name: icp_multi_insn_bits_do - -Description: - This function writes the appropriate digital outputs. - -Parameters: - struct comedi_device *dev Pointer to current device structure - struct comedi_subdevice *s Pointer to current subdevice structure - struct comedi_insn *insn Pointer to current comedi instruction - unsigned int *data Pointer to analogue output data - -Returns:int Nmuber of instructions executed - -============================================================================== -*/ static int icp_multi_insn_bits_do(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -482,24 +372,6 @@ static int icp_multi_insn_bits_do(struct comedi_device *dev, return insn->n; } -/* -============================================================================== - -Name: icp_multi_insn_read_ctr - -Description: - This function reads the specified counter. - -Parameters: - struct comedi_device *dev Pointer to current device structure - struct comedi_subdevice *s Pointer to current subdevice structure - struct comedi_insn *insn Pointer to current comedi instruction - unsigned int *data Pointer to counter data - -Returns:int Nmuber of instructions executed - -============================================================================== -*/ static int icp_multi_insn_read_ctr(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -507,24 +379,6 @@ static int icp_multi_insn_read_ctr(struct comedi_device *dev, return 0; } -/* -============================================================================== - -Name: icp_multi_insn_write_ctr - -Description: - This function write to the specified counter. - -Parameters: - struct comedi_device *dev Pointer to current device structure - struct comedi_subdevice *s Pointer to current subdevice structure - struct comedi_insn *insn Pointer to current comedi instruction - unsigned int *data Pointer to counter data - -Returns:int Nmuber of instructions executed - -============================================================================== -*/ static int icp_multi_insn_write_ctr(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, @@ -533,21 +387,6 @@ static int icp_multi_insn_write_ctr(struct comedi_device *dev, return 0; } -/* -============================================================================== - -Name: interrupt_service_icp_multi - -Description: - This function is the interrupt service routine for all - interrupts generated by the icp multi board. - -Parameters: - int irq - void *d Pointer to current device - -============================================================================== -*/ static irqreturn_t interrupt_service_icp_multi(int irq, void *d) { struct comedi_device *dev = d; @@ -587,26 +426,6 @@ static irqreturn_t interrupt_service_icp_multi(int irq, void *d) } #if 0 -/* -============================================================================== - -Name: check_channel_list - -Description: - This function checks if the channel list, provided by user - is built correctly - -Parameters: - struct comedi_device *dev Pointer to current service structure - struct comedi_subdevice *s Pointer to current subdevice structure - unsigned int *chanlist Pointer to packed channel list - unsigned int n_chan Number of channels to scan - -Returns:int 0 = failure - 1 = success - -============================================================================== -*/ static int check_channel_list(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int *chanlist, unsigned int n_chan) @@ -639,21 +458,6 @@ static int check_channel_list(struct comedi_device *dev, } #endif -/* -============================================================================== - -Name: icp_multi_reset - -Description: - This function resets the icp multi device to a 'safe' state - -Parameters: - struct comedi_device *dev Pointer to current service structure - -Returns:int 0 = success - -============================================================================== -*/ static int icp_multi_reset(struct comedi_device *dev) { struct icp_multi_private *devpriv = dev->private; -- cgit v0.10.2 From b67cd424600dd42527a3eeb21a148a10683d2491 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 13:54:21 -0700 Subject: staging: comedi: adl_pci9111: remove pci_dev_put() This driver no longer walks the pci bus to find the pci_dev. The pci_dev_put() is no longer needed. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index d2d072e..91efaa4 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -970,7 +970,6 @@ static void pci9111_detach(struct comedi_device *dev) if (pcidev) { if (dev->iobase) comedi_pci_disable(pcidev); - pci_dev_put(pcidev); } } -- cgit v0.10.2 From e3845b34e8bcda7a420af582f4a3f3986c35e709 Mon Sep 17 00:00:00 2001 From: Daniel Cotey Date: Tue, 11 Sep 2012 22:28:08 -0700 Subject: Staging: silicom: checkpatch: cleanup macros Fix msec_delay_bp macro formatting Signed-off-by: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/bp_mod.h b/drivers/staging/silicom/bp_mod.h index 9e488c0..70a9971 100644 --- a/drivers/staging/silicom/bp_mod.h +++ b/drivers/staging/silicom/bp_mod.h @@ -19,16 +19,17 @@ #define usec_delay(x) udelay(x) #ifndef msec_delay_bp -#define msec_delay_bp(x) do { \ - int i; \ - if(1) { \ - for(i = 0; i < 1000; i++) \ - { \ - udelay(x) ; \ - } \ - } else { \ - msleep(x); \ - } } while(0) +#define msec_delay_bp(x) \ +do { \ + int i; \ + if (1) { \ + for (i = 0; i < 1000; i++) { \ + udelay(x) ; \ + } \ + } else { \ + msleep(x); \ + } \ +} while (0) #endif -- cgit v0.10.2 From 13d6b7b21aedac9deb884d90f30ca66b0aef6cd1 Mon Sep 17 00:00:00 2001 From: Daniel Cotey Date: Tue, 11 Sep 2012 22:29:06 -0700 Subject: Staging: silicom: minor cleanup: remove unused define DEVICE_NODE not used Signed-off-by: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/bp_ioctl.h b/drivers/staging/silicom/bp_ioctl.h index 7d468a0..57de34a 100644 --- a/drivers/staging/silicom/bp_ioctl.h +++ b/drivers/staging/silicom/bp_ioctl.h @@ -135,7 +135,6 @@ struct bpctl_cmd { #define IOCTL_TX_MSG(cmd) _IOWR(MAGIC_NUM, cmd, struct bpctl_cmd) -#define DEVICE_NODE "/dev/bpctl0" #define DEVICE_NAME "bpctl" #endif diff --git a/drivers/staging/silicom/bypasslib/bp_ioctl.h b/drivers/staging/silicom/bypasslib/bp_ioctl.h index 9e736a4..040c6fa 100644 --- a/drivers/staging/silicom/bypasslib/bp_ioctl.h +++ b/drivers/staging/silicom/bypasslib/bp_ioctl.h @@ -193,7 +193,6 @@ struct bpctl_cmd { #define IOCTL_TX_MSG(cmd) _IOWR(MAGIC_NUM, cmd, struct bpctl_cmd) -#define DEVICE_NODE "/dev/bpctl0" #define DEVICE_NAME "bpctl" #endif -- cgit v0.10.2 From b84a9ce54430225053667cce146f06d6ee257372 Mon Sep 17 00:00:00 2001 From: Daniel Cotey Date: Tue, 11 Sep 2012 22:29:55 -0700 Subject: Staging: silicom: checkpatch cleanup: header tabs n spaces Fix defines to comply with style guidelines Signed-off-by: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/bp_mod.h b/drivers/staging/silicom/bp_mod.h index 70a9971..81cd97b 100644 --- a/drivers/staging/silicom/bp_mod.h +++ b/drivers/staging/silicom/bp_mod.h @@ -236,45 +236,45 @@ static inline unsigned int jiffies_to_msecs(const unsigned long j) #define SILICOM_PE210G2BPi40_SSID 0x01a0 #define PEG540_IF_SERIES(pid) \ - ((pid==SILICOM_PE210G2BPi40_SSID)) + ((pid == SILICOM_PE210G2BPi40_SSID)) -#define OLD_IF_SERIES(pid) \ - ((pid==SILICOM_PXG2BPFI_SSID)|| \ - (pid==SILICOM_PXG2BPFILX_SSID)) +#define OLD_IF_SERIES(pid)\ + ((pid == SILICOM_PXG2BPFI_SSID) || \ + (pid == SILICOM_PXG2BPFILX_SSID)) #define P2BPFI_IF_SERIES(pid) \ - ((pid==SILICOM_PXG2BPFI_SSID)|| \ - (pid==SILICOM_PXG2BPFILX_SSID)|| \ - (pid==SILICOM_PEG2BPFI_SSID)|| \ - (pid==SILICOM_PEG2BPFID_SSID)|| \ - (pid==SILICOM_PEG2BPFIDLX_SSID)|| \ - (pid==SILICOM_MEG2BPFILN_SSID)|| \ - (pid==SILICOM_MEG2BPFINX_SSID)|| \ - (pid==SILICOM_PEG4BPFILX_SSID)|| \ - (pid==SILICOM_PEG4BPFI_SSID)|| \ - (pid==SILICOM_PXEG4BPFI_SSID)|| \ - (pid==SILICOM_PXG4BPFID_SSID)|| \ - (pid==SILICOM_PEG2TBFI_SSID)|| \ - (pid==SILICOM_PE10G2BPISR_SSID)|| \ - (pid==SILICOM_PE10G2BPILR_SSID)|| \ - (pid==SILICOM_PEG2BPFILX_SSID)|| \ - (pid==SILICOM_PMCXG2BPFI_SSID) || \ - (pid==SILICOM_MHIO8AD_SSID) || \ - (pid==SILICOM_PEG4BPFI5LX_SSID) || \ - (pid==SILICOM_PEG4BPFI5_SSID) || \ - (pid==SILICOM_PEG4BPFI6FC_SSID) || \ - (pid==SILICOM_PEG4BPFI6FCLX_SSID) || \ - (pid==SILICOM_PEG4BPFI6FCZX_SSID) || \ - (pid==NOKIA_PMCXG2BPFIN_SSID)|| \ - (pid==SILICOM_MEG2BPFILXLN_SSID)|| \ - (pid==SILICOM_MEG2BPFILXNX_SSID)|| \ - (pid==SILICOM_XE10G2BPIT_SSID)|| \ - (pid==SILICOM_XE10G2BPICX4_SSID)|| \ - (pid==SILICOM_XE10G2BPISR_SSID)|| \ - (pid==NOKIA_XE10G2BPIXR_SSID)|| \ - (pid==SILICOM_PE10GDBISR_SSID)|| \ - (pid==SILICOM_PE10GDBILR_SSID)|| \ - (pid==SILICOM_XE10G2BPILR_SSID)) + ((pid == SILICOM_PXG2BPFI_SSID) || \ + (pid == SILICOM_PXG2BPFILX_SSID) || \ + (pid == SILICOM_PEG2BPFI_SSID) || \ + (pid == SILICOM_PEG2BPFID_SSID) || \ + (pid == SILICOM_PEG2BPFIDLX_SSID) || \ + (pid == SILICOM_MEG2BPFILN_SSID) || \ + (pid == SILICOM_MEG2BPFINX_SSID) || \ + (pid == SILICOM_PEG4BPFILX_SSID) || \ + (pid == SILICOM_PEG4BPFI_SSID) || \ + (pid == SILICOM_PXEG4BPFI_SSID) || \ + (pid == SILICOM_PXG4BPFID_SSID) || \ + (pid == SILICOM_PEG2TBFI_SSID) || \ + (pid == SILICOM_PE10G2BPISR_SSID) || \ + (pid == SILICOM_PE10G2BPILR_SSID) || \ + (pid == SILICOM_PEG2BPFILX_SSID) || \ + (pid == SILICOM_PMCXG2BPFI_SSID) || \ + (pid == SILICOM_MHIO8AD_SSID) || \ + (pid == SILICOM_PEG4BPFI5LX_SSID) || \ + (pid == SILICOM_PEG4BPFI5_SSID) || \ + (pid == SILICOM_PEG4BPFI6FC_SSID) || \ + (pid == SILICOM_PEG4BPFI6FCLX_SSID) || \ + (pid == SILICOM_PEG4BPFI6FCZX_SSID) || \ + (pid == NOKIA_PMCXG2BPFIN_SSID) || \ + (pid == SILICOM_MEG2BPFILXLN_SSID) || \ + (pid == SILICOM_MEG2BPFILXNX_SSID) || \ + (pid == SILICOM_XE10G2BPIT_SSID) || \ + (pid == SILICOM_XE10G2BPICX4_SSID) || \ + (pid == SILICOM_XE10G2BPISR_SSID) || \ + (pid == NOKIA_XE10G2BPIXR_SSID) || \ + (pid == SILICOM_PE10GDBISR_SSID) || \ + (pid == SILICOM_PE10GDBILR_SSID) || \ + (pid == SILICOM_XE10G2BPILR_SSID)) #define INTEL_IF_SERIES(pid) \ ((pid==INTEL_PEG4BPII_SSID)|| \ -- cgit v0.10.2 From bc4b4aa5f5153d42d03244c2cbb19546f6200aef Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 15:08:06 -0700 Subject: staging: comedi: adv_pci1710: remove board attach noise Remove the kernel message noise during the attach of the board. Use a simple/clean dev_info at the end of the attach. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 699f267..e589684 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -1332,8 +1332,6 @@ static int pci1710_attach(struct comedi_device *dev, int ret, subdev, n_subdevices; unsigned int irq; - dev_info(dev->class_dev, DRV_NAME ": attach\n"); - ret = alloc_private(dev, sizeof(*devpriv)); if (ret < 0) return -ENOMEM; @@ -1377,15 +1375,8 @@ static int pci1710_attach(struct comedi_device *dev, if (request_irq(irq, interrupt_service_pci1710, IRQF_SHARED, "Advantech PCI-1710", dev)) { - dev_dbg(dev->class_dev, - "unable to allocate IRQ %d, DISABLING IT", - irq); irq = 0; /* Can't use IRQ */ - } else { - dev_dbg(dev->class_dev, "irq=%u", irq); } - } else { - dev_dbg(dev->class_dev, "IRQ disabled"); } } else { irq = 0; @@ -1480,6 +1471,9 @@ static int pci1710_attach(struct comedi_device *dev, devpriv->valid = 1; + dev_info(dev->class_dev, "%s attached, irq %sabled\n", + dev->board_name, dev->irq ? "en" : "dis"); + return 0; } -- cgit v0.10.2 From f62608e3d01ecfc66e0d380dbd0a3927a1ca4b4f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 15:08:21 -0700 Subject: staging: comedi: adv_pci1710: use attach_pci callback Convert this PCI driver to use the comedi PCI auto config attach mechanism by adding an 'attach_pci' callback function. Since the driver does not require any external configuration options, and the legacy 'attach' callback is now optional, remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index e589684..571c22c 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -1282,75 +1282,45 @@ static int pci1710_reset(struct comedi_device *dev) } } -static struct pci_dev *pci1710_find_pci_dev(struct comedi_device *dev, - struct comedi_devconfig *it) +static const void *pci1710_find_boardinfo(struct comedi_device *dev, + struct pci_dev *pcidev) { - const struct boardtype *this_board = comedi_board(dev); - struct pci_dev *pcidev = NULL; - int bus = it->options[0]; - int slot = it->options[1]; - int board_index = this_board - boardtypes; + const struct boardtype *this_board; int i; - for_each_pci_dev(pcidev) { - if (bus || slot) { - if (bus != pcidev->bus->number || - slot != PCI_SLOT(pcidev->devfn)) - continue; - } - if (pcidev->vendor != PCI_VENDOR_ID_ADVANTECH) - continue; - if (strcmp(this_board->name, DRV_NAME) == 0) { - for (i = 0; i < ARRAY_SIZE(boardtypes); ++i) { - if (pcidev->device == boardtypes[i].device_id) { - board_index = i; - break; - } - } - if (i == ARRAY_SIZE(boardtypes)) - continue; - } else { - if (pcidev->device != boardtypes[board_index].device_id) - continue; - } - dev->board_ptr = &boardtypes[board_index]; - return pcidev; + for (i = 0; i < ARRAY_SIZE(boardtypes); i++) { + this_board = &boardtypes[i]; + if (pcidev->device == this_board->device_id) + return this_board; } - dev_err(dev->class_dev, - "No supported board found! (req. bus %d, slot %d)\n", - bus, slot); return NULL; } -static int pci1710_attach(struct comedi_device *dev, - struct comedi_devconfig *it) +static int pci1710_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) { const struct boardtype *this_board; struct pci1710_private *devpriv; - struct pci_dev *pcidev; struct comedi_subdevice *s; int ret, subdev, n_subdevices; - unsigned int irq; + + comedi_set_hw_dev(dev, &pcidev->dev); + + this_board = pci1710_find_boardinfo(dev, pcidev); + if (!this_board) + return -ENODEV; + dev->board_ptr = this_board; + dev->board_name = this_board->name; ret = alloc_private(dev, sizeof(*devpriv)); if (ret < 0) - return -ENOMEM; + return ret; devpriv = dev->private; - pcidev = pci1710_find_pci_dev(dev, it); - if (!pcidev) - return -EIO; - comedi_set_hw_dev(dev, &pcidev->dev); - this_board = comedi_board(dev); - - ret = comedi_pci_enable(pcidev, DRV_NAME); + ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) return ret; - dev->iobase = pci_resource_start(pcidev, 2); - irq = pcidev->irq; - - dev->board_name = this_board->name; n_subdevices = 0; if (this_board->n_aichan) @@ -1370,19 +1340,13 @@ static int pci1710_attach(struct comedi_device *dev, pci1710_reset(dev); - if (this_board->have_irq) { - if (irq) { - if (request_irq(irq, interrupt_service_pci1710, - IRQF_SHARED, "Advantech PCI-1710", - dev)) { - irq = 0; /* Can't use IRQ */ - } - } - } else { - irq = 0; + if (this_board->have_irq && pcidev->irq) { + ret = request_irq(pcidev->irq, interrupt_service_pci1710, + IRQF_SHARED, dev->board_name, dev); + if (ret == 0) + dev->irq = pcidev->irq; } - dev->irq = irq; subdev = 0; if (this_board->n_aichan) { @@ -1398,7 +1362,7 @@ static int pci1710_attach(struct comedi_device *dev, s->range_table = this_board->rangelist_ai; s->cancel = pci171x_ai_cancel; s->insn_read = pci171x_insn_read_ai; - if (irq) { + if (dev->irq) { s->subdev_flags |= SDF_CMD_READ; s->do_cmdtest = pci171x_ai_cmdtest; s->do_cmd = pci171x_ai_cmd; @@ -1491,18 +1455,14 @@ static void pci1710_detach(struct comedi_device *dev) if (pcidev) { if (dev->iobase) comedi_pci_disable(pcidev); - pci_dev_put(pcidev); } } static struct comedi_driver adv_pci1710_driver = { .driver_name = "adv_pci1710", .module = THIS_MODULE, - .attach = pci1710_attach, + .attach_pci = pci1710_attach_pci, .detach = pci1710_detach, - .num_names = ARRAY_SIZE(boardtypes), - .board_name = &boardtypes[0].name, - .offset = sizeof(struct boardtype), }; static int __devinit adv_pci1710_pci_probe(struct pci_dev *dev, -- cgit v0.10.2 From 398e6f1230160e614ef0f878725cdd5f51fda8cd Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 15:08:37 -0700 Subject: staging: comedi: adv_pci1710: remove unnecessary 'valid' The 'valid' variable in the private data is only used in the detach of the board to determine if the pci1710_reset() function can be called. That function only requires a valid dev->iobase to work. Use that for the check instead and remove the unneeded variable from the private data. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 571c22c..09fe373 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -300,7 +300,6 @@ static const struct boardtype boardtypes[] = { }; struct pci1710_private { - char valid; /* card is usable */ char neverending_ai; /* we do unlimited AI */ unsigned int CntrlReg; /* Control register */ unsigned int i8254_osc_base; /* frequence of onboard oscilator */ @@ -1433,8 +1432,6 @@ static int pci1710_attach_pci(struct comedi_device *dev, subdev++; } - devpriv->valid = 1; - dev_info(dev->class_dev, "%s attached, irq %sabled\n", dev->board_name, dev->irq ? "en" : "dis"); @@ -1443,15 +1440,12 @@ static int pci1710_attach_pci(struct comedi_device *dev, static void pci1710_detach(struct comedi_device *dev) { - struct pci1710_private *devpriv = dev->private; struct pci_dev *pcidev = comedi_to_pci_dev(dev); - if (devpriv) { - if (devpriv->valid) - pci1710_reset(dev); - if (dev->irq) - free_irq(dev->irq, dev); - } + if (dev->iobase) + pci1710_reset(dev); + if (dev->irq) + free_irq(dev->irq, dev); if (pcidev) { if (dev->iobase) comedi_pci_disable(pcidev); -- cgit v0.10.2 From 60a63228c80dd01694a7961d349350d87bed82d9 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 15:08:52 -0700 Subject: staging: comedi: adv_pci1710: remove "dummy" boardinfo entry The legacy attach used the "dummy" boardinfo entry to allow matching a boardinfo to a pci card based on the "name" passed by the comedi core. This driver now uses the PCI auto config mechanism which always matches to the PCI vendor/device ids. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 09fe373..a8825e45 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -52,8 +52,6 @@ Configuration options: * correct channel number on every 12 bit * sample */ -#define DRV_NAME "adv_pci1710" - #define PCI_VENDOR_ID_ADVANTECH 0x13fe /* hardware types of the cards */ @@ -293,9 +291,6 @@ static const struct boardtype boardtypes[] = { .rangecode_ai = range_codes_pci17x1, .ai_ns_min = 10000, .fifo_half_size = 512, - }, { - /* dummy entry corresponding to driver name */ - .name = DRV_NAME, }, }; -- cgit v0.10.2 From 8531fce9450bcb7bc0947d818c05644339b88a48 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 15:09:06 -0700 Subject: staging: comedi: adv_pci1710: use cfc_check_trigger_src Use the helper function cfc_check_trigger_src for the "step 1" tests of pci171x_ai_cmdtest(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index a8825e45..379a713 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -45,6 +45,7 @@ Configuration options: #include "../comedidev.h" +#include "comedi_fc.h" #include "8253.h" #include "amcc_s5933.h" @@ -1047,30 +1048,11 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, /* step 1: make sure trigger sources are trivially valid */ - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW | TRIG_EXT; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_FOLLOW; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_TIMER | TRIG_EXT; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_FOLLOW); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; -- cgit v0.10.2 From 85f3088b848900a1c904dde2ae6505ecad399910 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 15:09:23 -0700 Subject: staging: comedi: adv_pci1710: single source triggers are unique If a single source trigger passes "step 1" of the do_cmdtest function they are already unique. There is no need to recheck them. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 379a713..6fbf566 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -1064,19 +1064,9 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, err++; } - if (cmd->scan_begin_src != TRIG_FOLLOW) { - cmd->scan_begin_src = TRIG_FOLLOW; - err++; - } - if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT) err++; - if (cmd->scan_end_src != TRIG_COUNT) { - cmd->scan_end_src = TRIG_COUNT; - err++; - } - if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT) err++; -- cgit v0.10.2 From b7f16de6a4fc15b07d0ec86fdc78b1093dd07f52 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 15:09:39 -0700 Subject: staging: comedi: adv_pci1710: use cfc_check_trigger_is_unique Use the helper function cfc_check_trigger_is_unique for the "step 2a" tests of pci171x_ai_cmdtest(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 6fbf566..0fd021062 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -1057,18 +1057,13 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, if (err) return 1; - /* step2: make sure trigger srcs are unique and mutually compatible */ + /* step 2a: make sure trigger sources are unique */ - if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) { - cmd->start_src = TRIG_NOW; - err++; - } + err |= cfc_check_trigger_is_unique(cmd->start_src); + err |= cfc_check_trigger_is_unique(cmd->convert_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); - if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT) - err++; - - if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT) - err++; + /* step 2b: and mutually compatible */ if (err) return 2; -- cgit v0.10.2 From ae34f6aa4edff204b4a7b36ca20b576da3d857b3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 16:39:10 -0700 Subject: staging: comedi: adl_pci9118: remove devpriv and this_board macros These macros rely on a local variable having a specific name. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index fdb0f5d..b9d33d8 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -356,9 +356,6 @@ struct pci9118_private { unsigned int ai_inttrig_start; /* TRIG_INT for start */ }; -#define devpriv ((struct pci9118_private *)dev->private) -#define this_board ((struct boardtype *)dev->board_ptr) - /* ============================================================================== */ @@ -392,7 +389,7 @@ static int pci9118_insn_read_ai(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - + struct pci9118_private *devpriv = dev->private; int n, timeout; devpriv->AdControlReg = AdControl_Int & 0xff; @@ -449,6 +446,7 @@ static int pci9118_insn_write_ao(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pci9118_private *devpriv = dev->private; int n, chanreg, ch; ch = CR_CHAN(insn->chanspec); @@ -473,6 +471,7 @@ static int pci9118_insn_read_ao(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pci9118_private *devpriv = dev->private; int n, chan; chan = CR_CHAN(insn->chanspec); @@ -516,6 +515,8 @@ static int pci9118_insn_bits_do(struct comedi_device *dev, */ static void interrupt_pci9118_ai_mode4_switch(struct comedi_device *dev) { + struct pci9118_private *devpriv = dev->private; + devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg | AdFunction_AM; outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC); @@ -533,6 +534,7 @@ static unsigned int defragment_dma_buffer(struct comedi_device *dev, short *dma_buffer, unsigned int num_samples) { + struct pci9118_private *devpriv = dev->private; unsigned int i = 0, j = 0; unsigned int start_pos = devpriv->ai_add_front, stop_pos = devpriv->ai_add_front + devpriv->ai_n_chan; @@ -559,6 +561,7 @@ static int move_block_from_dma(struct comedi_device *dev, short *dma_buffer, unsigned int num_samples) { + struct pci9118_private *devpriv = dev->private; unsigned int num_bytes; num_samples = defragment_dma_buffer(dev, s, dma_buffer, num_samples); @@ -581,6 +584,8 @@ static char pci9118_decode_error_status(struct comedi_device *dev, struct comedi_subdevice *s, unsigned char m) { + struct pci9118_private *devpriv = dev->private; + if (m & 0x100) { comedi_error(dev, "A/D FIFO Full status (Fatal Error!)"); devpriv->ai_maskerr &= ~0x100L; @@ -613,6 +618,7 @@ static void pci9118_ai_munge(struct comedi_device *dev, unsigned int num_bytes, unsigned int start_chan_index) { + struct pci9118_private *devpriv = dev->private; unsigned int i, num_samples = num_bytes / sizeof(short); short *array = data; @@ -636,6 +642,7 @@ static void interrupt_pci9118_ai_onesample(struct comedi_device *dev, unsigned int int_amcc, unsigned short int_daq) { + struct pci9118_private *devpriv = dev->private; register short sampl; s->async->events = 0; @@ -689,6 +696,7 @@ static void interrupt_pci9118_ai_dma(struct comedi_device *dev, unsigned int int_amcc, unsigned short int_daq) { + struct pci9118_private *devpriv = dev->private; unsigned int next_dma_buf, samplesinbuf, sampls, m; if (int_amcc & MASTER_ABORT_INT) { @@ -774,6 +782,7 @@ static void interrupt_pci9118_ai_dma(struct comedi_device *dev, static irqreturn_t interrupt_pci9118(int irq, void *d) { struct comedi_device *dev = d; + struct pci9118_private *devpriv = dev->private; unsigned int int_daq = 0, int_amcc, int_adstat; if (!dev->attached) @@ -850,6 +859,8 @@ static irqreturn_t interrupt_pci9118(int irq, void *d) static int pci9118_ai_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int trignum) { + struct pci9118_private *devpriv = dev->private; + if (trignum != devpriv->ai_inttrig_start) return -EINVAL; @@ -875,6 +886,8 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { + const struct boardtype *this_board = comedi_board(dev); + struct pci9118_private *devpriv = dev->private; int err = 0; int tmp; unsigned int divisor1 = 0, divisor2 = 0; @@ -1136,6 +1149,7 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev, */ static int Compute_and_setup_dma(struct comedi_device *dev) { + struct pci9118_private *devpriv = dev->private; unsigned int dmalen0, dmalen1, i; DPRINTK("adl_pci9118 EDBG: BGN: Compute_and_setup_dma()\n"); @@ -1318,6 +1332,8 @@ static int Compute_and_setup_dma(struct comedi_device *dev) static int pci9118_ai_docmd_sampl(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pci9118_private *devpriv = dev->private; + DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_sampl(%d,) [%d]\n", dev->minor, devpriv->ai_do); switch (devpriv->ai_do) { @@ -1376,6 +1392,8 @@ static int pci9118_ai_docmd_sampl(struct comedi_device *dev, static int pci9118_ai_docmd_dma(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pci9118_private *devpriv = dev->private; + DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_dma(%d,) [%d,%d]\n", dev->minor, devpriv->ai_do, devpriv->usedma); Compute_and_setup_dma(dev); @@ -1449,6 +1467,8 @@ static int pci9118_ai_docmd_dma(struct comedi_device *dev, */ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + const struct boardtype *this_board = comedi_board(dev); + struct pci9118_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; unsigned int addchans = 0; int ret = 0; @@ -1699,6 +1719,8 @@ static int check_channel_list(struct comedi_device *dev, struct comedi_subdevice *s, int n_chan, unsigned int *chanlist, int frontadd, int backadd) { + const struct boardtype *this_board = comedi_board(dev); + struct pci9118_private *devpriv = dev->private; unsigned int i, differencial = 0, bipolar = 0; /* correct channel and range number check itself comedi/range.c */ @@ -1754,6 +1776,7 @@ static int setup_channel_list(struct comedi_device *dev, unsigned int *chanlist, int rot, int frontadd, int backadd, int usedma, char useeos) { + struct pci9118_private *devpriv = dev->private; unsigned int i, differencial = 0, bipolar = 0; unsigned int scanquad, gain, ssh = 0x00; @@ -1887,6 +1910,9 @@ static void pci9118_calc_divisors(char mode, struct comedi_device *dev, unsigned int *div1, unsigned int *div2, char usessh, unsigned int chnsshfront) { + const struct boardtype *this_board = comedi_board(dev); + struct pci9118_private *devpriv = dev->private; + DPRINTK ("adl_pci9118 EDBG: BGN: pci9118_calc_divisors" "(%d,%d,.,%u,%u,%u,%d,.,.,,%u,%u)\n", @@ -1967,6 +1993,8 @@ static void start_pacer(struct comedi_device *dev, int mode, */ static int pci9118_exttrg_add(struct comedi_device *dev, unsigned char source) { + struct pci9118_private *devpriv = dev->private; + if (source > 3) return -1; /* incorrect source */ devpriv->exttrg_users |= (1 << source); @@ -1983,6 +2011,8 @@ static int pci9118_exttrg_add(struct comedi_device *dev, unsigned char source) */ static int pci9118_exttrg_del(struct comedi_device *dev, unsigned char source) { + struct pci9118_private *devpriv = dev->private; + if (source > 3) return -1; /* incorrect source */ devpriv->exttrg_users &= ~(1 << source); @@ -2004,6 +2034,8 @@ static int pci9118_exttrg_del(struct comedi_device *dev, unsigned char source) static int pci9118_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pci9118_private *devpriv = dev->private; + if (devpriv->usedma) outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) & (~EN_A2P_TRANSFERS), @@ -2053,6 +2085,8 @@ static int pci9118_ai_cancel(struct comedi_device *dev, */ static int pci9118_reset(struct comedi_device *dev) { + struct pci9118_private *devpriv = dev->private; + devpriv->IntControlReg = 0; devpriv->exttrg_users = 0; inl(dev->iobase + PCI9118_INTCTRL); @@ -2112,6 +2146,7 @@ static int pci9118_reset(struct comedi_device *dev) static struct pci_dev *pci9118_find_pci(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct boardtype *this_board = comedi_board(dev); struct pci_dev *pcidev = NULL; int bus = it->options[0]; int slot = it->options[1]; @@ -2150,6 +2185,8 @@ static struct pci_dev *pci9118_find_pci(struct comedi_device *dev, static int pci9118_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct boardtype *this_board = comedi_board(dev); + struct pci9118_private *devpriv; struct pci_dev *pcidev; struct comedi_subdevice *s; int ret, pages, i; @@ -2164,11 +2201,12 @@ static int pci9118_attach(struct comedi_device *dev, else master = 1; - ret = alloc_private(dev, sizeof(struct pci9118_private)); + ret = alloc_private(dev, sizeof(*devpriv)); if (ret < 0) { printk(" - Allocation failed!\n"); return -ENOMEM; } + devpriv = dev->private; pcidev = pci9118_find_pci(dev, it); if (!pcidev) @@ -2345,8 +2383,9 @@ static int pci9118_attach(struct comedi_device *dev, static void pci9118_detach(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct pci9118_private *devpriv = dev->private; - if (dev->private) { + if (devpriv) { if (devpriv->valid) pci9118_reset(dev); if (dev->irq) -- cgit v0.10.2 From ca82a6e7e37693a84de542d06f3700037cc56525 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 16:39:44 -0700 Subject: staging: comedi: adl_pci9118: remove PCI9118_EXTDEBUG and DPRINTK These macros enable a bunch of function trace messages. These should not be in the final driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index b9d33d8..cfef739 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -81,18 +81,6 @@ Configuration options: * correct channel number on every 12 bit sample */ -#undef PCI9118_EXTDEBUG /* - * if defined then driver prints - * a lot of messages - */ - -#undef DPRINTK -#ifdef PCI9118_EXTDEBUG -#define DPRINTK(fmt, args...) printk(fmt, ## args) -#else -#define DPRINTK(fmt, args...) -#endif - #define IORANGE_9118 64 /* I hope */ #define PCI9118_CHANLEN 255 /* * len of chanlist, some source say 256, @@ -721,7 +709,6 @@ static void interrupt_pci9118_ai_dma(struct comedi_device *dev, samplesinbuf = devpriv->dmabuf_use_size[devpriv->dma_actbuf] >> 1; /* number of received real samples */ -/* DPRINTK("dma_actbuf=%d\n",devpriv->dma_actbuf); */ if (devpriv->dma_doublebuf) { /* * switch DMA buffers if is used @@ -743,17 +730,12 @@ static void interrupt_pci9118_ai_dma(struct comedi_device *dev, * how many samples is to * end of buffer */ -/* - * DPRINTK("samps=%d m=%d %d %d\n", - * samplesinbuf,m,s->async->buf_int_count,s->async->buf_int_ptr); - */ sampls = m; move_block_from_dma(dev, s, devpriv->dmabuf_virt[devpriv->dma_actbuf], samplesinbuf); m = m - sampls; /* m= how many samples was transferred */ } -/* DPRINTK("YYY\n"); */ if (!devpriv->ai_neverending) if (devpriv->ai_act_scan >= devpriv->ai_scans) { @@ -793,14 +775,6 @@ static irqreturn_t interrupt_pci9118(int irq, void *d) int_amcc = inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR); /* get INT register from AMCC chip */ -/* - * DPRINTK("INT daq=0x%01x amcc=0x%08x MWAR=0x%08x - * MWTC=0x%08x ADSTAT=0x%02x ai_do=%d\n", - * int_daq, int_amcc, inl(devpriv->iobase_a+AMCC_OP_REG_MWAR), - * inl(devpriv->iobase_a+AMCC_OP_REG_MWTC), - * inw(dev->iobase+PCI9118_ADSTAT)&0x1ff,devpriv->ai_do); - */ - if ((!int_daq) && (!(int_amcc & ANY_S593X_INT))) return IRQ_NONE; /* interrupt from other source */ @@ -1152,11 +1126,8 @@ static int Compute_and_setup_dma(struct comedi_device *dev) struct pci9118_private *devpriv = dev->private; unsigned int dmalen0, dmalen1, i; - DPRINTK("adl_pci9118 EDBG: BGN: Compute_and_setup_dma()\n"); dmalen0 = devpriv->dmabuf_size[0]; dmalen1 = devpriv->dmabuf_size[1]; - DPRINTK("1 dmalen0=%d dmalen1=%d ai_data_len=%d\n", dmalen0, dmalen1, - devpriv->ai_data_len); /* isn't output buff smaller that our DMA buff? */ if (dmalen0 > (devpriv->ai_data_len)) { dmalen0 = devpriv->ai_data_len & ~3L; /* @@ -1168,7 +1139,6 @@ static int Compute_and_setup_dma(struct comedi_device *dev) * align to 32bit down */ } - DPRINTK("2 dmalen0=%d dmalen1=%d\n", dmalen0, dmalen1); /* we want wake up every scan? */ if (devpriv->ai_flags & TRIG_WAKE_EOS) { @@ -1183,11 +1153,6 @@ static int Compute_and_setup_dma(struct comedi_device *dev) } else { /* short first DMA buffer to one scan */ dmalen0 = devpriv->ai_n_realscanlen << 1; - DPRINTK - ("21 dmalen0=%d ai_n_realscanlen=%d " - "useeoshandle=%d\n", - dmalen0, devpriv->ai_n_realscanlen, - devpriv->useeoshandle); if (devpriv->useeoshandle) dmalen0 += 2; if (dmalen0 < 4) { @@ -1211,11 +1176,6 @@ static int Compute_and_setup_dma(struct comedi_device *dev) } else { /* short second DMA buffer to one scan */ dmalen1 = devpriv->ai_n_realscanlen << 1; - DPRINTK - ("22 dmalen1=%d ai_n_realscanlen=%d " - "useeoshandle=%d\n", - dmalen1, devpriv->ai_n_realscanlen, - devpriv->useeoshandle); if (devpriv->useeoshandle) dmalen1 -= 2; if (dmalen1 < 4) { @@ -1228,7 +1188,6 @@ static int Compute_and_setup_dma(struct comedi_device *dev) } } - DPRINTK("3 dmalen0=%d dmalen1=%d\n", dmalen0, dmalen1); /* transfer without TRIG_WAKE_EOS */ if (!(devpriv->ai_flags & TRIG_WAKE_EOS)) { /* if it's possible then align DMA buffers to length of scan */ @@ -1255,15 +1214,9 @@ static int Compute_and_setup_dma(struct comedi_device *dev) if (dmalen0 > ((devpriv->ai_n_realscanlen << 1) * devpriv->ai_scans)) { - DPRINTK - ("3.0 ai_n_realscanlen=%d ai_scans=%d\n", - devpriv->ai_n_realscanlen, - devpriv->ai_scans); dmalen0 = (devpriv->ai_n_realscanlen << 1) * devpriv->ai_scans; - DPRINTK("3.1 dmalen0=%d dmalen1=%d\n", dmalen0, - dmalen1); dmalen0 &= ~3L; } else { /* * fits whole measure into @@ -1275,21 +1228,16 @@ static int Compute_and_setup_dma(struct comedi_device *dev) dmalen1 = (devpriv->ai_n_realscanlen << 1) * devpriv->ai_scans - dmalen0; - DPRINTK("3.2 dmalen0=%d dmalen1=%d\n", dmalen0, - dmalen1); dmalen1 &= ~3L; } } } - DPRINTK("4 dmalen0=%d dmalen1=%d\n", dmalen0, dmalen1); - /* these DMA buffer size will be used */ devpriv->dma_actbuf = 0; devpriv->dmabuf_use_size[0] = dmalen0; devpriv->dmabuf_use_size[1] = dmalen1; - DPRINTK("5 dmalen0=%d dmalen1=%d\n", dmalen0, dmalen1); #if 0 if (devpriv->ai_n_scanlen < this_board->half_fifo_size) { devpriv->dmabuf_panic_size[0] = @@ -1322,7 +1270,6 @@ static int Compute_and_setup_dma(struct comedi_device *dev) devpriv->iobase_a + AMCC_OP_REG_INTCSR); /* allow bus mastering */ - DPRINTK("adl_pci9118 EDBG: END: Compute_and_setup_dma()\n"); return 0; } @@ -1334,8 +1281,6 @@ static int pci9118_ai_docmd_sampl(struct comedi_device *dev, { struct pci9118_private *devpriv = dev->private; - DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_sampl(%d,) [%d]\n", - dev->minor, devpriv->ai_do); switch (devpriv->ai_do) { case 1: devpriv->AdControlReg |= AdControl_TmrTr; @@ -1382,7 +1327,6 @@ static int pci9118_ai_docmd_sampl(struct comedi_device *dev, outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL); } - DPRINTK("adl_pci9118 EDBG: END: pci9118_ai_docmd_sampl()\n"); return 0; } @@ -1394,8 +1338,6 @@ static int pci9118_ai_docmd_dma(struct comedi_device *dev, { struct pci9118_private *devpriv = dev->private; - DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_dma(%d,) [%d,%d]\n", - dev->minor, devpriv->ai_do, devpriv->usedma); Compute_and_setup_dma(dev); switch (devpriv->ai_do) { @@ -1458,7 +1400,6 @@ static int pci9118_ai_docmd_dma(struct comedi_device *dev, outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); } - DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_dma()\n"); return 0; } @@ -1473,7 +1414,6 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) unsigned int addchans = 0; int ret = 0; - DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_cmd(%d,)\n", dev->minor); devpriv->ai12_startstop = 0; devpriv->ai_flags = cmd->flags; devpriv->ai_n_chan = cmd->chanlist_len; @@ -1522,10 +1462,6 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->usessh = 0; /* no */ - DPRINTK("1 neverending=%d scans=%u usessh=%d ai_startstop=0x%2x\n", - devpriv->ai_neverending, devpriv->ai_scans, devpriv->usessh, - devpriv->ai12_startstop); - /* * use additional sample at end of every scan * to satisty DMA 32 bit transfer? @@ -1606,12 +1542,6 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->ai_add_back) * (devpriv->ai_n_scanlen / devpriv->ai_n_chan); - DPRINTK("2 usedma=%d realscan=%d af=%u n_chan=%d ab=%d n_scanlen=%d\n", - devpriv->usedma, - devpriv->ai_n_realscanlen, devpriv->ai_add_front, - devpriv->ai_n_chan, devpriv->ai_add_back, - devpriv->ai_n_scanlen); - /* check and setup channel list */ if (!check_channel_list(dev, s, devpriv->ai_n_chan, devpriv->ai_chanlist, devpriv->ai_add_front, @@ -1708,7 +1638,6 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) else ret = pci9118_ai_docmd_sampl(dev, s); - DPRINTK("adl_pci9118 EDBG: END: pci9118_ai_cmd()\n"); return ret; } @@ -1780,11 +1709,6 @@ static int setup_channel_list(struct comedi_device *dev, unsigned int i, differencial = 0, bipolar = 0; unsigned int scanquad, gain, ssh = 0x00; - DPRINTK - ("adl_pci9118 EDBG: BGN: setup_channel_list" - "(%d,.,%d,.,%d,%d,%d,%d)\n", - dev->minor, n_chan, rot, frontadd, backadd, usedma); - if (usedma == 1) { rot = 8; usedma = 0; @@ -1829,7 +1753,6 @@ static int setup_channel_list(struct comedi_device *dev, if (frontadd) { /* insert channels for S&H */ ssh = devpriv->softsshsample; - DPRINTK("FA: %04x: ", ssh); for (i = 0; i < frontadd; i++) { /* store range list to card */ scanquad = CR_CHAN(chanlist[0]); @@ -1838,13 +1761,10 @@ static int setup_channel_list(struct comedi_device *dev, /* get gain number */ scanquad |= ((gain & 0x03) << 8); outl(scanquad | ssh, dev->iobase + PCI9118_GAIN); - DPRINTK("%02x ", scanquad | ssh); ssh = devpriv->softsshhold; } - DPRINTK("\n "); } - DPRINTK("SL: ", ssh); for (i = 0; i < n_chan; i++) { /* store range list to card */ scanquad = CR_CHAN(chanlist[i]); /* get channel number */ #ifdef PCI9118_PARANOIDCHECK @@ -1853,21 +1773,16 @@ static int setup_channel_list(struct comedi_device *dev, gain = CR_RANGE(chanlist[i]); /* get gain number */ scanquad |= ((gain & 0x03) << 8); outl(scanquad | ssh, dev->iobase + PCI9118_GAIN); - DPRINTK("%02x ", scanquad | ssh); } - DPRINTK("\n "); if (backadd) { /* insert channels for fit onto 32bit DMA */ - DPRINTK("BA: %04x: ", ssh); for (i = 0; i < backadd; i++) { /* store range list to card */ scanquad = CR_CHAN(chanlist[0]); /* get channel number */ gain = CR_RANGE(chanlist[0]); /* get gain number */ scanquad |= ((gain & 0x03) << 8); outl(scanquad | ssh, dev->iobase + PCI9118_GAIN); - DPRINTK("%02x ", scanquad | ssh); } - DPRINTK("\n "); } #ifdef PCI9118_PARANOIDCHECK devpriv->chanlist[n_chan ^ usedma] = devpriv->chanlist[0 ^ usedma]; @@ -1884,18 +1799,10 @@ static int setup_channel_list(struct comedi_device *dev, } else { useeos = 1; } -#ifdef PCI9118_EXTDEBUG - DPRINTK("CHL: "); - for (i = 0; i <= (useeos * n_chan); i++) - DPRINTK("%04x ", devpriv->chanlist[i]); - - DPRINTK("\n "); -#endif #endif outl(0, dev->iobase + PCI9118_SCANMOD); /* close scan queue */ /* udelay(100); important delay, or first sample will be crippled */ - DPRINTK("adl_pci9118 EDBG: END: setup_channel_list()\n"); return 1; /* we can serve this with scan logic */ } @@ -1913,10 +1820,6 @@ static void pci9118_calc_divisors(char mode, struct comedi_device *dev, const struct boardtype *this_board = comedi_board(dev); struct pci9118_private *devpriv = dev->private; - DPRINTK - ("adl_pci9118 EDBG: BGN: pci9118_calc_divisors" - "(%d,%d,.,%u,%u,%u,%d,.,.,,%u,%u)\n", - mode, dev->minor, *tim1, *tim2, flags, chans, usessh, chnsshfront); switch (mode) { case 1: case 4: @@ -1924,32 +1827,18 @@ static void pci9118_calc_divisors(char mode, struct comedi_device *dev, *tim2 = this_board->ai_ns_min; i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, div1, div2, tim2, flags & TRIG_ROUND_NEAREST); - DPRINTK("OSC base=%u div1=%u div2=%u timer1=%u\n", - devpriv->i8254_osc_base, *div1, *div2, *tim1); break; case 2: if (*tim2 < this_board->ai_ns_min) *tim2 = this_board->ai_ns_min; - DPRINTK("1 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2, - *tim1, *tim2); *div1 = *tim2 / devpriv->i8254_osc_base; /* convert timer (burst) */ - DPRINTK("2 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2, - *tim1, *tim2); if (*div1 < this_board->ai_pacer_min) *div1 = this_board->ai_pacer_min; - DPRINTK("3 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2, - *tim1, *tim2); *div2 = *tim1 / devpriv->i8254_osc_base; /* scan timer */ - DPRINTK("4 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2, - *tim1, *tim2); *div2 = *div2 / *div1; /* major timer is c1*c2 */ - DPRINTK("5 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2, - *tim1, *tim2); if (*div2 < chans) *div2 = chans; - DPRINTK("6 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2, - *tim1, *tim2); *tim2 = *div1 * devpriv->i8254_osc_base; /* real convert timer */ @@ -1958,15 +1847,9 @@ static void pci9118_calc_divisors(char mode, struct comedi_device *dev, if (*div2 < (chans + 2)) *div2 = chans + 2; - DPRINTK("7 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2, - *tim1, *tim2); *tim1 = *div1 * *div2 * devpriv->i8254_osc_base; - DPRINTK("OSC base=%u div1=%u div2=%u timer1=%u timer2=%u\n", - devpriv->i8254_osc_base, *div1, *div2, *tim1, *tim2); break; } - DPRINTK("adl_pci9118 EDBG: END: pci9118_calc_divisors(%u,%u)\n", - *div1, *div2); } /* -- cgit v0.10.2 From 80f3023b452655155e1e216dfc64ce6767982d0a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 16:40:32 -0700 Subject: staging: comedi: adl_pci9118: remove the function separation comments These are just unnecessary whitespace. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index cfef739..c0f77a6 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -344,10 +344,6 @@ struct pci9118_private { unsigned int ai_inttrig_start; /* TRIG_INT for start */ }; -/* -============================================================================== -*/ - static int check_channel_list(struct comedi_device *dev, struct comedi_subdevice *s, int n_chan, unsigned int *chanlist, int frontadd, @@ -370,9 +366,6 @@ static void pci9118_calc_divisors(char mode, struct comedi_device *dev, unsigned int *div1, unsigned int *div2, char usessh, unsigned int chnsshfront); -/* -============================================================================== -*/ static int pci9118_insn_read_ai(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -427,9 +420,6 @@ conv_finish: } -/* -============================================================================== -*/ static int pci9118_insn_write_ao(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -452,9 +442,6 @@ static int pci9118_insn_write_ao(struct comedi_device *dev, return n; } -/* -============================================================================== -*/ static int pci9118_insn_read_ao(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -469,9 +456,6 @@ static int pci9118_insn_read_ao(struct comedi_device *dev, return n; } -/* -============================================================================== -*/ static int pci9118_insn_bits_di(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -481,9 +465,6 @@ static int pci9118_insn_bits_di(struct comedi_device *dev, return insn->n; } -/* -============================================================================== -*/ static int pci9118_insn_bits_do(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -498,9 +479,6 @@ static int pci9118_insn_bits_do(struct comedi_device *dev, return insn->n; } -/* -============================================================================== -*/ static void interrupt_pci9118_ai_mode4_switch(struct comedi_device *dev) { struct pci9118_private *devpriv = dev->private; @@ -541,9 +519,6 @@ static unsigned int defragment_dma_buffer(struct comedi_device *dev, return j; } -/* -============================================================================== -*/ static int move_block_from_dma(struct comedi_device *dev, struct comedi_subdevice *s, short *dma_buffer, @@ -565,9 +540,6 @@ static int move_block_from_dma(struct comedi_device *dev, return 0; } -/* -============================================================================== -*/ static char pci9118_decode_error_status(struct comedi_device *dev, struct comedi_subdevice *s, unsigned char m) @@ -621,9 +593,6 @@ static void pci9118_ai_munge(struct comedi_device *dev, } } -/* -============================================================================== -*/ static void interrupt_pci9118_ai_onesample(struct comedi_device *dev, struct comedi_subdevice *s, unsigned short int_adstat, @@ -675,9 +644,6 @@ static void interrupt_pci9118_ai_onesample(struct comedi_device *dev, comedi_event(dev, s); } -/* -============================================================================== -*/ static void interrupt_pci9118_ai_dma(struct comedi_device *dev, struct comedi_subdevice *s, unsigned short int_adstat, @@ -758,9 +724,6 @@ static void interrupt_pci9118_ai_dma(struct comedi_device *dev, comedi_event(dev, s); } -/* -============================================================================== -*/ static irqreturn_t interrupt_pci9118(int irq, void *d) { struct comedi_device *dev = d; @@ -827,9 +790,6 @@ static irqreturn_t interrupt_pci9118(int irq, void *d) return IRQ_HANDLED; } -/* -============================================================================== -*/ static int pci9118_ai_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int trignum) { @@ -853,9 +813,6 @@ static int pci9118_ai_inttrig(struct comedi_device *dev, return 1; } -/* -============================================================================== -*/ static int pci9118_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) @@ -1118,9 +1075,6 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev, return 0; } -/* -============================================================================== -*/ static int Compute_and_setup_dma(struct comedi_device *dev) { struct pci9118_private *devpriv = dev->private; @@ -1273,9 +1227,6 @@ static int Compute_and_setup_dma(struct comedi_device *dev) return 0; } -/* -============================================================================== -*/ static int pci9118_ai_docmd_sampl(struct comedi_device *dev, struct comedi_subdevice *s) { @@ -1330,9 +1281,6 @@ static int pci9118_ai_docmd_sampl(struct comedi_device *dev, return 0; } -/* -============================================================================== -*/ static int pci9118_ai_docmd_dma(struct comedi_device *dev, struct comedi_subdevice *s) { @@ -1403,9 +1351,6 @@ static int pci9118_ai_docmd_dma(struct comedi_device *dev, return 0; } -/* -============================================================================== -*/ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { const struct boardtype *this_board = comedi_board(dev); @@ -1641,9 +1586,6 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) return ret; } -/* -============================================================================== -*/ static int check_channel_list(struct comedi_device *dev, struct comedi_subdevice *s, int n_chan, unsigned int *chanlist, int frontadd, int backadd) @@ -1697,9 +1639,6 @@ static int check_channel_list(struct comedi_device *dev, return 1; } -/* -============================================================================== -*/ static int setup_channel_list(struct comedi_device *dev, struct comedi_subdevice *s, int n_chan, unsigned int *chanlist, int rot, int frontadd, @@ -1806,10 +1745,6 @@ static int setup_channel_list(struct comedi_device *dev, return 1; /* we can serve this with scan logic */ } -/* -============================================================================== - calculate 8254 divisors if they are used for dual timing -*/ static void pci9118_calc_divisors(char mode, struct comedi_device *dev, struct comedi_subdevice *s, unsigned int *tim1, unsigned int *tim2, @@ -1852,9 +1787,6 @@ static void pci9118_calc_divisors(char mode, struct comedi_device *dev, } } -/* -============================================================================== -*/ static void start_pacer(struct comedi_device *dev, int mode, unsigned int divisor1, unsigned int divisor2) { @@ -1871,9 +1803,6 @@ static void start_pacer(struct comedi_device *dev, int mode, } } -/* -============================================================================== -*/ static int pci9118_exttrg_add(struct comedi_device *dev, unsigned char source) { struct pci9118_private *devpriv = dev->private; @@ -1889,9 +1818,6 @@ static int pci9118_exttrg_add(struct comedi_device *dev, unsigned char source) return 0; } -/* -============================================================================== -*/ static int pci9118_exttrg_del(struct comedi_device *dev, unsigned char source) { struct pci9118_private *devpriv = dev->private; @@ -1911,9 +1837,6 @@ static int pci9118_exttrg_del(struct comedi_device *dev, unsigned char source) return 0; } -/* -============================================================================== -*/ static int pci9118_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { @@ -1963,9 +1886,6 @@ static int pci9118_ai_cancel(struct comedi_device *dev, return 0; } -/* -============================================================================== -*/ static int pci9118_reset(struct comedi_device *dev) { struct pci9118_private *devpriv = dev->private; -- cgit v0.10.2 From 435c8851eadb102475f8c025e6891290b47d6958 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 16:41:05 -0700 Subject: staging: comedi: adl_pci9118: remove commented out printk debug These debug messages should be removed from the final driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index c0f77a6..7c8ce2c 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -1018,11 +1018,9 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev, if (cmd->scan_begin_src == TRIG_TIMER) { tmp = cmd->scan_begin_arg; -/* printk("S1 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg); */ i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1, &divisor2, &cmd->scan_begin_arg, cmd->flags & TRIG_ROUND_MASK); -/* printk("S2 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg); */ if (cmd->scan_begin_arg < this_board->ai_ns_min) cmd->scan_begin_arg = this_board->ai_ns_min; if (tmp != cmd->scan_begin_arg) @@ -1034,7 +1032,6 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev, i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1, &divisor2, &cmd->convert_arg, cmd->flags & TRIG_ROUND_MASK); -/* printk("s1 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg); */ if (cmd->convert_arg < this_board->ai_ns_min) cmd->convert_arg = this_board->ai_ns_min; if (tmp != cmd->convert_arg) @@ -1048,7 +1045,6 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev, cmd->scan_begin_arg = this_board->ai_ns_min * (cmd->scan_end_arg + 2); -/* printk("s2 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg); */ err++; } } else { @@ -1057,7 +1053,6 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev, cmd->scan_begin_arg = cmd->convert_arg * cmd->chanlist_len; -/* printk("s3 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg); */ err++; } } -- cgit v0.10.2 From 5e49e5152cf10d3e5a3c699859f220a97852c687 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 16:41:36 -0700 Subject: staging: comedi: adl_pci9118: remove forward declarations Move some of the functions to remove the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index 7c8ce2c..f3beeb8 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -346,25 +346,162 @@ struct pci9118_private { static int check_channel_list(struct comedi_device *dev, struct comedi_subdevice *s, int n_chan, - unsigned int *chanlist, int frontadd, - int backadd); + unsigned int *chanlist, int frontadd, int backadd) +{ + const struct boardtype *this_board = comedi_board(dev); + struct pci9118_private *devpriv = dev->private; + unsigned int i, differencial = 0, bipolar = 0; + + /* correct channel and range number check itself comedi/range.c */ + if (n_chan < 1) { + comedi_error(dev, "range/channel list is empty!"); + return 0; + } + if ((frontadd + n_chan + backadd) > s->len_chanlist) { + printk + ("comedi%d: range/channel list is too long for " + "actual configuration (%d>%d)!", + dev->minor, n_chan, s->len_chanlist - frontadd - backadd); + return 0; + } + + if (CR_AREF(chanlist[0]) == AREF_DIFF) + differencial = 1; /* all input must be diff */ + if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES) + bipolar = 1; /* all input must be bipolar */ + if (n_chan > 1) + for (i = 1; i < n_chan; i++) { /* check S.E/diff */ + if ((CR_AREF(chanlist[i]) == AREF_DIFF) != + (differencial)) { + comedi_error(dev, + "Differencial and single ended " + "inputs can't be mixtured!"); + return 0; + } + if ((CR_RANGE(chanlist[i]) < PCI9118_BIPOLAR_RANGES) != + (bipolar)) { + comedi_error(dev, + "Bipolar and unipolar ranges " + "can't be mixtured!"); + return 0; + } + if (!devpriv->usemux && differencial && + (CR_CHAN(chanlist[i]) >= this_board->n_aichand)) { + comedi_error(dev, + "If AREF_DIFF is used then is " + "available only first 8 channels!"); + return 0; + } + } + + return 1; +} + static int setup_channel_list(struct comedi_device *dev, struct comedi_subdevice *s, int n_chan, unsigned int *chanlist, int rot, int frontadd, - int backadd, int usedma, char eoshandle); -static void start_pacer(struct comedi_device *dev, int mode, - unsigned int divisor1, unsigned int divisor2); -static int pci9118_reset(struct comedi_device *dev); -static int pci9118_exttrg_add(struct comedi_device *dev, unsigned char source); -static int pci9118_exttrg_del(struct comedi_device *dev, unsigned char source); -static int pci9118_ai_cancel(struct comedi_device *dev, - struct comedi_subdevice *s); -static void pci9118_calc_divisors(char mode, struct comedi_device *dev, - struct comedi_subdevice *s, - unsigned int *tim1, unsigned int *tim2, - unsigned int flags, int chans, - unsigned int *div1, unsigned int *div2, - char usessh, unsigned int chnsshfront); + int backadd, int usedma, char useeos) +{ + struct pci9118_private *devpriv = dev->private; + unsigned int i, differencial = 0, bipolar = 0; + unsigned int scanquad, gain, ssh = 0x00; + + if (usedma == 1) { + rot = 8; + usedma = 0; + } + + if (CR_AREF(chanlist[0]) == AREF_DIFF) + differencial = 1; /* all input must be diff */ + if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES) + bipolar = 1; /* all input must be bipolar */ + + /* All is ok, so we can setup channel/range list */ + + if (!bipolar) { + devpriv->AdControlReg |= AdControl_UniP; + /* set unibipolar */ + } else { + devpriv->AdControlReg &= ((~AdControl_UniP) & 0xff); + /* enable bipolar */ + } + + if (differencial) { + devpriv->AdControlReg |= AdControl_Diff; + /* enable diff inputs */ + } else { + devpriv->AdControlReg &= ((~AdControl_Diff) & 0xff); + /* set single ended inputs */ + } + + outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); + /* setup mode */ + + outl(2, dev->iobase + PCI9118_SCANMOD); + /* gods know why this sequence! */ + outl(0, dev->iobase + PCI9118_SCANMOD); + outl(1, dev->iobase + PCI9118_SCANMOD); + +#ifdef PCI9118_PARANOIDCHECK + devpriv->chanlistlen = n_chan; + for (i = 0; i < (PCI9118_CHANLEN + 1); i++) + devpriv->chanlist[i] = 0x55aa; +#endif + + if (frontadd) { /* insert channels for S&H */ + ssh = devpriv->softsshsample; + for (i = 0; i < frontadd; i++) { + /* store range list to card */ + scanquad = CR_CHAN(chanlist[0]); + /* get channel number; */ + gain = CR_RANGE(chanlist[0]); + /* get gain number */ + scanquad |= ((gain & 0x03) << 8); + outl(scanquad | ssh, dev->iobase + PCI9118_GAIN); + ssh = devpriv->softsshhold; + } + } + + for (i = 0; i < n_chan; i++) { /* store range list to card */ + scanquad = CR_CHAN(chanlist[i]); /* get channel number */ +#ifdef PCI9118_PARANOIDCHECK + devpriv->chanlist[i ^ usedma] = (scanquad & 0xf) << rot; +#endif + gain = CR_RANGE(chanlist[i]); /* get gain number */ + scanquad |= ((gain & 0x03) << 8); + outl(scanquad | ssh, dev->iobase + PCI9118_GAIN); + } + + if (backadd) { /* insert channels for fit onto 32bit DMA */ + for (i = 0; i < backadd; i++) { /* store range list to card */ + scanquad = CR_CHAN(chanlist[0]); + /* get channel number */ + gain = CR_RANGE(chanlist[0]); /* get gain number */ + scanquad |= ((gain & 0x03) << 8); + outl(scanquad | ssh, dev->iobase + PCI9118_GAIN); + } + } +#ifdef PCI9118_PARANOIDCHECK + devpriv->chanlist[n_chan ^ usedma] = devpriv->chanlist[0 ^ usedma]; + /* for 32bit operations */ + if (useeos) { + for (i = 1; i < n_chan; i++) { /* store range list to card */ + devpriv->chanlist[(n_chan + i) ^ usedma] = + (CR_CHAN(chanlist[i]) & 0xf) << rot; + } + devpriv->chanlist[(2 * n_chan) ^ usedma] = + devpriv->chanlist[0 ^ usedma]; + /* for 32bit operations */ + useeos = 2; + } else { + useeos = 1; + } +#endif + outl(0, dev->iobase + PCI9118_SCANMOD); /* close scan queue */ + /* udelay(100); important delay, or first sample will be crippled */ + + return 1; /* we can serve this with scan logic */ +} static int pci9118_insn_read_ai(struct comedi_device *dev, struct comedi_subdevice *s, @@ -540,69 +677,210 @@ static int move_block_from_dma(struct comedi_device *dev, return 0; } -static char pci9118_decode_error_status(struct comedi_device *dev, - struct comedi_subdevice *s, - unsigned char m) +static int pci9118_exttrg_add(struct comedi_device *dev, unsigned char source) { struct pci9118_private *devpriv = dev->private; - if (m & 0x100) { - comedi_error(dev, "A/D FIFO Full status (Fatal Error!)"); - devpriv->ai_maskerr &= ~0x100L; - } - if (m & 0x008) { - comedi_error(dev, - "A/D Burst Mode Overrun Status (Fatal Error!)"); - devpriv->ai_maskerr &= ~0x008L; - } - if (m & 0x004) { - comedi_error(dev, "A/D Over Speed Status (Warning!)"); - devpriv->ai_maskerr &= ~0x004L; - } - if (m & 0x002) { - comedi_error(dev, "A/D Overrun Status (Fatal Error!)"); - devpriv->ai_maskerr &= ~0x002L; - } - if (m & devpriv->ai_maskharderr) { - s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; - pci9118_ai_cancel(dev, s); - comedi_event(dev, s); - return 1; - } - + if (source > 3) + return -1; /* incorrect source */ + devpriv->exttrg_users |= (1 << source); + devpriv->IntControlReg |= Int_DTrg; + outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL); + outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00, + devpriv->iobase_a + AMCC_OP_REG_INTCSR); + /* allow INT in AMCC */ return 0; } -static void pci9118_ai_munge(struct comedi_device *dev, - struct comedi_subdevice *s, void *data, - unsigned int num_bytes, - unsigned int start_chan_index) +static int pci9118_exttrg_del(struct comedi_device *dev, unsigned char source) { struct pci9118_private *devpriv = dev->private; - unsigned int i, num_samples = num_bytes / sizeof(short); - short *array = data; - - for (i = 0; i < num_samples; i++) { - if (devpriv->usedma) - array[i] = be16_to_cpu(array[i]); - if (devpriv->ai16bits) - array[i] ^= 0x8000; - else - array[i] = (array[i] >> 4) & 0x0fff; + if (source > 3) + return -1; /* incorrect source */ + devpriv->exttrg_users &= ~(1 << source); + if (!devpriv->exttrg_users) { /* shutdown ext trg intterrupts */ + devpriv->IntControlReg &= ~Int_DTrg; + if (!devpriv->IntControlReg) /* all IRQ disabled */ + outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) & + (~0x00001f00), + devpriv->iobase_a + AMCC_OP_REG_INTCSR); + /* disable int in AMCC */ + outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL); } + return 0; } -static void interrupt_pci9118_ai_onesample(struct comedi_device *dev, - struct comedi_subdevice *s, - unsigned short int_adstat, - unsigned int int_amcc, - unsigned short int_daq) +static void pci9118_calc_divisors(char mode, struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned int *tim1, unsigned int *tim2, + unsigned int flags, int chans, + unsigned int *div1, unsigned int *div2, + char usessh, unsigned int chnsshfront) { + const struct boardtype *this_board = comedi_board(dev); struct pci9118_private *devpriv = dev->private; - register short sampl; - s->async->events = 0; + switch (mode) { + case 1: + case 4: + if (*tim2 < this_board->ai_ns_min) + *tim2 = this_board->ai_ns_min; + i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, div1, div2, + tim2, flags & TRIG_ROUND_NEAREST); + break; + case 2: + if (*tim2 < this_board->ai_ns_min) + *tim2 = this_board->ai_ns_min; + *div1 = *tim2 / devpriv->i8254_osc_base; + /* convert timer (burst) */ + if (*div1 < this_board->ai_pacer_min) + *div1 = this_board->ai_pacer_min; + *div2 = *tim1 / devpriv->i8254_osc_base; /* scan timer */ + *div2 = *div2 / *div1; /* major timer is c1*c2 */ + if (*div2 < chans) + *div2 = chans; + + *tim2 = *div1 * devpriv->i8254_osc_base; + /* real convert timer */ + + if (usessh & (chnsshfront == 0)) /* use BSSH signal */ + if (*div2 < (chans + 2)) + *div2 = chans + 2; + + *tim1 = *div1 * *div2 * devpriv->i8254_osc_base; + break; + } +} + +static void start_pacer(struct comedi_device *dev, int mode, + unsigned int divisor1, unsigned int divisor2) +{ + outl(0x74, dev->iobase + PCI9118_CNTCTRL); + outl(0xb4, dev->iobase + PCI9118_CNTCTRL); +/* outl(0x30, dev->iobase + PCI9118_CNTCTRL); */ + udelay(1); + + if ((mode == 1) || (mode == 2) || (mode == 4)) { + outl(divisor2 & 0xff, dev->iobase + PCI9118_CNT2); + outl((divisor2 >> 8) & 0xff, dev->iobase + PCI9118_CNT2); + outl(divisor1 & 0xff, dev->iobase + PCI9118_CNT1); + outl((divisor1 >> 8) & 0xff, dev->iobase + PCI9118_CNT1); + } +} + +static int pci9118_ai_cancel(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + struct pci9118_private *devpriv = dev->private; + + if (devpriv->usedma) + outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) & + (~EN_A2P_TRANSFERS), + devpriv->iobase_a + AMCC_OP_REG_MCSR); /* stop DMA */ + pci9118_exttrg_del(dev, EXTTRG_AI); + start_pacer(dev, 0, 0, 0); /* stop 8254 counters */ + devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg; + outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC); + /* + * positive triggers, no S&H, no burst, + * burst stop, no post trigger, + * no about trigger, trigger stop + */ + devpriv->AdControlReg = 0x00; + outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); + /* + * bipolar, S.E., use 8254, stop 8354, + * internal trigger, soft trigger, + * disable INT and DMA + */ + outl(0, dev->iobase + PCI9118_BURST); + outl(1, dev->iobase + PCI9118_SCANMOD); + outl(2, dev->iobase + PCI9118_SCANMOD); /* reset scan queue */ + outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */ + + devpriv->ai_do = 0; + devpriv->usedma = 0; + + devpriv->ai_act_scan = 0; + devpriv->ai_act_dmapos = 0; + s->async->cur_chan = 0; + s->async->inttrig = NULL; + devpriv->ai_buf_ptr = 0; + devpriv->ai_neverending = 0; + devpriv->dma_actbuf = 0; + + if (!devpriv->IntControlReg) + outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00, + devpriv->iobase_a + AMCC_OP_REG_INTCSR); + /* allow INT in AMCC */ + + return 0; +} + +static char pci9118_decode_error_status(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned char m) +{ + struct pci9118_private *devpriv = dev->private; + + if (m & 0x100) { + comedi_error(dev, "A/D FIFO Full status (Fatal Error!)"); + devpriv->ai_maskerr &= ~0x100L; + } + if (m & 0x008) { + comedi_error(dev, + "A/D Burst Mode Overrun Status (Fatal Error!)"); + devpriv->ai_maskerr &= ~0x008L; + } + if (m & 0x004) { + comedi_error(dev, "A/D Over Speed Status (Warning!)"); + devpriv->ai_maskerr &= ~0x004L; + } + if (m & 0x002) { + comedi_error(dev, "A/D Overrun Status (Fatal Error!)"); + devpriv->ai_maskerr &= ~0x002L; + } + if (m & devpriv->ai_maskharderr) { + s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; + pci9118_ai_cancel(dev, s); + comedi_event(dev, s); + return 1; + } + + return 0; +} + +static void pci9118_ai_munge(struct comedi_device *dev, + struct comedi_subdevice *s, void *data, + unsigned int num_bytes, + unsigned int start_chan_index) +{ + struct pci9118_private *devpriv = dev->private; + unsigned int i, num_samples = num_bytes / sizeof(short); + short *array = data; + + for (i = 0; i < num_samples; i++) { + if (devpriv->usedma) + array[i] = be16_to_cpu(array[i]); + if (devpriv->ai16bits) + array[i] ^= 0x8000; + else + array[i] = (array[i] >> 4) & 0x0fff; + + } +} + +static void interrupt_pci9118_ai_onesample(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned short int_adstat, + unsigned int int_amcc, + unsigned short int_daq) +{ + struct pci9118_private *devpriv = dev->private; + register short sampl; + + s->async->events = 0; if (int_adstat & devpriv->ai_maskerr) if (pci9118_decode_error_status(dev, s, int_adstat)) @@ -1581,306 +1859,6 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) return ret; } -static int check_channel_list(struct comedi_device *dev, - struct comedi_subdevice *s, int n_chan, - unsigned int *chanlist, int frontadd, int backadd) -{ - const struct boardtype *this_board = comedi_board(dev); - struct pci9118_private *devpriv = dev->private; - unsigned int i, differencial = 0, bipolar = 0; - - /* correct channel and range number check itself comedi/range.c */ - if (n_chan < 1) { - comedi_error(dev, "range/channel list is empty!"); - return 0; - } - if ((frontadd + n_chan + backadd) > s->len_chanlist) { - printk - ("comedi%d: range/channel list is too long for " - "actual configuration (%d>%d)!", - dev->minor, n_chan, s->len_chanlist - frontadd - backadd); - return 0; - } - - if (CR_AREF(chanlist[0]) == AREF_DIFF) - differencial = 1; /* all input must be diff */ - if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES) - bipolar = 1; /* all input must be bipolar */ - if (n_chan > 1) - for (i = 1; i < n_chan; i++) { /* check S.E/diff */ - if ((CR_AREF(chanlist[i]) == AREF_DIFF) != - (differencial)) { - comedi_error(dev, - "Differencial and single ended " - "inputs can't be mixtured!"); - return 0; - } - if ((CR_RANGE(chanlist[i]) < PCI9118_BIPOLAR_RANGES) != - (bipolar)) { - comedi_error(dev, - "Bipolar and unipolar ranges " - "can't be mixtured!"); - return 0; - } - if (!devpriv->usemux && differencial && - (CR_CHAN(chanlist[i]) >= this_board->n_aichand)) { - comedi_error(dev, - "If AREF_DIFF is used then is " - "available only first 8 channels!"); - return 0; - } - } - - return 1; -} - -static int setup_channel_list(struct comedi_device *dev, - struct comedi_subdevice *s, int n_chan, - unsigned int *chanlist, int rot, int frontadd, - int backadd, int usedma, char useeos) -{ - struct pci9118_private *devpriv = dev->private; - unsigned int i, differencial = 0, bipolar = 0; - unsigned int scanquad, gain, ssh = 0x00; - - if (usedma == 1) { - rot = 8; - usedma = 0; - } - - if (CR_AREF(chanlist[0]) == AREF_DIFF) - differencial = 1; /* all input must be diff */ - if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES) - bipolar = 1; /* all input must be bipolar */ - - /* All is ok, so we can setup channel/range list */ - - if (!bipolar) { - devpriv->AdControlReg |= AdControl_UniP; - /* set unibipolar */ - } else { - devpriv->AdControlReg &= ((~AdControl_UniP) & 0xff); - /* enable bipolar */ - } - - if (differencial) { - devpriv->AdControlReg |= AdControl_Diff; - /* enable diff inputs */ - } else { - devpriv->AdControlReg &= ((~AdControl_Diff) & 0xff); - /* set single ended inputs */ - } - - outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); - /* setup mode */ - - outl(2, dev->iobase + PCI9118_SCANMOD); - /* gods know why this sequence! */ - outl(0, dev->iobase + PCI9118_SCANMOD); - outl(1, dev->iobase + PCI9118_SCANMOD); - -#ifdef PCI9118_PARANOIDCHECK - devpriv->chanlistlen = n_chan; - for (i = 0; i < (PCI9118_CHANLEN + 1); i++) - devpriv->chanlist[i] = 0x55aa; -#endif - - if (frontadd) { /* insert channels for S&H */ - ssh = devpriv->softsshsample; - for (i = 0; i < frontadd; i++) { - /* store range list to card */ - scanquad = CR_CHAN(chanlist[0]); - /* get channel number; */ - gain = CR_RANGE(chanlist[0]); - /* get gain number */ - scanquad |= ((gain & 0x03) << 8); - outl(scanquad | ssh, dev->iobase + PCI9118_GAIN); - ssh = devpriv->softsshhold; - } - } - - for (i = 0; i < n_chan; i++) { /* store range list to card */ - scanquad = CR_CHAN(chanlist[i]); /* get channel number */ -#ifdef PCI9118_PARANOIDCHECK - devpriv->chanlist[i ^ usedma] = (scanquad & 0xf) << rot; -#endif - gain = CR_RANGE(chanlist[i]); /* get gain number */ - scanquad |= ((gain & 0x03) << 8); - outl(scanquad | ssh, dev->iobase + PCI9118_GAIN); - } - - if (backadd) { /* insert channels for fit onto 32bit DMA */ - for (i = 0; i < backadd; i++) { /* store range list to card */ - scanquad = CR_CHAN(chanlist[0]); - /* get channel number */ - gain = CR_RANGE(chanlist[0]); /* get gain number */ - scanquad |= ((gain & 0x03) << 8); - outl(scanquad | ssh, dev->iobase + PCI9118_GAIN); - } - } -#ifdef PCI9118_PARANOIDCHECK - devpriv->chanlist[n_chan ^ usedma] = devpriv->chanlist[0 ^ usedma]; - /* for 32bit operations */ - if (useeos) { - for (i = 1; i < n_chan; i++) { /* store range list to card */ - devpriv->chanlist[(n_chan + i) ^ usedma] = - (CR_CHAN(chanlist[i]) & 0xf) << rot; - } - devpriv->chanlist[(2 * n_chan) ^ usedma] = - devpriv->chanlist[0 ^ usedma]; - /* for 32bit operations */ - useeos = 2; - } else { - useeos = 1; - } -#endif - outl(0, dev->iobase + PCI9118_SCANMOD); /* close scan queue */ - /* udelay(100); important delay, or first sample will be crippled */ - - return 1; /* we can serve this with scan logic */ -} - -static void pci9118_calc_divisors(char mode, struct comedi_device *dev, - struct comedi_subdevice *s, - unsigned int *tim1, unsigned int *tim2, - unsigned int flags, int chans, - unsigned int *div1, unsigned int *div2, - char usessh, unsigned int chnsshfront) -{ - const struct boardtype *this_board = comedi_board(dev); - struct pci9118_private *devpriv = dev->private; - - switch (mode) { - case 1: - case 4: - if (*tim2 < this_board->ai_ns_min) - *tim2 = this_board->ai_ns_min; - i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, div1, div2, - tim2, flags & TRIG_ROUND_NEAREST); - break; - case 2: - if (*tim2 < this_board->ai_ns_min) - *tim2 = this_board->ai_ns_min; - *div1 = *tim2 / devpriv->i8254_osc_base; - /* convert timer (burst) */ - if (*div1 < this_board->ai_pacer_min) - *div1 = this_board->ai_pacer_min; - *div2 = *tim1 / devpriv->i8254_osc_base; /* scan timer */ - *div2 = *div2 / *div1; /* major timer is c1*c2 */ - if (*div2 < chans) - *div2 = chans; - - *tim2 = *div1 * devpriv->i8254_osc_base; - /* real convert timer */ - - if (usessh & (chnsshfront == 0)) /* use BSSH signal */ - if (*div2 < (chans + 2)) - *div2 = chans + 2; - - *tim1 = *div1 * *div2 * devpriv->i8254_osc_base; - break; - } -} - -static void start_pacer(struct comedi_device *dev, int mode, - unsigned int divisor1, unsigned int divisor2) -{ - outl(0x74, dev->iobase + PCI9118_CNTCTRL); - outl(0xb4, dev->iobase + PCI9118_CNTCTRL); -/* outl(0x30, dev->iobase + PCI9118_CNTCTRL); */ - udelay(1); - - if ((mode == 1) || (mode == 2) || (mode == 4)) { - outl(divisor2 & 0xff, dev->iobase + PCI9118_CNT2); - outl((divisor2 >> 8) & 0xff, dev->iobase + PCI9118_CNT2); - outl(divisor1 & 0xff, dev->iobase + PCI9118_CNT1); - outl((divisor1 >> 8) & 0xff, dev->iobase + PCI9118_CNT1); - } -} - -static int pci9118_exttrg_add(struct comedi_device *dev, unsigned char source) -{ - struct pci9118_private *devpriv = dev->private; - - if (source > 3) - return -1; /* incorrect source */ - devpriv->exttrg_users |= (1 << source); - devpriv->IntControlReg |= Int_DTrg; - outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL); - outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00, - devpriv->iobase_a + AMCC_OP_REG_INTCSR); - /* allow INT in AMCC */ - return 0; -} - -static int pci9118_exttrg_del(struct comedi_device *dev, unsigned char source) -{ - struct pci9118_private *devpriv = dev->private; - - if (source > 3) - return -1; /* incorrect source */ - devpriv->exttrg_users &= ~(1 << source); - if (!devpriv->exttrg_users) { /* shutdown ext trg intterrupts */ - devpriv->IntControlReg &= ~Int_DTrg; - if (!devpriv->IntControlReg) /* all IRQ disabled */ - outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) & - (~0x00001f00), - devpriv->iobase_a + AMCC_OP_REG_INTCSR); - /* disable int in AMCC */ - outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL); - } - return 0; -} - -static int pci9118_ai_cancel(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - struct pci9118_private *devpriv = dev->private; - - if (devpriv->usedma) - outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) & - (~EN_A2P_TRANSFERS), - devpriv->iobase_a + AMCC_OP_REG_MCSR); /* stop DMA */ - pci9118_exttrg_del(dev, EXTTRG_AI); - start_pacer(dev, 0, 0, 0); /* stop 8254 counters */ - devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg; - outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC); - /* - * positive triggers, no S&H, no burst, - * burst stop, no post trigger, - * no about trigger, trigger stop - */ - devpriv->AdControlReg = 0x00; - outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); - /* - * bipolar, S.E., use 8254, stop 8354, - * internal trigger, soft trigger, - * disable INT and DMA - */ - outl(0, dev->iobase + PCI9118_BURST); - outl(1, dev->iobase + PCI9118_SCANMOD); - outl(2, dev->iobase + PCI9118_SCANMOD); /* reset scan queue */ - outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */ - - devpriv->ai_do = 0; - devpriv->usedma = 0; - - devpriv->ai_act_scan = 0; - devpriv->ai_act_dmapos = 0; - s->async->cur_chan = 0; - s->async->inttrig = NULL; - devpriv->ai_buf_ptr = 0; - devpriv->ai_neverending = 0; - devpriv->dma_actbuf = 0; - - if (!devpriv->IntControlReg) - outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00, - devpriv->iobase_a + AMCC_OP_REG_INTCSR); - /* allow INT in AMCC */ - - return 0; -} - static int pci9118_reset(struct comedi_device *dev) { struct pci9118_private *devpriv = dev->private; -- cgit v0.10.2 From 22d4b56f5b4185db609f5c94113d8ee6ca8807dc Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 16:42:11 -0700 Subject: staging: comedi: adl_pci9118: use cfc_check_trigger_src The the cfc_check_trigger_src helper for the "step 1" tests in pci9118_ai_cmdtest(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index f3beeb8..f7b254d 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -1098,43 +1098,28 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev, const struct boardtype *this_board = comedi_board(dev); struct pci9118_private *devpriv = dev->private; int err = 0; + unsigned int flags; int tmp; unsigned int divisor1 = 0, divisor2 = 0; /* step 1: make sure trigger sources are trivially valid */ - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW | TRIG_EXT | TRIG_INT; - if (!cmd->start_src || tmp != cmd->start_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, + TRIG_NOW | TRIG_EXT | TRIG_INT); - tmp = cmd->scan_begin_src; + flags = TRIG_FOLLOW; if (devpriv->master) - cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT | TRIG_FOLLOW; - else - cmd->scan_begin_src &= TRIG_FOLLOW; + flags |= TRIG_TIMER | TRIG_EXT; + err |= cfc_check_trigger_src(&cmd->scan_begin_src, flags); - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; + flags = TRIG_TIMER | TRIG_EXT; if (devpriv->master) - cmd->convert_src &= TRIG_TIMER | TRIG_EXT | TRIG_NOW; - else - cmd->convert_src &= TRIG_TIMER | TRIG_EXT; + flags |= TRIG_NOW; + err |= cfc_check_trigger_src(&cmd->convert_src, flags); - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE | TRIG_EXT; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, + TRIG_COUNT | TRIG_NONE | TRIG_EXT); if (err) return 1; -- cgit v0.10.2 From 5c1eb3857a7fada597f6dc2746f5f700bdb780ee Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 11 Sep 2012 16:49:06 -0700 Subject: staging: comedi: adq12b: remove devpriv macro This macro relies on a local variable having a specific name. Also, remove the kfree in the detach. The comedi core handles the kfree of dev->private. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adq12b.c b/drivers/staging/comedi/drivers/adq12b.c index 0340c9c..3a2aa56 100644 --- a/drivers/staging/comedi/drivers/adq12b.c +++ b/drivers/staging/comedi/drivers/adq12b.c @@ -133,8 +133,6 @@ struct adq12b_private { unsigned int digital_state; }; -#define devpriv ((struct adq12b_private *)dev->private) - /* * "instructions" read/write data in "one-shot" or "software-triggered" * mode. @@ -144,6 +142,7 @@ static int adq12b_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct adq12b_private *devpriv = dev->private; int n, i; int range, channel; unsigned char hi, lo, status; @@ -200,6 +199,7 @@ static int adq12b_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct adq12b_private *devpriv = dev->private; int channel; for (channel = 0; channel < 8; channel++) @@ -221,6 +221,7 @@ static int adq12b_do_insn_bits(struct comedi_device *dev, static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct adq12b_board *board = comedi_board(dev); + struct adq12b_private *devpriv; struct comedi_subdevice *s; unsigned long iobase; int unipolar, differential; @@ -252,19 +253,18 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = board->name; -/* - * Allocate the private structure area. alloc_private() is a - * convenient macro defined in comedidev.h. - */ - if (alloc_private(dev, sizeof(struct adq12b_private)) < 0) - return -ENOMEM; + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; + devpriv = dev->private; -/* fill in devpriv structure */ devpriv->unipolar = unipolar; devpriv->differential = differential; devpriv->digital_state = 0; -/* initialize channel and range to -1 so we make sure we always write - at least once to the CTREG in the instruction */ + /* + * initialize channel and range to -1 so we make sure we + * always write at least once to the CTREG in the instruction + */ devpriv->last_channel = -1; devpriv->last_range = -1; @@ -321,7 +321,6 @@ static void adq12b_detach(struct comedi_device *dev) { if (dev->iobase) release_region(dev->iobase, ADQ12B_SIZE); - kfree(devpriv); } static const struct adq12b_board adq12b_boards[] = { -- cgit v0.10.2 From e66fc1fba248738d32f3b64508f9ef1176d9e767 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Tue, 11 Sep 2012 22:19:06 -0400 Subject: Staging: bcm: Create and initialize new device id in InterfaceInit This patch create and initalizes a new device id of 0x172 as reported by Rinat Camalov . In addition, a comment is added to the potential invalid existing device id. Reported-by: Rinat Camalov Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c index dfee0ce..b05f5f7 100644 --- a/drivers/staging/bcm/InterfaceInit.c +++ b/drivers/staging/bcm/InterfaceInit.c @@ -8,6 +8,7 @@ static struct usb_device_id InterfaceUsbtable[] = { { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_226) }, { USB_DEVICE(BCM_USB_VENDOR_ID_FOXCONN, BCM_USB_PRODUCT_ID_1901) }, { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_ZTE_TU25) }, + { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_ZTE_226) }, { } }; MODULE_DEVICE_TABLE(usb, InterfaceUsbtable); diff --git a/drivers/staging/bcm/InterfaceInit.h b/drivers/staging/bcm/InterfaceInit.h index 3b35832..866924e 100644 --- a/drivers/staging/bcm/InterfaceInit.h +++ b/drivers/staging/bcm/InterfaceInit.h @@ -11,7 +11,8 @@ #define BCM_USB_PRODUCT_ID_SM250 0xbccd #define BCM_USB_PRODUCT_ID_SYM 0x15E #define BCM_USB_PRODUCT_ID_1901 0xe017 -#define BCM_USB_PRODUCT_ID_226 0x0132 +#define BCM_USB_PRODUCT_ID_226 0x0132 /* not sure if this is valid */ +#define BCM_USB_PRODUCT_ID_ZTE_226 0x172 #define BCM_USB_PRODUCT_ID_ZTE_TU25 0x0007 #define BCM_USB_MINOR_BASE 192 -- cgit v0.10.2 From 2e464f00687931eeeab95c90e3796609d0c8ce4c Mon Sep 17 00:00:00 2001 From: Peter Senna Tschudin Date: Wed, 12 Sep 2012 17:06:43 +0200 Subject: drivers/staging/rtl8192u/r8192U_core.c: Remove useless kfree Remove useless kfree() and clean up code related to the removal. The semantic patch that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r exists@ position p1,p2; expression x; @@ if (x@p1 == NULL) { ... kfree@p2(x); ... return ...; } @unchanged exists@ position r.p1,r.p2; expression e <= r.x,x,e1; iterator I; statement S; @@ if (x@p1 == NULL) { ... when != I(x,...) S when != e = e1 when != e += e1 when != e -= e1 when != ++e when != --e when != e++ when != e-- when != &e kfree@p2(x); ... return ...; } @ok depends on unchanged exists@ position any r.p1; position r.p2; expression x; @@ ... when != true x@p1 == NULL kfree@p2(x); @depends on !ok && unchanged@ position r.p2; expression x; @@ *kfree@p2(x); // Signed-off-by: Peter Senna Tschudin Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index 5c132ac..5a2fab9 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -2232,24 +2232,15 @@ short rtl8192_usb_initendpoints(struct net_device *dev) memset(priv->rx_urb, 0, sizeof(struct urb*) * MAX_RX_URB); priv->pp_rxskb = kcalloc(MAX_RX_URB, sizeof(struct sk_buff *), GFP_KERNEL); - if (priv->pp_rxskb == NULL) - goto destroy; - - goto _middle; - - -destroy: - kfree(priv->pp_rxskb); - kfree(priv->rx_urb); - - priv->pp_rxskb = NULL; - priv->rx_urb = NULL; - - DMESGE("Endpoint Alloc Failure"); - return -ENOMEM; + if (!priv->pp_rxskb) { + kfree(priv->rx_urb); + priv->pp_rxskb = NULL; + priv->rx_urb = NULL; -_middle: + DMESGE("Endpoint Alloc Failure"); + return -ENOMEM; + } printk("End of initendpoints\n"); return 0; -- cgit v0.10.2 From 47ad3428a1086af425447f763705e06b16ae905d Mon Sep 17 00:00:00 2001 From: Peter Senna Tschudin Date: Wed, 12 Sep 2012 17:06:44 +0200 Subject: drivers/staging/gdm72xx/gdm_sdio.c: Remove useless kfree Remove useless kfree() and clean up code related to the removal. The semantic patch that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r exists@ position p1,p2; expression x; @@ if (x@p1 == NULL) { ... kfree@p2(x); ... return ...; } @unchanged exists@ position r.p1,r.p2; expression e <= r.x,x,e1; iterator I; statement S; @@ if (x@p1 == NULL) { ... when != I(x,...) S when != e = e1 when != e += e1 when != e -= e1 when != ++e when != --e when != e++ when != e-- when != &e kfree@p2(x); ... return ...; } @ok depends on unchanged exists@ position any r.p1; position r.p2; expression x; @@ ... when != true x@p1 == NULL kfree@p2(x); @depends on !ok && unchanged@ position r.p2; expression x; @@ *kfree@p2(x); // Signed-off-by: Peter Senna Tschudin Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/gdm72xx/gdm_sdio.c b/drivers/staging/gdm72xx/gdm_sdio.c index f824290..a0621d9 100644 --- a/drivers/staging/gdm72xx/gdm_sdio.c +++ b/drivers/staging/gdm72xx/gdm_sdio.c @@ -94,17 +94,14 @@ static struct sdio_rx *alloc_rx_struct(struct rx_cxt *rx) struct sdio_rx *r = NULL; r = kmalloc(sizeof(*r), GFP_ATOMIC); - if (r == NULL) - goto out; + if (!r) + return NULL; memset(r, 0, sizeof(*r)); r->rx_cxt = rx; return r; -out: - kfree(r); - return NULL; } static void free_rx_struct(struct sdio_rx *r) -- cgit v0.10.2 From f325129ae9006298cfbeffb669b30f57ba0cc3c4 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 12 Sep 2012 10:57:33 +0300 Subject: Staging: silicom: remove S_IWOTH from proc declaration We don't need these to be world writable or group writable. Signed-off-by: Dan Carpenter Cc: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/bp_mod.c b/drivers/staging/silicom/bp_mod.c index 0d96196..6e999c7 100644 --- a/drivers/staging/silicom/bp_mod.c +++ b/drivers/staging/silicom/bp_mod.c @@ -7724,8 +7724,7 @@ bypass_proc_create_entry_sd(struct pfs_unit_sd *pfs_unit_curr, pfs_unit_curr->proc_entry = create_proc_entry(pfs_unit_curr->proc_name, S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | - S_IWGRP | S_IROTH | - S_IWOTH, parent_pfs); + S_IROTH, parent_pfs); if (pfs_unit_curr->proc_entry == 0) { return -1; diff --git a/drivers/staging/silicom/bp_proc.c b/drivers/staging/silicom/bp_proc.c index 4fe862d..6ad4b27 100644 --- a/drivers/staging/silicom/bp_proc.c +++ b/drivers/staging/silicom/bp_proc.c @@ -106,8 +106,7 @@ bypass_proc_create_entry_sd(struct pfs_unit *pfs_unit_curr, pfs_unit_curr->proc_entry = create_proc_entry(pfs_unit_curr->proc_name, S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | - S_IWGRP | S_IROTH | - S_IWOTH, parent_pfs); + S_IROTH, parent_pfs); if (pfs_unit_curr->proc_entry == 0) { return -1; -- cgit v0.10.2 From a09f347c6cc0b2821557d1346c4733cc78a79ffa Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Wed, 12 Sep 2012 00:44:37 +0300 Subject: staging: xgifb: validate the mode against video memory size It's possible to select video mode that exceeds the available video memory. This is potentially dangerous, fix by adding a check. The patch fixes system hangs seen occasionally when playing random videos with mplayer. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 7fc3049..ba6c347 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -329,6 +329,7 @@ static int XGIfb_validate_mode(struct xgifb_video_info *xgifb_info, int myindex) { u16 xres, yres; struct xgi_hw_device_info *hw_info = &xgifb_info->hw_info; + unsigned long required_mem; if (xgifb_info->chip == XG21) { if (xgifb_info->display2 == XGIFB_DISP_LCD) { @@ -345,13 +346,13 @@ static int XGIfb_validate_mode(struct xgifb_video_info *xgifb_info, int myindex) } } - return myindex; + goto check_memory; } /* FIXME: for now, all is valid on XG27 */ if (xgifb_info->chip == XG27) - return myindex; + goto check_memory; if (!(XGIbios_mode[myindex].chipset & MD_XGI315)) return -1; @@ -539,6 +540,12 @@ static int XGIfb_validate_mode(struct xgifb_video_info *xgifb_info, int myindex) case XGIFB_DISP_NONE: break; } + +check_memory: + required_mem = XGIbios_mode[myindex].xres * XGIbios_mode[myindex].yres * + XGIbios_mode[myindex].bpp / 8; + if (required_mem > xgifb_info->video_size) + return -1; return myindex; } -- cgit v0.10.2 From 6b2a7e0c9bcc0a4df385d1ef8fe5109cea0260e2 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Wed, 12 Sep 2012 00:44:38 +0300 Subject: staging: xgifb: prevent video RAM size exceeding PCI window size Add a sanity check for the video RAM size. It should fit into the PCI window. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index ba6c347..98b8b09 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -1700,6 +1700,7 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, struct fb_info *fb_info; struct xgifb_video_info *xgifb_info; struct xgi_hw_device_info *hw_info; + unsigned long video_size_max; fb_info = framebuffer_alloc(sizeof(*xgifb_info), &pdev->dev); if (!fb_info) @@ -1720,6 +1721,7 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, xgifb_info->subsysvendor = pdev->subsystem_vendor; xgifb_info->subsysdevice = pdev->subsystem_device; + video_size_max = pci_resource_len(pdev, 0); xgifb_info->video_base = pci_resource_start(pdev, 0); xgifb_info->mmio_base = pci_resource_start(pdev, 1); xgifb_info->mmio_size = pci_resource_len(pdev, 1); @@ -1780,6 +1782,8 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, "Fatal error: Unable to determine RAM size.\n"); ret = -ENODEV; goto error_disable; + } else if (xgifb_info->video_size > video_size_max) { + xgifb_info->video_size = video_size_max; } /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */ -- cgit v0.10.2 From 0d660025564343e7c20c096d386f8ef8bacebdcd Mon Sep 17 00:00:00 2001 From: Macpaul Lin Date: Wed, 12 Sep 2012 17:49:24 +0800 Subject: staging/gdm72xx: gdm_usb coding style clean up gdm_usb.* coding style clean up. Signed-off-by: Macpaul Lin Cc: Paul Stewart Cc: Ben Chan Cc: Sage Ahn Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/gdm72xx/gdm_usb.c b/drivers/staging/gdm72xx/gdm_usb.c index 41e08a7..6d306f7 100644 --- a/drivers/staging/gdm72xx/gdm_usb.c +++ b/drivers/staging/gdm72xx/gdm_usb.c @@ -26,11 +26,11 @@ MODULE_DEVICE_TABLE(usb, id_table); -#define TX_BUF_SIZE 2048 +#define TX_BUF_SIZE 2048 #if defined(CONFIG_WIMAX_GDM72XX_WIMAX2) -#define RX_BUF_SIZE (128*1024) /* For packet aggregation */ +#define RX_BUF_SIZE (128*1024) /* For packet aggregation */ #else -#define RX_BUF_SIZE 2048 +#define RX_BUF_SIZE 2048 #endif #define GDM7205_PADDING 256 @@ -39,7 +39,7 @@ MODULE_DEVICE_TABLE(usb, id_table); #define B2H(x) __be16_to_cpu(x) #define DB2H(x) __be32_to_cpu(x) -#define DOWNLOAD_CONF_VALUE 0x21 +#define DOWNLOAD_CONF_VALUE 0x21 #ifdef CONFIG_WIMAX_GDM72XX_K_MODE @@ -48,7 +48,7 @@ static LIST_HEAD(k_list); static DEFINE_SPINLOCK(k_lock); static int k_mode_stop; -#define K_WAIT_TIME (2 * HZ / 100) +#define K_WAIT_TIME (2 * HZ / 100) #endif /* CONFIG_WIMAX_GDM72XX_K_MODE */ diff --git a/drivers/staging/gdm72xx/gdm_usb.h b/drivers/staging/gdm72xx/gdm_usb.h index ecb891f..f2c5451 100644 --- a/drivers/staging/gdm72xx/gdm_usb.h +++ b/drivers/staging/gdm72xx/gdm_usb.h @@ -18,8 +18,8 @@ #include #include -#define B_DIFF_DL_DRV (1<<4) -#define B_DOWNLOAD (1 << 5) +#define B_DIFF_DL_DRV (1 << 4) +#define B_DOWNLOAD (1 << 5) #define MAX_NR_SDU_BUF 64 struct usb_tx { @@ -29,7 +29,7 @@ struct usb_tx { #endif struct tx_cxt *tx_cxt; - struct urb *urb; + struct urb *urb; u8 *buf; void (*callback)(void *cb_data); @@ -44,14 +44,14 @@ struct tx_cxt { struct list_head pending_list; #endif - spinlock_t lock; + spinlock_t lock; }; struct usb_rx { struct list_head list; struct rx_cxt *rx_cxt; - struct urb *urb; + struct urb *urb; u8 *buf; void (*callback)(void *cb_data, void *data, int len); @@ -61,7 +61,7 @@ struct usb_rx { struct rx_cxt { struct list_head free_list; struct list_head used_list; - spinlock_t lock; + spinlock_t lock; }; struct usbwm_dev { @@ -76,8 +76,8 @@ struct usbwm_dev { struct list_head list; #endif - struct tx_cxt tx; - struct rx_cxt rx; + struct tx_cxt tx; + struct rx_cxt rx; int padding; }; -- cgit v0.10.2 From 0118681b2bc2f182b7cd4c6569632cf2729cc73e Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Wed, 12 Sep 2012 14:55:23 +0200 Subject: Staging: ipack/bridges/tpci200: add helpers for writing control regs. Convert tpci200_set_clockrate and tpci200_interrupt. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 9d886b7..2560519 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -53,6 +53,32 @@ static struct tpci200_board *check_slot(struct ipack_device *dev) return tpci200; } +static void __tpci200_clear_mask(__le16 __iomem *addr, u16 mask) +{ + iowrite16(ioread16(addr) & (~mask), addr); +} + +static void tpci200_clear_mask(struct tpci200_board *tpci200, + __le16 __iomem *addr, u16 mask) +{ + mutex_lock(&tpci200->mutex); + __tpci200_clear_mask(addr, mask); + mutex_unlock(&tpci200->mutex); +} + +static void __tpci200_set_mask(__le16 __iomem *addr, u16 mask) +{ + iowrite16(ioread16(addr) | mask, addr); +} + +static void tpci200_set_mask(struct tpci200_board *tpci200, + __le16 __iomem *addr, u16 mask) +{ + mutex_lock(&tpci200->mutex); + __tpci200_set_mask(addr, mask); + mutex_unlock(&tpci200->mutex); +} + static void tpci200_unregister(struct tpci200_board *tpci200) { int i; @@ -86,7 +112,7 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id) { struct tpci200_board *tpci200 = (struct tpci200_board *) dev_id; int i; - unsigned short status_reg, reg_value; + unsigned short status_reg; unsigned short unhandled_ints = 0; irqreturn_t ret = IRQ_NONE; struct slot_irq *slot_irq; @@ -124,12 +150,9 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id) dev_info(&slot_irq->holder->dev, "No registered ISR for slot [%d:%d]!. IRQ will be disabled.\n", tpci200->number, i); - reg_value = readw( - &tpci200->info->interface_regs->control[i]); - reg_value &= - ~(TPCI200_INT0_EN | TPCI200_INT1_EN); - writew(reg_value, - &tpci200->info->interface_regs->control[i]); + __tpci200_clear_mask( + &tpci200->info->interface_regs->control[i], + TPCI200_INT0_EN | TPCI200_INT1_EN); } } } @@ -518,30 +541,22 @@ static int tpci200_set_clockrate(struct ipack_device *dev, int mherz) { struct tpci200_board *tpci200 = check_slot(dev); u16 __iomem *addr; - u16 reg; if (!tpci200) return -ENODEV; addr = &tpci200->info->interface_regs->control[dev->slot]; - /* Ensure the control register is not changed by another task after we - * have read it. */ - mutex_lock(&tpci200->mutex); - reg = ioread16(addr); switch (mherz) { case 8: - reg &= ~(TPCI200_CLK32); + tpci200_clear_mask(tpci200, addr, TPCI200_CLK32); break; case 32: - reg |= TPCI200_CLK32; + tpci200_set_mask(tpci200, addr, TPCI200_CLK32); break; default: - mutex_unlock(&tpci200->mutex); return -EINVAL; } - iowrite16(reg, addr); - mutex_unlock(&tpci200->mutex); return 0; } -- cgit v0.10.2 From 9b27adbced2455bfd7e5d1b76a7f151de3d25dec Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Wed, 12 Sep 2012 14:55:24 +0200 Subject: Staging: ipack/bridges/tpci200: Remove side effects of tpci200_{request,free}_irq. Use the __tpci200_{set,clear}_mask routines to access control register. Do not overwrite flags unrelated to interrupt handling. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 2560519..3285dad 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -278,37 +278,18 @@ out_disable_pci: static int __tpci200_request_irq(struct tpci200_board *tpci200, struct ipack_device *dev) { - unsigned short slot_ctrl; - - /* Set the default parameters of the slot - * INT0 enabled, level sensitive - * INT1 enabled, level sensitive - * error interrupt disabled - * timeout interrupt disabled - * recover time disabled - * clock rate 8 MHz - */ - slot_ctrl = TPCI200_INT0_EN | TPCI200_INT1_EN; - writew(slot_ctrl, &tpci200->info->interface_regs->control[dev->slot]); - + __tpci200_set_mask( + &tpci200->info->interface_regs->control[dev->slot], + TPCI200_INT0_EN | TPCI200_INT1_EN); return 0; } static void __tpci200_free_irq(struct tpci200_board *tpci200, struct ipack_device *dev) { - unsigned short slot_ctrl; - - /* Set the default parameters of the slot - * INT0 disabled, level sensitive - * INT1 disabled, level sensitive - * error interrupt disabled - * timeout interrupt disabled - * recover time disabled - * clock rate 8 MHz - */ - slot_ctrl = 0; - writew(slot_ctrl, &tpci200->info->interface_regs->control[dev->slot]); + __tpci200_clear_mask( + &tpci200->info->interface_regs->control[dev->slot], + TPCI200_INT0_EN | TPCI200_INT1_EN); } static int tpci200_free_irq(struct ipack_device *dev) -- cgit v0.10.2 From af2140ce288fcb12a3c30a69b6ba93fd64d0a861 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Wed, 12 Sep 2012 14:55:25 +0200 Subject: Staging: ipack/bridges/tpci200: Clean up interrupt handler. This also removes a possible bug in the unhandles_ints part when slots[i] is not set. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 3285dad..24e2a11 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -108,12 +108,22 @@ static void tpci200_unregister(struct tpci200_board *tpci200) } } +static irqreturn_t tpci200_slot_irq(struct slot_irq *slot_irq) +{ + irqreturn_t ret = slot_irq->handler(slot_irq->arg); + + /* Dummy reads */ + readw(slot_irq->holder->io_space.address + 0xC0); + readw(slot_irq->holder->io_space.address + 0xC2); + + return ret; +} + static irqreturn_t tpci200_interrupt(int irq, void *dev_id) { struct tpci200_board *tpci200 = (struct tpci200_board *) dev_id; int i; unsigned short status_reg; - unsigned short unhandled_ints = 0; irqreturn_t ret = IRQ_NONE; struct slot_irq *slot_irq; @@ -121,33 +131,15 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id) status_reg = readw(&tpci200->info->interface_regs->status); if (status_reg & TPCI200_SLOT_INT_MASK) { - unhandled_ints = status_reg & TPCI200_SLOT_INT_MASK; /* callback to the IRQ handler for the corresponding slot */ for (i = 0; i < TPCI200_NB_SLOT; i++) { + if (!(status_reg & ((TPCI200_A_INT0 | TPCI200_A_INT1) << (2*i)))) + continue; slot_irq = tpci200->slots[i].irq; - - if ((slot_irq != NULL) && - (status_reg & ((TPCI200_A_INT0 | TPCI200_A_INT1) << (2*i)))) { - - ret = slot_irq->handler(slot_irq->arg); - - /* Dummy reads */ - readw(slot_irq->holder->io_space.address + - 0xC0); - readw(slot_irq->holder->io_space.address + - 0xC2); - - unhandled_ints &= ~(((TPCI200_A_INT0 | TPCI200_A_INT1) << (2*i))); - } - } - } - /* Interrupts not handled are disabled */ - if (unhandled_ints) { - for (i = 0; i < TPCI200_NB_SLOT; i++) { - slot_irq = tpci200->slots[i].irq; - - if (unhandled_ints & ((TPCI200_INT0_EN | TPCI200_INT1_EN) << (2*i))) { - dev_info(&slot_irq->holder->dev, + if (slot_irq) { + ret = tpci200_slot_irq(slot_irq); + } else { + dev_info(&tpci200->info->pdev->dev, "No registered ISR for slot [%d:%d]!. IRQ will be disabled.\n", tpci200->number, i); __tpci200_clear_mask( -- cgit v0.10.2 From 70a32811e5d1c3a48d99088065ef74367221cde3 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Wed, 12 Sep 2012 14:55:26 +0200 Subject: Staging: ipack/devices/ipoctal: split ipoctal_channel from ipoctal. By moving everything channel related into a separate struct we will be able to clean up a lot of code. In the end tty->driver_data will no longer need to point to ipoctal but instead can point to the respective channel. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index 35513d9..9ab0e80 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -30,22 +30,26 @@ static const struct tty_operations ipoctal_fops; +struct ipoctal_channel { + struct ipoctal_stats stats; + unsigned int nb_bytes; + unsigned int count_wr; + wait_queue_head_t queue; + spinlock_t lock; + unsigned int pointer_read; + unsigned int pointer_write; + atomic_t open; + struct tty_port tty_port; + union scc2698_channel __iomem *regs; + union scc2698_block __iomem *block_regs; +}; + struct ipoctal { struct list_head list; struct ipack_device *dev; unsigned int board_id; - union scc2698_channel __iomem *chan_regs; - union scc2698_block __iomem *block_regs; - struct ipoctal_stats chan_stats[NR_CHANNELS]; - unsigned int nb_bytes[NR_CHANNELS]; - unsigned int count_wr[NR_CHANNELS]; - wait_queue_head_t queue[NR_CHANNELS]; - spinlock_t lock[NR_CHANNELS]; - unsigned int pointer_read[NR_CHANNELS]; - unsigned int pointer_write[NR_CHANNELS]; - atomic_t open[NR_CHANNELS]; + struct ipoctal_channel channel[NR_CHANNELS]; unsigned char write; - struct tty_port tty_port[NR_CHANNELS]; struct tty_driver *tty_drv; }; @@ -87,7 +91,7 @@ static struct ipoctal *ipoctal_find_board(struct tty_struct *tty) static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty) { struct ipoctal *ipoctal; - int channel = tty->index; + struct ipoctal_channel *channel; ipoctal = ipoctal_find_board(tty); @@ -96,17 +100,18 @@ static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty) tty->driver->major); return -ENODEV; } + channel = &ipoctal->channel[tty->index]; - ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].w.cr, + ipoctal_write_io_reg(ipoctal, &channel->regs->w.cr, CR_ENABLE_RX); return 0; } static int ipoctal_open(struct tty_struct *tty, struct file *file) { - int channel = tty->index; int res; struct ipoctal *ipoctal; + struct ipoctal_channel *channel; ipoctal = ipoctal_find_board(tty); @@ -115,17 +120,18 @@ static int ipoctal_open(struct tty_struct *tty, struct file *file) tty->driver->major); return -ENODEV; } + channel = &ipoctal->channel[tty->index]; - if (atomic_read(&ipoctal->open[channel])) + if (atomic_read(&channel->open)) return -EBUSY; tty->driver_data = ipoctal; - res = tty_port_open(&ipoctal->tty_port[channel], tty, file); + res = tty_port_open(&channel->tty_port, tty, file); if (res) return res; - atomic_inc(&ipoctal->open[channel]); + atomic_inc(&channel->open); return 0; } @@ -141,26 +147,27 @@ static void ipoctal_reset_stats(struct ipoctal_stats *stats) static void ipoctal_free_channel(struct tty_struct *tty) { - int channel = tty->index; struct ipoctal *ipoctal = tty->driver_data; + struct ipoctal_channel *channel; if (ipoctal == NULL) return; + channel = &ipoctal->channel[tty->index]; - ipoctal_reset_stats(&ipoctal->chan_stats[channel]); - ipoctal->pointer_read[channel] = 0; - ipoctal->pointer_write[channel] = 0; - ipoctal->nb_bytes[channel] = 0; + ipoctal_reset_stats(&channel->stats); + channel->pointer_read = 0; + channel->pointer_write = 0; + channel->nb_bytes = 0; } static void ipoctal_close(struct tty_struct *tty, struct file *filp) { - int channel = tty->index; struct ipoctal *ipoctal = tty->driver_data; + struct ipoctal_channel *channel = &ipoctal->channel[tty->index]; - tty_port_close(&ipoctal->tty_port[channel], tty, filp); + tty_port_close(&channel->tty_port, tty, filp); - if (atomic_dec_and_test(&ipoctal->open[channel])) + if (atomic_dec_and_test(&channel->open)) ipoctal_free_channel(tty); } @@ -168,24 +175,23 @@ static int ipoctal_get_icount(struct tty_struct *tty, struct serial_icounter_struct *icount) { struct ipoctal *ipoctal = tty->driver_data; - int channel = tty->index; + struct ipoctal_channel *channel = &ipoctal->channel[tty->index]; icount->cts = 0; icount->dsr = 0; icount->rng = 0; icount->dcd = 0; - icount->rx = ipoctal->chan_stats[channel].rx; - icount->tx = ipoctal->chan_stats[channel].tx; - icount->frame = ipoctal->chan_stats[channel].framing_err; - icount->parity = ipoctal->chan_stats[channel].parity_err; - icount->brk = ipoctal->chan_stats[channel].rcv_break; + icount->rx = channel->stats.rx; + icount->tx = channel->stats.tx; + icount->frame = channel->stats.framing_err; + icount->parity = channel->stats.parity_err; + icount->brk = channel->stats.rcv_break; return 0; } static int ipoctal_irq_handler(void *arg) { - unsigned int channel; - unsigned int block; + unsigned int ichannel; unsigned char isr; unsigned char sr; unsigned char isr_tx_rdy, isr_rx_rdy; @@ -193,14 +199,16 @@ static int ipoctal_irq_handler(void *arg) unsigned char flag; struct tty_struct *tty; struct ipoctal *ipoctal = (struct ipoctal *) arg; + struct ipoctal_channel *channel; /* Check all channels */ - for (channel = 0; channel < NR_CHANNELS; channel++) { + for (ichannel = 0; ichannel < NR_CHANNELS; ichannel++) { + channel = &ipoctal->channel[ichannel]; /* If there is no client, skip the check */ - if (!atomic_read(&ipoctal->open[channel])) + if (!atomic_read(&channel->open)) continue; - tty = tty_port_tty_get(&ipoctal->tty_port[channel]); + tty = tty_port_tty_get(&channel->tty_port); if (!tty) continue; @@ -208,13 +216,12 @@ static int ipoctal_irq_handler(void *arg) * The HW is organized in pair of channels. * See which register we need to read from */ - block = channel / 2; isr = ipoctal_read_io_reg(ipoctal, - &ipoctal->block_regs[block].r.isr); + &channel->block_regs->r.isr); sr = ipoctal_read_io_reg(ipoctal, - &ipoctal->chan_regs[channel].r.sr); + &channel->regs->r.sr); - if ((channel % 2) == 1) { + if ((ichannel % 2) == 1) { isr_tx_rdy = isr & ISR_TxRDY_B; isr_rx_rdy = isr & ISR_RxRDY_FFULL_B; } else { @@ -227,47 +234,47 @@ static int ipoctal_irq_handler(void *arg) */ if ((ipoctal->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) && (sr & SR_TX_EMPTY) && - (ipoctal->nb_bytes[channel] == 0)) { + (channel->nb_bytes == 0)) { ipoctal_write_io_reg(ipoctal, - &ipoctal->chan_regs[channel].w.cr, + &channel->regs->w.cr, CR_DISABLE_TX); ipoctal_write_cr_cmd(ipoctal, - &ipoctal->chan_regs[channel].w.cr, + &channel->regs->w.cr, CR_CMD_NEGATE_RTSN); ipoctal_write_io_reg(ipoctal, - &ipoctal->chan_regs[channel].w.cr, + &channel->regs->w.cr, CR_ENABLE_RX); ipoctal->write = 1; - wake_up_interruptible(&ipoctal->queue[channel]); + wake_up_interruptible(&channel->queue); } /* RX data */ if (isr_rx_rdy && (sr & SR_RX_READY)) { value = ipoctal_read_io_reg(ipoctal, - &ipoctal->chan_regs[channel].r.rhr); + &channel->regs->r.rhr); flag = TTY_NORMAL; /* Error: count statistics */ if (sr & SR_ERROR) { ipoctal_write_cr_cmd(ipoctal, - &ipoctal->chan_regs[channel].w.cr, + &channel->regs->w.cr, CR_CMD_RESET_ERR_STATUS); if (sr & SR_OVERRUN_ERROR) { - ipoctal->chan_stats[channel].overrun_err++; + channel->stats.overrun_err++; /* Overrun doesn't affect the current character*/ tty_insert_flip_char(tty, 0, TTY_OVERRUN); } if (sr & SR_PARITY_ERROR) { - ipoctal->chan_stats[channel].parity_err++; + channel->stats.parity_err++; flag = TTY_PARITY; } if (sr & SR_FRAMING_ERROR) { - ipoctal->chan_stats[channel].framing_err++; + channel->stats.framing_err++; flag = TTY_FRAME; } if (sr & SR_RECEIVED_BREAK) { - ipoctal->chan_stats[channel].rcv_break++; + channel->stats.rcv_break++; flag = TTY_BREAK; } } @@ -277,30 +284,29 @@ static int ipoctal_irq_handler(void *arg) /* TX of each character */ if (isr_tx_rdy && (sr & SR_TX_READY)) { - unsigned int *pointer_write = - &ipoctal->pointer_write[channel]; + unsigned int *pointer_write = &channel->pointer_write; - if (ipoctal->nb_bytes[channel] <= 0) { - ipoctal->nb_bytes[channel] = 0; + if (channel->nb_bytes <= 0) { + channel->nb_bytes = 0; continue; } - value = ipoctal->tty_port[channel].xmit_buf[*pointer_write]; + value = channel->tty_port.xmit_buf[*pointer_write]; ipoctal_write_io_reg(ipoctal, - &ipoctal->chan_regs[channel].w.thr, + &channel->regs->w.thr, value); - ipoctal->chan_stats[channel].tx++; - ipoctal->count_wr[channel]++; + channel->stats.tx++; + channel->count_wr++; (*pointer_write)++; *pointer_write = *pointer_write % PAGE_SIZE; - ipoctal->nb_bytes[channel]--; + channel->nb_bytes--; - if ((ipoctal->nb_bytes[channel] == 0) && - (waitqueue_active(&ipoctal->queue[channel]))) { + if ((channel->nb_bytes == 0) && + (waitqueue_active(&channel->queue))) { if (ipoctal->board_id != IPACK1_DEVICE_ID_SBS_OCTAL_485) { ipoctal->write = 1; - wake_up_interruptible(&ipoctal->queue[channel]); + wake_up_interruptible(&channel->queue); } } } @@ -348,6 +354,9 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, struct tty_driver *tty; char name[20]; unsigned char board_id; + struct ipoctal_channel *channel; + union scc2698_channel __iomem *chan_regs; + union scc2698_block __iomem *block_regs; res = ipoctal->dev->bus->ops->map_space(ipoctal->dev, 0, IPACK_ID_SPACE); @@ -385,41 +394,45 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, } /* Save the virtual address to access the registers easily */ - ipoctal->chan_regs = + chan_regs = (union scc2698_channel __iomem *) ipoctal->dev->io_space.address; - ipoctal->block_regs = + block_regs = (union scc2698_block __iomem *) ipoctal->dev->io_space.address; /* Disable RX and TX before touching anything */ for (i = 0; i < NR_CHANNELS ; i++) { - ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[i].w.cr, + struct ipoctal_channel *channel = &ipoctal->channel[i]; + channel->regs = chan_regs + i; + channel->block_regs = block_regs + (i >> 1); + + ipoctal_write_io_reg(ipoctal, &channel->regs->w.cr, CR_DISABLE_RX | CR_DISABLE_TX); - ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[i].w.cr, + ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr, CR_CMD_RESET_RX); - ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[i].w.cr, + ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr, CR_CMD_RESET_TX); ipoctal_write_io_reg(ipoctal, - &ipoctal->chan_regs[i].w.mr, + &channel->regs->w.mr, MR1_CHRL_8_BITS | MR1_ERROR_CHAR | MR1_RxINT_RxRDY); /* mr1 */ ipoctal_write_io_reg(ipoctal, - &ipoctal->chan_regs[i].w.mr, + &channel->regs->w.mr, 0); /* mr2 */ ipoctal_write_io_reg(ipoctal, - &ipoctal->chan_regs[i].w.csr, + &channel->regs->w.csr, TX_CLK_9600 | RX_CLK_9600); } for (i = 0; i < IP_OCTAL_NB_BLOCKS; i++) { ipoctal_write_io_reg(ipoctal, - &ipoctal->block_regs[i].w.acr, + &block_regs[i].w.acr, ACR_BRG_SET2); ipoctal_write_io_reg(ipoctal, - &ipoctal->block_regs[i].w.opcr, + &block_regs[i].w.opcr, OPCR_MPP_OUTPUT | OPCR_MPOa_RTSN | OPCR_MPOb_RTSN); ipoctal_write_io_reg(ipoctal, - &ipoctal->block_regs[i].w.imr, + &block_regs[i].w.imr, IMR_TxRDY_A | IMR_RxRDY_FFULL_A | IMR_DELTA_BREAK_A | IMR_TxRDY_B | IMR_RxRDY_FFULL_B | IMR_DELTA_BREAK_B); @@ -472,25 +485,26 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, ipoctal->tty_drv = tty; for (i = 0; i < NR_CHANNELS; i++) { - tty_port_init(&ipoctal->tty_port[i]); - tty_port_alloc_xmit_buf(&ipoctal->tty_port[i]); - ipoctal->tty_port[i].ops = &ipoctal_tty_port_ops; - - ipoctal_reset_stats(&ipoctal->chan_stats[i]); - ipoctal->nb_bytes[i] = 0; - init_waitqueue_head(&ipoctal->queue[i]); - - spin_lock_init(&ipoctal->lock[i]); - ipoctal->pointer_read[i] = 0; - ipoctal->pointer_write[i] = 0; - ipoctal->nb_bytes[i] = 0; + channel = &ipoctal->channel[i]; + tty_port_init(&channel->tty_port); + tty_port_alloc_xmit_buf(&channel->tty_port); + channel->tty_port.ops = &ipoctal_tty_port_ops; + + ipoctal_reset_stats(&channel->stats); + channel->nb_bytes = 0; + init_waitqueue_head(&channel->queue); + + spin_lock_init(&channel->lock); + channel->pointer_read = 0; + channel->pointer_write = 0; + channel->nb_bytes = 0; tty_register_device(tty, i, NULL); /* * Enable again the RX. TX will be enabled when * there is something to send */ - ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[i].w.cr, + ipoctal_write_io_reg(ipoctal, &channel->regs->w.cr, CR_ENABLE_RX); } @@ -505,23 +519,22 @@ out_unregister_id_space: return res; } -static inline int ipoctal_copy_write_buffer(struct ipoctal *ipoctal, - unsigned int channel, +static inline int ipoctal_copy_write_buffer(struct ipoctal_channel *channel, const unsigned char *buf, int count) { unsigned long flags; int i; - unsigned int *pointer_read = &ipoctal->pointer_read[channel]; + unsigned int *pointer_read = &channel->pointer_read; /* Copy the bytes from the user buffer to the internal one */ for (i = 0; i < count; i++) { - if (i <= (PAGE_SIZE - ipoctal->nb_bytes[channel])) { - spin_lock_irqsave(&ipoctal->lock[channel], flags); - ipoctal->tty_port[channel].xmit_buf[*pointer_read] = buf[i]; + if (i <= (PAGE_SIZE - channel->nb_bytes)) { + spin_lock_irqsave(&channel->lock, flags); + channel->tty_port.xmit_buf[*pointer_read] = buf[i]; *pointer_read = (*pointer_read + 1) % PAGE_SIZE; - ipoctal->nb_bytes[channel]++; - spin_unlock_irqrestore(&ipoctal->lock[channel], flags); + channel->nb_bytes++; + spin_unlock_irqrestore(&channel->lock, flags); } else { break; } @@ -529,21 +542,22 @@ static inline int ipoctal_copy_write_buffer(struct ipoctal *ipoctal, return i; } -static int ipoctal_write(struct ipoctal *ipoctal, unsigned int channel, +static int ipoctal_write(struct ipoctal *ipoctal, unsigned int ichannel, const unsigned char *buf, int count) { - ipoctal->nb_bytes[channel] = 0; - ipoctal->count_wr[channel] = 0; + struct ipoctal_channel *channel = &ipoctal->channel[ichannel]; + channel->nb_bytes = 0; + channel->count_wr = 0; - ipoctal_copy_write_buffer(ipoctal, channel, buf, count); + ipoctal_copy_write_buffer(channel, buf, count); /* As the IP-OCTAL 485 only supports half duplex, do it manually */ if (ipoctal->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) { ipoctal_write_io_reg(ipoctal, - &ipoctal->chan_regs[channel].w.cr, + &channel->regs->w.cr, CR_DISABLE_RX); ipoctal_write_cr_cmd(ipoctal, - &ipoctal->chan_regs[channel].w.cr, + &channel->regs->w.cr, CR_CMD_ASSERT_RTSN); } @@ -552,40 +566,39 @@ static int ipoctal_write(struct ipoctal *ipoctal, unsigned int channel, * operations */ ipoctal_write_io_reg(ipoctal, - &ipoctal->chan_regs[channel].w.cr, + &channel->regs->w.cr, CR_ENABLE_TX); - wait_event_interruptible(ipoctal->queue[channel], ipoctal->write); + wait_event_interruptible(channel->queue, ipoctal->write); ipoctal_write_io_reg(ipoctal, - &ipoctal->chan_regs[channel].w.cr, + &channel->regs->w.cr, CR_DISABLE_TX); ipoctal->write = 0; - return ipoctal->count_wr[channel]; + return channel->count_wr; } static int ipoctal_write_tty(struct tty_struct *tty, const unsigned char *buf, int count) { - unsigned int channel = tty->index; struct ipoctal *ipoctal = tty->driver_data; - return ipoctal_write(ipoctal, channel, buf, count); + return ipoctal_write(ipoctal, tty->index, buf, count); } static int ipoctal_write_room(struct tty_struct *tty) { - int channel = tty->index; struct ipoctal *ipoctal = tty->driver_data; + struct ipoctal_channel *channel = &ipoctal->channel[tty->index]; - return PAGE_SIZE - ipoctal->nb_bytes[channel]; + return PAGE_SIZE - channel->nb_bytes; } static int ipoctal_chars_in_buffer(struct tty_struct *tty) { - int channel = tty->index; struct ipoctal *ipoctal = tty->driver_data; + struct ipoctal_channel *channel = &ipoctal->channel[tty->index]; - return ipoctal->nb_bytes[channel]; + return channel->nb_bytes; } static void ipoctal_set_termios(struct tty_struct *tty, @@ -595,22 +608,22 @@ static void ipoctal_set_termios(struct tty_struct *tty, unsigned char mr1 = 0; unsigned char mr2 = 0; unsigned char csr = 0; - unsigned int channel = tty->index; struct ipoctal *ipoctal = tty->driver_data; + struct ipoctal_channel *channel = &ipoctal->channel[tty->index]; speed_t baud; cflag = tty->termios->c_cflag; /* Disable and reset everything before change the setup */ - ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].w.cr, + ipoctal_write_io_reg(ipoctal, &channel->regs->w.cr, CR_DISABLE_RX | CR_DISABLE_TX); - ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr, + ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr, CR_CMD_RESET_RX); - ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr, + ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr, CR_CMD_RESET_TX); - ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr, + ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr, CR_CMD_RESET_ERR_STATUS); - ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr, + ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr, CR_CMD_RESET_MR); /* Set Bits per chars */ @@ -724,45 +737,45 @@ static void ipoctal_set_termios(struct tty_struct *tty, mr1 |= MR1_RxINT_RxRDY; /* Write the control registers */ - ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].w.mr, mr1); - ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].w.mr, mr2); - ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].w.csr, csr); + ipoctal_write_io_reg(ipoctal, &channel->regs->w.mr, mr1); + ipoctal_write_io_reg(ipoctal, &channel->regs->w.mr, mr2); + ipoctal_write_io_reg(ipoctal, &channel->regs->w.csr, csr); /* Enable again the RX */ - ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].w.cr, + ipoctal_write_io_reg(ipoctal, &channel->regs->w.cr, CR_ENABLE_RX); } static void ipoctal_hangup(struct tty_struct *tty) { unsigned long flags; - int channel = tty->index; struct ipoctal *ipoctal = tty->driver_data; + struct ipoctal_channel *channel = &ipoctal->channel[tty->index]; if (ipoctal == NULL) return; - spin_lock_irqsave(&ipoctal->lock[channel], flags); - ipoctal->nb_bytes[channel] = 0; - ipoctal->pointer_read[channel] = 0; - ipoctal->pointer_write[channel] = 0; - spin_unlock_irqrestore(&ipoctal->lock[channel], flags); + spin_lock_irqsave(&channel->lock, flags); + channel->nb_bytes = 0; + channel->pointer_read = 0; + channel->pointer_write = 0; + spin_unlock_irqrestore(&channel->lock, flags); - tty_port_hangup(&ipoctal->tty_port[channel]); + tty_port_hangup(&channel->tty_port); - ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].w.cr, + ipoctal_write_io_reg(ipoctal, &channel->regs->w.cr, CR_DISABLE_RX | CR_DISABLE_TX); - ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr, + ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr, CR_CMD_RESET_RX); - ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr, + ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr, CR_CMD_RESET_TX); - ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr, + ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr, CR_CMD_RESET_ERR_STATUS); - ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr, + ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr, CR_CMD_RESET_MR); - clear_bit(ASYNCB_INITIALIZED, &ipoctal->tty_port[channel].flags); - wake_up_interruptible(&ipoctal->tty_port[channel].open_wait); + clear_bit(ASYNCB_INITIALIZED, &channel->tty_port.flags); + wake_up_interruptible(&channel->tty_port.open_wait); } static const struct tty_operations ipoctal_fops = { @@ -806,8 +819,9 @@ static void __ipoctal_remove(struct ipoctal *ipoctal) ipoctal->dev->bus->ops->free_irq(ipoctal->dev); for (i = 0; i < NR_CHANNELS; i++) { + struct ipoctal_channel *channel = &ipoctal->channel[i]; tty_unregister_device(ipoctal->tty_drv, i); - tty_port_free_xmit_buf(&ipoctal->tty_port[i]); + tty_port_free_xmit_buf(&channel->tty_port); } tty_unregister_driver(ipoctal->tty_drv); -- cgit v0.10.2 From 459e6d7c93d47af0c0829b97bb17239eae79e3d6 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Wed, 12 Sep 2012 14:55:27 +0200 Subject: Staging: ipack/devices/ipoctal: Directly use ioread/iowrite function. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index 9ab0e80..c963456 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -56,26 +56,6 @@ struct ipoctal { /* Linked list to save the registered devices */ static LIST_HEAD(ipoctal_list); -static inline void ipoctal_write_io_reg(struct ipoctal *ipoctal, - u8 __iomem *dest, - u8 value) -{ - iowrite8(value, dest); -} - -static inline void ipoctal_write_cr_cmd(struct ipoctal *ipoctal, - u8 __iomem *dest, - u8 value) -{ - ipoctal_write_io_reg(ipoctal, dest, value); -} - -static inline unsigned char ipoctal_read_io_reg(struct ipoctal *ipoctal, - u8 __iomem *src) -{ - return ioread8(src); -} - static struct ipoctal *ipoctal_find_board(struct tty_struct *tty) { struct ipoctal *p; @@ -102,8 +82,7 @@ static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty) } channel = &ipoctal->channel[tty->index]; - ipoctal_write_io_reg(ipoctal, &channel->regs->w.cr, - CR_ENABLE_RX); + iowrite8(CR_ENABLE_RX, &channel->regs->w.cr); return 0; } @@ -216,10 +195,8 @@ static int ipoctal_irq_handler(void *arg) * The HW is organized in pair of channels. * See which register we need to read from */ - isr = ipoctal_read_io_reg(ipoctal, - &channel->block_regs->r.isr); - sr = ipoctal_read_io_reg(ipoctal, - &channel->regs->r.sr); + isr = ioread8(&channel->block_regs->r.isr); + sr = ioread8(&channel->regs->r.sr); if ((ichannel % 2) == 1) { isr_tx_rdy = isr & ISR_TxRDY_B; @@ -235,30 +212,21 @@ static int ipoctal_irq_handler(void *arg) if ((ipoctal->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) && (sr & SR_TX_EMPTY) && (channel->nb_bytes == 0)) { - ipoctal_write_io_reg(ipoctal, - &channel->regs->w.cr, - CR_DISABLE_TX); - ipoctal_write_cr_cmd(ipoctal, - &channel->regs->w.cr, - CR_CMD_NEGATE_RTSN); - ipoctal_write_io_reg(ipoctal, - &channel->regs->w.cr, - CR_ENABLE_RX); + iowrite8(CR_DISABLE_TX, &channel->regs->w.cr); + iowrite8(CR_CMD_NEGATE_RTSN, &channel->regs->w.cr); + iowrite8(CR_ENABLE_RX, &channel->regs->w.cr); ipoctal->write = 1; wake_up_interruptible(&channel->queue); } /* RX data */ if (isr_rx_rdy && (sr & SR_RX_READY)) { - value = ipoctal_read_io_reg(ipoctal, - &channel->regs->r.rhr); + value = ioread8(&channel->regs->r.rhr); flag = TTY_NORMAL; /* Error: count statistics */ if (sr & SR_ERROR) { - ipoctal_write_cr_cmd(ipoctal, - &channel->regs->w.cr, - CR_CMD_RESET_ERR_STATUS); + iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr); if (sr & SR_OVERRUN_ERROR) { channel->stats.overrun_err++; @@ -292,9 +260,7 @@ static int ipoctal_irq_handler(void *arg) } value = channel->tty_port.xmit_buf[*pointer_write]; - ipoctal_write_io_reg(ipoctal, - &channel->regs->w.thr, - value); + iowrite8(value, &channel->regs->w.thr); channel->stats.tx++; channel->count_wr++; (*pointer_write)++; @@ -405,37 +371,22 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, channel->regs = chan_regs + i; channel->block_regs = block_regs + (i >> 1); - ipoctal_write_io_reg(ipoctal, &channel->regs->w.cr, - CR_DISABLE_RX | CR_DISABLE_TX); - ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr, - CR_CMD_RESET_RX); - ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr, - CR_CMD_RESET_TX); - ipoctal_write_io_reg(ipoctal, - &channel->regs->w.mr, - MR1_CHRL_8_BITS | MR1_ERROR_CHAR | - MR1_RxINT_RxRDY); /* mr1 */ - ipoctal_write_io_reg(ipoctal, - &channel->regs->w.mr, - 0); /* mr2 */ - ipoctal_write_io_reg(ipoctal, - &channel->regs->w.csr, - TX_CLK_9600 | RX_CLK_9600); + iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr); + iowrite8(CR_CMD_RESET_RX, &channel->regs->w.cr); + iowrite8(CR_CMD_RESET_TX, &channel->regs->w.cr); + iowrite8(MR1_CHRL_8_BITS | MR1_ERROR_CHAR | MR1_RxINT_RxRDY, + &channel->regs->w.mr); /* mr1 */ + iowrite8(0, &channel->regs->w.mr); /* mr2 */ + iowrite8(TX_CLK_9600 | RX_CLK_9600, &channel->regs->w.csr); } for (i = 0; i < IP_OCTAL_NB_BLOCKS; i++) { - ipoctal_write_io_reg(ipoctal, - &block_regs[i].w.acr, - ACR_BRG_SET2); - ipoctal_write_io_reg(ipoctal, - &block_regs[i].w.opcr, - OPCR_MPP_OUTPUT | OPCR_MPOa_RTSN | - OPCR_MPOb_RTSN); - ipoctal_write_io_reg(ipoctal, - &block_regs[i].w.imr, - IMR_TxRDY_A | IMR_RxRDY_FFULL_A | - IMR_DELTA_BREAK_A | IMR_TxRDY_B | - IMR_RxRDY_FFULL_B | IMR_DELTA_BREAK_B); + iowrite8(ACR_BRG_SET2, &block_regs[i].w.acr); + iowrite8(OPCR_MPP_OUTPUT | OPCR_MPOa_RTSN | OPCR_MPOb_RTSN, + &block_regs[i].w.opcr); + iowrite8(IMR_TxRDY_A | IMR_RxRDY_FFULL_A | IMR_DELTA_BREAK_A | + IMR_TxRDY_B | IMR_RxRDY_FFULL_B | IMR_DELTA_BREAK_B, + &block_regs[i].w.imr); } /* @@ -504,8 +455,7 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, * Enable again the RX. TX will be enabled when * there is something to send */ - ipoctal_write_io_reg(ipoctal, &channel->regs->w.cr, - CR_ENABLE_RX); + iowrite8(CR_ENABLE_RX, &channel->regs->w.cr); } return 0; @@ -553,25 +503,17 @@ static int ipoctal_write(struct ipoctal *ipoctal, unsigned int ichannel, /* As the IP-OCTAL 485 only supports half duplex, do it manually */ if (ipoctal->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) { - ipoctal_write_io_reg(ipoctal, - &channel->regs->w.cr, - CR_DISABLE_RX); - ipoctal_write_cr_cmd(ipoctal, - &channel->regs->w.cr, - CR_CMD_ASSERT_RTSN); + iowrite8(CR_DISABLE_RX, &channel->regs->w.cr); + iowrite8(CR_CMD_ASSERT_RTSN, &channel->regs->w.cr); } /* * Send a packet and then disable TX to avoid failure after several send * operations */ - ipoctal_write_io_reg(ipoctal, - &channel->regs->w.cr, - CR_ENABLE_TX); + iowrite8(CR_ENABLE_TX, &channel->regs->w.cr); wait_event_interruptible(channel->queue, ipoctal->write); - ipoctal_write_io_reg(ipoctal, - &channel->regs->w.cr, - CR_DISABLE_TX); + iowrite8(CR_DISABLE_TX, &channel->regs->w.cr); ipoctal->write = 0; return channel->count_wr; @@ -615,16 +557,11 @@ static void ipoctal_set_termios(struct tty_struct *tty, cflag = tty->termios->c_cflag; /* Disable and reset everything before change the setup */ - ipoctal_write_io_reg(ipoctal, &channel->regs->w.cr, - CR_DISABLE_RX | CR_DISABLE_TX); - ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr, - CR_CMD_RESET_RX); - ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr, - CR_CMD_RESET_TX); - ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr, - CR_CMD_RESET_ERR_STATUS); - ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr, - CR_CMD_RESET_MR); + iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr); + iowrite8(CR_CMD_RESET_RX, &channel->regs->w.cr); + iowrite8(CR_CMD_RESET_TX, &channel->regs->w.cr); + iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr); + iowrite8(CR_CMD_RESET_MR, &channel->regs->w.cr); /* Set Bits per chars */ switch (cflag & CSIZE) { @@ -737,13 +674,12 @@ static void ipoctal_set_termios(struct tty_struct *tty, mr1 |= MR1_RxINT_RxRDY; /* Write the control registers */ - ipoctal_write_io_reg(ipoctal, &channel->regs->w.mr, mr1); - ipoctal_write_io_reg(ipoctal, &channel->regs->w.mr, mr2); - ipoctal_write_io_reg(ipoctal, &channel->regs->w.csr, csr); + iowrite8(mr1, &channel->regs->w.mr); + iowrite8(mr2, &channel->regs->w.mr); + iowrite8(csr, &channel->regs->w.csr); /* Enable again the RX */ - ipoctal_write_io_reg(ipoctal, &channel->regs->w.cr, - CR_ENABLE_RX); + iowrite8(CR_ENABLE_RX, &channel->regs->w.cr); } static void ipoctal_hangup(struct tty_struct *tty) @@ -763,16 +699,11 @@ static void ipoctal_hangup(struct tty_struct *tty) tty_port_hangup(&channel->tty_port); - ipoctal_write_io_reg(ipoctal, &channel->regs->w.cr, - CR_DISABLE_RX | CR_DISABLE_TX); - ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr, - CR_CMD_RESET_RX); - ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr, - CR_CMD_RESET_TX); - ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr, - CR_CMD_RESET_ERR_STATUS); - ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr, - CR_CMD_RESET_MR); + iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr); + iowrite8(CR_CMD_RESET_RX, &channel->regs->w.cr); + iowrite8(CR_CMD_RESET_TX, &channel->regs->w.cr); + iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr); + iowrite8(CR_CMD_RESET_MR, &channel->regs->w.cr); clear_bit(ASYNCB_INITIALIZED, &channel->tty_port.flags); wake_up_interruptible(&channel->tty_port.open_wait); -- cgit v0.10.2 From ef79de031437ead308093289604eeb3b5b9d924f Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Wed, 12 Sep 2012 14:55:28 +0200 Subject: Staging: ipack/devices/ipoctal: put ipoctal_channel into tty->driver_data. Each tty's driver_data is now pointing to the channel it is talking to. struct ipoctal_channel contains all the information the callbacks require to do their work. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index c963456..70dc7a2 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -42,6 +42,8 @@ struct ipoctal_channel { struct tty_port tty_port; union scc2698_channel __iomem *regs; union scc2698_block __iomem *block_regs; + unsigned int board_id; + unsigned char *board_write; }; struct ipoctal { @@ -104,7 +106,7 @@ static int ipoctal_open(struct tty_struct *tty, struct file *file) if (atomic_read(&channel->open)) return -EBUSY; - tty->driver_data = ipoctal; + tty->driver_data = channel; res = tty_port_open(&channel->tty_port, tty, file); if (res) @@ -124,15 +126,8 @@ static void ipoctal_reset_stats(struct ipoctal_stats *stats) stats->parity_err = 0; } -static void ipoctal_free_channel(struct tty_struct *tty) +static void ipoctal_free_channel(struct ipoctal_channel *channel) { - struct ipoctal *ipoctal = tty->driver_data; - struct ipoctal_channel *channel; - - if (ipoctal == NULL) - return; - channel = &ipoctal->channel[tty->index]; - ipoctal_reset_stats(&channel->stats); channel->pointer_read = 0; channel->pointer_write = 0; @@ -141,20 +136,18 @@ static void ipoctal_free_channel(struct tty_struct *tty) static void ipoctal_close(struct tty_struct *tty, struct file *filp) { - struct ipoctal *ipoctal = tty->driver_data; - struct ipoctal_channel *channel = &ipoctal->channel[tty->index]; + struct ipoctal_channel *channel = tty->driver_data; tty_port_close(&channel->tty_port, tty, filp); if (atomic_dec_and_test(&channel->open)) - ipoctal_free_channel(tty); + ipoctal_free_channel(channel); } static int ipoctal_get_icount(struct tty_struct *tty, struct serial_icounter_struct *icount) { - struct ipoctal *ipoctal = tty->driver_data; - struct ipoctal_channel *channel = &ipoctal->channel[tty->index]; + struct ipoctal_channel *channel = tty->driver_data; icount->cts = 0; icount->dsr = 0; @@ -370,6 +363,8 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, struct ipoctal_channel *channel = &ipoctal->channel[i]; channel->regs = chan_regs + i; channel->block_regs = block_regs + (i >> 1); + channel->board_write = &ipoctal->write; + channel->board_id = ipoctal->board_id; iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr); iowrite8(CR_CMD_RESET_RX, &channel->regs->w.cr); @@ -492,17 +487,16 @@ static inline int ipoctal_copy_write_buffer(struct ipoctal_channel *channel, return i; } -static int ipoctal_write(struct ipoctal *ipoctal, unsigned int ichannel, +static int ipoctal_write(struct ipoctal_channel *channel, const unsigned char *buf, int count) { - struct ipoctal_channel *channel = &ipoctal->channel[ichannel]; channel->nb_bytes = 0; channel->count_wr = 0; ipoctal_copy_write_buffer(channel, buf, count); /* As the IP-OCTAL 485 only supports half duplex, do it manually */ - if (ipoctal->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) { + if (channel->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) { iowrite8(CR_DISABLE_RX, &channel->regs->w.cr); iowrite8(CR_CMD_ASSERT_RTSN, &channel->regs->w.cr); } @@ -512,33 +506,31 @@ static int ipoctal_write(struct ipoctal *ipoctal, unsigned int ichannel, * operations */ iowrite8(CR_ENABLE_TX, &channel->regs->w.cr); - wait_event_interruptible(channel->queue, ipoctal->write); + wait_event_interruptible(channel->queue, *channel->board_write); iowrite8(CR_DISABLE_TX, &channel->regs->w.cr); - ipoctal->write = 0; + *channel->board_write = 0; return channel->count_wr; } static int ipoctal_write_tty(struct tty_struct *tty, const unsigned char *buf, int count) { - struct ipoctal *ipoctal = tty->driver_data; + struct ipoctal_channel *channel = tty->driver_data; - return ipoctal_write(ipoctal, tty->index, buf, count); + return ipoctal_write(channel, buf, count); } static int ipoctal_write_room(struct tty_struct *tty) { - struct ipoctal *ipoctal = tty->driver_data; - struct ipoctal_channel *channel = &ipoctal->channel[tty->index]; + struct ipoctal_channel *channel = tty->driver_data; return PAGE_SIZE - channel->nb_bytes; } static int ipoctal_chars_in_buffer(struct tty_struct *tty) { - struct ipoctal *ipoctal = tty->driver_data; - struct ipoctal_channel *channel = &ipoctal->channel[tty->index]; + struct ipoctal_channel *channel = tty->driver_data; return channel->nb_bytes; } @@ -550,8 +542,7 @@ static void ipoctal_set_termios(struct tty_struct *tty, unsigned char mr1 = 0; unsigned char mr2 = 0; unsigned char csr = 0; - struct ipoctal *ipoctal = tty->driver_data; - struct ipoctal_channel *channel = &ipoctal->channel[tty->index]; + struct ipoctal_channel *channel = tty->driver_data; speed_t baud; cflag = tty->termios->c_cflag; @@ -598,7 +589,7 @@ static void ipoctal_set_termios(struct tty_struct *tty, mr2 |= MR2_STOP_BITS_LENGTH_1; /* Set the flow control */ - switch (ipoctal->board_id) { + switch (channel->board_id) { case IPACK1_DEVICE_ID_SBS_OCTAL_232: if (cflag & CRTSCTS) { mr1 |= MR1_RxRTS_CONTROL_ON; @@ -685,10 +676,9 @@ static void ipoctal_set_termios(struct tty_struct *tty, static void ipoctal_hangup(struct tty_struct *tty) { unsigned long flags; - struct ipoctal *ipoctal = tty->driver_data; - struct ipoctal_channel *channel = &ipoctal->channel[tty->index]; + struct ipoctal_channel *channel = tty->driver_data; - if (ipoctal == NULL) + if (channel == NULL) return; spin_lock_irqsave(&channel->lock, flags); -- cgit v0.10.2 From 4e4732aca9679c1ec70c7a287bf04563e792923c Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Wed, 12 Sep 2012 14:55:29 +0200 Subject: Staging: ipack/devices/ipoctal: Store isr masks in ipoctal_channel This way interrupt handling becomes independent of the channel number. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index 70dc7a2..56e810b 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -44,6 +44,8 @@ struct ipoctal_channel { union scc2698_block __iomem *block_regs; unsigned int board_id; unsigned char *board_write; + u8 isr_rx_rdy_mask; + u8 isr_tx_rdy_mask; }; struct ipoctal { @@ -166,7 +168,6 @@ static int ipoctal_irq_handler(void *arg) unsigned int ichannel; unsigned char isr; unsigned char sr; - unsigned char isr_tx_rdy, isr_rx_rdy; unsigned char value; unsigned char flag; struct tty_struct *tty; @@ -191,14 +192,6 @@ static int ipoctal_irq_handler(void *arg) isr = ioread8(&channel->block_regs->r.isr); sr = ioread8(&channel->regs->r.sr); - if ((ichannel % 2) == 1) { - isr_tx_rdy = isr & ISR_TxRDY_B; - isr_rx_rdy = isr & ISR_RxRDY_FFULL_B; - } else { - isr_tx_rdy = isr & ISR_TxRDY_A; - isr_rx_rdy = isr & ISR_RxRDY_FFULL_A; - } - /* In case of RS-485, change from TX to RX when finishing TX. * Half-duplex. */ @@ -213,7 +206,7 @@ static int ipoctal_irq_handler(void *arg) } /* RX data */ - if (isr_rx_rdy && (sr & SR_RX_READY)) { + if ((isr && channel->isr_rx_rdy_mask) && (sr & SR_RX_READY)) { value = ioread8(&channel->regs->r.rhr); flag = TTY_NORMAL; @@ -244,7 +237,7 @@ static int ipoctal_irq_handler(void *arg) } /* TX of each character */ - if (isr_tx_rdy && (sr & SR_TX_READY)) { + if ((isr & channel->isr_tx_rdy_mask) && (sr & SR_TX_READY)) { unsigned int *pointer_write = &channel->pointer_write; if (channel->nb_bytes <= 0) { @@ -365,6 +358,13 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, channel->block_regs = block_regs + (i >> 1); channel->board_write = &ipoctal->write; channel->board_id = ipoctal->board_id; + if (i & 1) { + channel->isr_tx_rdy_mask = ISR_TxRDY_B; + channel->isr_rx_rdy_mask = ISR_RxRDY_FFULL_B; + } else { + channel->isr_tx_rdy_mask = ISR_TxRDY_A; + channel->isr_rx_rdy_mask = ISR_RxRDY_FFULL_A; + } iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr); iowrite8(CR_CMD_RESET_RX, &channel->regs->w.cr); -- cgit v0.10.2 From 87cfb955007ece1ba2a78a419c033942ee300972 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Wed, 12 Sep 2012 14:55:30 +0200 Subject: Staging: ipack/devices/ipoctal: Split interrupt service routine. Split the IRQ service routing in TX part and RX part. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index 56e810b..e0be660 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -163,109 +163,115 @@ static int ipoctal_get_icount(struct tty_struct *tty, return 0; } -static int ipoctal_irq_handler(void *arg) +static void ipoctal_irq_rx(struct ipoctal_channel *channel, + struct tty_struct *tty, u8 sr) +{ + unsigned char value = ioread8(&channel->regs->r.rhr); + unsigned char flag = TTY_NORMAL; + + /* Error: count statistics */ + if (sr & SR_ERROR) { + iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr); + + if (sr & SR_OVERRUN_ERROR) { + channel->stats.overrun_err++; + /* Overrun doesn't affect the current character*/ + tty_insert_flip_char(tty, 0, TTY_OVERRUN); + } + if (sr & SR_PARITY_ERROR) { + channel->stats.parity_err++; + flag = TTY_PARITY; + } + if (sr & SR_FRAMING_ERROR) { + channel->stats.framing_err++; + flag = TTY_FRAME; + } + if (sr & SR_RECEIVED_BREAK) { + channel->stats.rcv_break++; + flag = TTY_BREAK; + } + } + + tty_insert_flip_char(tty, value, flag); +} + +static void ipoctal_irq_tx(struct ipoctal_channel *channel) { - unsigned int ichannel; - unsigned char isr; - unsigned char sr; unsigned char value; - unsigned char flag; - struct tty_struct *tty; - struct ipoctal *ipoctal = (struct ipoctal *) arg; - struct ipoctal_channel *channel; + unsigned int *pointer_write = &channel->pointer_write; - /* Check all channels */ - for (ichannel = 0; ichannel < NR_CHANNELS; ichannel++) { - channel = &ipoctal->channel[ichannel]; - /* If there is no client, skip the check */ - if (!atomic_read(&channel->open)) - continue; + if (channel->nb_bytes <= 0) { + channel->nb_bytes = 0; + return; + } - tty = tty_port_tty_get(&channel->tty_port); - if (!tty) - continue; + value = channel->tty_port.xmit_buf[*pointer_write]; + iowrite8(value, &channel->regs->w.thr); + channel->stats.tx++; + channel->count_wr++; + (*pointer_write)++; + *pointer_write = *pointer_write % PAGE_SIZE; + channel->nb_bytes--; - /* - * The HW is organized in pair of channels. - * See which register we need to read from - */ - isr = ioread8(&channel->block_regs->r.isr); - sr = ioread8(&channel->regs->r.sr); + if ((channel->nb_bytes == 0) && + (waitqueue_active(&channel->queue))) { - /* In case of RS-485, change from TX to RX when finishing TX. - * Half-duplex. - */ - if ((ipoctal->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) && - (sr & SR_TX_EMPTY) && - (channel->nb_bytes == 0)) { - iowrite8(CR_DISABLE_TX, &channel->regs->w.cr); - iowrite8(CR_CMD_NEGATE_RTSN, &channel->regs->w.cr); - iowrite8(CR_ENABLE_RX, &channel->regs->w.cr); - ipoctal->write = 1; + if (channel->board_id != IPACK1_DEVICE_ID_SBS_OCTAL_485) { + *channel->board_write = 1; wake_up_interruptible(&channel->queue); } + } +} - /* RX data */ - if ((isr && channel->isr_rx_rdy_mask) && (sr & SR_RX_READY)) { - value = ioread8(&channel->regs->r.rhr); - flag = TTY_NORMAL; - - /* Error: count statistics */ - if (sr & SR_ERROR) { - iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr); - - if (sr & SR_OVERRUN_ERROR) { - channel->stats.overrun_err++; - /* Overrun doesn't affect the current character*/ - tty_insert_flip_char(tty, 0, TTY_OVERRUN); - } - if (sr & SR_PARITY_ERROR) { - channel->stats.parity_err++; - flag = TTY_PARITY; - } - if (sr & SR_FRAMING_ERROR) { - channel->stats.framing_err++; - flag = TTY_FRAME; - } - if (sr & SR_RECEIVED_BREAK) { - channel->stats.rcv_break++; - flag = TTY_BREAK; - } - } - - tty_insert_flip_char(tty, value, flag); - } +static void ipoctal_irq_channel(struct ipoctal_channel *channel) +{ + u8 isr, sr; + struct tty_struct *tty; - /* TX of each character */ - if ((isr & channel->isr_tx_rdy_mask) && (sr & SR_TX_READY)) { - unsigned int *pointer_write = &channel->pointer_write; - - if (channel->nb_bytes <= 0) { - channel->nb_bytes = 0; - continue; - } - - value = channel->tty_port.xmit_buf[*pointer_write]; - iowrite8(value, &channel->regs->w.thr); - channel->stats.tx++; - channel->count_wr++; - (*pointer_write)++; - *pointer_write = *pointer_write % PAGE_SIZE; - channel->nb_bytes--; - - if ((channel->nb_bytes == 0) && - (waitqueue_active(&channel->queue))) { - - if (ipoctal->board_id != IPACK1_DEVICE_ID_SBS_OCTAL_485) { - ipoctal->write = 1; - wake_up_interruptible(&channel->queue); - } - } - } + /* If there is no client, skip the check */ + if (!atomic_read(&channel->open)) + return; - tty_flip_buffer_push(tty); - tty_kref_put(tty); + tty = tty_port_tty_get(&channel->tty_port); + if (!tty) + return; + /* The HW is organized in pair of channels. See which register we need + * to read from */ + isr = ioread8(&channel->block_regs->r.isr); + sr = ioread8(&channel->regs->r.sr); + + /* In case of RS-485, change from TX to RX when finishing TX. + * Half-duplex. */ + if ((channel->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) && + (sr & SR_TX_EMPTY) && (channel->nb_bytes == 0)) { + iowrite8(CR_DISABLE_TX, &channel->regs->w.cr); + iowrite8(CR_CMD_NEGATE_RTSN, &channel->regs->w.cr); + iowrite8(CR_ENABLE_RX, &channel->regs->w.cr); + *channel->board_write = 1; + wake_up_interruptible(&channel->queue); } + + /* RX data */ + if ((isr & channel->isr_rx_rdy_mask) && (sr & SR_RX_READY)) + ipoctal_irq_rx(channel, tty, sr); + + /* TX of each character */ + if ((isr & channel->isr_tx_rdy_mask) && (sr & SR_TX_READY)) + ipoctal_irq_tx(channel); + + tty_flip_buffer_push(tty); + tty_kref_put(tty); +} + +static int ipoctal_irq_handler(void *arg) +{ + unsigned int i; + struct ipoctal *ipoctal = (struct ipoctal *) arg; + + /* Check all channels */ + for (i = 0; i < NR_CHANNELS; i++) + ipoctal_irq_channel(&ipoctal->channel[i]); + return IRQ_HANDLED; } -- cgit v0.10.2 From 699a89f1e291af0d47744200011d5c24d9e462a6 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Wed, 12 Sep 2012 14:55:31 +0200 Subject: Staging: ipack/devices/ipoctal: remove superfluous function. ipoctal_write_tty and ipoctal_write are merged. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index e0be660..4cc9173 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -493,9 +493,11 @@ static inline int ipoctal_copy_write_buffer(struct ipoctal_channel *channel, return i; } -static int ipoctal_write(struct ipoctal_channel *channel, - const unsigned char *buf, int count) +static int ipoctal_write_tty(struct tty_struct *tty, + const unsigned char *buf, int count) { + struct ipoctal_channel *channel = tty->driver_data; + channel->nb_bytes = 0; channel->count_wr = 0; @@ -519,14 +521,6 @@ static int ipoctal_write(struct ipoctal_channel *channel, return channel->count_wr; } -static int ipoctal_write_tty(struct tty_struct *tty, - const unsigned char *buf, int count) -{ - struct ipoctal_channel *channel = tty->driver_data; - - return ipoctal_write(channel, buf, count); -} - static int ipoctal_write_room(struct tty_struct *tty) { struct ipoctal_channel *channel = tty->driver_data; -- cgit v0.10.2 From b8d61d49b2437df3a0aef17d321948783d275bb3 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Wed, 12 Sep 2012 14:55:32 +0200 Subject: Staging: ipack/bridges/tpci200: RCU protect slot_irq pointers. In tpci200_request_irq as well as tpci200_free_irq we set and unset the pointer to struct slot_irq. This pointer is accessed in tpci200_interrupt. To ensure that the pointer is not freed after it has been fetched in tpci200_interrupt() it is now protected through RCU. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 24e2a11..9ce577a 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -132,10 +132,11 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id) if (status_reg & TPCI200_SLOT_INT_MASK) { /* callback to the IRQ handler for the corresponding slot */ + rcu_read_lock(); for (i = 0; i < TPCI200_NB_SLOT; i++) { if (!(status_reg & ((TPCI200_A_INT0 | TPCI200_A_INT1) << (2*i)))) continue; - slot_irq = tpci200->slots[i].irq; + slot_irq = rcu_dereference(tpci200->slots[i].irq); if (slot_irq) { ret = tpci200_slot_irq(slot_irq); } else { @@ -147,6 +148,7 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id) TPCI200_INT0_EN | TPCI200_INT1_EN); } } + rcu_read_unlock(); } return ret; @@ -303,9 +305,9 @@ static int tpci200_free_irq(struct ipack_device *dev) __tpci200_free_irq(tpci200, dev); slot_irq = tpci200->slots[dev->slot].irq; - tpci200->slots[dev->slot].irq = NULL; + RCU_INIT_POINTER(tpci200->slots[dev->slot].irq, NULL); + synchronize_rcu(); kfree(slot_irq); - mutex_unlock(&tpci200->mutex); return 0; } @@ -490,7 +492,7 @@ static int tpci200_request_irq(struct ipack_device *dev, int vector, slot_irq->arg = arg; slot_irq->holder = dev; - tpci200->slots[dev->slot].irq = slot_irq; + rcu_assign_pointer(tpci200->slots[dev->slot].irq, slot_irq); res = __tpci200_request_irq(tpci200, dev); out_unlock: -- cgit v0.10.2 From 487e0a608d8d7483be5b5fe3fe9414636c087588 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Wed, 12 Sep 2012 14:55:33 +0200 Subject: Staging: ipack/bridges/tpci200: Protect device registers with spinlock. Some of the device registers are accessed from both interrupt and non-interrupt context. To ensure proper read-modify-write modification of these registers we can not use the "global" tpci200 mutex. Instead a spin-lock is used. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 9ce577a..b1ddbe3 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -53,30 +53,22 @@ static struct tpci200_board *check_slot(struct ipack_device *dev) return tpci200; } -static void __tpci200_clear_mask(__le16 __iomem *addr, u16 mask) -{ - iowrite16(ioread16(addr) & (~mask), addr); -} - static void tpci200_clear_mask(struct tpci200_board *tpci200, __le16 __iomem *addr, u16 mask) { - mutex_lock(&tpci200->mutex); - __tpci200_clear_mask(addr, mask); - mutex_unlock(&tpci200->mutex); -} - -static void __tpci200_set_mask(__le16 __iomem *addr, u16 mask) -{ - iowrite16(ioread16(addr) | mask, addr); + unsigned long flags; + spin_lock_irqsave(&tpci200->regs_lock, flags); + iowrite16(ioread16(addr) & (~mask), addr); + spin_unlock_irqrestore(&tpci200->regs_lock, flags); } static void tpci200_set_mask(struct tpci200_board *tpci200, __le16 __iomem *addr, u16 mask) { - mutex_lock(&tpci200->mutex); - __tpci200_set_mask(addr, mask); - mutex_unlock(&tpci200->mutex); + unsigned long flags; + spin_lock_irqsave(&tpci200->regs_lock, flags); + iowrite16(ioread16(addr) | mask, addr); + spin_unlock_irqrestore(&tpci200->regs_lock, flags); } static void tpci200_unregister(struct tpci200_board *tpci200) @@ -143,7 +135,7 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id) dev_info(&tpci200->info->pdev->dev, "No registered ISR for slot [%d:%d]!. IRQ will be disabled.\n", tpci200->number, i); - __tpci200_clear_mask( + tpci200_clear_mask(tpci200, &tpci200->info->interface_regs->control[i], TPCI200_INT0_EN | TPCI200_INT1_EN); } @@ -213,6 +205,9 @@ static int tpci200_register(struct tpci200_board *tpci200) TPCI200_MEM8_SPACE_BAR), TPCI200_MEM8_SIZE); + /* Initialize lock that protects interface_regs */ + spin_lock_init(&tpci200->regs_lock); + ioidint_base = pci_resource_start(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR); mem_base = pci_resource_start(tpci200->info->pdev, @@ -272,7 +267,7 @@ out_disable_pci: static int __tpci200_request_irq(struct tpci200_board *tpci200, struct ipack_device *dev) { - __tpci200_set_mask( + tpci200_set_mask(tpci200, &tpci200->info->interface_regs->control[dev->slot], TPCI200_INT0_EN | TPCI200_INT1_EN); return 0; @@ -281,7 +276,7 @@ static int __tpci200_request_irq(struct tpci200_board *tpci200, static void __tpci200_free_irq(struct tpci200_board *tpci200, struct ipack_device *dev) { - __tpci200_clear_mask( + tpci200_clear_mask(tpci200, &tpci200->info->interface_regs->control[dev->slot], TPCI200_INT0_EN | TPCI200_INT1_EN); } diff --git a/drivers/staging/ipack/bridges/tpci200.h b/drivers/staging/ipack/bridges/tpci200.h index 75a5dcc..b8e9826 100644 --- a/drivers/staging/ipack/bridges/tpci200.h +++ b/drivers/staging/ipack/bridges/tpci200.h @@ -163,6 +163,7 @@ struct tpci200_infos { struct tpci200_board { unsigned int number; struct mutex mutex; + spinlock_t regs_lock; struct tpci200_slot *slots; struct tpci200_infos *info; }; -- cgit v0.10.2 From 88ff8480d39da6b2961444f0c28b5b0d194d2de6 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Wed, 12 Sep 2012 14:55:34 +0200 Subject: Staging: ipack/bridges/tpci200: Clean up interrupt handling. Previously the return value from tpci200_interrupt was not quite correct if a slot had caused an interrupt but no handler was instellalled: IRQ_NONE was returned. However in this case we react to the interrupt by disabling the IPack device interrupt. Basically there are two cases the code now distinguishes: - The tpci200 has raised an interrupt. We handle it and return IRQ_HANDLED. - Our device did not raise an interrupt. We return IRQ_NONE. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index b1ddbe3..0cbaf3a 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -116,7 +116,6 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id) struct tpci200_board *tpci200 = (struct tpci200_board *) dev_id; int i; unsigned short status_reg; - irqreturn_t ret = IRQ_NONE; struct slot_irq *slot_irq; /* Read status register */ @@ -130,7 +129,7 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id) continue; slot_irq = rcu_dereference(tpci200->slots[i].irq); if (slot_irq) { - ret = tpci200_slot_irq(slot_irq); + tpci200_slot_irq(slot_irq); } else { dev_info(&tpci200->info->pdev->dev, "No registered ISR for slot [%d:%d]!. IRQ will be disabled.\n", @@ -141,9 +140,11 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id) } } rcu_read_unlock(); - } - return ret; + return IRQ_HANDLED; + } else { + return IRQ_NONE; + } } static int tpci200_register(struct tpci200_board *tpci200) -- cgit v0.10.2 From ab0deffcb957d1e0bf8c7e1d6373b4e1587b8192 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Wed, 12 Sep 2012 14:55:35 +0200 Subject: Staging: ipack/bridges/tpci200: Cleanup in tpci200_slot_irq() and tpci200_interrupt() Minor cleanup. No functional changes. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 0cbaf3a..4eaa2aa 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -102,9 +102,13 @@ static void tpci200_unregister(struct tpci200_board *tpci200) static irqreturn_t tpci200_slot_irq(struct slot_irq *slot_irq) { - irqreturn_t ret = slot_irq->handler(slot_irq->arg); + irqreturn_t ret; - /* Dummy reads */ + if (!slot_irq) + return -ENODEV; + ret = slot_irq->handler(slot_irq->arg); + + /* Clear the IPack device interrupt */ readw(slot_irq->holder->io_space.address + 0xC0); readw(slot_irq->holder->io_space.address + 0xC2); @@ -114,37 +118,37 @@ static irqreturn_t tpci200_slot_irq(struct slot_irq *slot_irq) static irqreturn_t tpci200_interrupt(int irq, void *dev_id) { struct tpci200_board *tpci200 = (struct tpci200_board *) dev_id; - int i; - unsigned short status_reg; struct slot_irq *slot_irq; + irqreturn_t ret; + u16 status_reg; + int i; /* Read status register */ - status_reg = readw(&tpci200->info->interface_regs->status); - - if (status_reg & TPCI200_SLOT_INT_MASK) { - /* callback to the IRQ handler for the corresponding slot */ - rcu_read_lock(); - for (i = 0; i < TPCI200_NB_SLOT; i++) { - if (!(status_reg & ((TPCI200_A_INT0 | TPCI200_A_INT1) << (2*i)))) - continue; - slot_irq = rcu_dereference(tpci200->slots[i].irq); - if (slot_irq) { - tpci200_slot_irq(slot_irq); - } else { - dev_info(&tpci200->info->pdev->dev, - "No registered ISR for slot [%d:%d]!. IRQ will be disabled.\n", - tpci200->number, i); - tpci200_clear_mask(tpci200, - &tpci200->info->interface_regs->control[i], - TPCI200_INT0_EN | TPCI200_INT1_EN); - } - } - rcu_read_unlock(); + status_reg = ioread16(&tpci200->info->interface_regs->status); - return IRQ_HANDLED; - } else { + /* Did we cause the interrupt? */ + if (!(status_reg & TPCI200_SLOT_INT_MASK)) return IRQ_NONE; + + /* callback to the IRQ handler for the corresponding slot */ + rcu_read_lock(); + for (i = 0; i < TPCI200_NB_SLOT; i++) { + if (!(status_reg & ((TPCI200_A_INT0 | TPCI200_A_INT1) << (2 * i)))) + continue; + slot_irq = rcu_dereference(tpci200->slots[i].irq); + ret = tpci200_slot_irq(slot_irq); + if (ret == -ENODEV) { + dev_info(&tpci200->info->pdev->dev, + "No registered ISR for slot [%d:%d]!. IRQ will be disabled.\n", + tpci200->number, i); + tpci200_clear_mask(tpci200, + &tpci200->info->interface_regs->control[i], + TPCI200_INT0_EN | TPCI200_INT1_EN); + } } + rcu_read_unlock(); + + return IRQ_HANDLED; } static int tpci200_register(struct tpci200_board *tpci200) -- cgit v0.10.2 From 877adc406cc7aeb9610f32535ed61c24ff01bfe2 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Wed, 12 Sep 2012 14:55:36 +0200 Subject: Staging: ipack/bridges/tpci200: More cleanups. Rename __tpci_request_irq() to tpci_enable_irq() and __tpci_free_irq() to tpci_disable_irq(). Change their second argument, move them above tpci200_interrupt(), and use tpci_disable_irq() in the latter Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 4eaa2aa..c7ec342 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -100,6 +100,22 @@ static void tpci200_unregister(struct tpci200_board *tpci200) } } +static void tpci200_enable_irq(struct tpci200_board *tpci200, + int islot) +{ + tpci200_set_mask(tpci200, + &tpci200->info->interface_regs->control[islot], + TPCI200_INT0_EN | TPCI200_INT1_EN); +} + +static void tpci200_disable_irq(struct tpci200_board *tpci200, + int islot) +{ + tpci200_clear_mask(tpci200, + &tpci200->info->interface_regs->control[islot], + TPCI200_INT0_EN | TPCI200_INT1_EN); +} + static irqreturn_t tpci200_slot_irq(struct slot_irq *slot_irq) { irqreturn_t ret; @@ -141,9 +157,7 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id) dev_info(&tpci200->info->pdev->dev, "No registered ISR for slot [%d:%d]!. IRQ will be disabled.\n", tpci200->number, i); - tpci200_clear_mask(tpci200, - &tpci200->info->interface_regs->control[i], - TPCI200_INT0_EN | TPCI200_INT1_EN); + tpci200_disable_irq(tpci200, i); } } rcu_read_unlock(); @@ -269,23 +283,6 @@ out_disable_pci: return res; } -static int __tpci200_request_irq(struct tpci200_board *tpci200, - struct ipack_device *dev) -{ - tpci200_set_mask(tpci200, - &tpci200->info->interface_regs->control[dev->slot], - TPCI200_INT0_EN | TPCI200_INT1_EN); - return 0; -} - -static void __tpci200_free_irq(struct tpci200_board *tpci200, - struct ipack_device *dev) -{ - tpci200_clear_mask(tpci200, - &tpci200->info->interface_regs->control[dev->slot], - TPCI200_INT0_EN | TPCI200_INT1_EN); -} - static int tpci200_free_irq(struct ipack_device *dev) { struct slot_irq *slot_irq; @@ -303,8 +300,9 @@ static int tpci200_free_irq(struct ipack_device *dev) return -EINVAL; } - __tpci200_free_irq(tpci200, dev); + tpci200_disable_irq(tpci200, dev->slot); slot_irq = tpci200->slots[dev->slot].irq; + /* uninstall handler */ RCU_INIT_POINTER(tpci200->slots[dev->slot].irq, NULL); synchronize_rcu(); kfree(slot_irq); @@ -453,7 +451,7 @@ out_unlock: static int tpci200_request_irq(struct ipack_device *dev, int vector, int (*handler)(void *), void *arg) { - int res; + int res = 0; struct slot_irq *slot_irq; struct tpci200_board *tpci200; @@ -493,7 +491,7 @@ static int tpci200_request_irq(struct ipack_device *dev, int vector, slot_irq->holder = dev; rcu_assign_pointer(tpci200->slots[dev->slot].irq, slot_irq); - res = __tpci200_request_irq(tpci200, dev); + tpci200_enable_irq(tpci200, dev->slot); out_unlock: mutex_unlock(&tpci200->mutex); -- cgit v0.10.2 From 40733ed7636c6d255f7e6ad0b2bd66e8490fd22c Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Wed, 12 Sep 2012 14:55:37 +0200 Subject: Staging: ipack/bridges/tpci200: move tpci200_free_irq() and tpci200_request_irq() Now, all the interrupt related functions are next to each other. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index c7ec342..b0d2205 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -165,6 +165,83 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } +static int tpci200_free_irq(struct ipack_device *dev) +{ + struct slot_irq *slot_irq; + struct tpci200_board *tpci200; + + tpci200 = check_slot(dev); + if (tpci200 == NULL) + return -EINVAL; + + if (mutex_lock_interruptible(&tpci200->mutex)) + return -ERESTARTSYS; + + if (tpci200->slots[dev->slot].irq == NULL) { + mutex_unlock(&tpci200->mutex); + return -EINVAL; + } + + tpci200_disable_irq(tpci200, dev->slot); + slot_irq = tpci200->slots[dev->slot].irq; + /* uninstall handler */ + RCU_INIT_POINTER(tpci200->slots[dev->slot].irq, NULL); + synchronize_rcu(); + kfree(slot_irq); + mutex_unlock(&tpci200->mutex); + return 0; +} + +static int tpci200_request_irq(struct ipack_device *dev, int vector, + int (*handler)(void *), void *arg) +{ + int res = 0; + struct slot_irq *slot_irq; + struct tpci200_board *tpci200; + + tpci200 = check_slot(dev); + if (tpci200 == NULL) + return -EINVAL; + + if (mutex_lock_interruptible(&tpci200->mutex)) + return -ERESTARTSYS; + + if (tpci200->slots[dev->slot].irq != NULL) { + dev_err(&dev->dev, + "Slot [%d:%d] IRQ already registered !\n", dev->bus_nr, + dev->slot); + res = -EINVAL; + goto out_unlock; + } + + slot_irq = kzalloc(sizeof(struct slot_irq), GFP_KERNEL); + if (slot_irq == NULL) { + dev_err(&dev->dev, + "Slot [%d:%d] unable to allocate memory for IRQ !\n", + dev->bus_nr, dev->slot); + res = -ENOMEM; + goto out_unlock; + } + + /* + * WARNING: Setup Interrupt Vector in the IndustryPack device + * before an IRQ request. + * Read the User Manual of your IndustryPack device to know + * where to write the vector in memory. + */ + slot_irq->vector = vector; + slot_irq->handler = handler; + slot_irq->arg = arg; + slot_irq->holder = dev; + + rcu_assign_pointer(tpci200->slots[dev->slot].irq, slot_irq); + tpci200_enable_irq(tpci200, dev->slot); + +out_unlock: + mutex_unlock(&tpci200->mutex); + return res; +} + static int tpci200_register(struct tpci200_board *tpci200) { int i; @@ -283,33 +360,6 @@ out_disable_pci: return res; } -static int tpci200_free_irq(struct ipack_device *dev) -{ - struct slot_irq *slot_irq; - struct tpci200_board *tpci200; - - tpci200 = check_slot(dev); - if (tpci200 == NULL) - return -EINVAL; - - if (mutex_lock_interruptible(&tpci200->mutex)) - return -ERESTARTSYS; - - if (tpci200->slots[dev->slot].irq == NULL) { - mutex_unlock(&tpci200->mutex); - return -EINVAL; - } - - tpci200_disable_irq(tpci200, dev->slot); - slot_irq = tpci200->slots[dev->slot].irq; - /* uninstall handler */ - RCU_INIT_POINTER(tpci200->slots[dev->slot].irq, NULL); - synchronize_rcu(); - kfree(slot_irq); - mutex_unlock(&tpci200->mutex); - return 0; -} - static int tpci200_slot_unmap_space(struct ipack_device *dev, int space) { struct ipack_addr_space *virt_addr_space; @@ -448,56 +498,6 @@ out_unlock: return res; } -static int tpci200_request_irq(struct ipack_device *dev, int vector, - int (*handler)(void *), void *arg) -{ - int res = 0; - struct slot_irq *slot_irq; - struct tpci200_board *tpci200; - - tpci200 = check_slot(dev); - if (tpci200 == NULL) - return -EINVAL; - - if (mutex_lock_interruptible(&tpci200->mutex)) - return -ERESTARTSYS; - - if (tpci200->slots[dev->slot].irq != NULL) { - dev_err(&dev->dev, - "Slot [%d:%d] IRQ already registered !\n", dev->bus_nr, - dev->slot); - res = -EINVAL; - goto out_unlock; - } - - slot_irq = kzalloc(sizeof(struct slot_irq), GFP_KERNEL); - if (slot_irq == NULL) { - dev_err(&dev->dev, - "Slot [%d:%d] unable to allocate memory for IRQ !\n", - dev->bus_nr, dev->slot); - res = -ENOMEM; - goto out_unlock; - } - - /* - * WARNING: Setup Interrupt Vector in the IndustryPack device - * before an IRQ request. - * Read the User Manual of your IndustryPack device to know - * where to write the vector in memory. - */ - slot_irq->vector = vector; - slot_irq->handler = handler; - slot_irq->arg = arg; - slot_irq->holder = dev; - - rcu_assign_pointer(tpci200->slots[dev->slot].irq, slot_irq); - tpci200_enable_irq(tpci200, dev->slot); - -out_unlock: - mutex_unlock(&tpci200->mutex); - return res; -} - static int tpci200_get_clockrate(struct ipack_device *dev) { struct tpci200_board *tpci200 = check_slot(dev); -- cgit v0.10.2 From faa75c406e7396a952c3ebedfc2b1d6f1b8d2648 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Wed, 12 Sep 2012 14:55:38 +0200 Subject: Staging: ipack: Let interrupts return irqreturn_t. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index b0d2205..1a149d8 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -193,7 +193,7 @@ static int tpci200_free_irq(struct ipack_device *dev) } static int tpci200_request_irq(struct ipack_device *dev, int vector, - int (*handler)(void *), void *arg) + irqreturn_t (*handler)(void *), void *arg) { int res = 0; struct slot_irq *slot_irq; diff --git a/drivers/staging/ipack/bridges/tpci200.h b/drivers/staging/ipack/bridges/tpci200.h index b8e9826..2718d22 100644 --- a/drivers/staging/ipack/bridges/tpci200.h +++ b/drivers/staging/ipack/bridges/tpci200.h @@ -17,7 +17,6 @@ #include #include #include -#include #include #include @@ -123,7 +122,7 @@ struct tpci200_regs { struct slot_irq { struct ipack_device *holder; int vector; - int (*handler)(void *); + irqreturn_t (*handler)(void *); void *arg; }; diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index 4cc9173..8e61ebd 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -263,7 +263,7 @@ static void ipoctal_irq_channel(struct ipoctal_channel *channel) tty_kref_put(tty); } -static int ipoctal_irq_handler(void *arg) +static irqreturn_t ipoctal_irq_handler(void *arg) { unsigned int i; struct ipoctal *ipoctal = (struct ipoctal *) arg; diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h index 0ea9d84..9c3079d 100644 --- a/drivers/staging/ipack/ipack.h +++ b/drivers/staging/ipack/ipack.h @@ -11,6 +11,7 @@ #include #include +#include #include "ipack_ids.h" @@ -126,7 +127,8 @@ struct ipack_driver { struct ipack_bus_ops { int (*map_space) (struct ipack_device *dev, unsigned int memory_size, int space); int (*unmap_space) (struct ipack_device *dev, int space); - int (*request_irq) (struct ipack_device *dev, int vector, int (*handler)(void *), void *arg); + int (*request_irq) (struct ipack_device *dev, int vector, + irqreturn_t (*handler)(void *), void *arg); int (*free_irq) (struct ipack_device *dev); int (*get_clockrate) (struct ipack_device *dev); int (*set_clockrate) (struct ipack_device *dev, int mherz); -- cgit v0.10.2 From 1adda49706ff832e9fc4f4bcb62d38285145307c Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Wed, 12 Sep 2012 14:55:39 +0200 Subject: Staging: ipack/devices/ipoctal: Clean up device removal. Make use of dev_set_drvdata() and dev_get_drvdata() to store and obtain a pointer to the ipoctal struct corresponding to a struct dev. Previously we relied on a private list of devices. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index 8e61ebd..b84ab5e 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -725,6 +725,7 @@ static int ipoctal_probe(struct ipack_device *dev) if (res) goto out_uninst; + dev_set_drvdata(&dev->dev, ipoctal); list_add_tail(&ipoctal->list, &ipoctal_list); return 0; @@ -751,14 +752,9 @@ static void __ipoctal_remove(struct ipoctal *ipoctal) kfree(ipoctal); } -static void ipoctal_remove(struct ipack_device *device) +static void ipoctal_remove(struct ipack_device *idev) { - struct ipoctal *ipoctal, *next; - - list_for_each_entry_safe(ipoctal, next, &ipoctal_list, list) { - if (ipoctal->dev == device) - __ipoctal_remove(ipoctal); - } + __ipoctal_remove(dev_get_drvdata(&idev->dev)); } static DEFINE_IPACK_DEVICE_TABLE(ipoctal_ids) = { -- cgit v0.10.2 From 2afb41d9d30d33504c47a5dda3eeade692f388dc Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Wed, 12 Sep 2012 14:55:40 +0200 Subject: Staging: ipack/devices/ipoctal: Check tty_register_device return value. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index b84ab5e..7371270 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -437,6 +437,8 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, ipoctal->tty_drv = tty; for (i = 0; i < NR_CHANNELS; i++) { + struct device *tty_dev; + channel = &ipoctal->channel[i]; tty_port_init(&channel->tty_port); tty_port_alloc_xmit_buf(&channel->tty_port); @@ -450,7 +452,11 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, channel->pointer_read = 0; channel->pointer_write = 0; channel->nb_bytes = 0; - tty_register_device(tty, i, NULL); + tty_dev = tty_register_device(tty, i, NULL); + if (IS_ERR(tty_dev)) { + dev_err(&ipoctal->dev->dev, "Failed to register tty device.\n"); + continue; + } /* * Enable again the RX. TX will be enabled when -- cgit v0.10.2 From 3f3a592798fe4a6eff0448685280925a9b1830f4 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Wed, 12 Sep 2012 14:55:41 +0200 Subject: Staging: ipack/devices/ipoctal: Use KBUILD_MODNAME instead of hardcoded string. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index 7371270..a0c1e76 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -411,8 +411,8 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, /* Fill struct tty_driver with ipoctal data */ tty->owner = THIS_MODULE; - tty->driver_name = "ipoctal"; - sprintf(name, "ipoctal.%d.%d.", bus_nr, slot); + tty->driver_name = KBUILD_MODNAME; + sprintf(name, KBUILD_MODNAME ".%d.%d.", bus_nr, slot); tty->name = name; tty->major = 0; -- cgit v0.10.2 From 9c1d784afc6fc37d328623d1adf503031b524788 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Wed, 12 Sep 2012 14:55:42 +0200 Subject: Staging: ipack/devices/ipoctal: Get rid of ipoctal_list. Use tty_dev->dev's drdata to associate struct ipocal_channel to the respective tty_struct. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index a0c1e76..8b2be61 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -49,7 +49,6 @@ struct ipoctal_channel { }; struct ipoctal { - struct list_head list; struct ipack_device *dev; unsigned int board_id; struct ipoctal_channel channel[NR_CHANNELS]; @@ -57,34 +56,11 @@ struct ipoctal { struct tty_driver *tty_drv; }; -/* Linked list to save the registered devices */ -static LIST_HEAD(ipoctal_list); - -static struct ipoctal *ipoctal_find_board(struct tty_struct *tty) -{ - struct ipoctal *p; - - list_for_each_entry(p, &ipoctal_list, list) { - if (tty->driver->major == p->tty_drv->major) - return p; - } - - return NULL; -} - static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty) { - struct ipoctal *ipoctal; struct ipoctal_channel *channel; - ipoctal = ipoctal_find_board(tty); - - if (ipoctal == NULL) { - dev_err(tty->dev, "Device not found. Major %d\n", - tty->driver->major); - return -ENODEV; - } - channel = &ipoctal->channel[tty->index]; + channel = dev_get_drvdata(tty->dev); iowrite8(CR_ENABLE_RX, &channel->regs->w.cr); return 0; @@ -93,17 +69,9 @@ static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty) static int ipoctal_open(struct tty_struct *tty, struct file *file) { int res; - struct ipoctal *ipoctal; struct ipoctal_channel *channel; - ipoctal = ipoctal_find_board(tty); - - if (ipoctal == NULL) { - dev_err(tty->dev, "Device not found. Major %d\n", - tty->driver->major); - return -ENODEV; - } - channel = &ipoctal->channel[tty->index]; + channel = dev_get_drvdata(tty->dev); if (atomic_read(&channel->open)) return -EBUSY; @@ -457,6 +425,7 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, dev_err(&ipoctal->dev->dev, "Failed to register tty device.\n"); continue; } + dev_set_drvdata(tty_dev, channel); /* * Enable again the RX. TX will be enabled when @@ -732,7 +701,6 @@ static int ipoctal_probe(struct ipack_device *dev) goto out_uninst; dev_set_drvdata(&dev->dev, ipoctal); - list_add_tail(&ipoctal->list, &ipoctal_list); return 0; out_uninst: @@ -754,7 +722,6 @@ static void __ipoctal_remove(struct ipoctal *ipoctal) tty_unregister_driver(ipoctal->tty_drv); put_tty_driver(ipoctal->tty_drv); - list_del(&ipoctal->list); kfree(ipoctal); } -- cgit v0.10.2 From ab0a71f06d44334154091c6cdc823f908398623e Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Wed, 12 Sep 2012 14:55:43 +0200 Subject: Staging: ipack/devices/ipoctal: read more than one character from RX FIFO. The RX FIFO has a size of 3 characters. Check if when we are picking the oldest one, we have more to read. Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index 8b2be61..4f79fad 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -134,33 +134,45 @@ static int ipoctal_get_icount(struct tty_struct *tty, static void ipoctal_irq_rx(struct ipoctal_channel *channel, struct tty_struct *tty, u8 sr) { - unsigned char value = ioread8(&channel->regs->r.rhr); + unsigned char value; unsigned char flag = TTY_NORMAL; - - /* Error: count statistics */ - if (sr & SR_ERROR) { - iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr); - - if (sr & SR_OVERRUN_ERROR) { - channel->stats.overrun_err++; - /* Overrun doesn't affect the current character*/ - tty_insert_flip_char(tty, 0, TTY_OVERRUN); - } - if (sr & SR_PARITY_ERROR) { - channel->stats.parity_err++; - flag = TTY_PARITY; - } - if (sr & SR_FRAMING_ERROR) { - channel->stats.framing_err++; - flag = TTY_FRAME; + u8 isr; + + do { + value = ioread8(&channel->regs->r.rhr); + /* Error: count statistics */ + if (sr & SR_ERROR) { + iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr); + + if (sr & SR_OVERRUN_ERROR) { + channel->stats.overrun_err++; + /* Overrun doesn't affect the current character*/ + tty_insert_flip_char(tty, 0, TTY_OVERRUN); + } + if (sr & SR_PARITY_ERROR) { + channel->stats.parity_err++; + flag = TTY_PARITY; + } + if (sr & SR_FRAMING_ERROR) { + channel->stats.framing_err++; + flag = TTY_FRAME; + } + if (sr & SR_RECEIVED_BREAK) { + channel->stats.rcv_break++; + flag = TTY_BREAK; + } } - if (sr & SR_RECEIVED_BREAK) { - channel->stats.rcv_break++; - flag = TTY_BREAK; - } - } + tty_insert_flip_char(tty, value, flag); - tty_insert_flip_char(tty, value, flag); + /* Check if there are more characters in RX FIFO + * If there are more, the isr register for this channel + * has enabled the RxRDY|FFULL bit. + */ + isr = ioread8(&channel->block_regs->r.isr); + sr = ioread8(&channel->regs->r.sr); + } while (isr & channel->isr_rx_rdy_mask); + + tty_flip_buffer_push(tty); } static void ipoctal_irq_tx(struct ipoctal_channel *channel) -- cgit v0.10.2 From cacd55c1b7854234f45f510dec57ee9baee0b40c Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Wed, 12 Sep 2012 14:55:44 +0200 Subject: Staging: ipack: update TODO file With the latest patches, the TODO file was outdated. Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/TODO b/drivers/staging/ipack/TODO index b21d33a..ffafe69 100644 --- a/drivers/staging/ipack/TODO +++ b/drivers/staging/ipack/TODO @@ -12,29 +12,8 @@ operations between the two kind of boards. TODO ==== -TPCI-200 --------- - -* It has a linked list with the tpci200 devices it is managing. Get rid of it - and use driver_for_each_device() instead. - -IP-OCTAL --------- - -* It has a linked list which saves the devices it is currently - managing. It should use the driver_for_each_device() function. It is not there - due to the impossibility of using container_of macro to recover the - corresponding "struct ipoctal" because the attribute "struct ipack_device" is - a pointer. This code should be refactored. - -Ipack ------ - -* The structures and API exported can be improved a lot. For example, the - way to unregistering IP module devices, doing the IP module driver a call to - remove_device() to notify the carrier driver, or the opposite with the call to - the ipack_driver_ops' remove() function could be improved. - +checkpatch.pl warnings +cleanup Contact ======= -- cgit v0.10.2 From 6f892216830df9bcde74aca33f1f998cce99e401 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Wed, 12 Sep 2012 14:55:45 +0200 Subject: Staging: ipack/devices/ipoctal: Unmap memory on device removal. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index 4f79fad..0292364 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -734,6 +734,9 @@ static void __ipoctal_remove(struct ipoctal *ipoctal) tty_unregister_driver(ipoctal->tty_drv); put_tty_driver(ipoctal->tty_drv); + ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_MEM_SPACE); + ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_IO_SPACE); + ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_ID_SPACE); kfree(ipoctal); } -- cgit v0.10.2 From 7dd73b866ed656b4ef7b475de4588cb1a3f765d4 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Wed, 12 Sep 2012 14:55:46 +0200 Subject: staging: ipack/bridges/tpci200: Use endianess-aware types where applicable. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 1a149d8..21b2b75 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -501,7 +501,7 @@ out_unlock: static int tpci200_get_clockrate(struct ipack_device *dev) { struct tpci200_board *tpci200 = check_slot(dev); - u16 __iomem *addr; + __le16 __iomem *addr; if (!tpci200) return -ENODEV; @@ -513,7 +513,7 @@ static int tpci200_get_clockrate(struct ipack_device *dev) static int tpci200_set_clockrate(struct ipack_device *dev, int mherz) { struct tpci200_board *tpci200 = check_slot(dev); - u16 __iomem *addr; + __le16 __iomem *addr; if (!tpci200) return -ENODEV; @@ -536,7 +536,7 @@ static int tpci200_set_clockrate(struct ipack_device *dev, int mherz) static int tpci200_get_error(struct ipack_device *dev) { struct tpci200_board *tpci200 = check_slot(dev); - u16 __iomem *addr; + __le16 __iomem *addr; u16 mask; if (!tpci200) @@ -550,7 +550,7 @@ static int tpci200_get_error(struct ipack_device *dev) static int tpci200_get_timeout(struct ipack_device *dev) { struct tpci200_board *tpci200 = check_slot(dev); - u16 __iomem *addr; + __le16 __iomem *addr; u16 mask; if (!tpci200) @@ -565,7 +565,7 @@ static int tpci200_get_timeout(struct ipack_device *dev) static int tpci200_reset_timeout(struct ipack_device *dev) { struct tpci200_board *tpci200 = check_slot(dev); - u16 __iomem *addr; + __le16 __iomem *addr; u16 mask; if (!tpci200) diff --git a/drivers/staging/ipack/bridges/tpci200.h b/drivers/staging/ipack/bridges/tpci200.h index 2718d22..e1f60f3 100644 --- a/drivers/staging/ipack/bridges/tpci200.h +++ b/drivers/staging/ipack/bridges/tpci200.h @@ -37,12 +37,12 @@ #define TPCI200_MEM8_SPACE_BAR 5 struct tpci200_regs { - u16 revision; + __le16 revision; /* writes to control should occur with the mutex held to protect * read-modify-write operations */ - u16 control[4]; - u16 reset; - u16 status; + __le16 control[4]; + __le16 reset; + __le16 status; u8 reserved[242]; } __packed; -- cgit v0.10.2 From cb75f2335c4068414e4b48aea38a3351bd6785a0 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 10 Sep 2012 09:34:00 +0100 Subject: staging:iio:ad7476: Fix off by one error for channel shift The datasheet is a bit confusing about this. It says that a dataword has 4 leading zeros, but the first zero is already put on the bus when CS is pulled low and the second zero is put on the bus on the first leading edge of SCLK, so when the first bit is sampled on the first trailing edge it will sample what the datasheet refers to as the second leading zero. Subsequently we only see 3 leading zeros in the 16 bit dataword and the result we get is shifted to the left by one bit. Fix this by adjusting the channel shift by 1. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/adc/ad7476_core.c b/drivers/staging/iio/adc/ad7476_core.c index 4f6d59e..33435ed 100644 --- a/drivers/staging/iio/adc/ad7476_core.c +++ b/drivers/staging/iio/adc/ad7476_core.c @@ -76,7 +76,7 @@ static int ad7476_read_raw(struct iio_dev *indio_dev, .sign = 'u', \ .realbits = bits, \ .storagebits = 16, \ - .shift = 12 - bits, \ + .shift = 13 - bits, \ }, \ } -- cgit v0.10.2 From fcc7800b652e55420b85d1c885f39e8a230ace59 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 10 Sep 2012 09:34:00 +0100 Subject: staging:iio:ad7476: Remove duplicated chip info entries Some of the parts supported by this driver are software compatible. The difference between them is only in the operating voltage range. So we do not need extra chip info entries for them. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/adc/ad7476.h b/drivers/staging/iio/adc/ad7476.h index b1dd931..6085fad 100644 --- a/drivers/staging/iio/adc/ad7476.h +++ b/drivers/staging/iio/adc/ad7476.h @@ -41,10 +41,6 @@ enum ad7476_supported_device_ids { ID_AD7466, ID_AD7467, ID_AD7468, - ID_AD7475, - ID_AD7476, - ID_AD7477, - ID_AD7478, ID_AD7495 }; diff --git a/drivers/staging/iio/adc/ad7476_core.c b/drivers/staging/iio/adc/ad7476_core.c index 33435ed..c97300b 100644 --- a/drivers/staging/iio/adc/ad7476_core.c +++ b/drivers/staging/iio/adc/ad7476_core.c @@ -93,22 +93,6 @@ static const struct ad7476_chip_info ad7476_chip_info_tbl[] = { .channel[0] = AD7476_CHAN(8), .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), }, - [ID_AD7475] = { - .channel[0] = AD7476_CHAN(12), - .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), - }, - [ID_AD7476] = { - .channel[0] = AD7476_CHAN(12), - .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), - }, - [ID_AD7477] = { - .channel[0] = AD7476_CHAN(10), - .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), - }, - [ID_AD7478] = { - .channel[0] = AD7476_CHAN(8), - .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), - }, [ID_AD7495] = { .channel[0] = AD7476_CHAN(12), .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), @@ -216,13 +200,13 @@ static const struct spi_device_id ad7476_id[] = { {"ad7466", ID_AD7466}, {"ad7467", ID_AD7467}, {"ad7468", ID_AD7468}, - {"ad7475", ID_AD7475}, - {"ad7476", ID_AD7476}, - {"ad7476a", ID_AD7476}, - {"ad7477", ID_AD7477}, - {"ad7477a", ID_AD7477}, - {"ad7478", ID_AD7478}, - {"ad7478a", ID_AD7478}, + {"ad7475", ID_AD7466}, + {"ad7476", ID_AD7466}, + {"ad7476a", ID_AD7466}, + {"ad7477", ID_AD7467}, + {"ad7477a", ID_AD7467}, + {"ad7478", ID_AD7468}, + {"ad7478a", ID_AD7468}, {"ad7495", ID_AD7495}, {} }; -- cgit v0.10.2 From 93e33d703030fe0348c1ff9d8f40bc6c2d82dc30 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 10 Sep 2012 09:34:00 +0100 Subject: staging:iio:ad7476: Avoid alloc/free for each sample in buffered mode The ad7476 driver has only support for 1 channel ADCs. So the upper limit for the buffer size is the size of one sample plus the size of the timestamp. Preallocate a buffer large enough to hold this to avoid having to allocate and free a new buffer for each sample being captured. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/adc/ad7476.h b/drivers/staging/iio/adc/ad7476.h index 6085fad..c4f1150 100644 --- a/drivers/staging/iio/adc/ad7476.h +++ b/drivers/staging/iio/adc/ad7476.h @@ -33,8 +33,11 @@ struct ad7476_state { /* * DMA (thus cache coherency maintenance) requires the * transfer buffers to live in their own cache lines. + * Make the buffer large enough for one 16 bit sample and one 64 bit + * aligned 64 bit timestamp. */ - unsigned char data[2] ____cacheline_aligned; + unsigned char data[ALIGN(2, sizeof(s64)) + sizeof(s64)] + ____cacheline_aligned; }; enum ad7476_supported_device_ids { diff --git a/drivers/staging/iio/adc/ad7476_ring.c b/drivers/staging/iio/adc/ad7476_ring.c index 940681f..3c869b0 100644 --- a/drivers/staging/iio/adc/ad7476_ring.c +++ b/drivers/staging/iio/adc/ad7476_ring.c @@ -26,28 +26,20 @@ static irqreturn_t ad7476_trigger_handler(int irq, void *p) struct iio_dev *indio_dev = pf->indio_dev; struct ad7476_state *st = iio_priv(indio_dev); s64 time_ns; - __u8 *rxbuf; int b_sent; - rxbuf = kzalloc(indio_dev->scan_bytes, GFP_KERNEL); - if (rxbuf == NULL) - goto done; - - b_sent = spi_read(st->spi, rxbuf, - st->chip_info->channel[0].scan_type.storagebits / 8); + b_sent = spi_sync(st->spi, &st->msg); if (b_sent < 0) goto done; time_ns = iio_get_time_ns(); if (indio_dev->scan_timestamp) - memcpy(rxbuf + indio_dev->scan_bytes - sizeof(s64), - &time_ns, sizeof(time_ns)); + ((s64 *)st->data)[1] = time_ns; - iio_push_to_buffer(indio_dev->buffer, rxbuf); + iio_push_to_buffer(indio_dev->buffer, st->data); done: iio_trigger_notify_done(indio_dev->trig); - kfree(rxbuf); return IRQ_HANDLED; } -- cgit v0.10.2 From 41518de2e1cdb27a6c4af4770435466322f065be Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 12 Sep 2012 15:37:14 -0700 Subject: staging: comedi: rename adl_pci7296 driver This driver will be used for all generic PCI based 8255 digital i/o boards. Rename the driver accordingly.. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index d36486e..1ecf213 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -549,6 +549,19 @@ menuconfig COMEDI_PCI_DRIVERS if COMEDI_PCI_DRIVERS +config COMEDI_8255_PCI + tristate "Generic PCI based 8255 digital i/o board support" + select COMEDI_8255 + ---help--- + Enable support for PCI based 8255 digital i/o boards. This driver + provides a PCI wrapper around the generic 8255 driver. + + Supported boards: + ADlink - PCI-7224, PCI-7248, and PCI-7296 + + To compile this driver as a module, choose M here: the module will + be called 8255_pci. + config COMEDI_ADDI_APCI_035 tristate "ADDI-DATA APCI_035 support" depends on VIRT_TO_BUS @@ -687,17 +700,6 @@ config COMEDI_ADL_PCI7X3X To compile this driver as a module, choose M here: the module will be called adl_pci7x3x. -config COMEDI_ADL_PCI7296 - tristate "ADLink PCI-72xx opto-22 compatible digital i/o board support" - select COMEDI_8255 - ---help--- - Enable support for ADlink PCI-72xx opto-22 compatible digital i/o - boards. Supported boards include the 24-channel PCI-7224, 48-channel - PCI-7248, and 96-channel PCI-7296. - - To compile this driver as a module, choose M here: the module will be - called adl_pci7296. - config COMEDI_ADL_PCI8164 tristate "ADLink PCI-8164 4 Axes Motion Control board support" ---help--- @@ -1259,8 +1261,8 @@ config COMEDI_8255 that has an 8255 chip. For multifunction boards, the main driver will configure the 8255 subdevice automatically. - Note that most PCI 8255 boards do NOT work with this driver, and - need a separate driver as a wrapper. + Note that most PCI based 8255 boards use the 8255_pci driver as a + wrapper around this driver. To compile this driver as a module, choose M here: the module will be called 8255. diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c new file mode 100644 index 0000000..96cfc9c --- /dev/null +++ b/drivers/staging/comedi/drivers/8255_pci.c @@ -0,0 +1,191 @@ +/* + * COMEDI driver for the ADLINK PCI-72xx series boards. + * + * COMEDI - Linux Control and Measurement Device Interface + * Copyright (C) 2000 David A. Schleef + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* +Driver: adl_pci7296 +Description: 24/48/96-Channel Opto-22 Compatible Digital I/O Boards +Devices: (ADLink) PCI-7224 [adl_pci7224] - 24 channels + (ADLink) PCI-7248 [adl_pci7248] - 48 channels + (ADLink) PCI-7296 [adl_pci7296] - 96 channels +Author: Jon Grierson +Updated: Mon, 14 Apr 2008 15:05:56 +0100 +Status: testing + +This driver only attaches using the PCI PnP auto config support +in the comedi core. The module parameter 'comedi_autoconfig' +must be 1 (default) to enable this feature. The COMEDI_DEVCONFIG +ioctl, used by the comedi_config utility, is not supported by +this driver. + +These boards also have an 8254 programmable timer/counter chip. +This chip is not currently supported by this driver. + +Interrupt support for these boards is also not currently supported. + +Configuration Options: not applicable +*/ + +#include "../comedidev.h" + +#include "8255.h" + +/* + * PCI Device ID's supported by this driver + */ +#define PCI_DEVICE_ID_PCI7224 0x7224 +#define PCI_DEVICE_ID_PCI7248 0x7248 +#define PCI_DEVICE_ID_PCI7296 0x7296 + +struct adl_pci7296_boardinfo { + const char *name; + unsigned short device; + int nsubdevs; +}; + +static const struct adl_pci7296_boardinfo adl_pci7296_boards[] = { + { + .name = "adl_pci7224", + .device = PCI_DEVICE_ID_PCI7224, + .nsubdevs = 1, + }, { + .name = "adl_pci7248", + .device = PCI_DEVICE_ID_PCI7248, + .nsubdevs = 2, + }, { + .name = "adl_pci7296", + .device = PCI_DEVICE_ID_PCI7296, + .nsubdevs = 4, + }, +}; + +static const void *adl_pci7296_find_boardinfo(struct comedi_device *dev, + struct pci_dev *pcidev) +{ + const struct adl_pci7296_boardinfo *board; + int i; + + for (i = 0; i < ARRAY_SIZE(adl_pci7296_boards); i++) { + board = &adl_pci7296_boards[i]; + if (pcidev->device == board->device) + return board; + } + return NULL; +} + +static int adl_pci7296_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) +{ + const struct adl_pci7296_boardinfo *board; + struct comedi_subdevice *s; + int ret; + int i; + + comedi_set_hw_dev(dev, &pcidev->dev); + + board = adl_pci7296_find_boardinfo(dev, pcidev); + if (!board) + return -ENODEV; + dev->board_ptr = board; + dev->board_name = board->name; + + ret = comedi_pci_enable(pcidev, dev->board_name); + if (ret) + return ret; + dev->iobase = pci_resource_start(pcidev, 2); + + /* + * One, two, or four subdevices are setup by this driver depending + * on the number of channels provided by the board. Each subdevice + * has 24 channels supported by the 8255 module. + */ + ret = comedi_alloc_subdevices(dev, board->nsubdevs); + if (ret) + return ret; + + for (i = 0; i < board->nsubdevs; i++) { + s = &dev->subdevices[i]; + ret = subdev_8255_init(dev, s, NULL, dev->iobase + (i * 4)); + if (ret) + return ret; + } + + dev_info(dev->class_dev, "%s attached (%d digital i/o channels)\n", + dev->board_name, board->nsubdevs * 24); + + return 0; +} + +static void adl_pci7296_detach(struct comedi_device *dev) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + const struct adl_pci7296_boardinfo *board = comedi_board(dev); + struct comedi_subdevice *s; + int i; + + if (dev->subdevices) { + for (i = 0; i < board->nsubdevs; i++) { + s = &dev->subdevices[i]; + subdev_8255_cleanup(dev, s); + } + } + if (pcidev) { + if (dev->iobase) + comedi_pci_disable(pcidev); + } +} + +static struct comedi_driver adl_pci7296_driver = { + .driver_name = "adl_pci7296", + .module = THIS_MODULE, + .attach_pci = adl_pci7296_attach_pci, + .detach = adl_pci7296_detach, +}; + +static int __devinit adl_pci7296_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &adl_pci7296_driver); +} + +static void __devexit adl_pci7296_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(adl_pci7296_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7224) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7248) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7296) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, adl_pci7296_pci_table); + +static struct pci_driver adl_pci7296_pci_driver = { + .name = "adl_pci7296", + .id_table = adl_pci7296_pci_table, + .probe = adl_pci7296_pci_probe, + .remove = __devexit_p(adl_pci7296_pci_remove), +}; +module_comedi_pci_driver(adl_pci7296_driver, adl_pci7296_pci_driver); + +MODULE_DESCRIPTION("ADLINK PCI-72xx Opto-22 Compatible Digital I/O Boards"); +MODULE_AUTHOR("Comedi http://www.comedi.org"); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile index 849ea7f..7798cdc 100644 --- a/drivers/staging/comedi/drivers/Makefile +++ b/drivers/staging/comedi/drivers/Makefile @@ -55,6 +55,7 @@ obj-$(CONFIG_COMEDI_MULTIQ3) += multiq3.o obj-$(CONFIG_COMEDI_POC) += poc.o # Comedi PCI drivers +obj-$(CONFIG_COMEDI_8255_PCI) += 8255_pci.o obj-$(CONFIG_COMEDI_ADDI_APCI_035) += addi_apci_035.o obj-$(CONFIG_COMEDI_ADDI_APCI_1032) += addi_apci_1032.o obj-$(CONFIG_COMEDI_ADDI_APCI_1500) += addi_apci_1500.o @@ -70,7 +71,6 @@ obj-$(CONFIG_COMEDI_ADDI_APCI_3501) += addi_apci_3501.o obj-$(CONFIG_COMEDI_ADDI_APCI_3XXX) += addi_apci_3xxx.o obj-$(CONFIG_COMEDI_ADL_PCI6208) += adl_pci6208.o obj-$(CONFIG_COMEDI_ADL_PCI7X3X) += adl_pci7x3x.o -obj-$(CONFIG_COMEDI_ADL_PCI7296) += adl_pci7296.o obj-$(CONFIG_COMEDI_ADL_PCI8164) += adl_pci8164.o obj-$(CONFIG_COMEDI_ADL_PCI9111) += adl_pci9111.o obj-$(CONFIG_COMEDI_ADL_PCI9118) += adl_pci9118.o diff --git a/drivers/staging/comedi/drivers/adl_pci7296.c b/drivers/staging/comedi/drivers/adl_pci7296.c deleted file mode 100644 index 96cfc9c..0000000 --- a/drivers/staging/comedi/drivers/adl_pci7296.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * COMEDI driver for the ADLINK PCI-72xx series boards. - * - * COMEDI - Linux Control and Measurement Device Interface - * Copyright (C) 2000 David A. Schleef - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* -Driver: adl_pci7296 -Description: 24/48/96-Channel Opto-22 Compatible Digital I/O Boards -Devices: (ADLink) PCI-7224 [adl_pci7224] - 24 channels - (ADLink) PCI-7248 [adl_pci7248] - 48 channels - (ADLink) PCI-7296 [adl_pci7296] - 96 channels -Author: Jon Grierson -Updated: Mon, 14 Apr 2008 15:05:56 +0100 -Status: testing - -This driver only attaches using the PCI PnP auto config support -in the comedi core. The module parameter 'comedi_autoconfig' -must be 1 (default) to enable this feature. The COMEDI_DEVCONFIG -ioctl, used by the comedi_config utility, is not supported by -this driver. - -These boards also have an 8254 programmable timer/counter chip. -This chip is not currently supported by this driver. - -Interrupt support for these boards is also not currently supported. - -Configuration Options: not applicable -*/ - -#include "../comedidev.h" - -#include "8255.h" - -/* - * PCI Device ID's supported by this driver - */ -#define PCI_DEVICE_ID_PCI7224 0x7224 -#define PCI_DEVICE_ID_PCI7248 0x7248 -#define PCI_DEVICE_ID_PCI7296 0x7296 - -struct adl_pci7296_boardinfo { - const char *name; - unsigned short device; - int nsubdevs; -}; - -static const struct adl_pci7296_boardinfo adl_pci7296_boards[] = { - { - .name = "adl_pci7224", - .device = PCI_DEVICE_ID_PCI7224, - .nsubdevs = 1, - }, { - .name = "adl_pci7248", - .device = PCI_DEVICE_ID_PCI7248, - .nsubdevs = 2, - }, { - .name = "adl_pci7296", - .device = PCI_DEVICE_ID_PCI7296, - .nsubdevs = 4, - }, -}; - -static const void *adl_pci7296_find_boardinfo(struct comedi_device *dev, - struct pci_dev *pcidev) -{ - const struct adl_pci7296_boardinfo *board; - int i; - - for (i = 0; i < ARRAY_SIZE(adl_pci7296_boards); i++) { - board = &adl_pci7296_boards[i]; - if (pcidev->device == board->device) - return board; - } - return NULL; -} - -static int adl_pci7296_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) -{ - const struct adl_pci7296_boardinfo *board; - struct comedi_subdevice *s; - int ret; - int i; - - comedi_set_hw_dev(dev, &pcidev->dev); - - board = adl_pci7296_find_boardinfo(dev, pcidev); - if (!board) - return -ENODEV; - dev->board_ptr = board; - dev->board_name = board->name; - - ret = comedi_pci_enable(pcidev, dev->board_name); - if (ret) - return ret; - dev->iobase = pci_resource_start(pcidev, 2); - - /* - * One, two, or four subdevices are setup by this driver depending - * on the number of channels provided by the board. Each subdevice - * has 24 channels supported by the 8255 module. - */ - ret = comedi_alloc_subdevices(dev, board->nsubdevs); - if (ret) - return ret; - - for (i = 0; i < board->nsubdevs; i++) { - s = &dev->subdevices[i]; - ret = subdev_8255_init(dev, s, NULL, dev->iobase + (i * 4)); - if (ret) - return ret; - } - - dev_info(dev->class_dev, "%s attached (%d digital i/o channels)\n", - dev->board_name, board->nsubdevs * 24); - - return 0; -} - -static void adl_pci7296_detach(struct comedi_device *dev) -{ - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - const struct adl_pci7296_boardinfo *board = comedi_board(dev); - struct comedi_subdevice *s; - int i; - - if (dev->subdevices) { - for (i = 0; i < board->nsubdevs; i++) { - s = &dev->subdevices[i]; - subdev_8255_cleanup(dev, s); - } - } - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - } -} - -static struct comedi_driver adl_pci7296_driver = { - .driver_name = "adl_pci7296", - .module = THIS_MODULE, - .attach_pci = adl_pci7296_attach_pci, - .detach = adl_pci7296_detach, -}; - -static int __devinit adl_pci7296_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) -{ - return comedi_pci_auto_config(dev, &adl_pci7296_driver); -} - -static void __devexit adl_pci7296_pci_remove(struct pci_dev *dev) -{ - comedi_pci_auto_unconfig(dev); -} - -static DEFINE_PCI_DEVICE_TABLE(adl_pci7296_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7224) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7248) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7296) }, - { 0 } -}; -MODULE_DEVICE_TABLE(pci, adl_pci7296_pci_table); - -static struct pci_driver adl_pci7296_pci_driver = { - .name = "adl_pci7296", - .id_table = adl_pci7296_pci_table, - .probe = adl_pci7296_pci_probe, - .remove = __devexit_p(adl_pci7296_pci_remove), -}; -module_comedi_pci_driver(adl_pci7296_driver, adl_pci7296_pci_driver); - -MODULE_DESCRIPTION("ADLINK PCI-72xx Opto-22 Compatible Digital I/O Boards"); -MODULE_AUTHOR("Comedi http://www.comedi.org"); -MODULE_LICENSE("GPL"); -- cgit v0.10.2 From f7c22868267da71c65fd09556fc07d62058ff8e6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 12 Sep 2012 15:37:36 -0700 Subject: staging: comedi: 8255_pci: fix namespace due to rename of driver Due to the rename of this file, change all the adl_pci7296_* to pci_8255_* so that everything has namespace associated with this driver. Also, fix the comedi description comment based on the rename of the file. Remove the extra comment about the driver attach. Modify the PCI_DEVICE_ID_* defines in preparation of moving additional vendor/device ids into this driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c index 96cfc9c..cc8b1e0 100644 --- a/drivers/staging/comedi/drivers/8255_pci.c +++ b/drivers/staging/comedi/drivers/8255_pci.c @@ -1,5 +1,9 @@ /* - * COMEDI driver for the ADLINK PCI-72xx series boards. + * COMEDI driver for generic PCI based 8255 digital i/o boards + * Copyright (C) 2012 H Hartley Sweeten + * + * Based on the tested adl_pci7296 driver written by: + * Jon Grierson * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef @@ -20,27 +24,21 @@ */ /* -Driver: adl_pci7296 -Description: 24/48/96-Channel Opto-22 Compatible Digital I/O Boards -Devices: (ADLink) PCI-7224 [adl_pci7224] - 24 channels - (ADLink) PCI-7248 [adl_pci7248] - 48 channels - (ADLink) PCI-7296 [adl_pci7296] - 96 channels -Author: Jon Grierson -Updated: Mon, 14 Apr 2008 15:05:56 +0100 -Status: testing - -This driver only attaches using the PCI PnP auto config support -in the comedi core. The module parameter 'comedi_autoconfig' -must be 1 (default) to enable this feature. The COMEDI_DEVCONFIG -ioctl, used by the comedi_config utility, is not supported by -this driver. - -These boards also have an 8254 programmable timer/counter chip. -This chip is not currently supported by this driver. +Driver: 8255_pci +Description: Generic PCI based 8255 Digital I/O boards +Devices: (ADLink) PCI-7224 [adl_pci-7224] - 24 channels + (ADLink) PCI-7248 [adl_pci-7248] - 48 channels + (ADLink) PCI-7296 [adl_pci-7296] - 96 channels +Author: H Hartley Sweeten +Updated: Wed, 12 Sep 2012 11:52:01 -0700 +Status: untested + +Some of these boards also have an 8254 programmable timer/counter +chip. This chip is not currently supported by this driver. Interrupt support for these boards is also not currently supported. -Configuration Options: not applicable +Configuration Options: not applicable, uses PCI auto config */ #include "../comedidev.h" @@ -50,57 +48,57 @@ Configuration Options: not applicable /* * PCI Device ID's supported by this driver */ -#define PCI_DEVICE_ID_PCI7224 0x7224 -#define PCI_DEVICE_ID_PCI7248 0x7248 -#define PCI_DEVICE_ID_PCI7296 0x7296 +#define PCI_DEVICE_ID_ADLINK_PCI7224 0x7224 +#define PCI_DEVICE_ID_ADLINK_PCI7248 0x7248 +#define PCI_DEVICE_ID_ADLINK_PCI7296 0x7296 -struct adl_pci7296_boardinfo { +struct pci_8255_boardinfo { const char *name; unsigned short device; - int nsubdevs; + int n_8255; }; -static const struct adl_pci7296_boardinfo adl_pci7296_boards[] = { +static const struct pci_8255_boardinfo pci_8255_boards[] = { { - .name = "adl_pci7224", - .device = PCI_DEVICE_ID_PCI7224, - .nsubdevs = 1, + .name = "adl_pci-7224", + .device = PCI_DEVICE_ID_ADLINK_PCI7224, + .n_8255 = 1, }, { - .name = "adl_pci7248", - .device = PCI_DEVICE_ID_PCI7248, - .nsubdevs = 2, + .name = "adl_pci-7248", + .device = PCI_DEVICE_ID_ADLINK_PCI7248, + .n_8255 = 2, }, { - .name = "adl_pci7296", - .device = PCI_DEVICE_ID_PCI7296, - .nsubdevs = 4, + .name = "adl_pci-7296", + .device = PCI_DEVICE_ID_ADLINK_PCI7296, + .n_8255 = 4, }, }; -static const void *adl_pci7296_find_boardinfo(struct comedi_device *dev, +static const void *pci_8255_find_boardinfo(struct comedi_device *dev, struct pci_dev *pcidev) { - const struct adl_pci7296_boardinfo *board; + const struct pci_8255_boardinfo *board; int i; - for (i = 0; i < ARRAY_SIZE(adl_pci7296_boards); i++) { - board = &adl_pci7296_boards[i]; + for (i = 0; i < ARRAY_SIZE(pci_8255_boards); i++) { + board = &pci_8255_boards[i]; if (pcidev->device == board->device) return board; } return NULL; } -static int adl_pci7296_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int pci_8255_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) { - const struct adl_pci7296_boardinfo *board; + const struct pci_8255_boardinfo *board; struct comedi_subdevice *s; int ret; int i; comedi_set_hw_dev(dev, &pcidev->dev); - board = adl_pci7296_find_boardinfo(dev, pcidev); + board = pci_8255_find_boardinfo(dev, pcidev); if (!board) return -ENODEV; dev->board_ptr = board; @@ -116,11 +114,11 @@ static int adl_pci7296_attach_pci(struct comedi_device *dev, * on the number of channels provided by the board. Each subdevice * has 24 channels supported by the 8255 module. */ - ret = comedi_alloc_subdevices(dev, board->nsubdevs); + ret = comedi_alloc_subdevices(dev, board->n_8255); if (ret) return ret; - for (i = 0; i < board->nsubdevs; i++) { + for (i = 0; i < board->n_8255; i++) { s = &dev->subdevices[i]; ret = subdev_8255_init(dev, s, NULL, dev->iobase + (i * 4)); if (ret) @@ -128,20 +126,20 @@ static int adl_pci7296_attach_pci(struct comedi_device *dev, } dev_info(dev->class_dev, "%s attached (%d digital i/o channels)\n", - dev->board_name, board->nsubdevs * 24); + dev->board_name, board->n_8255 * 24); return 0; } -static void adl_pci7296_detach(struct comedi_device *dev) +static void pci_8255_detach(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - const struct adl_pci7296_boardinfo *board = comedi_board(dev); + const struct pci_8255_boardinfo *board = comedi_board(dev); struct comedi_subdevice *s; int i; if (dev->subdevices) { - for (i = 0; i < board->nsubdevs; i++) { + for (i = 0; i < board->n_8255; i++) { s = &dev->subdevices[i]; subdev_8255_cleanup(dev, s); } @@ -152,40 +150,40 @@ static void adl_pci7296_detach(struct comedi_device *dev) } } -static struct comedi_driver adl_pci7296_driver = { - .driver_name = "adl_pci7296", +static struct comedi_driver pci_8255_driver = { + .driver_name = "8255_pci", .module = THIS_MODULE, - .attach_pci = adl_pci7296_attach_pci, - .detach = adl_pci7296_detach, + .attach_pci = pci_8255_attach_pci, + .detach = pci_8255_detach, }; -static int __devinit adl_pci7296_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) +static int __devinit pci_8255_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, &adl_pci7296_driver); + return comedi_pci_auto_config(dev, &pci_8255_driver); } -static void __devexit adl_pci7296_pci_remove(struct pci_dev *dev) +static void __devexit pci_8255_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } -static DEFINE_PCI_DEVICE_TABLE(adl_pci7296_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7224) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7248) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7296) }, +static DEFINE_PCI_DEVICE_TABLE(pci_8255_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_ADLINK_PCI7224) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_ADLINK_PCI7248) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_ADLINK_PCI7296) }, { 0 } }; -MODULE_DEVICE_TABLE(pci, adl_pci7296_pci_table); +MODULE_DEVICE_TABLE(pci, pci_8255_pci_table); -static struct pci_driver adl_pci7296_pci_driver = { - .name = "adl_pci7296", - .id_table = adl_pci7296_pci_table, - .probe = adl_pci7296_pci_probe, - .remove = __devexit_p(adl_pci7296_pci_remove), +static struct pci_driver pci_8255_pci_driver = { + .name = "8255_pci", + .id_table = pci_8255_pci_table, + .probe = pci_8255_pci_probe, + .remove = __devexit_p(pci_8255_pci_remove), }; -module_comedi_pci_driver(adl_pci7296_driver, adl_pci7296_pci_driver); +module_comedi_pci_driver(pci_8255_driver, pci_8255_pci_driver); -MODULE_DESCRIPTION("ADLINK PCI-72xx Opto-22 Compatible Digital I/O Boards"); +MODULE_DESCRIPTION("COMEDI - Generic PCI based 8255 Digital I/O boards"); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From df1a3f87967a2eaadf22936b30c05a7427d78db8 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 12 Sep 2012 15:37:55 -0700 Subject: staging: comedi: remove cb_pcidio driver Move the support for the boards in the cb_pcidio driver to the generic 8255_pci driver and remove the cb_pcidio driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 1ecf213..1bd7e93 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -558,6 +558,7 @@ config COMEDI_8255_PCI Supported boards: ADlink - PCI-7224, PCI-7248, and PCI-7296 + Measurement Computing - PCI-DIO24, PCI-DIO24H and PCI-DIO48H To compile this driver as a module, choose M here: the module will be called 8255_pci. @@ -934,16 +935,6 @@ config COMEDI_CB_PCIDDA To compile this driver as a module, choose M here: the module will be called cb_pcidda. -config COMEDI_CB_PCIDIO - tristate "MeasurementComputing PCI-DIO series support" - select COMEDI_8255 - ---help--- - Enable support for ComputerBoards/MeasurementComputing PCI-DIO series - PCI-DIO24, PCI-DIO24H and PCI-DIO48H - - To compile this driver as a module, choose M here: the module will be - called cb_pcidio. - config COMEDI_CB_PCIMDAS tristate "MeasurementComputing PCIM-DAS1602/16 support" select COMEDI_8255 diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c index cc8b1e0..e011b0a 100644 --- a/drivers/staging/comedi/drivers/8255_pci.c +++ b/drivers/staging/comedi/drivers/8255_pci.c @@ -4,6 +4,8 @@ * * Based on the tested adl_pci7296 driver written by: * Jon Grierson + * and the experimental cb_pcidio driver written by: + * Yoshiya Matsuzaka * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef @@ -29,6 +31,9 @@ Description: Generic PCI based 8255 Digital I/O boards Devices: (ADLink) PCI-7224 [adl_pci-7224] - 24 channels (ADLink) PCI-7248 [adl_pci-7248] - 48 channels (ADLink) PCI-7296 [adl_pci-7296] - 96 channels + (Measurement Computing) PCI-DIO24 [cb_pci-dio24] - 24 channels + (Measurement Computing) PCI-DIO24H [cb_pci-dio24h] - 24 channels + (Measurement Computing) PCI-DIO48H [cb_pci-dio48h] - 48 channels Author: H Hartley Sweeten Updated: Wed, 12 Sep 2012 11:52:01 -0700 Status: untested @@ -52,9 +57,17 @@ Configuration Options: not applicable, uses PCI auto config #define PCI_DEVICE_ID_ADLINK_PCI7248 0x7248 #define PCI_DEVICE_ID_ADLINK_PCI7296 0x7296 +/* ComputerBoards is now known as Measurement Computing */ +#define PCI_VENDOR_ID_CB 0x1307 + +#define PCI_DEVICE_ID_CB_PCIDIO48H 0x000b +#define PCI_DEVICE_ID_CB_PCIDIO24H 0x0014 +#define PCI_DEVICE_ID_CB_PCIDIO24 0x0028 + struct pci_8255_boardinfo { const char *name; unsigned short device; + int dio_badr; int n_8255; }; @@ -62,15 +75,33 @@ static const struct pci_8255_boardinfo pci_8255_boards[] = { { .name = "adl_pci-7224", .device = PCI_DEVICE_ID_ADLINK_PCI7224, + .dio_badr = 2, .n_8255 = 1, }, { .name = "adl_pci-7248", .device = PCI_DEVICE_ID_ADLINK_PCI7248, + .dio_badr = 2, .n_8255 = 2, }, { .name = "adl_pci-7296", .device = PCI_DEVICE_ID_ADLINK_PCI7296, + .dio_badr = 2, .n_8255 = 4, + }, { + .name = "cb_pci-dio24", + .device = PCI_DEVICE_ID_CB_PCIDIO24, + .dio_badr = 2, + .n_8255 = 1, + }, { + .name = "cb_pci-dio24h", + .device = PCI_DEVICE_ID_CB_PCIDIO24H, + .dio_badr = 2, + .n_8255 = 1, + }, { + .name = "cb_pci-dio48h", + .device = PCI_DEVICE_ID_CB_PCIDIO48H, + .dio_badr = 1, + .n_8255 = 2, }, }; @@ -107,7 +138,7 @@ static int pci_8255_attach_pci(struct comedi_device *dev, ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) return ret; - dev->iobase = pci_resource_start(pcidev, 2); + dev->iobase = pci_resource_start(pcidev, board->dio_badr); /* * One, two, or four subdevices are setup by this driver depending @@ -172,6 +203,9 @@ static DEFINE_PCI_DEVICE_TABLE(pci_8255_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_ADLINK_PCI7224) }, { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_ADLINK_PCI7248) }, { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_ADLINK_PCI7296) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_CB_PCIDIO24) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_CB_PCIDIO24H) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_CB_PCIDIO48H) }, { 0 } }; MODULE_DEVICE_TABLE(pci, pci_8255_pci_table); diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile index 7798cdc..a2787c0 100644 --- a/drivers/staging/comedi/drivers/Makefile +++ b/drivers/staging/comedi/drivers/Makefile @@ -95,7 +95,6 @@ obj-$(CONFIG_COMEDI_KE_COUNTER) += ke_counter.o obj-$(CONFIG_COMEDI_CB_PCIDAS64) += cb_pcidas64.o obj-$(CONFIG_COMEDI_CB_PCIDAS) += cb_pcidas.o obj-$(CONFIG_COMEDI_CB_PCIDDA) += cb_pcidda.o -obj-$(CONFIG_COMEDI_CB_PCIDIO) += cb_pcidio.o obj-$(CONFIG_COMEDI_CB_PCIMDAS) += cb_pcimdas.o obj-$(CONFIG_COMEDI_CB_PCIMDDA) += cb_pcimdda.o obj-$(CONFIG_COMEDI_ME4000) += me4000.o diff --git a/drivers/staging/comedi/drivers/cb_pcidio.c b/drivers/staging/comedi/drivers/cb_pcidio.c deleted file mode 100644 index 9f406ef..0000000 --- a/drivers/staging/comedi/drivers/cb_pcidio.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - comedi/drivers/cb_pcidio.c - A Comedi driver for PCI-DIO24H & PCI-DIO48H of ComputerBoards (currently MeasurementComputing) - - COMEDI - Linux Control and Measurement Device Interface - Copyright (C) 2000 David A. Schleef - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ -/* -Driver: cb_pcidio -Description: ComputerBoards' DIO boards with PCI interface -Devices: [Measurement Computing] PCI-DIO24 (cb_pcidio), PCI-DIO24H, PCI-DIO48H -Author: Yoshiya Matsuzaka -Updated: Mon, 29 Oct 2007 15:40:47 +0000 -Status: experimental - -This driver has been modified from skel.c of comedi-0.7.70. - -Configuration Options: not applicable, uses PCI auto config -*/ - -/*------------------------------ HEADER FILES ---------------------------------*/ -#include "../comedidev.h" -#include "8255.h" - -/*-------------------------- MACROS and DATATYPES -----------------------------*/ -#define PCI_VENDOR_ID_CB 0x1307 - -/* - * Board descriptions for two imaginary boards. Describing the - * boards in this way is optional, and completely driver-dependent. - * Some drivers use arrays such as this, other do not. - */ -struct pcidio_board { - const char *name; /* name of the board */ - int dev_id; - int n_8255; /* number of 8255 chips on board */ - - /* indices of base address regions */ - int pcicontroler_badrindex; - int dioregs_badrindex; -}; - -static const struct pcidio_board pcidio_boards[] = { - { - .name = "pci-dio24", - .dev_id = 0x0028, - .n_8255 = 1, - .pcicontroler_badrindex = 1, - .dioregs_badrindex = 2, - }, - { - .name = "pci-dio24h", - .dev_id = 0x0014, - .n_8255 = 1, - .pcicontroler_badrindex = 1, - .dioregs_badrindex = 2, - }, - { - .name = "pci-dio48h", - .dev_id = 0x000b, - .n_8255 = 2, - .pcicontroler_badrindex = 0, - .dioregs_badrindex = 1, - }, -}; - -static const void *pcidio_find_boardinfo(struct comedi_device *dev, - struct pci_dev *pcidev) -{ - const struct pcidio_board *board; - int i; - - for (i = 0; i < ARRAY_SIZE(pcidio_boards); i++) { - board = &pcidio_boards[i]; - if (board->dev_id == pcidev->device) - return board; - } - return NULL; -} - -static int pcidio_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) -{ - const struct pcidio_board *board; - struct comedi_subdevice *s; - int i; - int ret; - - comedi_set_hw_dev(dev, &pcidev->dev); - - board = pcidio_find_boardinfo(dev, pcidev); - if (!board) - return -ENODEV; - dev->board_ptr = board; - dev->board_name = board->name; - - ret = comedi_pci_enable(pcidev, dev->board_name); - if (ret) - return ret; - dev->iobase = pci_resource_start(pcidev, board->dioregs_badrindex); - - ret = comedi_alloc_subdevices(dev, board->n_8255); - if (ret) - return ret; - - for (i = 0; i < board->n_8255; i++) { - s = &dev->subdevices[i]; - ret = subdev_8255_init(dev, s, NULL, dev->iobase + i * 4); - if (ret) - return ret; - } - - dev_info(dev->class_dev, "%s attached (%d digital i/o channels)\n", - dev->board_name, board->n_8255 * 24); - - return 0; -} - -static void pcidio_detach(struct comedi_device *dev) -{ - const struct pcidio_board *board = comedi_board(dev); - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - struct comedi_subdevice *s; - int i; - - if (dev->subdevices) { - for (i = 0; i < board->n_8255; i++) { - s = &dev->subdevices[i]; - subdev_8255_cleanup(dev, s); - } - } - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - } -} - -static struct comedi_driver cb_pcidio_driver = { - .driver_name = "cb_pcidio", - .module = THIS_MODULE, - .attach_pci = pcidio_attach_pci, - .detach = pcidio_detach, -}; - -static int __devinit cb_pcidio_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) -{ - return comedi_pci_auto_config(dev, &cb_pcidio_driver); -} - -static void __devexit cb_pcidio_pci_remove(struct pci_dev *dev) -{ - comedi_pci_auto_unconfig(dev); -} - -static DEFINE_PCI_DEVICE_TABLE(cb_pcidio_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0028) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0014) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x000b) }, - { 0 } -}; -MODULE_DEVICE_TABLE(pci, cb_pcidio_pci_table); - -static struct pci_driver cb_pcidio_pci_driver = { - .name = "cb_pcidio", - .id_table = cb_pcidio_pci_table, - .probe = cb_pcidio_pci_probe, - .remove = __devexit_p(cb_pcidio_pci_remove), -}; -module_comedi_pci_driver(cb_pcidio_driver, cb_pcidio_pci_driver); - -MODULE_AUTHOR("Comedi http://www.comedi.org"); -MODULE_DESCRIPTION("Comedi low-level driver"); -MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 606b04707e39cfc109273e8047c2b5600e407327 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 12 Sep 2012 15:39:48 -0700 Subject: staging: comedi: 8255_pci: add support for the PCI-DIO96H board Add support for the Measurement Computing PCI-DIO96H board to the generic 8255_pci driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 1bd7e93..3f67b98 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -558,7 +558,8 @@ config COMEDI_8255_PCI Supported boards: ADlink - PCI-7224, PCI-7248, and PCI-7296 - Measurement Computing - PCI-DIO24, PCI-DIO24H and PCI-DIO48H + Measurement Computing - PCI-DIO24, PCI-DIO24H, PCI-DIO48H and + PCI-DIO96H To compile this driver as a module, choose M here: the module will be called 8255_pci. diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c index e011b0a..075f98b 100644 --- a/drivers/staging/comedi/drivers/8255_pci.c +++ b/drivers/staging/comedi/drivers/8255_pci.c @@ -34,6 +34,7 @@ Devices: (ADLink) PCI-7224 [adl_pci-7224] - 24 channels (Measurement Computing) PCI-DIO24 [cb_pci-dio24] - 24 channels (Measurement Computing) PCI-DIO24H [cb_pci-dio24h] - 24 channels (Measurement Computing) PCI-DIO48H [cb_pci-dio48h] - 48 channels + (Measurement Computing) PCI-DIO96H [cb_pci-dio96h] - 96 channels Author: H Hartley Sweeten Updated: Wed, 12 Sep 2012 11:52:01 -0700 Status: untested @@ -62,6 +63,7 @@ Configuration Options: not applicable, uses PCI auto config #define PCI_DEVICE_ID_CB_PCIDIO48H 0x000b #define PCI_DEVICE_ID_CB_PCIDIO24H 0x0014 +#define PCI_DEVICE_ID_CB_PCIDIO96H 0x0017 #define PCI_DEVICE_ID_CB_PCIDIO24 0x0028 struct pci_8255_boardinfo { @@ -102,6 +104,11 @@ static const struct pci_8255_boardinfo pci_8255_boards[] = { .device = PCI_DEVICE_ID_CB_PCIDIO48H, .dio_badr = 1, .n_8255 = 2, + }, { + .name = "cb_pci-dio96h", + .device = PCI_DEVICE_ID_CB_PCIDIO96H, + .dio_badr = 2, + .n_8255 = 4, }, }; @@ -206,6 +213,7 @@ static DEFINE_PCI_DEVICE_TABLE(pci_8255_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_CB_PCIDIO24) }, { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_CB_PCIDIO24H) }, { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_CB_PCIDIO48H) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_CB_PCIDIO96H) }, { 0 } }; MODULE_DEVICE_TABLE(pci, pci_8255_pci_table); -- cgit v0.10.2 From 6b79db383f77da171c9a60b607d761a357f36d2d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 13 Sep 2012 09:57:12 -0700 Subject: staging: comedi: 8255_pci: add vendor id to boardinfo This driver supports PCI boards from multiple vendors. It's possible for boards from different vendors to have the same device id. Add the vendor id to the boardinfo so pci_8255_find_boardinfo() matches the pci_dev to the correct boardinfo. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c index 075f98b..314b21b 100644 --- a/drivers/staging/comedi/drivers/8255_pci.c +++ b/drivers/staging/comedi/drivers/8255_pci.c @@ -68,6 +68,7 @@ Configuration Options: not applicable, uses PCI auto config struct pci_8255_boardinfo { const char *name; + unsigned short vendor; unsigned short device; int dio_badr; int n_8255; @@ -76,36 +77,43 @@ struct pci_8255_boardinfo { static const struct pci_8255_boardinfo pci_8255_boards[] = { { .name = "adl_pci-7224", + .vendor = PCI_VENDOR_ID_ADLINK, .device = PCI_DEVICE_ID_ADLINK_PCI7224, .dio_badr = 2, .n_8255 = 1, }, { .name = "adl_pci-7248", + .vendor = PCI_VENDOR_ID_ADLINK, .device = PCI_DEVICE_ID_ADLINK_PCI7248, .dio_badr = 2, .n_8255 = 2, }, { .name = "adl_pci-7296", + .vendor = PCI_VENDOR_ID_ADLINK, .device = PCI_DEVICE_ID_ADLINK_PCI7296, .dio_badr = 2, .n_8255 = 4, }, { .name = "cb_pci-dio24", + .vendor = PCI_VENDOR_ID_CB, .device = PCI_DEVICE_ID_CB_PCIDIO24, .dio_badr = 2, .n_8255 = 1, }, { .name = "cb_pci-dio24h", + .vendor = PCI_VENDOR_ID_CB, .device = PCI_DEVICE_ID_CB_PCIDIO24H, .dio_badr = 2, .n_8255 = 1, }, { .name = "cb_pci-dio48h", + .vendor = PCI_VENDOR_ID_CB, .device = PCI_DEVICE_ID_CB_PCIDIO48H, .dio_badr = 1, .n_8255 = 2, }, { .name = "cb_pci-dio96h", + .vendor = PCI_VENDOR_ID_CB, .device = PCI_DEVICE_ID_CB_PCIDIO96H, .dio_badr = 2, .n_8255 = 4, @@ -120,7 +128,8 @@ static const void *pci_8255_find_boardinfo(struct comedi_device *dev, for (i = 0; i < ARRAY_SIZE(pci_8255_boards); i++) { board = &pci_8255_boards[i]; - if (pcidev->device == board->device) + if (pcidev->vendor == board->vendor && + pcidev->device == board->device) return board; } return NULL; -- cgit v0.10.2 From 77f17d3714675d1966d07f7e4939816f5cf52e04 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 13 Sep 2012 10:23:40 -0700 Subject: staging: comedi: 8255_pci: support memory mapped i/o boards Some of the PCI based 8255 boards that can be supported by this driver use memory mapped i/o. Add the code needed to support these boards. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c index 314b21b..93990fa 100644 --- a/drivers/staging/comedi/drivers/8255_pci.c +++ b/drivers/staging/comedi/drivers/8255_pci.c @@ -71,6 +71,7 @@ struct pci_8255_boardinfo { unsigned short vendor; unsigned short device; int dio_badr; + int is_mmio; int n_8255; }; @@ -120,6 +121,22 @@ static const struct pci_8255_boardinfo pci_8255_boards[] = { }, }; +struct pci_8255_private { + void __iomem *mmio_base; +}; + +static int pci_8255_mmio(int dir, int port, int data, unsigned long iobase) +{ + void __iomem *mmio_base = (void __iomem *)iobase; + + if (dir) { + writeb(data, mmio_base + port); + return 0; + } else { + return readb(mmio_base + port); + } +} + static const void *pci_8255_find_boardinfo(struct comedi_device *dev, struct pci_dev *pcidev) { @@ -139,7 +156,10 @@ static int pci_8255_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) { const struct pci_8255_boardinfo *board; + struct pci_8255_private *devpriv; struct comedi_subdevice *s; + resource_size_t iobase; + unsigned long len; int ret; int i; @@ -151,10 +171,23 @@ static int pci_8255_attach_pci(struct comedi_device *dev, dev->board_ptr = board; dev->board_name = board->name; + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret < 0) + return ret; + devpriv = dev->private; + ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) return ret; - dev->iobase = pci_resource_start(pcidev, board->dio_badr); + iobase = pci_resource_start(pcidev, board->dio_badr); + len = pci_resource_len(pcidev, board->dio_badr); + + if (board->is_mmio) { + devpriv->mmio_base = ioremap(iobase, len); + if (!devpriv->mmio_base) + return -ENOMEM; + } + dev->iobase = iobase; /* * One, two, or four subdevices are setup by this driver depending @@ -167,7 +200,13 @@ static int pci_8255_attach_pci(struct comedi_device *dev, for (i = 0; i < board->n_8255; i++) { s = &dev->subdevices[i]; - ret = subdev_8255_init(dev, s, NULL, dev->iobase + (i * 4)); + if (board->is_mmio) { + iobase = (unsigned long)(devpriv->mmio_base + (i * 4)); + ret = subdev_8255_init(dev, s, pci_8255_mmio, iobase); + } else { + iobase = dev->iobase + (i * 4); + ret = subdev_8255_init(dev, s, NULL, iobase); + } if (ret) return ret; } @@ -182,6 +221,7 @@ static void pci_8255_detach(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct pci_8255_boardinfo *board = comedi_board(dev); + struct pci_8255_private *devpriv = dev->private; struct comedi_subdevice *s; int i; @@ -192,6 +232,8 @@ static void pci_8255_detach(struct comedi_device *dev) } } if (pcidev) { + if (devpriv->mmio_base) + iounmap(devpriv->mmio_base); if (dev->iobase) comedi_pci_disable(pcidev); } -- cgit v0.10.2 From b37c1aeed89062a82da9bf78c83db0328d08e95d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 13 Sep 2012 10:24:00 -0700 Subject: staging: comedi: 8255_pci: move ni_pcidio 8255 board support The 8255 based boards in the ni_pcidio driver are all simple memory mapped 8255 boards that don't require the dma support provided by the mite driver. Move the support for these boards from the ni_pcidio driver to the generic 8255_pci driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 3f67b98..2093403 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -560,6 +560,8 @@ config COMEDI_8255_PCI ADlink - PCI-7224, PCI-7248, and PCI-7296 Measurement Computing - PCI-DIO24, PCI-DIO24H, PCI-DIO48H and PCI-DIO96H + National Instruments - PCI-DIO-96, PCI-DIO-96B, PXI-6508, PCI-6503, + PCI-6503B, PCI-6503X, and PXI-6503 To compile this driver as a module, choose M here: the module will be called 8255_pci. @@ -1030,15 +1032,12 @@ config COMEDI_NI_LABPC called ni_labpc. config COMEDI_NI_PCIDIO - tristate "NI PCI-DIO32HS, PCI-DIO96, PCI-6533, PCI-6503 support" + tristate "NI PCI-DIO32HS, PCI-6533, PCI-6534 support" select COMEDI_MITE select COMEDI_8255 ---help--- Enable support for National Instruments PCI-DIO-32HS, PXI-6533, - PCI-DIO-96, PCI-DIO-96B, PXI-6508, PCI-6503, PCI-6503B, PCI-6503X, - PXI-6503, PCI-6533 and PCI-6534 - The DIO-96 appears as four 8255 subdevices. See the 8255 - driver notes for details. + PCI-6533 and PCI-6534 To compile this driver as a module, choose M here: the module will be called ni_pcidio. diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c index 93990fa..7dff3c0 100644 --- a/drivers/staging/comedi/drivers/8255_pci.c +++ b/drivers/staging/comedi/drivers/8255_pci.c @@ -35,6 +35,13 @@ Devices: (ADLink) PCI-7224 [adl_pci-7224] - 24 channels (Measurement Computing) PCI-DIO24H [cb_pci-dio24h] - 24 channels (Measurement Computing) PCI-DIO48H [cb_pci-dio48h] - 48 channels (Measurement Computing) PCI-DIO96H [cb_pci-dio96h] - 96 channels + (National Instruments) PCI-DIO-96 [ni_pci-dio-96] - 96 channels + (National Instruments) PCI-DIO-96B [ni_pci-dio-96b] - 96 channels + (National Instruments) PXI-6508 [ni_pxi-6508] - 96 channels + (National Instruments) PCI-6503 [ni_pci-6503] - 24 channels + (National Instruments) PCI-6503B [ni_pci-6503b] - 24 channels + (National Instruments) PCI-6503X [ni_pci-6503x] - 24 channels + (National Instruments) PXI-6503 [ni_pxi-6503] - 24 channels Author: H Hartley Sweeten Updated: Wed, 12 Sep 2012 11:52:01 -0700 Status: untested @@ -66,6 +73,14 @@ Configuration Options: not applicable, uses PCI auto config #define PCI_DEVICE_ID_CB_PCIDIO96H 0x0017 #define PCI_DEVICE_ID_CB_PCIDIO24 0x0028 +#define PCI_DEVICE_ID_NI_PCIDIO96 0x0160 +#define PCI_DEVICE_ID_NI_PCI6503 0x0400 +#define PCI_DEVICE_ID_NI_PCI6503B 0x1250 +#define PCI_DEVICE_ID_NI_PXI6508 0x13c0 +#define PCI_DEVICE_ID_NI_PCIDIO96B 0x1630 +#define PCI_DEVICE_ID_NI_PCI6503X 0x17d0 +#define PCI_DEVICE_ID_NI_PXI_6503 0x1800 + struct pci_8255_boardinfo { const char *name; unsigned short vendor; @@ -118,6 +133,55 @@ static const struct pci_8255_boardinfo pci_8255_boards[] = { .device = PCI_DEVICE_ID_CB_PCIDIO96H, .dio_badr = 2, .n_8255 = 4, + }, { + .name = "ni_pci-dio-96", + .vendor = PCI_VENDOR_ID_NI, + .device = PCI_DEVICE_ID_NI_PCIDIO96, + .dio_badr = 1, + .is_mmio = 1, + .n_8255 = 4, + }, { + .name = "ni_pci-dio-96b", + .vendor = PCI_VENDOR_ID_NI, + .device = PCI_DEVICE_ID_NI_PCIDIO96B, + .dio_badr = 1, + .is_mmio = 1, + .n_8255 = 4, + }, { + .name = "ni_pxi-6508", + .vendor = PCI_VENDOR_ID_NI, + .device = PCI_DEVICE_ID_NI_PXI6508, + .dio_badr = 1, + .is_mmio = 1, + .n_8255 = 4, + }, { + .name = "ni_pci-6503", + .vendor = PCI_VENDOR_ID_NI, + .device = PCI_DEVICE_ID_NI_PCI6503, + .dio_badr = 1, + .is_mmio = 1, + .n_8255 = 1, + }, { + .name = "ni_pci-6503b", + .vendor = PCI_VENDOR_ID_NI, + .device = PCI_DEVICE_ID_NI_PCI6503B, + .dio_badr = 1, + .is_mmio = 1, + .n_8255 = 1, + }, { + .name = "ni_pci-6503x", + .vendor = PCI_VENDOR_ID_NI, + .device = PCI_DEVICE_ID_NI_PCI6503X, + .dio_badr = 1, + .is_mmio = 1, + .n_8255 = 1, + }, { + .name = "ni_pxi-6503", + .vendor = PCI_VENDOR_ID_NI, + .device = PCI_DEVICE_ID_NI_PXI_6503, + .dio_badr = 1, + .is_mmio = 1, + .n_8255 = 1, }, }; @@ -265,6 +329,13 @@ static DEFINE_PCI_DEVICE_TABLE(pci_8255_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_CB_PCIDIO24H) }, { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_CB_PCIDIO48H) }, { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_CB_PCIDIO96H) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCIDIO96) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCIDIO96B) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI6508) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI6503) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI6503B) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI6503X) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI_6503) }, { 0 } }; MODULE_DEVICE_TABLE(pci, pci_8255_pci_table); diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index a83f525..0f86506 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -1,8 +1,6 @@ /* comedi/drivers/ni_pcidio.c - driver for National Instruments PCI-DIO-96/PCI-6508 - National Instruments PCI-DIO-32HS - National Instruments PCI-6503 + driver for National Instruments PCI-DIO-32HS COMEDI - Linux Control and Measurement Device Interface Copyright (C) 1999,2002 David A. Schleef @@ -24,17 +22,14 @@ */ /* Driver: ni_pcidio -Description: National Instruments PCI-DIO32HS, PCI-DIO96, PCI-6533, PCI-6503 +Description: National Instruments PCI-DIO32HS, PCI-6533 Author: ds Status: works -Devices: [National Instruments] PCI-DIO-32HS (ni_pcidio), PXI-6533, - PCI-DIO-96, PCI-DIO-96B, PXI-6508, PCI-6503, PCI-6503B, PCI-6503X, - PXI-6503, PCI-6533, PCI-6534 +Devices: [National Instruments] PCI-DIO-32HS (ni_pcidio) + [National Instruments] PXI-6533, PCI-6533 (pxi-6533) + [National Instruments] PCI-6534 (pci-6534) Updated: Mon, 09 Jan 2012 14:27:23 +0000 -The DIO-96 appears as four 8255 subdevices. See the 8255 -driver notes for details. - The DIO32HS board appears as one subdevice, with 32 channels. Each channel is individually I/O configurable. The channel order is 0=A0, 1=A1, 2=A2, ... 8=B0, 16=C0, 24=D0. The driver only @@ -56,20 +51,6 @@ it are contained in the comedi_nonfree_firmware tarball available from http://www.comedi.org */ -/* - This driver is for both the NI PCI-DIO-32HS and the PCI-DIO-96, - which have very different architectures. But, since the '96 is - so simple, it is included here. - - Manuals (available from ftp://ftp.natinst.com/support/manuals) - - 320938c.pdf PCI-DIO-96/PXI-6508/PCI-6503 User Manual - 321464b.pdf AT/PCI-DIO-32HS User Manual - 341329A.pdf PCI-6533 Register-Level Programmer Manual - 341330A.pdf DAQ-DIO Technical Reference Manual - - */ - #define USE_DMA /* #define DEBUG 1 */ /* #define DEBUG_FLAGS */ @@ -79,7 +60,6 @@ comedi_nonfree_firmware tarball available from http://www.comedi.org #include "../comedidev.h" #include "mite.h" -#include "8255.h" #undef DPRINTK #ifdef DEBUG @@ -91,14 +71,6 @@ comedi_nonfree_firmware tarball available from http://www.comedi.org #define PCI_DIO_SIZE 4096 #define PCI_MITE_SIZE 4096 -/* defines for the PCI-DIO-96 */ - -#define NIDIO_8255_BASE(x) ((x)*4) -#define NIDIO_A 0 -#define NIDIO_B 4 -#define NIDIO_C 8 -#define NIDIO_D 12 - /* defines for the PCI-DIO-32HS */ #define Window_Address 4 /* W */ @@ -297,76 +269,23 @@ static int ni_pcidio_cancel(struct comedi_device *dev, struct comedi_subdevice *s); struct nidio_board { - int dev_id; const char *name; - int n_8255; - unsigned int is_diodaq:1; unsigned int uses_firmware:1; }; static const struct nidio_board nidio_boards[] = { { - .dev_id = 0x1150, - .name = "pci-dio-32hs", - .n_8255 = 0, - .is_diodaq = 1, - }, - { - .dev_id = 0x1320, - .name = "pxi-6533", - .n_8255 = 0, - .is_diodaq = 1, - }, - { - .dev_id = 0x12b0, - .name = "pci-6534", - .n_8255 = 0, - .is_diodaq = 1, - .uses_firmware = 1, - }, - { - .dev_id = 0x0160, - .name = "pci-dio-96", - .n_8255 = 4, - .is_diodaq = 0, - }, - { - .dev_id = 0x1630, - .name = "pci-dio-96b", - .n_8255 = 4, - .is_diodaq = 0, - }, - { - .dev_id = 0x13c0, - .name = "pxi-6508", - .n_8255 = 4, - .is_diodaq = 0, - }, - { - .dev_id = 0x0400, - .name = "pci-6503", - .n_8255 = 1, - .is_diodaq = 0, - }, - { - .dev_id = 0x1250, - .name = "pci-6503b", - .n_8255 = 1, - .is_diodaq = 0, - }, - { - .dev_id = 0x17d0, - .name = "pci-6503x", - .n_8255 = 1, - .is_diodaq = 0, - }, - { - .dev_id = 0x1800, - .name = "pxi-6503", - .n_8255 = 1, - .is_diodaq = 0, - }, + .dev_id = 0x1150, + .name = "pci-dio-32hs", + }, { + .dev_id = 0x1320, + .name = "pxi-6533", + }, { + .dev_id = 0x12b0, + .name = "pci-6534", + .uses_firmware = 1, + }, }; #define n_nidio_boards ARRAY_SIZE(nidio_boards) @@ -442,16 +361,6 @@ static void ni_pcidio_release_di_mite_channel(struct comedi_device *dev) spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); } -static int nidio96_8255_cb(int dir, int port, int data, unsigned long iobase) -{ - if (dir) { - writeb(data, (void *)(iobase + port)); - return 0; - } else { - return readb((void *)(iobase + port)); - } -} - void ni_pcidio_event(struct comedi_device *dev, struct comedi_subdevice *s) { if (s-> @@ -1207,9 +1116,7 @@ static int nidio_find_device(struct comedi_device *dev, int bus, int slot) static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct comedi_subdevice *s; - int i; int ret; - int n_subdevices; unsigned int irq; printk(KERN_INFO "comedi%d: nidio:", dev->minor); @@ -1241,64 +1148,49 @@ static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret < 0) return ret; } - if (!this_board->is_diodaq) - n_subdevices = this_board->n_8255; - else - n_subdevices = 1; - ret = comedi_alloc_subdevices(dev, n_subdevices); + ret = comedi_alloc_subdevices(dev, 1); if (ret) return ret; - if (!this_board->is_diodaq) { - for (i = 0; i < this_board->n_8255; i++) { - s = &dev->subdevices[i]; - subdev_8255_init(dev, s, nidio96_8255_cb, - (unsigned long)(devpriv->mite-> - daq_io_addr + - NIDIO_8255_BASE(i))); - } - } else { - - printk(KERN_INFO " rev=%d", - readb(devpriv->mite->daq_io_addr + Chip_Version)); - - s = &dev->subdevices[0]; - - dev->read_subdev = s; - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = - SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | SDF_PACKED | - SDF_CMD_READ; - s->n_chan = 32; - s->range_table = &range_digital; - s->maxdata = 1; - s->insn_config = &ni_pcidio_insn_config; - s->insn_bits = &ni_pcidio_insn_bits; - s->do_cmd = &ni_pcidio_cmd; - s->do_cmdtest = &ni_pcidio_cmdtest; - s->cancel = &ni_pcidio_cancel; - s->len_chanlist = 32; /* XXX */ - s->buf_change = &ni_pcidio_change; - s->async_dma_dir = DMA_BIDIRECTIONAL; - s->poll = &ni_pcidio_poll; - - writel(0, devpriv->mite->daq_io_addr + Port_IO(0)); - writel(0, devpriv->mite->daq_io_addr + Port_Pin_Directions(0)); - writel(0, devpriv->mite->daq_io_addr + Port_Pin_Mask(0)); - - /* disable interrupts on board */ - writeb(0x00, - devpriv->mite->daq_io_addr + - Master_DMA_And_Interrupt_Control); + printk(KERN_INFO " rev=%d", + readb(devpriv->mite->daq_io_addr + Chip_Version)); + + s = &dev->subdevices[0]; + + dev->read_subdev = s; + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = + SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | SDF_PACKED | + SDF_CMD_READ; + s->n_chan = 32; + s->range_table = &range_digital; + s->maxdata = 1; + s->insn_config = &ni_pcidio_insn_config; + s->insn_bits = &ni_pcidio_insn_bits; + s->do_cmd = &ni_pcidio_cmd; + s->do_cmdtest = &ni_pcidio_cmdtest; + s->cancel = &ni_pcidio_cancel; + s->len_chanlist = 32; /* XXX */ + s->buf_change = &ni_pcidio_change; + s->async_dma_dir = DMA_BIDIRECTIONAL; + s->poll = &ni_pcidio_poll; + + writel(0, devpriv->mite->daq_io_addr + Port_IO(0)); + writel(0, devpriv->mite->daq_io_addr + Port_Pin_Directions(0)); + writel(0, devpriv->mite->daq_io_addr + Port_Pin_Mask(0)); + + /* disable interrupts on board */ + writeb(0x00, + devpriv->mite->daq_io_addr + + Master_DMA_And_Interrupt_Control); - ret = request_irq(irq, nidio_interrupt, IRQF_SHARED, - "ni_pcidio", dev); - if (ret < 0) - printk(KERN_WARNING " irq not available"); + ret = request_irq(irq, nidio_interrupt, IRQF_SHARED, + "ni_pcidio", dev); + if (ret < 0) + printk(KERN_WARNING " irq not available"); - dev->irq = irq; - } + dev->irq = irq; printk("\n"); @@ -1307,15 +1199,6 @@ static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void nidio_detach(struct comedi_device *dev) { - struct comedi_subdevice *s; - int i; - - if (this_board && !this_board->is_diodaq) { - for (i = 0; i < this_board->n_8255; i++) { - s = &dev->subdevices[i]; - subdev_8255_cleanup(dev, s); - } - } if (dev->irq) free_irq(dev->irq, dev); if (devpriv) { @@ -1350,13 +1233,6 @@ static DEFINE_PCI_DEVICE_TABLE(ni_pcidio_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1150) }, { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1320) }, { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x12b0) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x0160) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1630) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x13c0) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x0400) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1250) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x17d0) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1800) }, { 0 } }; MODULE_DEVICE_TABLE(pci, ni_pcidio_pci_table); -- cgit v0.10.2 From 129575f2a8958a1e90780b0d5b80702bb45b5aac Mon Sep 17 00:00:00 2001 From: Ben Chan Date: Wed, 12 Sep 2012 11:43:41 -0700 Subject: staging: gdm72xx: simplify alloc_tx_struct and alloc_rx_struct This patch simplifies alloc_tx_struct and alloc_rx_struct in gdm_sdio.c and gdm_usb.c by replacing kmalloc+memset with kzalloc and reorganizing the code. Signed-off-by: Ben Chan Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/gdm72xx/gdm_sdio.c b/drivers/staging/gdm72xx/gdm_sdio.c index a0621d9..ca38d71 100644 --- a/drivers/staging/gdm72xx/gdm_sdio.c +++ b/drivers/staging/gdm72xx/gdm_sdio.c @@ -60,25 +60,20 @@ static void hexdump(char *title, u8 *data, int len) static struct sdio_tx *alloc_tx_struct(struct tx_cxt *tx) { - struct sdio_tx *t = NULL; + struct sdio_tx *t = kzalloc(sizeof(*t), GFP_ATOMIC); - t = kzalloc(sizeof(*t), GFP_ATOMIC); - if (t == NULL) - goto out; + if (!t) + return NULL; t->buf = kmalloc(TX_BUF_SIZE, GFP_ATOMIC); - if (t->buf == NULL) - goto out; + if (!t->buf) { + kfree(t); + return NULL; + } t->tx_cxt = tx; return t; -out: - if (t) { - kfree(t->buf); - kfree(t); - } - return NULL; } static void free_tx_struct(struct sdio_tx *t) @@ -91,15 +86,10 @@ static void free_tx_struct(struct sdio_tx *t) static struct sdio_rx *alloc_rx_struct(struct rx_cxt *rx) { - struct sdio_rx *r = NULL; - - r = kmalloc(sizeof(*r), GFP_ATOMIC); - if (!r) - return NULL; - - memset(r, 0, sizeof(*r)); + struct sdio_rx *r = kzalloc(sizeof(*r), GFP_ATOMIC); - r->rx_cxt = rx; + if (r) + r->rx_cxt = rx; return r; } diff --git a/drivers/staging/gdm72xx/gdm_usb.c b/drivers/staging/gdm72xx/gdm_usb.c index 6d306f7..0c9e895 100644 --- a/drivers/staging/gdm72xx/gdm_usb.c +++ b/drivers/staging/gdm72xx/gdm_usb.c @@ -73,27 +73,23 @@ static void hexdump(char *title, u8 *data, int len) static struct usb_tx *alloc_tx_struct(struct tx_cxt *tx) { - struct usb_tx *t = NULL; + struct usb_tx *t = kzalloc(sizeof(*t), GFP_ATOMIC); - t = kzalloc(sizeof(*t), GFP_ATOMIC); - if (t == NULL) - goto out; + if (!t) + return NULL; t->urb = usb_alloc_urb(0, GFP_ATOMIC); t->buf = kmalloc(TX_BUF_SIZE, GFP_ATOMIC); - if (t->urb == NULL || t->buf == NULL) - goto out; - - t->tx_cxt = tx; - - return t; -out: - if (t) { + if (!t->urb || !t->buf) { usb_free_urb(t->urb); kfree(t->buf); kfree(t); + return NULL; } - return NULL; + + t->tx_cxt = tx; + + return t; } static void free_tx_struct(struct usb_tx *t) @@ -107,28 +103,22 @@ static void free_tx_struct(struct usb_tx *t) static struct usb_rx *alloc_rx_struct(struct rx_cxt *rx) { - struct usb_rx *r = NULL; + struct usb_rx *r = kzalloc(sizeof(*r), GFP_ATOMIC); - r = kmalloc(sizeof(*r), GFP_ATOMIC); - if (r == NULL) - goto out; - - memset(r, 0, sizeof(*r)); + if (!r) + return NULL; r->urb = usb_alloc_urb(0, GFP_ATOMIC); r->buf = kmalloc(RX_BUF_SIZE, GFP_ATOMIC); - if (r->urb == NULL || r->buf == NULL) - goto out; - - r->rx_cxt = rx; - return r; -out: - if (r) { + if (!r->urb || !r->buf) { usb_free_urb(r->urb); kfree(r->buf); kfree(r); + return NULL; } - return NULL; + + r->rx_cxt = rx; + return r; } static void free_rx_struct(struct usb_rx *r) -- cgit v0.10.2 From 43bf2f4bfeb57601a9ccba382e0f378763df4b26 Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso Date: Thu, 13 Sep 2012 00:45:29 +0200 Subject: staging: keucr: remove String func prototypes Commit 1b9f644dfeb638e0146ce54f4e48c87a2841a603 already got rid of StringCopy and StringCmp, so remove the left over prototypes. Signed-off-by: Davidlohr Bueso Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/keucr/smcommon.h b/drivers/staging/keucr/smcommon.h index 278bdb8..4d57203 100644 --- a/drivers/staging/keucr/smcommon.h +++ b/drivers/staging/keucr/smcommon.h @@ -25,7 +25,5 @@ Define Difinetion #define ERR_NoSmartMedia 0x003A /* Medium Not Present */ /***************************************************************************/ -void StringCopy(char *, char *, int); -int StringCmp(char *, char *, int); #endif -- cgit v0.10.2 From 99d4b1a6cbfa8449dad5fb58e8c8044301e2667a Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Thu, 13 Sep 2012 13:08:48 -0400 Subject: staging:ccg: fix a class_destroy when kmalloc fails after the class_create we do class_create and call kmalloc to allocate dev pointer, and if kmalloc fail we forget destoying class Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ccg/ccg.c b/drivers/staging/ccg/ccg.c index 81ac6bb..565249b 100644 --- a/drivers/staging/ccg/ccg.c +++ b/drivers/staging/ccg/ccg.c @@ -1254,8 +1254,10 @@ static int __init init(void) return PTR_ERR(ccg_class); dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) + if (!dev) { + class_destroy(ccg_class); return -ENOMEM; + } dev->functions = supported_functions; INIT_LIST_HEAD(&dev->enabled_functions); -- cgit v0.10.2 From 7505817603854506732affb584ef6568a4702d6f Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Thu, 13 Sep 2012 13:09:29 -0400 Subject: staging:ccg: cleanup a bit of binding the ccg_bind_function uses ret variable and a logic around the ccg_bind_enabled_functions to return a value other than 0 if bind function fail, other wise returns 0, this can be achieved with just a return ccg_bind_enabled_functions(dev, c); Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ccg/ccg.c b/drivers/staging/ccg/ccg.c index 565249b..3fbb300 100644 --- a/drivers/staging/ccg/ccg.c +++ b/drivers/staging/ccg/ccg.c @@ -1101,13 +1101,7 @@ static struct device_attribute *ccg_usb_attributes[] = { static int ccg_bind_config(struct usb_configuration *c) { struct ccg_dev *dev = _ccg_dev; - int ret = 0; - - ret = ccg_bind_enabled_functions(dev, c); - if (ret) - return ret; - - return 0; + return ccg_bind_enabled_functions(dev, c); } static void ccg_unbind_config(struct usb_configuration *c) -- cgit v0.10.2 From e4af9497b65a8245ad7ef756d5f698e78db6e11c Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Thu, 13 Sep 2012 12:32:19 +0200 Subject: Staging: ipack: Add IPACK_INT_SPACE memory space. This will allow us to correctly access the IPack INT space. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 21b2b75..3462783 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -95,6 +95,8 @@ static void tpci200_unregister(struct tpci200_board *tpci200) tpci200->slots[i].io_phys.size = 0; tpci200->slots[i].id_phys.address = NULL; tpci200->slots[i].id_phys.size = 0; + tpci200->slots[i].int_phys.address = NULL; + tpci200->slots[i].int_phys.size = 0; tpci200->slots[i].mem_phys.address = NULL; tpci200->slots[i].mem_phys.size = 0; } @@ -331,6 +333,11 @@ static int tpci200_register(struct tpci200_board *tpci200) TPCI200_ID_SPACE_OFF + TPCI200_ID_SPACE_GAP*i; tpci200->slots[i].id_phys.size = TPCI200_ID_SPACE_SIZE; + tpci200->slots[i].int_phys.address = + (void __iomem *)ioidint_base + + TPCI200_INT_SPACE_OFF + TPCI200_INT_SPACE_GAP * i; + tpci200->slots[i].int_phys.size = TPCI200_INT_SPACE_SIZE; + tpci200->slots[i].mem_phys.address = (void __iomem *)mem_base + TPCI200_MEM8_GAP*i; tpci200->slots[i].mem_phys.size = TPCI200_MEM8_SIZE; @@ -391,6 +398,15 @@ static int tpci200_slot_unmap_space(struct ipack_device *dev, int space) } virt_addr_space = &dev->id_space; break; + case IPACK_INT_SPACE: + if (dev->int_space.address == NULL) { + dev_info(&dev->dev, + "Slot [%d:%d] INT space not mapped !\n", + dev->bus_nr, dev->slot); + goto out_unlock; + } + virt_addr_space = &dev->int_space; + break; case IPACK_MEM_SPACE: if (dev->mem_space.address == NULL) { dev_info(&dev->dev, @@ -460,6 +476,19 @@ static int tpci200_slot_map_space(struct ipack_device *dev, phys_address = tpci200->slots[dev->slot].id_phys.address; size_to_map = tpci200->slots[dev->slot].id_phys.size; break; + case IPACK_INT_SPACE: + if (dev->int_space.address != NULL) { + dev_err(&dev->dev, + "Slot [%d:%d] INT space already mapped !\n", + tpci200->number, dev->slot); + res = -EINVAL; + goto out_unlock; + } + virt_addr_space = &dev->int_space; + + phys_address = tpci200->slots[dev->slot].int_phys.address; + size_to_map = tpci200->slots[dev->slot].int_phys.size; + break; case IPACK_MEM_SPACE: if (dev->mem_space.address != NULL) { dev_err(&dev->dev, diff --git a/drivers/staging/ipack/bridges/tpci200.h b/drivers/staging/ipack/bridges/tpci200.h index e1f60f3..235d1fe 100644 --- a/drivers/staging/ipack/bridges/tpci200.h +++ b/drivers/staging/ipack/bridges/tpci200.h @@ -132,6 +132,7 @@ struct slot_irq { * @irq Slot IRQ infos * @io_phys IO physical base address register of the slot * @id_phys ID physical base address register of the slot + * @int_phys INT physical base address register of the slot * @mem_phys MEM physical base address register of the slot * */ @@ -139,6 +140,7 @@ struct tpci200_slot { struct slot_irq *irq; struct ipack_addr_space io_phys; struct ipack_addr_space id_phys; + struct ipack_addr_space int_phys; struct ipack_addr_space mem_phys; }; diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h index 9c3079d..f8405df 100644 --- a/drivers/staging/ipack/ipack.h +++ b/drivers/staging/ipack/ipack.h @@ -35,6 +35,7 @@ enum ipack_space { IPACK_IO_SPACE = 0, IPACK_ID_SPACE = 1, IPACK_MEM_SPACE = 2, + IPACK_INT_SPACE, }; /** @@ -71,6 +72,7 @@ struct ipack_device { struct ipack_bus_device *bus; struct ipack_addr_space id_space; struct ipack_addr_space io_space; + struct ipack_addr_space int_space; struct ipack_addr_space mem_space; struct device dev; u8 *id; -- cgit v0.10.2 From ea991147ecd0a2ed9172b8b32211ae3d86f95b99 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Thu, 13 Sep 2012 12:32:20 +0200 Subject: Staging: ipack: move the responsibility to clear interrupts to the IPack devices. Now the IPack device acknowledges its own IRQ. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 3462783..43f2f38 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -126,10 +126,6 @@ static irqreturn_t tpci200_slot_irq(struct slot_irq *slot_irq) return -ENODEV; ret = slot_irq->handler(slot_irq->arg); - /* Clear the IPack device interrupt */ - readw(slot_irq->holder->io_space.address + 0xC0); - readw(slot_irq->holder->io_space.address + 0xC2); - return ret; } diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index 0292364..30d8d42 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -252,6 +252,10 @@ static irqreturn_t ipoctal_irq_handler(void *arg) for (i = 0; i < NR_CHANNELS; i++) ipoctal_irq_channel(&ipoctal->channel[i]); + /* Clear the IPack device interrupt */ + readw(ipoctal->dev->int_space.address + ACK_INT_REQ0); + readw(ipoctal->dev->int_space.address + ACK_INT_REQ1); + return IRQ_HANDLED; } @@ -264,7 +268,6 @@ static int ipoctal_check_model(struct ipack_device *dev, unsigned char *id) manufacturerID = ioread8(dev->id_space.address + IPACK_IDPROM_OFFSET_MANUFACTURER_ID); if (manufacturerID != IPACK1_VENDOR_ID_SBS) return -ENODEV; - board_id = ioread8(dev->id_space.address + IPACK_IDPROM_OFFSET_MODEL); switch (board_id) { case IPACK1_DEVICE_ID_SBS_OCTAL_232: @@ -322,13 +325,22 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, goto out_unregister_id_space; } + res = ipoctal->dev->bus->ops->map_space(ipoctal->dev, 0, + IPACK_INT_SPACE); + if (res) { + dev_err(&ipoctal->dev->dev, + "Unable to map slot [%d:%d] INT space!\n", + bus_nr, slot); + goto out_unregister_io_space; + } + res = ipoctal->dev->bus->ops->map_space(ipoctal->dev, 0x8000, IPACK_MEM_SPACE); if (res) { dev_err(&ipoctal->dev->dev, "Unable to map slot [%d:%d] MEM space!\n", bus_nr, slot); - goto out_unregister_io_space; + goto out_unregister_int_space; } /* Save the virtual address to access the registers easily */ @@ -450,6 +462,8 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, out_unregister_slot_unmap: ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_ID_SPACE); +out_unregister_int_space: + ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_INT_SPACE); out_unregister_io_space: ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_IO_SPACE); out_unregister_id_space: @@ -735,6 +749,7 @@ static void __ipoctal_remove(struct ipoctal *ipoctal) tty_unregister_driver(ipoctal->tty_drv); put_tty_driver(ipoctal->tty_drv); ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_MEM_SPACE); + ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_INT_SPACE); ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_IO_SPACE); ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_ID_SPACE); kfree(ipoctal); diff --git a/drivers/staging/ipack/devices/scc2698.h b/drivers/staging/ipack/devices/scc2698.h index 223838a..96e8d8c 100644 --- a/drivers/staging/ipack/devices/scc2698.h +++ b/drivers/staging/ipack/devices/scc2698.h @@ -221,4 +221,7 @@ union scc2698_block { #define ISR_DELTA_BREAK_B (0x1 << 6) #define ISR_INPUT_PORT_CHANGE (0x1 << 7) +#define ACK_INT_REQ0 0 +#define ACK_INT_REQ1 2 + #endif /* SCC2698_H_ */ -- cgit v0.10.2 From c6e2dfaa5251f584a05df74911685775dd750e2d Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Thu, 13 Sep 2012 12:32:21 +0200 Subject: staging: ipack: remove irq field in struct ipack_device. The field irq currently is identical to the slot number. It does not seem to have any real use. The number is written to hardware in ipoctal but it seems the value that is written does not matter. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 43f2f38..bb8aa70 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -190,7 +190,7 @@ static int tpci200_free_irq(struct ipack_device *dev) return 0; } -static int tpci200_request_irq(struct ipack_device *dev, int vector, +static int tpci200_request_irq(struct ipack_device *dev, irqreturn_t (*handler)(void *), void *arg) { int res = 0; @@ -227,7 +227,6 @@ static int tpci200_request_irq(struct ipack_device *dev, int vector, * Read the User Manual of your IndustryPack device to know * where to write the vector in memory. */ - slot_irq->vector = vector; slot_irq->handler = handler; slot_irq->arg = arg; slot_irq->holder = dev; @@ -715,12 +714,8 @@ static int tpci200_pci_probe(struct pci_dev *pdev, tpci200->number = tpci200->info->ipack_bus->bus_nr; dev_set_drvdata(&pdev->dev, tpci200); - /* - * Give the same IRQ number as the slot number. - * The TPCI200 has assigned his own two IRQ by PCI bus driver - */ for (i = 0; i < TPCI200_NB_SLOT; i++) - ipack_device_register(tpci200->info->ipack_bus, i, i); + ipack_device_register(tpci200->info->ipack_bus, i); return 0; out_err_bus_register: diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index 30d8d42..9fc2f7f 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -288,7 +288,7 @@ static const struct tty_port_operations ipoctal_tty_port_ops = { }; static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, - unsigned int slot, unsigned int vector) + unsigned int slot) { int res = 0; int i; @@ -387,9 +387,10 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, * Depending of the carrier these addresses are accesible or not. * More info in the datasheet. */ - ipoctal->dev->bus->ops->request_irq(ipoctal->dev, vector, + ipoctal->dev->bus->ops->request_irq(ipoctal->dev, ipoctal_irq_handler, ipoctal); - iowrite8(vector, ipoctal->dev->mem_space.address + 1); + /* Dummy write */ + iowrite8(1, ipoctal->dev->mem_space.address + 1); /* Register the TTY device */ @@ -722,7 +723,7 @@ static int ipoctal_probe(struct ipack_device *dev) return -ENOMEM; ipoctal->dev = dev; - res = ipoctal_inst_slot(ipoctal, dev->bus_nr, dev->slot, dev->irq); + res = ipoctal_inst_slot(ipoctal, dev->bus_nr, dev->slot); if (res) goto out_uninst; diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c index c83f015..d1e0651 100644 --- a/drivers/staging/ipack/ipack.c +++ b/drivers/staging/ipack/ipack.c @@ -427,7 +427,7 @@ out: } struct ipack_device *ipack_device_register(struct ipack_bus_device *bus, - int slot, int irqv) + int slot) { int ret; struct ipack_device *dev; @@ -441,7 +441,6 @@ struct ipack_device *ipack_device_register(struct ipack_bus_device *bus, dev->dev.parent = bus->parent; dev->slot = slot; dev->bus_nr = bus->bus_nr; - dev->irq = irqv; dev->bus = bus; dev_set_name(&dev->dev, "ipack-dev.%u.%u", dev->bus_nr, dev->slot); diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h index f8405df..d8e3bb6 100644 --- a/drivers/staging/ipack/ipack.h +++ b/drivers/staging/ipack/ipack.h @@ -54,7 +54,6 @@ struct ipack_addr_space { * * @bus_nr: IP bus number where the device is plugged * @slot: Slot where the device is plugged in the carrier board - * @irq: IRQ vector * @bus: ipack_bus_device where the device is plugged to. * @id_space: Virtual address to ID space. * @io_space: Virtual address to IO space. @@ -68,7 +67,6 @@ struct ipack_addr_space { struct ipack_device { unsigned int bus_nr; unsigned int slot; - unsigned int irq; struct ipack_bus_device *bus; struct ipack_addr_space id_space; struct ipack_addr_space io_space; @@ -129,7 +127,7 @@ struct ipack_driver { struct ipack_bus_ops { int (*map_space) (struct ipack_device *dev, unsigned int memory_size, int space); int (*unmap_space) (struct ipack_device *dev, int space); - int (*request_irq) (struct ipack_device *dev, int vector, + int (*request_irq) (struct ipack_device *dev, irqreturn_t (*handler)(void *), void *arg); int (*free_irq) (struct ipack_device *dev); int (*get_clockrate) (struct ipack_device *dev); @@ -187,13 +185,11 @@ void ipack_driver_unregister(struct ipack_driver *edrv); * * @bus: ipack bus device it is plugged to. * @slot: slot position in the bus device. - * @irqv: IRQ vector for the mezzanine. * * Register a new ipack device (mezzanine device). The call is done by * the carrier device driver. */ -struct ipack_device *ipack_device_register(struct ipack_bus_device *bus, - int slot, int irqv); +struct ipack_device *ipack_device_register(struct ipack_bus_device *bus, int slot); void ipack_device_unregister(struct ipack_device *dev); /** -- cgit v0.10.2 From 4514108c5b8088ab4a72ba27eb093882d76619cf Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Thu, 13 Sep 2012 12:32:22 +0200 Subject: Staging: ipack/devices/ipoctal: acknowledge BREAK condition. Clear the BREAK flag from the ISR register. Doing that, we avoid to read the same condition for the next character received. Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index 9fc2f7f..164e43c 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -158,6 +158,7 @@ static void ipoctal_irq_rx(struct ipoctal_channel *channel, flag = TTY_FRAME; } if (sr & SR_RECEIVED_BREAK) { + iowrite8(CR_CMD_RESET_BREAK_CHANGE, &channel->regs->w.cr); channel->stats.rcv_break++; flag = TTY_BREAK; } -- cgit v0.10.2 From d04600679ba08f40f5a3be597f44250b129af552 Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Thu, 13 Sep 2012 12:32:23 +0200 Subject: Staging: ipack/devices/ipoctal: simplify ipoctal_write_tty() Remove count_wr and the assigment of nb_bytes = 0 in that function as is useless. Now it returns the count of the characters actually sent. There is other nb_bytes = 0 deleted that has a duplicate a few lines before. Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index 164e43c..2cdbf28 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -33,7 +33,6 @@ static const struct tty_operations ipoctal_fops; struct ipoctal_channel { struct ipoctal_stats stats; unsigned int nb_bytes; - unsigned int count_wr; wait_queue_head_t queue; spinlock_t lock; unsigned int pointer_read; @@ -189,7 +188,6 @@ static void ipoctal_irq_tx(struct ipoctal_channel *channel) value = channel->tty_port.xmit_buf[*pointer_write]; iowrite8(value, &channel->regs->w.thr); channel->stats.tx++; - channel->count_wr++; (*pointer_write)++; *pointer_write = *pointer_write % PAGE_SIZE; channel->nb_bytes--; @@ -445,7 +443,6 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, spin_lock_init(&channel->lock); channel->pointer_read = 0; channel->pointer_write = 0; - channel->nb_bytes = 0; tty_dev = tty_register_device(tty, i, NULL); if (IS_ERR(tty_dev)) { dev_err(&ipoctal->dev->dev, "Failed to register tty device.\n"); @@ -500,11 +497,9 @@ static int ipoctal_write_tty(struct tty_struct *tty, const unsigned char *buf, int count) { struct ipoctal_channel *channel = tty->driver_data; + unsigned int char_copied; - channel->nb_bytes = 0; - channel->count_wr = 0; - - ipoctal_copy_write_buffer(channel, buf, count); + char_copied = ipoctal_copy_write_buffer(channel, buf, count); /* As the IP-OCTAL 485 only supports half duplex, do it manually */ if (channel->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) { @@ -521,7 +516,7 @@ static int ipoctal_write_tty(struct tty_struct *tty, iowrite8(CR_DISABLE_TX, &channel->regs->w.cr); *channel->board_write = 0; - return channel->count_wr; + return char_copied; } static int ipoctal_write_room(struct tty_struct *tty) -- cgit v0.10.2 From 3f45932720b7d4e1d409b3cc5cbc0bf18d67553b Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Thu, 13 Sep 2012 15:00:30 +0530 Subject: staging:wlan-ng: make wlan_unsetup void this is because this function does a deinit job and most of the deinit functions are expected to return void. Also this function doesn't fail anywhere.. Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c index 8afb193..6ca07e7 100644 --- a/drivers/staging/wlan-ng/p80211netdev.c +++ b/drivers/staging/wlan-ng/p80211netdev.c @@ -803,15 +803,13 @@ int wlan_setup(wlandevice_t *wlandev, struct device *physdev) * Arguments: * wlandev ptr to the wlandev structure for the * interface. -* Returns: -* zero on success, non-zero otherwise. * Call Context: * Should be process thread. We'll assume it might be * interrupt though. When we add support for statically * compiled drivers, this function will be called in the * context of the kernel startup code. ----------------------------------------------------------------*/ -int wlan_unsetup(wlandevice_t *wlandev) +void wlan_unsetup(wlandevice_t *wlandev) { struct wireless_dev *wdev; @@ -824,8 +822,6 @@ int wlan_unsetup(wlandevice_t *wlandev) free_netdev(wlandev->netdev); wlandev->netdev = NULL; } - - return 0; } /*---------------------------------------------------------------- diff --git a/drivers/staging/wlan-ng/p80211netdev.h b/drivers/staging/wlan-ng/p80211netdev.h index 8588417..2fecca2 100644 --- a/drivers/staging/wlan-ng/p80211netdev.h +++ b/drivers/staging/wlan-ng/p80211netdev.h @@ -235,7 +235,7 @@ int wep_encrypt(wlandevice_t *wlandev, u8 *buf, u8 *dst, u32 len, int keynum, u8 *iv, u8 *icv); int wlan_setup(wlandevice_t *wlandev, struct device *physdev); -int wlan_unsetup(wlandevice_t *wlandev); +void wlan_unsetup(wlandevice_t *wlandev); int register_wlandev(wlandevice_t *wlandev); int unregister_wlandev(wlandevice_t *wlandev); void p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb); -- cgit v0.10.2 From 675be12f45f3f90ed22949fe08ad164316f75316 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Thu, 13 Sep 2012 15:00:54 +0530 Subject: staging:wlan-ng: clean hfa384x_usbctlx_submit else is not required as such we can do with just with a single if Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c b/drivers/staging/wlan-ng/hfa384x_usb.c index bdc63a6..f180c3d 100644 --- a/drivers/staging/wlan-ng/hfa384x_usb.c +++ b/drivers/staging/wlan-ng/hfa384x_usb.c @@ -4045,23 +4045,20 @@ static void hfa384x_usb_throttlefn(unsigned long data) static int hfa384x_usbctlx_submit(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx) { unsigned long flags; - int ret; spin_lock_irqsave(&hw->ctlxq.lock, flags); if (hw->wlandev->hwremoved) { spin_unlock_irqrestore(&hw->ctlxq.lock, flags); - ret = -ENODEV; - } else { - ctlx->state = CTLX_PENDING; - list_add_tail(&ctlx->list, &hw->ctlxq.pending); - - spin_unlock_irqrestore(&hw->ctlxq.lock, flags); - hfa384x_usbctlxq_run(hw); - ret = 0; + return -ENODEV; } - return ret; + ctlx->state = CTLX_PENDING; + list_add_tail(&ctlx->list, &hw->ctlxq.pending); + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + hfa384x_usbctlxq_run(hw); + + return 0; } /*---------------------------------------------------------------- -- cgit v0.10.2 From 2b970b2d308c61983609a789785d32d01a2dec26 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Thu, 13 Sep 2012 15:01:18 +0530 Subject: staging:wlan-ng: remove all the return statements at the end of functions this file is having all unnecessary return statements at the end of functions which return void, remove all of them. some of the functions still uses the return for having the goto end, which the label end defined at the end of the function which returns void, this will be cleaned up in next change Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlan-ng/prism2sta.c b/drivers/staging/wlan-ng/prism2sta.c index 32a2f66..37f183d 100644 --- a/drivers/staging/wlan-ng/prism2sta.c +++ b/drivers/staging/wlan-ng/prism2sta.c @@ -242,7 +242,6 @@ static int prism2sta_close(wlandevice_t *wlandev) ----------------------------------------------------------------*/ static void prism2sta_reset(wlandevice_t *wlandev) { - return; } /*---------------------------------------------------------------- @@ -988,7 +987,6 @@ static void prism2sta_inf_handover(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf) { pr_debug("received infoframe:HANDOVER (unhandled)\n"); - return; } /*---------------------------------------------------------------- @@ -1035,8 +1033,6 @@ static void prism2sta_inf_tallies(wlandevice_t *wlandev, for (i = 0; i < cnt; i++, dst++, src16++) *dst += le16_to_cpu(*src16); } - - return; } /*---------------------------------------------------------------- @@ -1093,8 +1089,6 @@ static void prism2sta_inf_scanresults(wlandevice_t *wlandev, printk(KERN_ERR "setconfig(joinreq) failed, result=%d\n", result); } - - return; } /*---------------------------------------------------------------- @@ -1194,7 +1188,6 @@ static void prism2sta_inf_chinforesults(wlandevice_t *wlandev, atomic_set(&hw->channel_info.done, 2); hw->channel_info.count = n; - return; } void prism2sta_processing_defer(struct work_struct *data) @@ -1478,8 +1471,6 @@ static void prism2sta_inf_linkstatus(wlandevice_t *wlandev, hw->link_status_new = le16_to_cpu(inf->info.linkstatus.linkstatus); schedule_work(&hw->link_bh); - - return; } /*---------------------------------------------------------------- @@ -1540,8 +1531,6 @@ static void prism2sta_inf_assocstatus(wlandevice_t *wlandev, printk(KERN_WARNING "authfail assocstatus info frame received for authenticated station.\n"); } - - return; } /*---------------------------------------------------------------- @@ -1731,7 +1720,6 @@ static void prism2sta_inf_authreq_defer(wlandevice_t *wlandev, "setconfig(authenticatestation) failed, result=%d\n", result); } - return; } /*---------------------------------------------------------------- @@ -1758,8 +1746,6 @@ static void prism2sta_inf_psusercnt(wlandevice_t *wlandev, hfa384x_t *hw = (hfa384x_t *) wlandev->priv; hw->psusercount = le16_to_cpu(inf->info.psusercnt.usercnt); - - return; } /*---------------------------------------------------------------- @@ -1825,7 +1811,6 @@ void prism2sta_ev_info(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf) "Unknown info type=0x%02x\n", inf->infotype); break; } - return; } /*---------------------------------------------------------------- @@ -1850,8 +1835,6 @@ void prism2sta_ev_info(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf) void prism2sta_ev_txexc(wlandevice_t *wlandev, u16 status) { pr_debug("TxExc status=0x%x.\n", status); - - return; } /*---------------------------------------------------------------- @@ -1875,7 +1858,6 @@ void prism2sta_ev_tx(wlandevice_t *wlandev, u16 status) pr_debug("Tx Complete, status=0x%04x\n", status); /* update linux network stats */ wlandev->linux_stats.tx_packets++; - return; } /*---------------------------------------------------------------- @@ -1897,7 +1879,6 @@ void prism2sta_ev_tx(wlandevice_t *wlandev, u16 status) void prism2sta_ev_rx(wlandevice_t *wlandev, struct sk_buff *skb) { p80211netdev_rx(wlandev, skb); - return; } /*---------------------------------------------------------------- @@ -1919,7 +1900,6 @@ void prism2sta_ev_rx(wlandevice_t *wlandev, struct sk_buff *skb) void prism2sta_ev_alloc(wlandevice_t *wlandev) { netif_wake_queue(wlandev->netdev); - return; } /*---------------------------------------------------------------- -- cgit v0.10.2 From 5d6f5054e8ee9af23db3df4471cd3c30d5f2fadc Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Thu, 13 Sep 2012 15:01:39 +0530 Subject: staging:wlan-ng: remove the remaining return at the end of void function this removes the remaining return which the function actually wants to return, for that it used goto failed and failed lable have the return statement at the end of function, which is all unnecessary, remove this and make the function return at the places where it does the goto failed Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlan-ng/prism2sta.c b/drivers/staging/wlan-ng/prism2sta.c index 37f183d..8d2277b 100644 --- a/drivers/staging/wlan-ng/prism2sta.c +++ b/drivers/staging/wlan-ng/prism2sta.c @@ -1211,7 +1211,7 @@ void prism2sta_processing_defer(struct work_struct *data) /* Now let's handle the linkstatus stuff */ if (hw->link_status == hw->link_status_new) - goto failed; + return; hw->link_status = hw->link_status_new; @@ -1265,7 +1265,7 @@ void prism2sta_processing_defer(struct work_struct *data) pr_debug ("getconfig(0x%02x) failed, result = %d\n", HFA384x_RID_CURRENTBSSID, result); - goto failed; + return; } result = hfa384x_drvr_getconfig(hw, @@ -1275,7 +1275,7 @@ void prism2sta_processing_defer(struct work_struct *data) pr_debug ("getconfig(0x%02x) failed, result = %d\n", HFA384x_RID_CURRENTSSID, result); - goto failed; + return; } prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *) &ssid, (p80211pstrd_t *) & @@ -1289,7 +1289,7 @@ void prism2sta_processing_defer(struct work_struct *data) pr_debug ("getconfig(0x%02x) failed, result = %d\n", HFA384x_RID_PORTSTATUS, result); - goto failed; + return; } wlandev->macmode = (portstatus == HFA384x_PSTATUS_CONN_IBSS) ? @@ -1348,7 +1348,7 @@ void prism2sta_processing_defer(struct work_struct *data) if (result) { pr_debug("getconfig(0x%02x) failed, result = %d\n", HFA384x_RID_CURRENTBSSID, result); - goto failed; + return; } result = hfa384x_drvr_getconfig(hw, @@ -1357,7 +1357,7 @@ void prism2sta_processing_defer(struct work_struct *data) if (result) { pr_debug("getconfig(0x%02x) failed, result = %d\n", HFA384x_RID_CURRENTSSID, result); - goto failed; + return; } prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *) &ssid, (p80211pstrd_t *) &wlandev->ssid); @@ -1436,14 +1436,10 @@ void prism2sta_processing_defer(struct work_struct *data) /* This is bad, IO port problems? */ printk(KERN_WARNING "unknown linkstatus=0x%02x\n", hw->link_status); - goto failed; - break; + return; } wlandev->linkstatus = (hw->link_status == HFA384x_LINK_CONNECTED); - -failed: - return; } /*---------------------------------------------------------------- -- cgit v0.10.2 From 22976bc354938e2064cedde83f7b995dc8a1ea41 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Thu, 13 Sep 2012 21:11:34 -0400 Subject: Staging: bcm: Fix all white space issues in Transmit.c This patch fixes all white space issues as reported by checkpatch.pl. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/Transmit.c b/drivers/staging/bcm/Transmit.c index 5e603ce..e7b91c1 100644 --- a/drivers/staging/bcm/Transmit.c +++ b/drivers/staging/bcm/Transmit.c @@ -35,7 +35,6 @@ SendPacketFromQueue->SetupNextSend->bcm_cmd53 #include "headers.h" - /** @ingroup ctrl_pkt_functions This function dispatches control packet to the h/w interface @@ -45,36 +44,36 @@ INT SendControlPacket(struct bcm_mini_adapter *Adapter, char *pControlPacket) { struct bcm_leader *PLeader = (struct bcm_leader *)pControlPacket; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Tx"); - if(!pControlPacket || !Adapter) + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Tx"); + if (!pControlPacket || !Adapter) + { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Got NULL Control Packet or Adapter"); + return STATUS_FAILURE; + } + if ((atomic_read(&Adapter->CurrNumFreeTxDesc) < + ((PLeader->PLength-1)/MAX_DEVICE_DESC_SIZE)+1)) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Got NULL Control Packet or Adapter"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "NO FREE DESCRIPTORS TO SEND CONTROL PACKET"); return STATUS_FAILURE; } - if((atomic_read( &Adapter->CurrNumFreeTxDesc ) < - ((PLeader->PLength-1)/MAX_DEVICE_DESC_SIZE)+1)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "NO FREE DESCRIPTORS TO SEND CONTROL PACKET"); - return STATUS_FAILURE; - } /* Update the netdevice statistics */ /* Dump Packet */ - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader Status: %x", PLeader->Status); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader VCID: %x",PLeader->Vcid); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader Length: %x",PLeader->PLength); - if(Adapter->device_removed) + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader Status: %x", PLeader->Status); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader VCID: %x", PLeader->Vcid); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader Length: %x", PLeader->PLength); + if (Adapter->device_removed) return 0; if (netif_msg_pktdata(Adapter)) print_hex_dump(KERN_DEBUG, PFX "tx control: ", DUMP_PREFIX_NONE, - 16, 1, pControlPacket, PLeader->PLength + LEADER_SIZE, 0); + 16, 1, pControlPacket, PLeader->PLength + LEADER_SIZE, 0); Adapter->interface_transmit(Adapter->pvInterfaceAdapter, - pControlPacket, (PLeader->PLength + LEADER_SIZE)); + pControlPacket, (PLeader->PLength + LEADER_SIZE)); atomic_dec(&Adapter->CurrNumFreeTxDesc); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "<========="); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "<========="); return STATUS_SUCCESS; } @@ -86,54 +85,54 @@ to the target via the host h/w interface. */ INT SetupNextSend(struct bcm_mini_adapter *Adapter, struct sk_buff *Packet, USHORT Vcid) { - int status=0; - BOOLEAN bHeaderSupressionEnabled = FALSE; - B_UINT16 uiClassifierRuleID; + int status = 0; + BOOLEAN bHeaderSupressionEnabled = FALSE; + B_UINT16 uiClassifierRuleID; u16 QueueIndex = skb_get_queue_mapping(Packet); - struct bcm_leader Leader={0}; + struct bcm_leader Leader = {0}; - if(Packet->len > MAX_DEVICE_DESC_SIZE) + if (Packet->len > MAX_DEVICE_DESC_SIZE) { status = STATUS_FAILURE; goto errExit; } /* Get the Classifier Rule ID */ - uiClassifierRuleID = *((UINT32*) (Packet->cb)+SKB_CB_CLASSIFICATION_OFFSET); + uiClassifierRuleID = *((UINT32 *) (Packet->cb) + SKB_CB_CLASSIFICATION_OFFSET); bHeaderSupressionEnabled = Adapter->PackInfo[QueueIndex].bHeaderSuppressionEnabled & Adapter->bPHSEnabled; - if(Adapter->device_removed) - { + if (Adapter->device_removed) + { status = STATUS_FAILURE; goto errExit; - } + } status = PHSTransmit(Adapter, &Packet, Vcid, uiClassifierRuleID, bHeaderSupressionEnabled, - (UINT *)&Packet->len, Adapter->PackInfo[QueueIndex].bEthCSSupport); + (UINT *)&Packet->len, Adapter->PackInfo[QueueIndex].bEthCSSupport); - if(status != STATUS_SUCCESS) + if (status != STATUS_SUCCESS) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "PHS Transmit failed..\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "PHS Transmit failed..\n"); goto errExit; } - Leader.Vcid = Vcid; + Leader.Vcid = Vcid; - if(TCP_ACK == *((UINT32*) (Packet->cb) + SKB_CB_TCPACK_OFFSET )) + if (TCP_ACK == *((UINT32 *) (Packet->cb) + SKB_CB_TCPACK_OFFSET)) Leader.Status = LEADER_STATUS_TCP_ACK; else Leader.Status = LEADER_STATUS; - if(Adapter->PackInfo[QueueIndex].bEthCSSupport) + if (Adapter->PackInfo[QueueIndex].bEthCSSupport) { Leader.PLength = Packet->len; - if(skb_headroom(Packet) < LEADER_SIZE) - { - if((status = skb_cow(Packet,LEADER_SIZE))) + if (skb_headroom(Packet) < LEADER_SIZE) + { + if ((status = skb_cow(Packet, LEADER_SIZE))) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"bcm_transmit : Failed To Increase headRoom\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "bcm_transmit : Failed To Increase headRoom\n"); goto errExit; } } @@ -147,8 +146,8 @@ INT SetupNextSend(struct bcm_mini_adapter *Adapter, struct sk_buff *Packet, USH } status = Adapter->interface_transmit(Adapter->pvInterfaceAdapter, - Packet->data, (Leader.PLength + LEADER_SIZE)); - if(status) + Packet->data, (Leader.PLength + LEADER_SIZE)); + if (status) { ++Adapter->dev->stats.tx_errors; if (netif_msg_tx_err(Adapter)) @@ -175,7 +174,6 @@ INT SetupNextSend(struct bcm_mini_adapter *Adapter, struct sk_buff *Packet, USH atomic_dec(&Adapter->CurrNumFreeTxDesc); errExit: - dev_kfree_skb(Packet); return status; } @@ -191,70 +189,68 @@ static int tx_pending(struct bcm_mini_adapter *Adapter) @ingroup tx_functions Transmit thread */ -int tx_pkt_handler(struct bcm_mini_adapter *Adapter /**< pointer to adapter object*/ - ) +int tx_pkt_handler(struct bcm_mini_adapter *Adapter /**< pointer to adapter object*/) { int status = 0; - while(! kthread_should_stop()) { + while (!kthread_should_stop()) { /* FIXME - the timeout looks like workaround for racey usage of TxPktAvail */ - if(Adapter->LinkUpStatus) + if (Adapter->LinkUpStatus) wait_event_timeout(Adapter->tx_packet_wait_queue, - tx_pending(Adapter), msecs_to_jiffies(10)); + tx_pending(Adapter), msecs_to_jiffies(10)); else wait_event_interruptible(Adapter->tx_packet_wait_queue, - tx_pending(Adapter)); + tx_pending(Adapter)); if (Adapter->device_removed) break; - if(Adapter->downloadDDR == 1) + if (Adapter->downloadDDR == 1) { - Adapter->downloadDDR +=1; + Adapter->downloadDDR += 1; status = download_ddr_settings(Adapter); - if(status) + if (status) pr_err(PFX "DDR DOWNLOAD FAILED! %d\n", status); continue; } //Check end point for halt/stall. - if(Adapter->bEndPointHalted == TRUE) + if (Adapter->bEndPointHalted == TRUE) { Bcm_clear_halt_of_endpoints(Adapter); Adapter->bEndPointHalted = FALSE; StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter)); } - if(Adapter->LinkUpStatus && !Adapter->IdleMode) + if (Adapter->LinkUpStatus && !Adapter->IdleMode) { - if(atomic_read(&Adapter->TotalPacketCount)) + if (atomic_read(&Adapter->TotalPacketCount)) { update_per_sf_desc_cnts(Adapter); } } - if( atomic_read(&Adapter->CurrNumFreeTxDesc) && + if (atomic_read(&Adapter->CurrNumFreeTxDesc) && Adapter->LinkStatus == SYNC_UP_REQUEST && !Adapter->bSyncUpRequestSent) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Calling LinkMessage"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Calling LinkMessage"); LinkMessage(Adapter); } - if((Adapter->IdleMode || Adapter->bShutStatus) && atomic_read(&Adapter->TotalPacketCount)) + if ((Adapter->IdleMode || Adapter->bShutStatus) && atomic_read(&Adapter->TotalPacketCount)) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Device in Low Power mode...waking up"); - Adapter->usIdleModePattern = ABORT_IDLE_MODE; - Adapter->bWakeUpDevice = TRUE; - wake_up(&Adapter->process_rx_cntrlpkt); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Device in Low Power mode...waking up"); + Adapter->usIdleModePattern = ABORT_IDLE_MODE; + Adapter->bWakeUpDevice = TRUE; + wake_up(&Adapter->process_rx_cntrlpkt); } transmit_packets(Adapter); - atomic_set(&Adapter->TxPktAvail, 0); } - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Exiting the tx thread..\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Exiting the tx thread..\n"); Adapter->transmit_packet_thread = NULL; return 0; } -- cgit v0.10.2 From 97e0a509d90d539db4b70362cf5e82983b5bc305 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Thu, 13 Sep 2012 21:11:35 -0400 Subject: Staging: bcm: Properly format braces in Transmit.c This patch cuddles braces as reported by checkpatch.pl. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/Transmit.c b/drivers/staging/bcm/Transmit.c index e7b91c1..7a80e62 100644 --- a/drivers/staging/bcm/Transmit.c +++ b/drivers/staging/bcm/Transmit.c @@ -45,14 +45,12 @@ INT SendControlPacket(struct bcm_mini_adapter *Adapter, char *pControlPacket) struct bcm_leader *PLeader = (struct bcm_leader *)pControlPacket; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Tx"); - if (!pControlPacket || !Adapter) - { + if (!pControlPacket || !Adapter) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Got NULL Control Packet or Adapter"); return STATUS_FAILURE; } if ((atomic_read(&Adapter->CurrNumFreeTxDesc) < - ((PLeader->PLength-1)/MAX_DEVICE_DESC_SIZE)+1)) - { + ((PLeader->PLength-1)/MAX_DEVICE_DESC_SIZE)+1)) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "NO FREE DESCRIPTORS TO SEND CONTROL PACKET"); return STATUS_FAILURE; } @@ -91,8 +89,7 @@ INT SetupNextSend(struct bcm_mini_adapter *Adapter, struct sk_buff *Packet, USH u16 QueueIndex = skb_get_queue_mapping(Packet); struct bcm_leader Leader = {0}; - if (Packet->len > MAX_DEVICE_DESC_SIZE) - { + if (Packet->len > MAX_DEVICE_DESC_SIZE) { status = STATUS_FAILURE; goto errExit; } @@ -103,8 +100,7 @@ INT SetupNextSend(struct bcm_mini_adapter *Adapter, struct sk_buff *Packet, USH bHeaderSupressionEnabled = Adapter->PackInfo[QueueIndex].bHeaderSuppressionEnabled & Adapter->bPHSEnabled; - if (Adapter->device_removed) - { + if (Adapter->device_removed) { status = STATUS_FAILURE; goto errExit; } @@ -112,8 +108,7 @@ INT SetupNextSend(struct bcm_mini_adapter *Adapter, struct sk_buff *Packet, USH status = PHSTransmit(Adapter, &Packet, Vcid, uiClassifierRuleID, bHeaderSupressionEnabled, (UINT *)&Packet->len, Adapter->PackInfo[QueueIndex].bEthCSSupport); - if (status != STATUS_SUCCESS) - { + if (status != STATUS_SUCCESS) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "PHS Transmit failed..\n"); goto errExit; } @@ -125,37 +120,29 @@ INT SetupNextSend(struct bcm_mini_adapter *Adapter, struct sk_buff *Packet, USH else Leader.Status = LEADER_STATUS; - if (Adapter->PackInfo[QueueIndex].bEthCSSupport) - { + if (Adapter->PackInfo[QueueIndex].bEthCSSupport) { Leader.PLength = Packet->len; - if (skb_headroom(Packet) < LEADER_SIZE) - { - if ((status = skb_cow(Packet, LEADER_SIZE))) - { + if (skb_headroom(Packet) < LEADER_SIZE) { + if ((status = skb_cow(Packet, LEADER_SIZE))) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "bcm_transmit : Failed To Increase headRoom\n"); goto errExit; } } skb_push(Packet, LEADER_SIZE); memcpy(Packet->data, &Leader, LEADER_SIZE); - } - else - { + } else { Leader.PLength = Packet->len - ETH_HLEN; memcpy((struct bcm_leader *)skb_pull(Packet, (ETH_HLEN - LEADER_SIZE)), &Leader, LEADER_SIZE); } status = Adapter->interface_transmit(Adapter->pvInterfaceAdapter, Packet->data, (Leader.PLength + LEADER_SIZE)); - if (status) - { + if (status) { ++Adapter->dev->stats.tx_errors; if (netif_msg_tx_err(Adapter)) pr_info(PFX "%s: transmit error %d\n", Adapter->dev->name, status); - } - else - { + } else { struct net_device_stats *netstats = &Adapter->dev->stats; Adapter->PackInfo[QueueIndex].uiTotalTxBytes += Leader.PLength; @@ -205,8 +192,7 @@ int tx_pkt_handler(struct bcm_mini_adapter *Adapter /**< pointer to adapter obje if (Adapter->device_removed) break; - if (Adapter->downloadDDR == 1) - { + if (Adapter->downloadDDR == 1) { Adapter->downloadDDR += 1; status = download_ddr_settings(Adapter); if (status) @@ -215,31 +201,26 @@ int tx_pkt_handler(struct bcm_mini_adapter *Adapter /**< pointer to adapter obje } //Check end point for halt/stall. - if (Adapter->bEndPointHalted == TRUE) - { + if (Adapter->bEndPointHalted == TRUE) { Bcm_clear_halt_of_endpoints(Adapter); Adapter->bEndPointHalted = FALSE; StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter)); } - if (Adapter->LinkUpStatus && !Adapter->IdleMode) - { + if (Adapter->LinkUpStatus && !Adapter->IdleMode) { if (atomic_read(&Adapter->TotalPacketCount)) - { update_per_sf_desc_cnts(Adapter); - } } if (atomic_read(&Adapter->CurrNumFreeTxDesc) && Adapter->LinkStatus == SYNC_UP_REQUEST && - !Adapter->bSyncUpRequestSent) - { + !Adapter->bSyncUpRequestSent) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Calling LinkMessage"); LinkMessage(Adapter); } - if ((Adapter->IdleMode || Adapter->bShutStatus) && atomic_read(&Adapter->TotalPacketCount)) - { + if ((Adapter->IdleMode || Adapter->bShutStatus) && atomic_read(&Adapter->TotalPacketCount)) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Device in Low Power mode...waking up"); Adapter->usIdleModePattern = ABORT_IDLE_MODE; Adapter->bWakeUpDevice = TRUE; -- cgit v0.10.2 From d5873d381713ecf8a61a733b983676c68c8e67b5 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Thu, 13 Sep 2012 21:11:36 -0400 Subject: Staging: bcm: Remove initialization from if statement in Transmit.c This patch Remove initialization from if statement in Transmit.c as reported by checkpatch.pl. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/Transmit.c b/drivers/staging/bcm/Transmit.c index 7a80e62..1fbb54a 100644 --- a/drivers/staging/bcm/Transmit.c +++ b/drivers/staging/bcm/Transmit.c @@ -123,7 +123,8 @@ INT SetupNextSend(struct bcm_mini_adapter *Adapter, struct sk_buff *Packet, USH if (Adapter->PackInfo[QueueIndex].bEthCSSupport) { Leader.PLength = Packet->len; if (skb_headroom(Packet) < LEADER_SIZE) { - if ((status = skb_cow(Packet, LEADER_SIZE))) { + status = skb_cow(Packet, LEADER_SIZE); + if (status) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "bcm_transmit : Failed To Increase headRoom\n"); goto errExit; } -- cgit v0.10.2 From b9e25f81c5a0b52097daff30fe72522d05967228 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Thu, 13 Sep 2012 21:11:37 -0400 Subject: Staging: bcm: Properly format comments in Transmit.c This patch properly formats comments as reported by checkpatch.pl. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/Transmit.c b/drivers/staging/bcm/Transmit.c index 1fbb54a..adf545f 100644 --- a/drivers/staging/bcm/Transmit.c +++ b/drivers/staging/bcm/Transmit.c @@ -1,45 +1,45 @@ /** -@file Transmit.c -@defgroup tx_functions Transmission -@section Queueing -@dot -digraph transmit1 { -node[shape=box] -edge[weight=5;color=red] - -bcm_transmit->GetPacketQueueIndex[label="IP Packet"] -GetPacketQueueIndex->IpVersion4[label="IPV4"] -GetPacketQueueIndex->IpVersion6[label="IPV6"] -} - -@enddot - -@section De-Queueing -@dot -digraph transmit2 { -node[shape=box] -edge[weight=5;color=red] -interrupt_service_thread->transmit_packets -tx_pkt_hdler->transmit_packets -transmit_packets->CheckAndSendPacketFromIndex -transmit_packets->UpdateTokenCount -CheckAndSendPacketFromIndex->PruneQueue -CheckAndSendPacketFromIndex->IsPacketAllowedForFlow -CheckAndSendPacketFromIndex->SendControlPacket[label="control pkt"] -SendControlPacket->bcm_cmd53 -CheckAndSendPacketFromIndex->SendPacketFromQueue[label="data pkt"] -SendPacketFromQueue->SetupNextSend->bcm_cmd53 -} -@enddot -*/ + * @file Transmit.c + * @defgroup tx_functions Transmission + * @section Queueing + * @dot + * digraph transmit1 { + * node[shape=box] + * edge[weight=5;color=red] + * + * bcm_transmit->GetPacketQueueIndex[label="IP Packet"] + * GetPacketQueueIndex->IpVersion4[label="IPV4"] + * GetPacketQueueIndex->IpVersion6[label="IPV6"] + * } + * + * @enddot + * + * @section De-Queueing + * @dot + * digraph transmit2 { + * node[shape=box] + * edge[weight=5;color=red] + * interrupt_service_thread->transmit_packets + * tx_pkt_hdler->transmit_packets + * transmit_packets->CheckAndSendPacketFromIndex + * transmit_packets->UpdateTokenCount + * CheckAndSendPacketFromIndex->PruneQueue + * CheckAndSendPacketFromIndex->IsPacketAllowedForFlow + * CheckAndSendPacketFromIndex->SendControlPacket[label="control pkt"] + * SendControlPacket->bcm_cmd53 + * CheckAndSendPacketFromIndex->SendPacketFromQueue[label="data pkt"] + * SendPacketFromQueue->SetupNextSend->bcm_cmd53 + * } + * @enddot + */ #include "headers.h" /** -@ingroup ctrl_pkt_functions -This function dispatches control packet to the h/w interface -@return zero(success) or -ve value(failure) -*/ + * @ingroup ctrl_pkt_functions + * This function dispatches control packet to the h/w interface + * @return zero(success) or -ve value(failure) + */ INT SendControlPacket(struct bcm_mini_adapter *Adapter, char *pControlPacket) { struct bcm_leader *PLeader = (struct bcm_leader *)pControlPacket; @@ -76,11 +76,11 @@ INT SendControlPacket(struct bcm_mini_adapter *Adapter, char *pControlPacket) } /** -@ingroup tx_functions -This function despatches the IP packets with the given vcid -to the target via the host h/w interface. -@return zero(success) or -ve value(failure) -*/ + * @ingroup tx_functions + * This function despatches the IP packets with the given vcid + * to the target via the host h/w interface. + * @return zero(success) or -ve value(failure) + */ INT SetupNextSend(struct bcm_mini_adapter *Adapter, struct sk_buff *Packet, USHORT Vcid) { int status = 0; @@ -174,9 +174,9 @@ static int tx_pending(struct bcm_mini_adapter *Adapter) } /** -@ingroup tx_functions -Transmit thread -*/ + * @ingroup tx_functions + * Transmit thread + */ int tx_pkt_handler(struct bcm_mini_adapter *Adapter /**< pointer to adapter object*/) { int status = 0; @@ -201,7 +201,7 @@ int tx_pkt_handler(struct bcm_mini_adapter *Adapter /**< pointer to adapter obje continue; } - //Check end point for halt/stall. + /* Check end point for halt/stall. */ if (Adapter->bEndPointHalted == TRUE) { Bcm_clear_halt_of_endpoints(Adapter); Adapter->bEndPointHalted = FALSE; -- cgit v0.10.2 From ae1cbea5f9ae9d88da3ba7299f7d2d2574797f62 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Thu, 13 Sep 2012 21:11:38 -0400 Subject: Staging: bcm: Convert INT to int in Transmit.c This patch converts INT to int in Transmit.c Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/Transmit.c b/drivers/staging/bcm/Transmit.c index adf545f..27e8c89 100644 --- a/drivers/staging/bcm/Transmit.c +++ b/drivers/staging/bcm/Transmit.c @@ -40,7 +40,7 @@ * This function dispatches control packet to the h/w interface * @return zero(success) or -ve value(failure) */ -INT SendControlPacket(struct bcm_mini_adapter *Adapter, char *pControlPacket) +int SendControlPacket(struct bcm_mini_adapter *Adapter, char *pControlPacket) { struct bcm_leader *PLeader = (struct bcm_leader *)pControlPacket; @@ -81,7 +81,7 @@ INT SendControlPacket(struct bcm_mini_adapter *Adapter, char *pControlPacket) * to the target via the host h/w interface. * @return zero(success) or -ve value(failure) */ -INT SetupNextSend(struct bcm_mini_adapter *Adapter, struct sk_buff *Packet, USHORT Vcid) +int SetupNextSend(struct bcm_mini_adapter *Adapter, struct sk_buff *Packet, USHORT Vcid) { int status = 0; BOOLEAN bHeaderSupressionEnabled = FALSE; -- cgit v0.10.2 From 443242d2feb68c90fbd96de212d76d7858ac0834 Mon Sep 17 00:00:00 2001 From: Macpaul Lin Date: Thu, 13 Sep 2012 18:11:54 +0800 Subject: staging/gdm72xx: usb_boot: coding style cleanup 1. Coding style re-formatting (tabs). 2. Remove unused MIN() marco. Signed-off-by: Macpaul Lin Cc: Paul Stewart Cc: Ben Chan Cc: Sage Ahn Cc: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/gdm72xx/usb_boot.c b/drivers/staging/gdm72xx/usb_boot.c index e3dbd5a..78a16d8 100644 --- a/drivers/staging/gdm72xx/usb_boot.c +++ b/drivers/staging/gdm72xx/usb_boot.c @@ -23,15 +23,13 @@ #include "gdm_usb.h" #include "usb_boot.h" -#define DN_KERNEL_MAGIC_NUMBER 0x10760001 -#define DN_ROOTFS_MAGIC_NUMBER 0x10760002 +#define DN_KERNEL_MAGIC_NUMBER 0x10760001 +#define DN_ROOTFS_MAGIC_NUMBER 0x10760002 -#define DOWNLOAD_SIZE 1024 +#define DOWNLOAD_SIZE 1024 -#define DH2B(x) __cpu_to_be32(x) -#define DL2H(x) __le32_to_cpu(x) - -#define MIN(a, b) ((a) > (b) ? (b) : (a)) +#define DH2B(x) __cpu_to_be32(x) +#define DL2H(x) __le32_to_cpu(x) #define MAX_IMG_CNT 16 #define UIMG_PATH "/lib/firmware/gdm72xx/gdmuimg.bin" @@ -44,23 +42,23 @@ struct dn_header { }; struct img_header { - u32 magic_code; - u32 count; - u32 len; - u32 offset[MAX_IMG_CNT]; + u32 magic_code; + u32 count; + u32 len; + u32 offset[MAX_IMG_CNT]; char hostname[32]; char date[32]; }; struct fw_info { - u32 id; - u32 len; - u32 kernel_len; - u32 rootfs_len; - u32 kernel_offset; - u32 rootfs_offset; - u32 fw_ver; - u32 mac_ver; + u32 id; + u32 len; + u32 kernel_len; + u32 rootfs_len; + u32 kernel_offset; + u32 rootfs_offset; + u32 fw_ver; + u32 mac_ver; char hostname[32]; char userid[16]; char date[32]; -- cgit v0.10.2 From 1839c7ebd9363cc73b55ce48d4c3c6823c2fdd42 Mon Sep 17 00:00:00 2001 From: Macpaul Lin Date: Thu, 13 Sep 2012 18:11:55 +0800 Subject: staging/gdm72xx: usb_boot: replace firmware upgrade API Replace file I/O of reading firmware usb_boot() by request_firmware(). Signed-off-by: Macpaul Lin Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/gdm72xx/usb_boot.c b/drivers/staging/gdm72xx/usb_boot.c index 78a16d8..80870a0 100644 --- a/drivers/staging/gdm72xx/usb_boot.c +++ b/drivers/staging/gdm72xx/usb_boot.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "gdm_usb.h" @@ -28,11 +29,9 @@ #define DOWNLOAD_SIZE 1024 -#define DH2B(x) __cpu_to_be32(x) -#define DL2H(x) __le32_to_cpu(x) - #define MAX_IMG_CNT 16 -#define UIMG_PATH "/lib/firmware/gdm72xx/gdmuimg.bin" +#define FW_DIR "gdm72xx/" +#define FW_UIMG "gdmuimg.bin" #define KERN_PATH "/lib/firmware/gdm72xx/zImage" #define FS_PATH "/lib/firmware/gdm72xx/ramdisk.jffs2" @@ -69,7 +68,7 @@ static void array_le32_to_cpu(u32 *arr, int num) { int i; for (i = 0; i < num; i++, arr++) - *arr = DL2H(*arr); + *arr = __le32_to_cpu(*arr); } static u8 *tx_buf; @@ -105,44 +104,37 @@ static int gdm_wibro_recv(struct usb_device *usbdev, void *data, int len) return 0; } -static int download_image(struct usb_device *usbdev, struct file *filp, - loff_t *pos, u32 img_len, u32 magic_num) +static int download_image(struct usb_device *usbdev, + const struct firmware *firm, + loff_t pos, u32 img_len, u32 magic_num) { struct dn_header h; int ret = 0; u32 size; - int len, readn; - size = (img_len + DOWNLOAD_SIZE - 1) & ~(DOWNLOAD_SIZE - 1); - h.magic_num = DH2B(magic_num); - h.file_size = DH2B(size); + size = ALIGN(img_len, DOWNLOAD_SIZE); + h.magic_num = __cpu_to_be32(magic_num); + h.file_size = __cpu_to_be32(size); ret = gdm_wibro_send(usbdev, &h, sizeof(h)); if (ret < 0) - goto out; + return ret; - readn = 0; - while ((len = filp->f_op->read(filp, tx_buf, DOWNLOAD_SIZE, pos))) { + while (img_len > 0) { + if (img_len > DOWNLOAD_SIZE) + size = DOWNLOAD_SIZE; + else + size = img_len; /* the last chunk of data */ - if (len < 0) { - ret = -1; - goto out; - } - readn += len; + memcpy(tx_buf, firm->data + pos, size); + ret = gdm_wibro_send(usbdev, tx_buf, size); - ret = gdm_wibro_send(usbdev, tx_buf, DOWNLOAD_SIZE); if (ret < 0) - goto out; - if (readn >= img_len) - break; - } + return ret; - if (readn < img_len) { - printk(KERN_ERR "gdmwm: Cannot read to the requested size. " - "Read = %d Requested = %d\n", readn, img_len); - ret = -EIO; + img_len -= size; + pos += size; } -out: return ret; } @@ -150,14 +142,19 @@ out: int usb_boot(struct usb_device *usbdev, u16 pid) { int i, ret = 0; - struct file *filp = NULL; - struct inode *inode = NULL; - static mm_segment_t fs; struct img_header hdr; struct fw_info fw_info; loff_t pos = 0; - char *img_name = UIMG_PATH; - int len; + char *img_name = FW_DIR FW_UIMG; + const struct firmware *firm; + + ret = request_firmware(&firm, img_name, &usbdev->dev); + if (ret < 0) { + printk(KERN_ERR + "requesting firmware %s failed with error %d\n", + img_name, ret); + return ret; + } tx_buf = kmalloc(DOWNLOAD_SIZE, GFP_KERNEL); if (tx_buf == NULL) { @@ -165,29 +162,12 @@ int usb_boot(struct usb_device *usbdev, u16 pid) return -ENOMEM; } - fs = get_fs(); - set_fs(get_ds()); - - filp = filp_open(img_name, O_RDONLY | O_LARGEFILE, 0); - if (IS_ERR(filp)) { - printk(KERN_ERR "Can't find %s.\n", img_name); - ret = PTR_ERR(filp); - goto restore_fs; - } - - inode = filp->f_dentry->d_inode; - if (!S_ISREG(inode->i_mode)) { - printk(KERN_ERR "Invalid file type: %s\n", img_name); - ret = -EINVAL; - goto out; - } - - len = filp->f_op->read(filp, (u8 *)&hdr, sizeof(hdr), &pos); - if (len != sizeof(hdr)) { + if (firm->size < sizeof(hdr)) { printk(KERN_ERR "gdmwm: Cannot read the image info.\n"); ret = -EIO; goto out; } + memcpy(&hdr, firm->data, sizeof(hdr)); array_le32_to_cpu((u32 *)&hdr, 19); #if 0 @@ -215,13 +195,12 @@ int usb_boot(struct usb_device *usbdev, u16 pid) } pos = hdr.offset[i]; - len = filp->f_op->read(filp, (u8 *)&fw_info, sizeof(fw_info), - &pos); - if (len != sizeof(fw_info)) { + if (firm->size < sizeof(fw_info) + pos) { printk(KERN_ERR "gdmwm: Cannot read the FW info.\n"); ret = -EIO; goto out; } + memcpy(&fw_info, firm->data + pos, sizeof(fw_info)); array_le32_to_cpu((u32 *)&fw_info, 8); #if 0 @@ -237,14 +216,23 @@ int usb_boot(struct usb_device *usbdev, u16 pid) continue; pos = hdr.offset[i] + fw_info.kernel_offset; - ret = download_image(usbdev, filp, &pos, fw_info.kernel_len, - DN_KERNEL_MAGIC_NUMBER); + if (firm->size < fw_info.kernel_len + pos) { + printk(KERN_ERR "gdmwm: Kernel FW is too small.\n"); + goto out; + } + + ret = download_image(usbdev, firm, pos, + fw_info.kernel_len, DN_KERNEL_MAGIC_NUMBER); if (ret < 0) goto out; printk(KERN_INFO "GCT: Kernel download success.\n"); pos = hdr.offset[i] + fw_info.rootfs_offset; - ret = download_image(usbdev, filp, &pos, fw_info.rootfs_len, + if (firm->size < fw_info.rootfs_len + pos) { + printk(KERN_ERR "gdmwm: Filesystem FW is too small.\n"); + goto out; + } + ret = download_image(usbdev, firm, pos, fw_info.rootfs_len, DN_ROOTFS_MAGIC_NUMBER); if (ret < 0) goto out; @@ -258,10 +246,7 @@ int usb_boot(struct usb_device *usbdev, u16 pid) ret = -EINVAL; } out: - filp_close(filp, NULL); - -restore_fs: - set_fs(fs); + release_firmware(firm); kfree(tx_buf); return ret; } -- cgit v0.10.2 From 98f4eade14b4bb077304ca16a1be45ec9c72b381 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Thu, 13 Sep 2012 00:45:42 +0300 Subject: staging: xgifb: setup initial video RAM size for systems without BIOS On embedded systems without a BIOS, the DRAM sizing register is 0 after the boot, and the driver thinks we have only 1 MB video memory. On such cases, use the PCI window size for the initial size. This information is needed only to create the I/O mapping - the driver will later detect and configure the memory size correctly. Limit the size to 16 MB as it should be sufficient for all supported video modes. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 98b8b09..f775c54 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -6,6 +6,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include #include #ifdef CONFIG_MTRR @@ -1470,6 +1471,9 @@ static int XGIfb_get_dram_size(struct xgifb_video_info *xgifb_info) xgifb_reg_set(XGISR, IND_SIS_DRAM_SIZE, 0x51); reg = xgifb_reg_get(XGISR, IND_SIS_DRAM_SIZE); + if (!reg) + return -1; + switch ((reg & XGI_DRAM_SIZE_MASK) >> 4) { case XGI_DRAM_SIZE_1MB: xgifb_info->video_size = 0x100000; @@ -1778,10 +1782,8 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, hw_info->jChipType = xgifb_info->chip; if (XGIfb_get_dram_size(xgifb_info)) { - dev_err(&pdev->dev, - "Fatal error: Unable to determine RAM size.\n"); - ret = -ENODEV; - goto error_disable; + xgifb_info->video_size = min_t(unsigned long, video_size_max, + SZ_16M); } else if (xgifb_info->video_size > video_size_max) { xgifb_info->video_size = video_size_max; } -- cgit v0.10.2 From d42bb0fbd93582adee0f404b1b82af809e9c0483 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Thu, 13 Sep 2012 00:45:43 +0300 Subject: staging: xgifb: delete bogus video RAM configuration The driver reconfigures DRAM size register to 8M (regardless what the actual size was) once the init has been completed, overwriting the correct value written during the early init. As a result if the driver is unloaded and reloaded, the user will be limited to 8M video memory and may lose some of the available video modes. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 0f6a529..7739dbd 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -1492,7 +1492,6 @@ unsigned char XGIInitNew(struct pci_dev *pdev) XGINew_SetModeScratch(HwDeviceExtension, pVBInfo); xgifb_reg_set(pVBInfo->P3d4, 0x8c, 0x87); - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x31); return 1; } /* end of init */ -- cgit v0.10.2 From 8e360ec82322358056786e651322085af3ef6960 Mon Sep 17 00:00:00 2001 From: Tushar Behera Date: Fri, 14 Sep 2012 10:07:33 +0530 Subject: Staging: bcm: Fix udelay related compilation error commit 6788d7dab6a5 ("Staging: bcm: Use udelay instead of msleep for delays in nvm.c") replaces msleep with udelay values. udelay values of more than 1000 should be replaced by mdelay instead. This fixes following build error. ERROR: "__bad_udelay" [drivers/staging/bcm/bcm_wimax.ko] undefined! make[1]: *** [__modpost] Error 1 make: *** [modules] Error 2 Cc: Kevin McKinney Cc: Greg Kroah-Hartman Signed-off-by: Tushar Behera Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/nvm.c b/drivers/staging/bcm/nvm.c index ed592e0..b034eb5 100644 --- a/drivers/staging/bcm/nvm.c +++ b/drivers/staging/bcm/nvm.c @@ -577,7 +577,7 @@ static int FlashSectorErase(struct bcm_mini_adapter *Adapter, * the sector erase cycle is 500 ms to 40000 msec. hence sleeping 10 ms * won't hamper performance in any case. */ - udelay(10000); + mdelay(10); } while ((uiStatus & 0x1) && (iRetries < 400)); if (uiStatus & 0x1) { -- cgit v0.10.2 From cb093e444fede72c1ee31265dac475dc87ff321b Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 10 Sep 2012 09:34:00 +0100 Subject: staging:iio:ad7476: Rework reference voltage handling Slightly rework the reference voltage handling for the ad7476 driver. Now the only way to specify a external reference voltage is to use the regulator API, previously it was possible to use either platform_data or the regulator API. The new way is more consistent with what other drivers do. Also do not ignore errors when requesting the regulator, since this will cope very poorly with e.g. deferred probing. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/adc/ad7476.h b/drivers/staging/iio/adc/ad7476.h index c4f1150..4ed5494 100644 --- a/drivers/staging/iio/adc/ad7476.h +++ b/drivers/staging/iio/adc/ad7476.h @@ -10,16 +10,8 @@ #define RES_MASK(bits) ((1 << (bits)) - 1) -/* - * TODO: struct ad7476_platform_data needs to go into include/linux/iio - */ - -struct ad7476_platform_data { - u16 vref_mv; -}; - struct ad7476_chip_info { - u16 int_vref_mv; + unsigned int int_vref_uv; struct iio_chan_spec channel[2]; }; @@ -27,7 +19,6 @@ struct ad7476_state { struct spi_device *spi; const struct ad7476_chip_info *chip_info; struct regulator *reg; - u16 int_vref_mv; struct spi_transfer xfer; struct spi_message msg; /* diff --git a/drivers/staging/iio/adc/ad7476_core.c b/drivers/staging/iio/adc/ad7476_core.c index c97300b..3be34f9 100644 --- a/drivers/staging/iio/adc/ad7476_core.c +++ b/drivers/staging/iio/adc/ad7476_core.c @@ -40,7 +40,7 @@ static int ad7476_read_raw(struct iio_dev *indio_dev, { int ret; struct ad7476_state *st = iio_priv(indio_dev); - unsigned int scale_uv; + int scale_uv; switch (m) { case IIO_CHAN_INFO_RAW: @@ -57,10 +57,16 @@ static int ad7476_read_raw(struct iio_dev *indio_dev, RES_MASK(st->chip_info->channel[0].scan_type.realbits); return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: - scale_uv = (st->int_vref_mv * 1000) - >> st->chip_info->channel[0].scan_type.realbits; - *val = scale_uv/1000; - *val2 = (scale_uv%1000)*1000; + if (!st->chip_info->int_vref_uv) { + scale_uv = regulator_get_voltage(st->reg); + if (scale_uv < 0) + return scale_uv; + } else { + scale_uv = st->chip_info->int_vref_uv; + } + scale_uv >>= chan->scan_type.realbits; + *val = scale_uv / 1000; + *val2 = (scale_uv % 1000) * 1000; return IIO_VAL_INT_PLUS_MICRO; } return -EINVAL; @@ -96,7 +102,7 @@ static const struct ad7476_chip_info ad7476_chip_info_tbl[] = { [ID_AD7495] = { .channel[0] = AD7476_CHAN(12), .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), - .int_vref_mv = 2500, + .int_vref_uv = 2500000, }, }; @@ -107,10 +113,9 @@ static const struct iio_info ad7476_info = { static int __devinit ad7476_probe(struct spi_device *spi) { - struct ad7476_platform_data *pdata = spi->dev.platform_data; struct ad7476_state *st; struct iio_dev *indio_dev; - int ret, voltage_uv = 0; + int ret; indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { @@ -118,25 +123,18 @@ static int __devinit ad7476_probe(struct spi_device *spi) goto error_ret; } st = iio_priv(indio_dev); - st->reg = regulator_get(&spi->dev, "vcc"); - if (!IS_ERR(st->reg)) { - ret = regulator_enable(st->reg); - if (ret) - goto error_put_reg; - - voltage_uv = regulator_get_voltage(st->reg); - } st->chip_info = &ad7476_chip_info_tbl[spi_get_device_id(spi)->driver_data]; - if (st->chip_info->int_vref_mv) - st->int_vref_mv = st->chip_info->int_vref_mv; - else if (pdata && pdata->vref_mv) - st->int_vref_mv = pdata->vref_mv; - else if (voltage_uv) - st->int_vref_mv = voltage_uv / 1000; - else - dev_warn(&spi->dev, "reference voltage unspecified\n"); + st->reg = regulator_get(&spi->dev, "vcc"); + if (IS_ERR(st->reg)) { + ret = PTR_ERR(st->reg); + goto error_free_dev; + } + + ret = regulator_enable(st->reg); + if (ret) + goto error_put_reg; spi_set_drvdata(spi, indio_dev); @@ -169,11 +167,10 @@ static int __devinit ad7476_probe(struct spi_device *spi) error_ring_unregister: ad7476_ring_cleanup(indio_dev); error_disable_reg: - if (!IS_ERR(st->reg)) - regulator_disable(st->reg); + regulator_disable(st->reg); error_put_reg: - if (!IS_ERR(st->reg)) - regulator_put(st->reg); + regulator_put(st->reg); +error_free_dev: iio_device_free(indio_dev); error_ret: @@ -187,10 +184,8 @@ static int __devexit ad7476_remove(struct spi_device *spi) iio_device_unregister(indio_dev); ad7476_ring_cleanup(indio_dev); - if (!IS_ERR(st->reg)) { - regulator_disable(st->reg); - regulator_put(st->reg); - } + regulator_disable(st->reg); + regulator_put(st->reg); iio_device_free(indio_dev); return 0; -- cgit v0.10.2 From 7a28fe3c93d6cd920c84678a1bf45af8b4248577 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 10 Sep 2012 09:34:00 +0100 Subject: staging:iio:ad7476: Squash driver into a single file. After the recent cleanups the buffer support is just a single 23 line function. This does not really justify a file on its own, so move it to the main driver file. And with only one source file left the header file containing the device state struct becomes superflousious so move the content of the header file to the main driver source file as well. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile index ecac9a0..6b60af0 100644 --- a/drivers/staging/iio/adc/Makefile +++ b/drivers/staging/iio/adc/Makefile @@ -17,8 +17,6 @@ ad799x-y := ad799x_core.o ad799x-$(CONFIG_AD799X_RING_BUFFER) += ad799x_ring.o obj-$(CONFIG_AD799X) += ad799x.o -ad7476-y := ad7476_core.o -ad7476-$(CONFIG_IIO_BUFFER) += ad7476_ring.o obj-$(CONFIG_AD7476) += ad7476.o ad7887-y := ad7887_core.o diff --git a/drivers/staging/iio/adc/ad7476.c b/drivers/staging/iio/adc/ad7476.c new file mode 100644 index 0000000..12e6e4b --- /dev/null +++ b/drivers/staging/iio/adc/ad7476.c @@ -0,0 +1,278 @@ +/* + * AD7466/7/8 AD7476/5/7/8 (A) SPI ADC driver + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define RES_MASK(bits) ((1 << (bits)) - 1) + +struct ad7476_chip_info { + unsigned int int_vref_uv; + struct iio_chan_spec channel[2]; +}; + +struct ad7476_state { + struct spi_device *spi; + const struct ad7476_chip_info *chip_info; + struct regulator *reg; + struct spi_transfer xfer; + struct spi_message msg; + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + * Make the buffer large enough for one 16 bit sample and one 64 bit + * aligned 64 bit timestamp. + */ + unsigned char data[ALIGN(2, sizeof(s64)) + sizeof(s64)] + ____cacheline_aligned; +}; + +enum ad7476_supported_device_ids { + ID_AD7466, + ID_AD7467, + ID_AD7468, + ID_AD7495 +}; + +static irqreturn_t ad7476_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct ad7476_state *st = iio_priv(indio_dev); + s64 time_ns; + int b_sent; + + b_sent = spi_sync(st->spi, &st->msg); + if (b_sent < 0) + goto done; + + time_ns = iio_get_time_ns(); + + if (indio_dev->scan_timestamp) + ((s64 *)st->data)[1] = time_ns; + + iio_push_to_buffer(indio_dev->buffer, st->data); +done: + iio_trigger_notify_done(indio_dev->trig); + + return IRQ_HANDLED; +} + +static int ad7476_scan_direct(struct ad7476_state *st) +{ + int ret; + + ret = spi_sync(st->spi, &st->msg); + if (ret) + return ret; + + return (st->data[0] << 8) | st->data[1]; +} + +static int ad7476_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long m) +{ + int ret; + struct ad7476_state *st = iio_priv(indio_dev); + int scale_uv; + + switch (m) { + case IIO_CHAN_INFO_RAW: + mutex_lock(&indio_dev->mlock); + if (iio_buffer_enabled(indio_dev)) + ret = -EBUSY; + else + ret = ad7476_scan_direct(st); + mutex_unlock(&indio_dev->mlock); + + if (ret < 0) + return ret; + *val = (ret >> st->chip_info->channel[0].scan_type.shift) & + RES_MASK(st->chip_info->channel[0].scan_type.realbits); + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + if (!st->chip_info->int_vref_uv) { + scale_uv = regulator_get_voltage(st->reg); + if (scale_uv < 0) + return scale_uv; + } else { + scale_uv = st->chip_info->int_vref_uv; + } + scale_uv >>= chan->scan_type.realbits; + *val = scale_uv / 1000; + *val2 = (scale_uv % 1000) * 1000; + return IIO_VAL_INT_PLUS_MICRO; + } + return -EINVAL; +} + +#define AD7476_CHAN(bits) \ + { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .scan_type = { \ + .sign = 'u', \ + .realbits = bits, \ + .storagebits = 16, \ + .shift = 13 - bits, \ + }, \ +} + +static const struct ad7476_chip_info ad7476_chip_info_tbl[] = { + [ID_AD7466] = { + .channel[0] = AD7476_CHAN(12), + .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), + }, + [ID_AD7467] = { + .channel[0] = AD7476_CHAN(10), + .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), + }, + [ID_AD7468] = { + .channel[0] = AD7476_CHAN(8), + .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), + }, + [ID_AD7495] = { + .channel[0] = AD7476_CHAN(12), + .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), + .int_vref_uv = 2500000, + }, +}; + +static const struct iio_info ad7476_info = { + .driver_module = THIS_MODULE, + .read_raw = &ad7476_read_raw, +}; + +static int __devinit ad7476_probe(struct spi_device *spi) +{ + struct ad7476_state *st; + struct iio_dev *indio_dev; + int ret; + + indio_dev = iio_device_alloc(sizeof(*st)); + if (indio_dev == NULL) { + ret = -ENOMEM; + goto error_ret; + } + st = iio_priv(indio_dev); + st->chip_info = + &ad7476_chip_info_tbl[spi_get_device_id(spi)->driver_data]; + + st->reg = regulator_get(&spi->dev, "vcc"); + if (IS_ERR(st->reg)) { + ret = PTR_ERR(st->reg); + goto error_free_dev; + } + + ret = regulator_enable(st->reg); + if (ret) + goto error_put_reg; + + spi_set_drvdata(spi, indio_dev); + + st->spi = spi; + + /* Establish that the iio_dev is a child of the spi device */ + indio_dev->dev.parent = &spi->dev; + indio_dev->name = spi_get_device_id(spi)->name; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = st->chip_info->channel; + indio_dev->num_channels = 2; + indio_dev->info = &ad7476_info; + /* Setup default message */ + + st->xfer.rx_buf = &st->data; + st->xfer.len = st->chip_info->channel[0].scan_type.storagebits / 8; + + spi_message_init(&st->msg); + spi_message_add_tail(&st->xfer, &st->msg); + + ret = iio_triggered_buffer_setup(indio_dev, NULL, + &ad7476_trigger_handler, NULL); + if (ret) + goto error_disable_reg; + + ret = iio_device_register(indio_dev); + if (ret) + goto error_ring_unregister; + return 0; + +error_ring_unregister: + iio_triggered_buffer_cleanup(indio_dev); +error_disable_reg: + regulator_disable(st->reg); +error_put_reg: + regulator_put(st->reg); +error_free_dev: + iio_device_free(indio_dev); + +error_ret: + return ret; +} + +static int __devexit ad7476_remove(struct spi_device *spi) +{ + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct ad7476_state *st = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + iio_triggered_buffer_cleanup(indio_dev); + regulator_disable(st->reg); + regulator_put(st->reg); + iio_device_free(indio_dev); + + return 0; +} + +static const struct spi_device_id ad7476_id[] = { + {"ad7466", ID_AD7466}, + {"ad7467", ID_AD7467}, + {"ad7468", ID_AD7468}, + {"ad7475", ID_AD7466}, + {"ad7476", ID_AD7466}, + {"ad7476a", ID_AD7466}, + {"ad7477", ID_AD7467}, + {"ad7477a", ID_AD7467}, + {"ad7478", ID_AD7468}, + {"ad7478a", ID_AD7468}, + {"ad7495", ID_AD7495}, + {} +}; +MODULE_DEVICE_TABLE(spi, ad7476_id); + +static struct spi_driver ad7476_driver = { + .driver = { + .name = "ad7476", + .owner = THIS_MODULE, + }, + .probe = ad7476_probe, + .remove = __devexit_p(ad7476_remove), + .id_table = ad7476_id, +}; +module_spi_driver(ad7476_driver); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices AD7475/6/7/8(A) AD7466/7/8 ADC"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/adc/ad7476.h b/drivers/staging/iio/adc/ad7476.h deleted file mode 100644 index 4ed5494..0000000 --- a/drivers/staging/iio/adc/ad7476.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * AD7476/5/7/8 (A) SPI ADC driver - * - * Copyright 2010 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ -#ifndef IIO_ADC_AD7476_H_ -#define IIO_ADC_AD7476_H_ - -#define RES_MASK(bits) ((1 << (bits)) - 1) - -struct ad7476_chip_info { - unsigned int int_vref_uv; - struct iio_chan_spec channel[2]; -}; - -struct ad7476_state { - struct spi_device *spi; - const struct ad7476_chip_info *chip_info; - struct regulator *reg; - struct spi_transfer xfer; - struct spi_message msg; - /* - * DMA (thus cache coherency maintenance) requires the - * transfer buffers to live in their own cache lines. - * Make the buffer large enough for one 16 bit sample and one 64 bit - * aligned 64 bit timestamp. - */ - unsigned char data[ALIGN(2, sizeof(s64)) + sizeof(s64)] - ____cacheline_aligned; -}; - -enum ad7476_supported_device_ids { - ID_AD7466, - ID_AD7467, - ID_AD7468, - ID_AD7495 -}; - -#ifdef CONFIG_IIO_BUFFER -int ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev); -void ad7476_ring_cleanup(struct iio_dev *indio_dev); -#else /* CONFIG_IIO_BUFFER */ - -static inline int -ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline void ad7476_ring_cleanup(struct iio_dev *indio_dev) -{ -} -#endif /* CONFIG_IIO_BUFFER */ -#endif /* IIO_ADC_AD7476_H_ */ diff --git a/drivers/staging/iio/adc/ad7476_core.c b/drivers/staging/iio/adc/ad7476_core.c deleted file mode 100644 index 3be34f9..0000000 --- a/drivers/staging/iio/adc/ad7476_core.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * AD7466/7/8 AD7476/5/7/8 (A) SPI ADC driver - * - * Copyright 2010 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "ad7476.h" - -static int ad7476_scan_direct(struct ad7476_state *st) -{ - int ret; - - ret = spi_sync(st->spi, &st->msg); - if (ret) - return ret; - - return (st->data[0] << 8) | st->data[1]; -} - -static int ad7476_read_raw(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int *val, - int *val2, - long m) -{ - int ret; - struct ad7476_state *st = iio_priv(indio_dev); - int scale_uv; - - switch (m) { - case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); - if (iio_buffer_enabled(indio_dev)) - ret = -EBUSY; - else - ret = ad7476_scan_direct(st); - mutex_unlock(&indio_dev->mlock); - - if (ret < 0) - return ret; - *val = (ret >> st->chip_info->channel[0].scan_type.shift) & - RES_MASK(st->chip_info->channel[0].scan_type.realbits); - return IIO_VAL_INT; - case IIO_CHAN_INFO_SCALE: - if (!st->chip_info->int_vref_uv) { - scale_uv = regulator_get_voltage(st->reg); - if (scale_uv < 0) - return scale_uv; - } else { - scale_uv = st->chip_info->int_vref_uv; - } - scale_uv >>= chan->scan_type.realbits; - *val = scale_uv / 1000; - *val2 = (scale_uv % 1000) * 1000; - return IIO_VAL_INT_PLUS_MICRO; - } - return -EINVAL; -} - -#define AD7476_CHAN(bits) \ - { \ - .type = IIO_VOLTAGE, \ - .indexed = 1, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT, \ - .scan_type = { \ - .sign = 'u', \ - .realbits = bits, \ - .storagebits = 16, \ - .shift = 13 - bits, \ - }, \ -} - -static const struct ad7476_chip_info ad7476_chip_info_tbl[] = { - [ID_AD7466] = { - .channel[0] = AD7476_CHAN(12), - .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), - }, - [ID_AD7467] = { - .channel[0] = AD7476_CHAN(10), - .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), - }, - [ID_AD7468] = { - .channel[0] = AD7476_CHAN(8), - .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), - }, - [ID_AD7495] = { - .channel[0] = AD7476_CHAN(12), - .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), - .int_vref_uv = 2500000, - }, -}; - -static const struct iio_info ad7476_info = { - .driver_module = THIS_MODULE, - .read_raw = &ad7476_read_raw, -}; - -static int __devinit ad7476_probe(struct spi_device *spi) -{ - struct ad7476_state *st; - struct iio_dev *indio_dev; - int ret; - - indio_dev = iio_device_alloc(sizeof(*st)); - if (indio_dev == NULL) { - ret = -ENOMEM; - goto error_ret; - } - st = iio_priv(indio_dev); - st->chip_info = - &ad7476_chip_info_tbl[spi_get_device_id(spi)->driver_data]; - - st->reg = regulator_get(&spi->dev, "vcc"); - if (IS_ERR(st->reg)) { - ret = PTR_ERR(st->reg); - goto error_free_dev; - } - - ret = regulator_enable(st->reg); - if (ret) - goto error_put_reg; - - spi_set_drvdata(spi, indio_dev); - - st->spi = spi; - - /* Establish that the iio_dev is a child of the spi device */ - indio_dev->dev.parent = &spi->dev; - indio_dev->name = spi_get_device_id(spi)->name; - indio_dev->modes = INDIO_DIRECT_MODE; - indio_dev->channels = st->chip_info->channel; - indio_dev->num_channels = 2; - indio_dev->info = &ad7476_info; - /* Setup default message */ - - st->xfer.rx_buf = &st->data; - st->xfer.len = st->chip_info->channel[0].scan_type.storagebits / 8; - - spi_message_init(&st->msg); - spi_message_add_tail(&st->xfer, &st->msg); - - ret = ad7476_register_ring_funcs_and_init(indio_dev); - if (ret) - goto error_disable_reg; - - ret = iio_device_register(indio_dev); - if (ret) - goto error_ring_unregister; - return 0; - -error_ring_unregister: - ad7476_ring_cleanup(indio_dev); -error_disable_reg: - regulator_disable(st->reg); -error_put_reg: - regulator_put(st->reg); -error_free_dev: - iio_device_free(indio_dev); - -error_ret: - return ret; -} - -static int __devexit ad7476_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct ad7476_state *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - ad7476_ring_cleanup(indio_dev); - regulator_disable(st->reg); - regulator_put(st->reg); - iio_device_free(indio_dev); - - return 0; -} - -static const struct spi_device_id ad7476_id[] = { - {"ad7466", ID_AD7466}, - {"ad7467", ID_AD7467}, - {"ad7468", ID_AD7468}, - {"ad7475", ID_AD7466}, - {"ad7476", ID_AD7466}, - {"ad7476a", ID_AD7466}, - {"ad7477", ID_AD7467}, - {"ad7477a", ID_AD7467}, - {"ad7478", ID_AD7468}, - {"ad7478a", ID_AD7468}, - {"ad7495", ID_AD7495}, - {} -}; -MODULE_DEVICE_TABLE(spi, ad7476_id); - -static struct spi_driver ad7476_driver = { - .driver = { - .name = "ad7476", - .owner = THIS_MODULE, - }, - .probe = ad7476_probe, - .remove = __devexit_p(ad7476_remove), - .id_table = ad7476_id, -}; -module_spi_driver(ad7476_driver); - -MODULE_AUTHOR("Michael Hennerich "); -MODULE_DESCRIPTION("Analog Devices AD7475/6/7/8(A) AD7466/7/8 ADC"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/adc/ad7476_ring.c b/drivers/staging/iio/adc/ad7476_ring.c deleted file mode 100644 index 3c869b0..0000000 --- a/drivers/staging/iio/adc/ad7476_ring.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2010-2012 Analog Devices Inc. - * Copyright (C) 2008 Jonathan Cameron - * - * Licensed under the GPL-2 or later. - * - * ad7476_ring.c - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "ad7476.h" - -static irqreturn_t ad7476_trigger_handler(int irq, void *p) -{ - struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->indio_dev; - struct ad7476_state *st = iio_priv(indio_dev); - s64 time_ns; - int b_sent; - - b_sent = spi_sync(st->spi, &st->msg); - if (b_sent < 0) - goto done; - - time_ns = iio_get_time_ns(); - - if (indio_dev->scan_timestamp) - ((s64 *)st->data)[1] = time_ns; - - iio_push_to_buffer(indio_dev->buffer, st->data); -done: - iio_trigger_notify_done(indio_dev->trig); - - return IRQ_HANDLED; -} - -int ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev) -{ - return iio_triggered_buffer_setup(indio_dev, NULL, - &ad7476_trigger_handler, NULL); -} - -void ad7476_ring_cleanup(struct iio_dev *indio_dev) -{ - iio_triggered_buffer_cleanup(indio_dev); -} -- cgit v0.10.2 From 610a407cdc5a8ab5358fb253b3c5457452ff1d75 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 10 Sep 2012 09:34:00 +0100 Subject: staging:iio:ad7476: Use be16_to_cpup instead of open-coding it Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/adc/ad7476.c b/drivers/staging/iio/adc/ad7476.c index 12e6e4b..a33a406 100644 --- a/drivers/staging/iio/adc/ad7476.c +++ b/drivers/staging/iio/adc/ad7476.c @@ -83,7 +83,7 @@ static int ad7476_scan_direct(struct ad7476_state *st) if (ret) return ret; - return (st->data[0] << 8) | st->data[1]; + return be16_to_cpup((__be16 *)st->data); } static int ad7476_read_raw(struct iio_dev *indio_dev, -- cgit v0.10.2 From 968f3d5ba006d21677145739d8b3f864b5af15c6 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 10 Sep 2012 09:34:00 +0100 Subject: iio: Move ad7476 driver out of staging The ad7476 driver is a driver for simple single channel ADCs. The driver does not export any experimental or custom ABI files nor do the static code check tools report any issues, so move the driver out of staging. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index d0ae71e..f98c493 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -30,6 +30,20 @@ config AD7791 To compile this driver as a module, choose M here: the module will be called ad7791. +config AD7476 + tristate "Analog Devices AD7475/6/7/8 AD7466/7/8 and AD7495 ADC driver" + depends on SPI + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER + help + Say yes here to build support for Analog Devices + AD7475, AD7476, AD7477, AD7478, AD7466, AD7467, AD7468, AD7495 + SPI analog to digital converters (ADC). + If unsure, say N (but it's safe to say "Y"). + + To compile this driver as a module, choose M here: the + module will be called ad7476. + config AT91_ADC tristate "Atmel AT91 ADC" depends on ARCH_AT91 diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index f187ff6..9824a70 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -4,5 +4,6 @@ obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o obj-$(CONFIG_AD7266) += ad7266.o +obj-$(CONFIG_AD7476) += ad7476.o obj-$(CONFIG_AD7791) += ad7791.o obj-$(CONFIG_AT91_ADC) += at91_adc.o diff --git a/drivers/iio/adc/ad7476.c b/drivers/iio/adc/ad7476.c new file mode 100644 index 0000000..a33a406 --- /dev/null +++ b/drivers/iio/adc/ad7476.c @@ -0,0 +1,278 @@ +/* + * AD7466/7/8 AD7476/5/7/8 (A) SPI ADC driver + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define RES_MASK(bits) ((1 << (bits)) - 1) + +struct ad7476_chip_info { + unsigned int int_vref_uv; + struct iio_chan_spec channel[2]; +}; + +struct ad7476_state { + struct spi_device *spi; + const struct ad7476_chip_info *chip_info; + struct regulator *reg; + struct spi_transfer xfer; + struct spi_message msg; + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + * Make the buffer large enough for one 16 bit sample and one 64 bit + * aligned 64 bit timestamp. + */ + unsigned char data[ALIGN(2, sizeof(s64)) + sizeof(s64)] + ____cacheline_aligned; +}; + +enum ad7476_supported_device_ids { + ID_AD7466, + ID_AD7467, + ID_AD7468, + ID_AD7495 +}; + +static irqreturn_t ad7476_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct ad7476_state *st = iio_priv(indio_dev); + s64 time_ns; + int b_sent; + + b_sent = spi_sync(st->spi, &st->msg); + if (b_sent < 0) + goto done; + + time_ns = iio_get_time_ns(); + + if (indio_dev->scan_timestamp) + ((s64 *)st->data)[1] = time_ns; + + iio_push_to_buffer(indio_dev->buffer, st->data); +done: + iio_trigger_notify_done(indio_dev->trig); + + return IRQ_HANDLED; +} + +static int ad7476_scan_direct(struct ad7476_state *st) +{ + int ret; + + ret = spi_sync(st->spi, &st->msg); + if (ret) + return ret; + + return be16_to_cpup((__be16 *)st->data); +} + +static int ad7476_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long m) +{ + int ret; + struct ad7476_state *st = iio_priv(indio_dev); + int scale_uv; + + switch (m) { + case IIO_CHAN_INFO_RAW: + mutex_lock(&indio_dev->mlock); + if (iio_buffer_enabled(indio_dev)) + ret = -EBUSY; + else + ret = ad7476_scan_direct(st); + mutex_unlock(&indio_dev->mlock); + + if (ret < 0) + return ret; + *val = (ret >> st->chip_info->channel[0].scan_type.shift) & + RES_MASK(st->chip_info->channel[0].scan_type.realbits); + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + if (!st->chip_info->int_vref_uv) { + scale_uv = regulator_get_voltage(st->reg); + if (scale_uv < 0) + return scale_uv; + } else { + scale_uv = st->chip_info->int_vref_uv; + } + scale_uv >>= chan->scan_type.realbits; + *val = scale_uv / 1000; + *val2 = (scale_uv % 1000) * 1000; + return IIO_VAL_INT_PLUS_MICRO; + } + return -EINVAL; +} + +#define AD7476_CHAN(bits) \ + { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .scan_type = { \ + .sign = 'u', \ + .realbits = bits, \ + .storagebits = 16, \ + .shift = 13 - bits, \ + }, \ +} + +static const struct ad7476_chip_info ad7476_chip_info_tbl[] = { + [ID_AD7466] = { + .channel[0] = AD7476_CHAN(12), + .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), + }, + [ID_AD7467] = { + .channel[0] = AD7476_CHAN(10), + .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), + }, + [ID_AD7468] = { + .channel[0] = AD7476_CHAN(8), + .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), + }, + [ID_AD7495] = { + .channel[0] = AD7476_CHAN(12), + .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), + .int_vref_uv = 2500000, + }, +}; + +static const struct iio_info ad7476_info = { + .driver_module = THIS_MODULE, + .read_raw = &ad7476_read_raw, +}; + +static int __devinit ad7476_probe(struct spi_device *spi) +{ + struct ad7476_state *st; + struct iio_dev *indio_dev; + int ret; + + indio_dev = iio_device_alloc(sizeof(*st)); + if (indio_dev == NULL) { + ret = -ENOMEM; + goto error_ret; + } + st = iio_priv(indio_dev); + st->chip_info = + &ad7476_chip_info_tbl[spi_get_device_id(spi)->driver_data]; + + st->reg = regulator_get(&spi->dev, "vcc"); + if (IS_ERR(st->reg)) { + ret = PTR_ERR(st->reg); + goto error_free_dev; + } + + ret = regulator_enable(st->reg); + if (ret) + goto error_put_reg; + + spi_set_drvdata(spi, indio_dev); + + st->spi = spi; + + /* Establish that the iio_dev is a child of the spi device */ + indio_dev->dev.parent = &spi->dev; + indio_dev->name = spi_get_device_id(spi)->name; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = st->chip_info->channel; + indio_dev->num_channels = 2; + indio_dev->info = &ad7476_info; + /* Setup default message */ + + st->xfer.rx_buf = &st->data; + st->xfer.len = st->chip_info->channel[0].scan_type.storagebits / 8; + + spi_message_init(&st->msg); + spi_message_add_tail(&st->xfer, &st->msg); + + ret = iio_triggered_buffer_setup(indio_dev, NULL, + &ad7476_trigger_handler, NULL); + if (ret) + goto error_disable_reg; + + ret = iio_device_register(indio_dev); + if (ret) + goto error_ring_unregister; + return 0; + +error_ring_unregister: + iio_triggered_buffer_cleanup(indio_dev); +error_disable_reg: + regulator_disable(st->reg); +error_put_reg: + regulator_put(st->reg); +error_free_dev: + iio_device_free(indio_dev); + +error_ret: + return ret; +} + +static int __devexit ad7476_remove(struct spi_device *spi) +{ + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct ad7476_state *st = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + iio_triggered_buffer_cleanup(indio_dev); + regulator_disable(st->reg); + regulator_put(st->reg); + iio_device_free(indio_dev); + + return 0; +} + +static const struct spi_device_id ad7476_id[] = { + {"ad7466", ID_AD7466}, + {"ad7467", ID_AD7467}, + {"ad7468", ID_AD7468}, + {"ad7475", ID_AD7466}, + {"ad7476", ID_AD7466}, + {"ad7476a", ID_AD7466}, + {"ad7477", ID_AD7467}, + {"ad7477a", ID_AD7467}, + {"ad7478", ID_AD7468}, + {"ad7478a", ID_AD7468}, + {"ad7495", ID_AD7495}, + {} +}; +MODULE_DEVICE_TABLE(spi, ad7476_id); + +static struct spi_driver ad7476_driver = { + .driver = { + .name = "ad7476", + .owner = THIS_MODULE, + }, + .probe = ad7476_probe, + .remove = __devexit_p(ad7476_remove), + .id_table = ad7476_id, +}; +module_spi_driver(ad7476_driver); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices AD7475/6/7/8(A) AD7466/7/8 ADC"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index a1fa172..1b4a356 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -68,20 +68,6 @@ config AD799X_RING_BUFFER Say yes here to include ring buffer support in the AD799X ADC driver. -config AD7476 - tristate "Analog Devices AD7475/6/7/8 AD7466/7/8 and AD7495 ADC driver" - depends on SPI - select IIO_BUFFER - select IIO_TRIGGERED_BUFFER - help - Say yes here to build support for Analog Devices - AD7475, AD7476, AD7477, AD7478, AD7466, AD7467, AD7468, AD7495 - SPI analog to digital converters (ADC). - If unsure, say N (but it's safe to say "Y"). - - To compile this driver as a module, choose M here: the - module will be called ad7476. - config AD7887 tristate "Analog Devices AD7887 ADC driver" depends on SPI diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile index 6b60af0..62ee02e 100644 --- a/drivers/staging/iio/adc/Makefile +++ b/drivers/staging/iio/adc/Makefile @@ -17,8 +17,6 @@ ad799x-y := ad799x_core.o ad799x-$(CONFIG_AD799X_RING_BUFFER) += ad799x_ring.o obj-$(CONFIG_AD799X) += ad799x.o -obj-$(CONFIG_AD7476) += ad7476.o - ad7887-y := ad7887_core.o ad7887-$(CONFIG_IIO_BUFFER) += ad7887_ring.o obj-$(CONFIG_AD7887) += ad7887.o diff --git a/drivers/staging/iio/adc/ad7476.c b/drivers/staging/iio/adc/ad7476.c deleted file mode 100644 index a33a406..0000000 --- a/drivers/staging/iio/adc/ad7476.c +++ /dev/null @@ -1,278 +0,0 @@ -/* - * AD7466/7/8 AD7476/5/7/8 (A) SPI ADC driver - * - * Copyright 2010 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#define RES_MASK(bits) ((1 << (bits)) - 1) - -struct ad7476_chip_info { - unsigned int int_vref_uv; - struct iio_chan_spec channel[2]; -}; - -struct ad7476_state { - struct spi_device *spi; - const struct ad7476_chip_info *chip_info; - struct regulator *reg; - struct spi_transfer xfer; - struct spi_message msg; - /* - * DMA (thus cache coherency maintenance) requires the - * transfer buffers to live in their own cache lines. - * Make the buffer large enough for one 16 bit sample and one 64 bit - * aligned 64 bit timestamp. - */ - unsigned char data[ALIGN(2, sizeof(s64)) + sizeof(s64)] - ____cacheline_aligned; -}; - -enum ad7476_supported_device_ids { - ID_AD7466, - ID_AD7467, - ID_AD7468, - ID_AD7495 -}; - -static irqreturn_t ad7476_trigger_handler(int irq, void *p) -{ - struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->indio_dev; - struct ad7476_state *st = iio_priv(indio_dev); - s64 time_ns; - int b_sent; - - b_sent = spi_sync(st->spi, &st->msg); - if (b_sent < 0) - goto done; - - time_ns = iio_get_time_ns(); - - if (indio_dev->scan_timestamp) - ((s64 *)st->data)[1] = time_ns; - - iio_push_to_buffer(indio_dev->buffer, st->data); -done: - iio_trigger_notify_done(indio_dev->trig); - - return IRQ_HANDLED; -} - -static int ad7476_scan_direct(struct ad7476_state *st) -{ - int ret; - - ret = spi_sync(st->spi, &st->msg); - if (ret) - return ret; - - return be16_to_cpup((__be16 *)st->data); -} - -static int ad7476_read_raw(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int *val, - int *val2, - long m) -{ - int ret; - struct ad7476_state *st = iio_priv(indio_dev); - int scale_uv; - - switch (m) { - case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); - if (iio_buffer_enabled(indio_dev)) - ret = -EBUSY; - else - ret = ad7476_scan_direct(st); - mutex_unlock(&indio_dev->mlock); - - if (ret < 0) - return ret; - *val = (ret >> st->chip_info->channel[0].scan_type.shift) & - RES_MASK(st->chip_info->channel[0].scan_type.realbits); - return IIO_VAL_INT; - case IIO_CHAN_INFO_SCALE: - if (!st->chip_info->int_vref_uv) { - scale_uv = regulator_get_voltage(st->reg); - if (scale_uv < 0) - return scale_uv; - } else { - scale_uv = st->chip_info->int_vref_uv; - } - scale_uv >>= chan->scan_type.realbits; - *val = scale_uv / 1000; - *val2 = (scale_uv % 1000) * 1000; - return IIO_VAL_INT_PLUS_MICRO; - } - return -EINVAL; -} - -#define AD7476_CHAN(bits) \ - { \ - .type = IIO_VOLTAGE, \ - .indexed = 1, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT, \ - .scan_type = { \ - .sign = 'u', \ - .realbits = bits, \ - .storagebits = 16, \ - .shift = 13 - bits, \ - }, \ -} - -static const struct ad7476_chip_info ad7476_chip_info_tbl[] = { - [ID_AD7466] = { - .channel[0] = AD7476_CHAN(12), - .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), - }, - [ID_AD7467] = { - .channel[0] = AD7476_CHAN(10), - .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), - }, - [ID_AD7468] = { - .channel[0] = AD7476_CHAN(8), - .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), - }, - [ID_AD7495] = { - .channel[0] = AD7476_CHAN(12), - .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), - .int_vref_uv = 2500000, - }, -}; - -static const struct iio_info ad7476_info = { - .driver_module = THIS_MODULE, - .read_raw = &ad7476_read_raw, -}; - -static int __devinit ad7476_probe(struct spi_device *spi) -{ - struct ad7476_state *st; - struct iio_dev *indio_dev; - int ret; - - indio_dev = iio_device_alloc(sizeof(*st)); - if (indio_dev == NULL) { - ret = -ENOMEM; - goto error_ret; - } - st = iio_priv(indio_dev); - st->chip_info = - &ad7476_chip_info_tbl[spi_get_device_id(spi)->driver_data]; - - st->reg = regulator_get(&spi->dev, "vcc"); - if (IS_ERR(st->reg)) { - ret = PTR_ERR(st->reg); - goto error_free_dev; - } - - ret = regulator_enable(st->reg); - if (ret) - goto error_put_reg; - - spi_set_drvdata(spi, indio_dev); - - st->spi = spi; - - /* Establish that the iio_dev is a child of the spi device */ - indio_dev->dev.parent = &spi->dev; - indio_dev->name = spi_get_device_id(spi)->name; - indio_dev->modes = INDIO_DIRECT_MODE; - indio_dev->channels = st->chip_info->channel; - indio_dev->num_channels = 2; - indio_dev->info = &ad7476_info; - /* Setup default message */ - - st->xfer.rx_buf = &st->data; - st->xfer.len = st->chip_info->channel[0].scan_type.storagebits / 8; - - spi_message_init(&st->msg); - spi_message_add_tail(&st->xfer, &st->msg); - - ret = iio_triggered_buffer_setup(indio_dev, NULL, - &ad7476_trigger_handler, NULL); - if (ret) - goto error_disable_reg; - - ret = iio_device_register(indio_dev); - if (ret) - goto error_ring_unregister; - return 0; - -error_ring_unregister: - iio_triggered_buffer_cleanup(indio_dev); -error_disable_reg: - regulator_disable(st->reg); -error_put_reg: - regulator_put(st->reg); -error_free_dev: - iio_device_free(indio_dev); - -error_ret: - return ret; -} - -static int __devexit ad7476_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct ad7476_state *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - iio_triggered_buffer_cleanup(indio_dev); - regulator_disable(st->reg); - regulator_put(st->reg); - iio_device_free(indio_dev); - - return 0; -} - -static const struct spi_device_id ad7476_id[] = { - {"ad7466", ID_AD7466}, - {"ad7467", ID_AD7467}, - {"ad7468", ID_AD7468}, - {"ad7475", ID_AD7466}, - {"ad7476", ID_AD7466}, - {"ad7476a", ID_AD7466}, - {"ad7477", ID_AD7467}, - {"ad7477a", ID_AD7467}, - {"ad7478", ID_AD7468}, - {"ad7478a", ID_AD7468}, - {"ad7495", ID_AD7495}, - {} -}; -MODULE_DEVICE_TABLE(spi, ad7476_id); - -static struct spi_driver ad7476_driver = { - .driver = { - .name = "ad7476", - .owner = THIS_MODULE, - }, - .probe = ad7476_probe, - .remove = __devexit_p(ad7476_remove), - .id_table = ad7476_id, -}; -module_spi_driver(ad7476_driver); - -MODULE_AUTHOR("Michael Hennerich "); -MODULE_DESCRIPTION("Analog Devices AD7475/6/7/8(A) AD7466/7/8 ADC"); -MODULE_LICENSE("GPL v2"); -- cgit v0.10.2 From ac5332b1475b474a478d9336635849339546e235 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 10 Sep 2012 09:34:00 +0100 Subject: iio:ad7476: Add ad7910/ad7920 device table entries The ad7910/ad7920 are software compatible to the ad7467/ad7466. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index f98c493..c71a000 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -31,14 +31,15 @@ config AD7791 called ad7791. config AD7476 - tristate "Analog Devices AD7475/6/7/8 AD7466/7/8 and AD7495 ADC driver" + tristate "Analog Devices AD7476 and similar 1-channel ADCs driver" depends on SPI select IIO_BUFFER select IIO_TRIGGERED_BUFFER help - Say yes here to build support for Analog Devices - AD7475, AD7476, AD7477, AD7478, AD7466, AD7467, AD7468, AD7495 - SPI analog to digital converters (ADC). + Say yes here to build support for Analog Devices AD7475, AD7476, AD7477, + AD7478, AD7466, AD7467, AD7468, AD7495, AD7910, AD7920 SPI analog to + digital converters (ADC). + If unsure, say N (but it's safe to say "Y"). To compile this driver as a module, choose M here: the diff --git a/drivers/iio/adc/ad7476.c b/drivers/iio/adc/ad7476.c index a33a406..093a4ed 100644 --- a/drivers/iio/adc/ad7476.c +++ b/drivers/iio/adc/ad7476.c @@ -258,6 +258,8 @@ static const struct spi_device_id ad7476_id[] = { {"ad7478", ID_AD7468}, {"ad7478a", ID_AD7468}, {"ad7495", ID_AD7495}, + {"ad7910", ID_AD7467}, + {"ad7920", ID_AD7466}, {} }; MODULE_DEVICE_TABLE(spi, ad7476_id); @@ -274,5 +276,5 @@ static struct spi_driver ad7476_driver = { module_spi_driver(ad7476_driver); MODULE_AUTHOR("Michael Hennerich "); -MODULE_DESCRIPTION("Analog Devices AD7475/6/7/8(A) AD7466/7/8 ADC"); +MODULE_DESCRIPTION("Analog Devices AD7476 and similar 1-channel ADCs"); MODULE_LICENSE("GPL v2"); -- cgit v0.10.2 From 4c337de870d9bd1459ab603574256bb0e7644ad6 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 10 Sep 2012 09:34:00 +0100 Subject: iio:ad7476: Add ad7940 support The AD7940 is a single channel 14 bit ADC similar to the ADCs already supported by the ad7476 driver, but it does have a different shift factor. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index c71a000..e2e6963 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -37,8 +37,8 @@ config AD7476 select IIO_TRIGGERED_BUFFER help Say yes here to build support for Analog Devices AD7475, AD7476, AD7477, - AD7478, AD7466, AD7467, AD7468, AD7495, AD7910, AD7920 SPI analog to - digital converters (ADC). + AD7478, AD7466, AD7467, AD7468, AD7495, AD7910, AD7920, AD7920 SPI analog + to digital converters (ADC). If unsure, say N (but it's safe to say "Y"). diff --git a/drivers/iio/adc/ad7476.c b/drivers/iio/adc/ad7476.c index 093a4ed..be22757 100644 --- a/drivers/iio/adc/ad7476.c +++ b/drivers/iio/adc/ad7476.c @@ -48,7 +48,8 @@ enum ad7476_supported_device_ids { ID_AD7466, ID_AD7467, ID_AD7468, - ID_AD7495 + ID_AD7495, + ID_AD7940, }; static irqreturn_t ad7476_trigger_handler(int irq, void *p) @@ -126,7 +127,7 @@ static int ad7476_read_raw(struct iio_dev *indio_dev, return -EINVAL; } -#define AD7476_CHAN(bits) \ +#define _AD7476_CHAN(bits, _shift) \ { \ .type = IIO_VOLTAGE, \ .indexed = 1, \ @@ -134,12 +135,16 @@ static int ad7476_read_raw(struct iio_dev *indio_dev, IIO_CHAN_INFO_SCALE_SHARED_BIT, \ .scan_type = { \ .sign = 'u', \ - .realbits = bits, \ + .realbits = (bits), \ .storagebits = 16, \ - .shift = 13 - bits, \ + .shift = (_shift), \ + .endianness = IIO_BE, \ }, \ } +#define AD7476_CHAN(bits) _AD7476_CHAN((bits), 13 - (bits)) +#define AD7940_CHAN(bits) _AD7476_CHAN((bits), 15 - (bits)) + static const struct ad7476_chip_info ad7476_chip_info_tbl[] = { [ID_AD7466] = { .channel[0] = AD7476_CHAN(12), @@ -158,6 +163,10 @@ static const struct ad7476_chip_info ad7476_chip_info_tbl[] = { .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), .int_vref_uv = 2500000, }, + [ID_AD7940] = { + .channel[0] = AD7940_CHAN(14), + .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), + }, }; static const struct iio_info ad7476_info = { @@ -260,6 +269,7 @@ static const struct spi_device_id ad7476_id[] = { {"ad7495", ID_AD7495}, {"ad7910", ID_AD7467}, {"ad7920", ID_AD7466}, + {"ad7940", ID_AD7940}, {} }; MODULE_DEVICE_TABLE(spi, ad7476_id); -- cgit v0.10.2 From c26cc89e8d758804499dcaa58ba7d2a993b954fe Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 10 Sep 2012 10:33:00 +0100 Subject: iio:ad7476: Add support for ad7273/ad7274/ad7276/ad7277/ad7278 The ad7276/ad7277/ad7278 are similar to the ad7476/ad7477/ad7478 but have the same number of leading zeros as the ad7940. The ad7273/ad7274 have a extra pin for VREF where as for the ad7276/ad7277/ad7278 VREF is taken from VDD, but otherwise they are compatible to the ad7276/ad7277. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index e2e6963..03791a6 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -36,9 +36,9 @@ config AD7476 select IIO_BUFFER select IIO_TRIGGERED_BUFFER help - Say yes here to build support for Analog Devices AD7475, AD7476, AD7477, - AD7478, AD7466, AD7467, AD7468, AD7495, AD7910, AD7920, AD7920 SPI analog - to digital converters (ADC). + Say yes here to build support for Analog Devices AD7273, AD7274, AD7276, + AD7277, AD7278, AD7475, AD7476, AD7477, AD7478, AD7466, AD7467, AD7468, + AD7495, AD7910, AD7920, AD7920 SPI analog to digital converters (ADC). If unsure, say N (but it's safe to say "Y"). diff --git a/drivers/iio/adc/ad7476.c b/drivers/iio/adc/ad7476.c index be22757..be2098d 100644 --- a/drivers/iio/adc/ad7476.c +++ b/drivers/iio/adc/ad7476.c @@ -45,6 +45,9 @@ struct ad7476_state { }; enum ad7476_supported_device_ids { + ID_AD7276, + ID_AD7277, + ID_AD7278, ID_AD7466, ID_AD7467, ID_AD7468, @@ -146,6 +149,18 @@ static int ad7476_read_raw(struct iio_dev *indio_dev, #define AD7940_CHAN(bits) _AD7476_CHAN((bits), 15 - (bits)) static const struct ad7476_chip_info ad7476_chip_info_tbl[] = { + [ID_AD7276] = { + .channel[0] = AD7940_CHAN(12), + .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), + }, + [ID_AD7277] = { + .channel[0] = AD7940_CHAN(10), + .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), + }, + [ID_AD7278] = { + .channel[0] = AD7940_CHAN(8), + .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), + }, [ID_AD7466] = { .channel[0] = AD7476_CHAN(12), .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), @@ -256,6 +271,11 @@ static int __devexit ad7476_remove(struct spi_device *spi) } static const struct spi_device_id ad7476_id[] = { + {"ad7273", ID_AD7277}, + {"ad7274", ID_AD7276}, + {"ad7276", ID_AD7276}, + {"ad7277", ID_AD7277}, + {"ad7278", ID_AD7278}, {"ad7466", ID_AD7466}, {"ad7467", ID_AD7467}, {"ad7468", ID_AD7468}, -- cgit v0.10.2 From ca7d1b32d2a0d4c62533b9401cf9ce4d14d183f7 Mon Sep 17 00:00:00 2001 From: anish kumar Date: Sat, 8 Sep 2012 20:42:00 +0100 Subject: iio: Documentation change for inkern interface. This commit- 314be14bb renamed the _st_ functions to loose the bit that was meant for staging version but forgot to change the documentation which still have _st_ sprinkled in some of the places. Signed-off-by: anish kumar Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/Documentation/inkernel.txt b/drivers/staging/iio/Documentation/inkernel.txt index a05823e..ab528409 100644 --- a/drivers/staging/iio/Documentation/inkernel.txt +++ b/drivers/staging/iio/Documentation/inkernel.txt @@ -48,11 +48,11 @@ There are then a number of functions that can be used to get information about this channel such as it's current reading. e.g. -iio_st_read_channel_raw() - get a reading -iio_st_read_channel_type() - get the type of channel +iio_read_channel_raw() - get a reading +iio_get_channel_type() - get the type of channel There is also provision for retrieving all of the channels associated with a given consumer. This is useful for generic drivers such as iio_hwmon where the number and naming of channels is not known by the -consumer driver. To do this, use iio_st_channel_get_all. +consumer driver. To do this, use iio_channel_get_all. -- cgit v0.10.2 From 7985e7c1003bc5cdfa20755f8cfdada946ed8e18 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 14 Sep 2012 16:21:00 +0100 Subject: iio: Introduce a new fractional value type Currently IIO uses a decimal fixed point representations for real type numbers. This patch introduces a new representation for rational type numbers. The number will be expressed by specifying a numerator and denominator. For converting a raw value to a processed value multiply it by the numerator and divide it by the denominator. The reasoning for introducing this new type is that for a lot of devices the scale can be represented easily by a fractional number, but it is not possible to represent it as fixed point number without rounding. E.g. for a simple DAC the scale is often the reference voltage divided by the number of possible values (Usually 2**n_bits - 1). Each driver currently implements the conversion of this fraction to a fixed point number on its own. Also when it comes to the in-kernel interface this allows to directly use the fractional factors to convert a raw value to a processed value. This should on one hand require less instructions and on the other hand increase the precision. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 0499330..6eb24db 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -366,6 +366,7 @@ static ssize_t iio_read_channel_info(struct device *dev, { struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + unsigned long long tmp; int val, val2; bool scale_db = false; int ret = indio_dev->info->read_raw(indio_dev, this_attr->c, @@ -391,6 +392,11 @@ static ssize_t iio_read_channel_info(struct device *dev, return sprintf(buf, "-%d.%09u\n", val, -val2); else return sprintf(buf, "%d.%09u\n", val, val2); + case IIO_VAL_FRACTIONAL: + tmp = div_s64((s64)val * 1000000000LL, val2); + val2 = do_div(tmp, 1000000000LL); + val = tmp; + return sprintf(buf, "%d.%09u\n", val, val2); default: return 0; } diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h index 44e3977..5c647ec 100644 --- a/include/linux/iio/types.h +++ b/include/linux/iio/types.h @@ -57,5 +57,6 @@ enum iio_modifier { #define IIO_VAL_INT_PLUS_MICRO 2 #define IIO_VAL_INT_PLUS_NANO 3 #define IIO_VAL_INT_PLUS_MICRO_DB 4 +#define IIO_VAL_FRACTIONAL 10 #endif /* _IIO_TYPES_H_ */ -- cgit v0.10.2 From 2cc412b513f70ce914a3554a34917f7585a16f04 Mon Sep 17 00:00:00 2001 From: "Kim, Milo" Date: Fri, 14 Sep 2012 02:24:00 +0100 Subject: iio: inkern: allocate zeroed memory Use kzalloc() rather than kmalloc() for initializing the iio_channel structure. This patch enables the iio_dev and iio_chan_spec are set to NULL. This may prevent the page fault problem because the pointer of iio_chan_spec is initialized as NULL. The iio_chan_spec is updated only in case that the IIO map has specific channel label. When the map has no ADC channel label, then the value of iio_chan_spec remains as invalid pointer. To prevent this problem, the pointer should be initialized as NULL. Signed-off-by: Milo(Woogyom) Kim Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index a14e55d..028c657 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -130,7 +130,7 @@ struct iio_channel *iio_channel_get(const char *name, const char *channel_name) if (c == NULL) return ERR_PTR(-ENODEV); - channel = kmalloc(sizeof(*channel), GFP_KERNEL); + channel = kzalloc(sizeof(*channel), GFP_KERNEL); if (channel == NULL) return ERR_PTR(-ENOMEM); -- cgit v0.10.2 From ca33f4ce35648c2301f398052d0081ebc8e5d7cd Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:33:58 +0100 Subject: staging: comedi: ni_6527: convert printk() to dev_...() Convert the `printk()` calls in this drivers to use the `dev_...()` calls instead. Remove the initial `printk()` call in the comedi `attach()` handler (`ni6527_attach()`) as it's a bit redundant - the board type and contents of a board ID register are printed later in the function. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index cfebd0b..1f52f36 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -369,8 +369,6 @@ static int ni6527_attach(struct comedi_device *dev, struct comedi_devconfig *it) struct comedi_subdevice *s; int ret; - printk(KERN_INFO "comedi%d: ni6527\n", dev->minor); - ret = alloc_private(dev, sizeof(struct ni6527_private)); if (ret < 0) return ret; @@ -381,13 +379,13 @@ static int ni6527_attach(struct comedi_device *dev, struct comedi_devconfig *it) ret = mite_setup(devpriv->mite); if (ret < 0) { - printk(KERN_ERR "comedi: error setting up mite\n"); + dev_err(dev->class_dev, "error setting up mite\n"); return ret; } dev->board_name = this_board->name; - printk(KERN_INFO "comedi board: %s, ID=0x%02x\n", dev->board_name, - readb(devpriv->mite->daq_io_addr + ID_Register)); + dev_info(dev->class_dev, "board: %s, ID=0x%02x\n", dev->board_name, + readb(devpriv->mite->daq_io_addr + ID_Register)); ret = comedi_alloc_subdevices(dev, 3); if (ret) @@ -434,7 +432,7 @@ static int ni6527_attach(struct comedi_device *dev, struct comedi_devconfig *it) ret = request_irq(mite_irq(devpriv->mite), ni6527_interrupt, IRQF_SHARED, "ni6527", dev); if (ret < 0) - printk(KERN_WARNING "comedi i6527 irq not available\n"); + dev_warn(dev->class_dev, "irq not available\n"); else dev->irq = mite_irq(devpriv->mite); @@ -473,7 +471,7 @@ static int ni6527_find_device(struct comedi_device *dev, int bus, int slot) } } } - printk(KERN_ERR "comedi 6527: no device found\n"); + dev_err(dev->class_dev, "ni6527: no device found\n"); mite_list_devices(); return -EIO; } -- cgit v0.10.2 From 38b951f18e3535c62bc288aeefa14a790efa8072 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:33:59 +0100 Subject: staging: comedi: ni_6527: change driver name string Change the driver name string used in data structures, kernel messages, etc. from "ni6527" to "ni_6527" to match the module name. Use a macro `DRIVER_NAME` that expands to this string literal. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index 1f52f36..6f0659a 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -46,6 +46,8 @@ Updated: Sat, 25 Jan 2003 13:24:40 -0800 #include "mite.h" +#define DRIVER_NAME "ni_6527" + #define NI6527_DIO_SIZE 4096 #define NI6527_MITE_SIZE 4096 @@ -80,7 +82,7 @@ static int ni6527_attach(struct comedi_device *dev, struct comedi_devconfig *it); static void ni6527_detach(struct comedi_device *dev); static struct comedi_driver driver_ni6527 = { - .driver_name = "ni6527", + .driver_name = DRIVER_NAME, .module = THIS_MODULE, .attach = ni6527_attach, .detach = ni6527_detach, @@ -430,7 +432,7 @@ static int ni6527_attach(struct comedi_device *dev, struct comedi_devconfig *it) writeb(0x00, devpriv->mite->daq_io_addr + Master_Interrupt_Control); ret = request_irq(mite_irq(devpriv->mite), ni6527_interrupt, - IRQF_SHARED, "ni6527", dev); + IRQF_SHARED, DRIVER_NAME, dev); if (ret < 0) dev_warn(dev->class_dev, "irq not available\n"); else @@ -471,7 +473,7 @@ static int ni6527_find_device(struct comedi_device *dev, int bus, int slot) } } } - dev_err(dev->class_dev, "ni6527: no device found\n"); + dev_err(dev->class_dev, DRIVER_NAME ": no device found\n"); mite_list_devices(); return -EIO; } -- cgit v0.10.2 From 7ae09413c7195f87d02e7fd0a67ba6dafbab4546 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:34:00 +0100 Subject: staging: comedi: ni_6527: use module_comedi_pci_driver() Use the macro `module_comedi_pci_driver(comedi_driver, pci_driver)` to register the module as a Comedi PCI driver. Rename variables and functions that have prefix `driver_` for consistency. Set the `name` member of the `struct pci_driver` variable in its initializer instead of initializing it in the module initialization function. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index 6f0659a..79e756b 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -81,7 +81,7 @@ Updated: Sat, 25 Jan 2003 13:24:40 -0800 static int ni6527_attach(struct comedi_device *dev, struct comedi_devconfig *it); static void ni6527_detach(struct comedi_device *dev); -static struct comedi_driver driver_ni6527 = { +static struct comedi_driver ni6527_driver = { .driver_name = DRIVER_NAME, .module = THIS_MODULE, .attach = ni6527_attach, @@ -478,43 +478,24 @@ static int ni6527_find_device(struct comedi_device *dev, int bus, int slot) return -EIO; } -static int __devinit driver_ni6527_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) +static int __devinit ni6527_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, &driver_ni6527); + return comedi_pci_auto_config(dev, &ni6527_driver); } -static void __devexit driver_ni6527_pci_remove(struct pci_dev *dev) +static void __devexit ni6527_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } -static struct pci_driver driver_ni6527_pci_driver = { +static struct pci_driver ni6527_pci_driver = { + .name = DRIVER_NAME, .id_table = ni6527_pci_table, - .probe = &driver_ni6527_pci_probe, - .remove = __devexit_p(&driver_ni6527_pci_remove) + .probe = ni6527_pci_probe, + .remove = __devexit_p(ni6527_pci_remove) }; - -static int __init driver_ni6527_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&driver_ni6527); - if (retval < 0) - return retval; - - driver_ni6527_pci_driver.name = (char *)driver_ni6527.driver_name; - return pci_register_driver(&driver_ni6527_pci_driver); -} - -static void __exit driver_ni6527_cleanup_module(void) -{ - pci_unregister_driver(&driver_ni6527_pci_driver); - comedi_driver_unregister(&driver_ni6527); -} - -module_init(driver_ni6527_init_module); -module_exit(driver_ni6527_cleanup_module); +module_comedi_pci_driver(ni6527_driver, ni6527_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); -- cgit v0.10.2 From fcdd5ecd66db871befa755df768bf43fbe38d383 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:34:01 +0100 Subject: staging: comedi: ni_6527: move ni6527_driver Move the `struct comedi_driver ni6527_driver` variable further down the function to be closer to the `module_comedi_pci_driver()` module call and to avoid having to forward declare `ni6527_attach()` and `ni6527_detach()`. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index 79e756b..c666a43 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -78,16 +78,6 @@ Updated: Sat, 25 Jan 2003 13:24:40 -0800 #define Rising_Edge_Detection_Enable(x) (0x018+(x)) #define Falling_Edge_Detection_Enable(x) (0x020+(x)) -static int ni6527_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static void ni6527_detach(struct comedi_device *dev); -static struct comedi_driver ni6527_driver = { - .driver_name = DRIVER_NAME, - .module = THIS_MODULE, - .attach = ni6527_attach, - .detach = ni6527_detach, -}; - struct ni6527_board { int dev_id; @@ -478,6 +468,13 @@ static int ni6527_find_device(struct comedi_device *dev, int bus, int slot) return -EIO; } +static struct comedi_driver ni6527_driver = { + .driver_name = DRIVER_NAME, + .module = THIS_MODULE, + .attach = ni6527_attach, + .detach = ni6527_detach, +}; + static int __devinit ni6527_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { -- cgit v0.10.2 From 372959d246014478e4cb8d05356777cd2baf2b0a Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:34:02 +0100 Subject: staging: comedi: ni_6527: use comedi attach_pci callback Convert this PCI driver to use the comedi `attach_pci` callback instead of the `attach` callback for PCI auto-configuration. There is no need to support manual attachment of PCI devices supported by this driver, so remove the `attach` callback altogether. Note that this driver still uses the list of PCI "mite" devices created by the "mite" module. This will be dealt with by a later patch once dynamic allocation of "mite" structures has been implemented. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index c666a43..170edb7 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -95,7 +95,6 @@ static const struct ni6527_board ni6527_boards[] = { }, }; -#define n_ni6527_boards ARRAY_SIZE(ni6527_boards) #define this_board ((const struct ni6527_board *)dev->board_ptr) static DEFINE_PCI_DEVICE_TABLE(ni6527_pci_table) = { @@ -114,8 +113,6 @@ struct ni6527_private { #define devpriv ((struct ni6527_private *)dev->private) -static int ni6527_find_device(struct comedi_device *dev, int bus, int slot); - static int ni6527_di_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -356,7 +353,36 @@ static int ni6527_intr_insn_config(struct comedi_device *dev, return 2; } -static int ni6527_attach(struct comedi_device *dev, struct comedi_devconfig *it) +/* FIXME: remove this when dynamic MITE allocation implemented. */ +static struct mite_struct *ni6527_find_mite(struct pci_dev *pcidev) +{ + struct mite_struct *mite; + + for (mite = mite_devices; mite; mite = mite->next) { + if (mite->used) + continue; + if (mite->pcidev == pcidev) + return mite; + } + return NULL; +} + +static const struct ni6527_board * +ni6527_find_boardinfo(struct pci_dev *pcidev) +{ + unsigned int dev_id = pcidev->device; + unsigned int n; + + for (n = 0; n < ARRAY_SIZE(ni6527_boards); n++) { + const struct ni6527_board *board = &ni6527_boards[n]; + if (board->dev_id == dev_id) + return board; + } + return NULL; +} + +static int __devinit ni6527_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) { struct comedi_subdevice *s; int ret; @@ -365,9 +391,13 @@ static int ni6527_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret < 0) return ret; - ret = ni6527_find_device(dev, it->options[0], it->options[1]); - if (ret < 0) - return ret; + dev->board_ptr = ni6527_find_boardinfo(pcidev); + if (!dev->board_ptr) + return -ENODEV; + + devpriv->mite = ni6527_find_mite(pcidev); + if (!devpriv->mite) + return -ENODEV; ret = mite_setup(devpriv->mite); if (ret < 0) { @@ -442,36 +472,10 @@ static void ni6527_detach(struct comedi_device *dev) mite_unsetup(devpriv->mite); } -static int ni6527_find_device(struct comedi_device *dev, int bus, int slot) -{ - struct mite_struct *mite; - int i; - - for (mite = mite_devices; mite; mite = mite->next) { - if (mite->used) - continue; - if (bus || slot) { - if (bus != mite->pcidev->bus->number || - slot != PCI_SLOT(mite->pcidev->devfn)) - continue; - } - for (i = 0; i < n_ni6527_boards; i++) { - if (mite_device_id(mite) == ni6527_boards[i].dev_id) { - dev->board_ptr = ni6527_boards + i; - devpriv->mite = mite; - return 0; - } - } - } - dev_err(dev->class_dev, DRIVER_NAME ": no device found\n"); - mite_list_devices(); - return -EIO; -} - static struct comedi_driver ni6527_driver = { .driver_name = DRIVER_NAME, .module = THIS_MODULE, - .attach = ni6527_attach, + .attach_pci = ni6527_attach_pci, .detach = ni6527_detach, }; -- cgit v0.10.2 From 0e5789f57a1f6f28018281fdc2f013199c7b0767 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:34:03 +0100 Subject: staging: comedi: ni_65xx: convert printk() to dev_...() Convert the `printk()` calls in this drivers to use the `dev_...()` calls instead. Remove the initial `printk()` call in the comedi `attach()` handler (`ni_65xx_attach()`) as it's a bit redundant - the board type and contents of a board ID register are printed later in the function. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index f4c4233..ca5e075 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -453,11 +453,9 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev, writeb(bits, private(dev)->mite->daq_io_addr + Port_Data(port)); -/* printk("wrote 0x%x to port %i\n", bits, port); */ } port_read_bits = readb(private(dev)->mite->daq_io_addr + Port_Data(port)); -/* printk("read 0x%x from port %i\n", port_read_bits, port); */ if (s->type == COMEDI_SUBD_DO && board(dev)->invert_outputs) { /* Outputs inverted, so invert value read back from * DO subdevice. (Does not apply to boards with DIO @@ -651,8 +649,6 @@ static int ni_65xx_attach(struct comedi_device *dev, unsigned i; int ret; - printk(KERN_INFO "comedi%d: ni_65xx:", dev->minor); - ret = alloc_private(dev, sizeof(struct ni_65xx_private)); if (ret < 0) return ret; @@ -663,15 +659,13 @@ static int ni_65xx_attach(struct comedi_device *dev, ret = mite_setup(private(dev)->mite); if (ret < 0) { - printk(KERN_WARNING "error setting up mite\n"); + dev_warn(dev->class_dev, "error setting up mite\n"); return ret; } dev->board_name = board(dev)->name; dev->irq = mite_irq(private(dev)->mite); - printk(KERN_INFO " %s", dev->board_name); - - printk(KERN_INFO " ID=0x%02x", + dev_info(dev->class_dev, "board: %s, ID=0x%02x", dev->board_name, readb(private(dev)->mite->daq_io_addr + ID_Register)); ret = comedi_alloc_subdevices(dev, 4); @@ -772,11 +766,9 @@ static int ni_65xx_attach(struct comedi_device *dev, "ni_65xx", dev); if (ret < 0) { dev->irq = 0; - printk(KERN_WARNING " irq not available"); + dev_warn(dev->class_dev, "irq not available\n"); } - printk("\n"); - return 0; } @@ -825,7 +817,7 @@ static int ni_65xx_find_device(struct comedi_device *dev, int bus, int slot) } } } - printk(KERN_WARNING "no device found\n"); + dev_warn(dev->class_dev, "no device found\n"); mite_list_devices(); return -EIO; } -- cgit v0.10.2 From 7e661293119cff3c726c2d1d5f646ae9a1060b10 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:34:04 +0100 Subject: staging: comedi: ni_65xx: use module_comedi_pci_driver() Use the macro `module_comedi_pci_driver(comedi_driver, pci_driver)` to register the module as a Comedi PCI driver. Rename variables and functions that have prefix `driver_` for consistency. Set the `name` member of the `struct pci_driver` variable in its initializer instead of initializing it in the module initialization function. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index ca5e075..529f4d5 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -112,7 +112,7 @@ static inline unsigned Filter_Enable(unsigned port) static int ni_65xx_attach(struct comedi_device *dev, struct comedi_devconfig *it); static void ni_65xx_detach(struct comedi_device *dev); -static struct comedi_driver driver_ni_65xx = { +static struct comedi_driver ni_65xx_driver = { .driver_name = "ni_65xx", .module = THIS_MODULE, .attach = ni_65xx_attach, @@ -822,43 +822,24 @@ static int ni_65xx_find_device(struct comedi_device *dev, int bus, int slot) return -EIO; } -static int __devinit driver_ni_65xx_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) +static int __devinit ni_65xx_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, &driver_ni_65xx); + return comedi_pci_auto_config(dev, &ni_65xx_driver); } -static void __devexit driver_ni_65xx_pci_remove(struct pci_dev *dev) +static void __devexit ni_65xx_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } -static struct pci_driver driver_ni_65xx_pci_driver = { +static struct pci_driver ni_65xx_pci_driver = { + .name = "ni_65xx", .id_table = ni_65xx_pci_table, - .probe = &driver_ni_65xx_pci_probe, - .remove = __devexit_p(&driver_ni_65xx_pci_remove) + .probe = ni_65xx_pci_probe, + .remove = __devexit_p(ni_65xx_pci_remove) }; - -static int __init driver_ni_65xx_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&driver_ni_65xx); - if (retval < 0) - return retval; - - driver_ni_65xx_pci_driver.name = (char *)driver_ni_65xx.driver_name; - return pci_register_driver(&driver_ni_65xx_pci_driver); -} - -static void __exit driver_ni_65xx_cleanup_module(void) -{ - pci_unregister_driver(&driver_ni_65xx_pci_driver); - comedi_driver_unregister(&driver_ni_65xx); -} - -module_init(driver_ni_65xx_init_module); -module_exit(driver_ni_65xx_cleanup_module); +module_comedi_pci_driver(ni_65xx_driver, ni_65xx_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); -- cgit v0.10.2 From 2927eda60977fde11a106cd9590cd710cd41884a Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:34:05 +0100 Subject: staging: comedi: ni_65xx: move ni_65xx_driver Move the `struct comedi_driver ni_65xx_driver` variable further down the function to be closer to the `module_comedi_pci_driver()` module call and to avoid having to forward declare `ni_65xx_attach()` and `ni_65xx_detach()`. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index 529f4d5..6a5e84e 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -109,18 +109,7 @@ static inline unsigned Filter_Enable(unsigned port) #define OverflowIntEnable 0x02 #define EdgeIntEnable 0x01 -static int ni_65xx_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static void ni_65xx_detach(struct comedi_device *dev); -static struct comedi_driver ni_65xx_driver = { - .driver_name = "ni_65xx", - .module = THIS_MODULE, - .attach = ni_65xx_attach, - .detach = ni_65xx_detach, -}; - struct ni_65xx_board { - int dev_id; const char *name; unsigned num_dio_ports; @@ -822,6 +811,13 @@ static int ni_65xx_find_device(struct comedi_device *dev, int bus, int slot) return -EIO; } +static struct comedi_driver ni_65xx_driver = { + .driver_name = "ni_65xx", + .module = THIS_MODULE, + .attach = ni_65xx_attach, + .detach = ni_65xx_detach, +}; + static int __devinit ni_65xx_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { -- cgit v0.10.2 From c50e9939ed3c7db1c8fa7d50ebe07c0c13f81fbc Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:34:06 +0100 Subject: staging: comedi: ni_65xx: use comedi attach_pci callback Convert this PCI driver to use the comedi `attach_pci` callback instead of the `attach` callback for PCI auto-configuration. There is no need to support manual attachment of PCI devices supported by this driver, so remove the `attach` callback altogether. Note that this driver still uses the list of PCI "mite" devices created by the "mite" module. This will be dealt with by a later patch once dynamic allocation of "mite" structures has been implemented. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index 6a5e84e..c4174da 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -314,8 +314,6 @@ static struct ni_65xx_subdevice_private *ni_65xx_alloc_subdevice_private(void) return subdev_private; } -static int ni_65xx_find_device(struct comedi_device *dev, int bus, int slot); - static int ni_65xx_config_filter(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -631,8 +629,36 @@ static int ni_65xx_intr_insn_config(struct comedi_device *dev, return 2; } -static int ni_65xx_attach(struct comedi_device *dev, - struct comedi_devconfig *it) +/* FIXME: remove this when dynamic MITE allocation implemented. */ +static struct mite_struct *ni_65xx_find_mite(struct pci_dev *pcidev) +{ + struct mite_struct *mite; + + for (mite = mite_devices; mite; mite = mite->next) { + if (mite->used) + continue; + if (mite->pcidev == pcidev) + return mite; + } + return NULL; +} + +static const struct ni_65xx_board * +ni_65xx_find_boardinfo(struct pci_dev *pcidev) +{ + unsigned int dev_id = pcidev->device; + unsigned int n; + + for (n = 0; n < ARRAY_SIZE(ni_65xx_boards); n++) { + const struct ni_65xx_board *board = &ni_65xx_boards[n]; + if (board->dev_id == dev_id) + return board; + } + return NULL; +} + +static int __devinit ni_65xx_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) { struct comedi_subdevice *s; unsigned i; @@ -642,9 +668,13 @@ static int ni_65xx_attach(struct comedi_device *dev, if (ret < 0) return ret; - ret = ni_65xx_find_device(dev, it->options[0], it->options[1]); - if (ret < 0) - return ret; + dev->board_ptr = ni_65xx_find_boardinfo(pcidev); + if (!dev->board_ptr) + return -ENODEV; + + private(dev)->mite = ni_65xx_find_mite(pcidev); + if (!private(dev)->mite) + return -ENODEV; ret = mite_setup(private(dev)->mite); if (ret < 0) { @@ -785,36 +815,10 @@ static void ni_65xx_detach(struct comedi_device *dev) } } -static int ni_65xx_find_device(struct comedi_device *dev, int bus, int slot) -{ - struct mite_struct *mite; - int i; - - for (mite = mite_devices; mite; mite = mite->next) { - if (mite->used) - continue; - if (bus || slot) { - if (bus != mite->pcidev->bus->number || - slot != PCI_SLOT(mite->pcidev->devfn)) - continue; - } - for (i = 0; i < n_ni_65xx_boards; i++) { - if (mite_device_id(mite) == ni_65xx_boards[i].dev_id) { - dev->board_ptr = ni_65xx_boards + i; - private(dev)->mite = mite; - return 0; - } - } - } - dev_warn(dev->class_dev, "no device found\n"); - mite_list_devices(); - return -EIO; -} - static struct comedi_driver ni_65xx_driver = { .driver_name = "ni_65xx", .module = THIS_MODULE, - .attach = ni_65xx_attach, + .attach_pci = ni_65xx_attach_pci, .detach = ni_65xx_detach, }; -- cgit v0.10.2 From a8adadee9427e23fe7513fc214fe29f7307e7aa1 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:34:07 +0100 Subject: staging: comedi: ni_660x: convert printk() to dev_...() Convert the `printk()` calls in this drivers to use the `dev_...()` calls instead. Replace some `printk()` calls in the comedi `attach()` handler (`ni_660x_attach()`) with a single `dev_info()` at the end. Remove some `printk()` calls before `BUG()` calls. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 6bd5b55..43254cc 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -748,8 +748,6 @@ static enum NI_660x_Register ni_gpct_to_660x_register(enum ni_gpct_register reg) ni_660x_register = G3InterruptEnable; break; default: - printk(KERN_WARNING "%s: unhandled register 0x%x in switch.\n", - __func__, reg); BUG(); return 0; break; @@ -773,8 +771,6 @@ static inline void ni_660x_write_register(struct comedi_device *dev, writel(bits, write_address); break; default: - printk(KERN_WARNING "%s: %s: bug! unhandled case (reg=0x%x) in switch.\n", - __FILE__, __func__, reg); BUG(); break; } @@ -796,8 +792,6 @@ static inline unsigned ni_660x_read_register(struct comedi_device *dev, return readl(read_address); break; default: - printk(KERN_WARNING "%s: %s: bug! unhandled case (reg=0x%x) in switch.\n", - __FILE__, __func__, reg); BUG(); break; } @@ -1070,8 +1064,6 @@ static int ni_660x_attach(struct comedi_device *dev, unsigned i; unsigned global_interrupt_config_bits; - printk(KERN_INFO "comedi%d: ni_660x: ", dev->minor); - ret = ni_660x_allocate_private(dev); if (ret < 0) return ret; @@ -1083,7 +1075,7 @@ static int ni_660x_attach(struct comedi_device *dev, ret = mite_setup2(private(dev)->mite, 1); if (ret < 0) { - printk(KERN_WARNING "error setting up mite\n"); + dev_warn(dev->class_dev, "error setting up mite\n"); return ret; } comedi_set_hw_dev(dev, &private(dev)->mite->pcidev->dev); @@ -1091,8 +1083,6 @@ static int ni_660x_attach(struct comedi_device *dev, if (ret < 0) return ret; - printk(KERN_INFO " %s ", dev->board_name); - ret = comedi_alloc_subdevices(dev, 2 + NI_660X_MAX_NUM_COUNTERS); if (ret) return ret; @@ -1174,7 +1164,7 @@ static int ni_660x_attach(struct comedi_device *dev, ret = request_irq(mite_irq(private(dev)->mite), ni_660x_interrupt, IRQF_SHARED, "ni_660x", dev); if (ret < 0) { - printk(KERN_WARNING " irq not available\n"); + dev_warn(dev->class_dev, " irq not available\n"); return ret; } dev->irq = mite_irq(private(dev)->mite); @@ -1183,7 +1173,7 @@ static int ni_660x_attach(struct comedi_device *dev, global_interrupt_config_bits |= Cascade_Int_Enable_Bit; ni_660x_write_register(dev, 0, global_interrupt_config_bits, GlobalInterruptConfigRegister); - printk(KERN_INFO "attached\n"); + dev_info(dev->class_dev, "ni_660x: %s attached\n", dev->board_name); return 0; } @@ -1262,7 +1252,7 @@ static int ni_660x_find_device(struct comedi_device *dev, int bus, int slot) } } } - printk(KERN_WARNING "no device found\n"); + dev_warn(dev->class_dev, "no device found\n"); mite_list_devices(); return -EIO; } -- cgit v0.10.2 From b4c9a598a7d858bbb845b9b4067c065f63abc10a Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:34:08 +0100 Subject: staging: comedi: ni_660x: use module_comedi_pci_driver() Use the macro `module_comedi_pci_driver(comedi_driver, pci_driver)` to register the module as a Comedi PCI driver. Rename variables and functions that have prefix `driver_` for consistency. Set the `name` member of the `struct pci_driver` variable in its initializer instead of initializing it in the module initialization function. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 43254cc..54738c9 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -464,50 +464,31 @@ static void ni_660x_select_pfi_output(struct comedi_device *dev, unsigned pfi_channel, unsigned output_select); -static struct comedi_driver driver_ni_660x = { +static struct comedi_driver ni_660x_driver = { .driver_name = "ni_660x", .module = THIS_MODULE, .attach = ni_660x_attach, .detach = ni_660x_detach, }; -static int __devinit driver_ni_660x_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) +static int __devinit ni_660x_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, &driver_ni_660x); + return comedi_pci_auto_config(dev, &ni_660x_driver); } -static void __devexit driver_ni_660x_pci_remove(struct pci_dev *dev) +static void __devexit ni_660x_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } -static struct pci_driver driver_ni_660x_pci_driver = { +static struct pci_driver ni_660x_pci_driver = { + .name = "ni_660x", .id_table = ni_660x_pci_table, - .probe = &driver_ni_660x_pci_probe, - .remove = __devexit_p(&driver_ni_660x_pci_remove) + .probe = ni_660x_pci_probe, + .remove = __devexit_p(ni_660x_pci_remove) }; - -static int __init driver_ni_660x_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&driver_ni_660x); - if (retval < 0) - return retval; - - driver_ni_660x_pci_driver.name = (char *)driver_ni_660x.driver_name; - return pci_register_driver(&driver_ni_660x_pci_driver); -} - -static void __exit driver_ni_660x_cleanup_module(void) -{ - pci_unregister_driver(&driver_ni_660x_pci_driver); - comedi_driver_unregister(&driver_ni_660x); -} - -module_init(driver_ni_660x_init_module); -module_exit(driver_ni_660x_cleanup_module); +module_comedi_pci_driver(ni_660x_driver, ni_660x_pci_driver); static int ni_660x_find_device(struct comedi_device *dev, int bus, int slot); static int ni_660x_set_pfi_routing(struct comedi_device *dev, unsigned chan, -- cgit v0.10.2 From b64c0f51cbf5e38ffad8e2624a3416a6fa10223b Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:34:09 +0100 Subject: staging: comedi: ni_660x: use comedi attach_pci callback Convert this PCI driver to use the comedi `attach_pci` callback instead of the `attach` callback for PCI auto-configuration. There is no need to support manual attachment of PCI devices supported by this driver, so remove the `attach` callback altogether. Note that this driver still uses the list of PCI "mite" devices created by the "mite" module. This will be dealt with by a later patch once dynamic allocation of "mite" structures has been implemented. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 54738c9..3b125a6 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -448,16 +448,14 @@ static inline struct ni_660x_private *private(struct comedi_device *dev) return dev->private; } -/* initialized in ni_660x_find_device() */ +/* initialized in ni_660x_attach_pci() */ static inline const struct ni_660x_board *board(struct comedi_device *dev) { return dev->board_ptr; } -#define n_ni_660x_boards ARRAY_SIZE(ni_660x_boards) - -static int ni_660x_attach(struct comedi_device *dev, - struct comedi_devconfig *it); +static int ni_660x_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev); static void ni_660x_detach(struct comedi_device *dev); static void init_tio_chip(struct comedi_device *dev, int chipset); static void ni_660x_select_pfi_output(struct comedi_device *dev, @@ -467,7 +465,7 @@ static void ni_660x_select_pfi_output(struct comedi_device *dev, static struct comedi_driver ni_660x_driver = { .driver_name = "ni_660x", .module = THIS_MODULE, - .attach = ni_660x_attach, + .attach_pci = ni_660x_attach_pci, .detach = ni_660x_detach, }; @@ -490,7 +488,6 @@ static struct pci_driver ni_660x_pci_driver = { }; module_comedi_pci_driver(ni_660x_driver, ni_660x_pci_driver); -static int ni_660x_find_device(struct comedi_device *dev, int bus, int slot); static int ni_660x_set_pfi_routing(struct comedi_device *dev, unsigned chan, unsigned source); @@ -1037,8 +1034,36 @@ static void ni_660x_free_mite_rings(struct comedi_device *dev) } } -static int ni_660x_attach(struct comedi_device *dev, - struct comedi_devconfig *it) +/* FIXME: remove this when dynamic MITE allocation implemented. */ +static struct mite_struct *ni_660x_find_mite(struct pci_dev *pcidev) +{ + struct mite_struct *mite; + + for (mite = mite_devices; mite; mite = mite->next) { + if (mite->used) + continue; + if (mite->pcidev == pcidev) + return mite; + } + return NULL; +} + +static const struct ni_660x_board * +ni_660x_find_boardinfo(struct pci_dev *pcidev) +{ + unsigned int dev_id = pcidev->device; + unsigned int n; + + for (n = 0; n < ARRAY_SIZE(ni_660x_boards); n++) { + const struct ni_660x_board *board = &ni_660x_boards[n]; + if (board->dev_id == dev_id) + return board; + } + return NULL; +} + +static int __devinit ni_660x_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) { struct comedi_subdevice *s; int ret; @@ -1048,9 +1073,12 @@ static int ni_660x_attach(struct comedi_device *dev, ret = ni_660x_allocate_private(dev); if (ret < 0) return ret; - ret = ni_660x_find_device(dev, it->options[0], it->options[1]); - if (ret < 0) - return ret; + dev->board_ptr = ni_660x_find_boardinfo(pcidev); + if (!dev->board_ptr) + return -ENODEV; + private(dev)->mite = ni_660x_find_mite(pcidev); + if (!private(dev)->mite) + return -ENODEV; dev->board_name = board(dev)->name; @@ -1211,33 +1239,6 @@ static int ni_660x_GPCT_winsn(struct comedi_device *dev, return ni_tio_winsn(subdev_to_counter(s), insn, data); } -static int ni_660x_find_device(struct comedi_device *dev, int bus, int slot) -{ - struct mite_struct *mite; - int i; - - for (mite = mite_devices; mite; mite = mite->next) { - if (mite->used) - continue; - if (bus || slot) { - if (bus != mite->pcidev->bus->number || - slot != PCI_SLOT(mite->pcidev->devfn)) - continue; - } - - for (i = 0; i < n_ni_660x_boards; i++) { - if (mite_device_id(mite) == ni_660x_boards[i].dev_id) { - dev->board_ptr = ni_660x_boards + i; - private(dev)->mite = mite; - return 0; - } - } - } - dev_warn(dev->class_dev, "no device found\n"); - mite_list_devices(); - return -EIO; -} - static int ni_660x_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) -- cgit v0.10.2 From c33e23f776bbf2f70165eabefaaab4b6f1d66638 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:34:10 +0100 Subject: staging: comedi: ni_670x: use comedi attach_pci callback Convert this PCI driver to use the comedi `attach_pci` callback instead of the `attach` callback for PCI auto-configuration. There is no need to support manual attachment of PCI devices supported by this driver, so remove the `attach` callback altogether. Note that this driver still uses the list of PCI "mite" devices created by the "mite" module. This will be dealt with by a later patch once dynamic allocation of "mite" structures has been implemented. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c index cdb36b8..1783219 100644 --- a/drivers/staging/comedi/drivers/ni_670x.c +++ b/drivers/staging/comedi/drivers/ni_670x.c @@ -187,37 +187,36 @@ static int ni_670x_dio_insn_config(struct comedi_device *dev, return insn->n; } -static int ni_670x_find_device(struct comedi_device *dev, int bus, int slot) +/* FIXME: remove this when dynamic MITE allocation implemented. */ +static struct mite_struct *ni_670x_find_mite(struct pci_dev *pcidev) { - struct ni_670x_private *devpriv = dev->private; struct mite_struct *mite; - int i; for (mite = mite_devices; mite; mite = mite->next) { if (mite->used) continue; - if (bus || slot) { - if (bus != mite->pcidev->bus->number - || slot != PCI_SLOT(mite->pcidev->devfn)) - continue; - } + if (mite->pcidev == pcidev) + return mite; + } + return NULL; +} - for (i = 0; i < ARRAY_SIZE(ni_670x_boards); i++) { - if (mite_device_id(mite) == ni_670x_boards[i].dev_id) { - dev->board_ptr = ni_670x_boards + i; - devpriv->mite = mite; +static const struct ni_670x_board * +ni_670x_find_boardinfo(struct pci_dev *pcidev) +{ + unsigned int dev_id = pcidev->device; + unsigned int n; - return 0; - } - } + for (n = 0; n < ARRAY_SIZE(ni_670x_boards); n++) { + const struct ni_670x_board *board = &ni_670x_boards[n]; + if (board->dev_id == dev_id) + return board; } - dev_warn(dev->class_dev, "no device found\n"); - mite_list_devices(); - return -EIO; + return NULL; } -static int ni_670x_attach(struct comedi_device *dev, - struct comedi_devconfig *it) +static int __devinit ni_670x_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) { const struct ni_670x_board *thisboard; struct ni_670x_private *devpriv; @@ -229,10 +228,12 @@ static int ni_670x_attach(struct comedi_device *dev, if (ret < 0) return ret; devpriv = dev->private; - - ret = ni_670x_find_device(dev, it->options[0], it->options[1]); - if (ret < 0) - return ret; + dev->board_ptr = ni_670x_find_boardinfo(pcidev); + if (!dev->board_ptr) + return -ENODEV; + devpriv->mite = ni_670x_find_mite(pcidev); + if (!devpriv->mite) + return -ENODEV; thisboard = comedi_board(dev); ret = mite_setup(devpriv->mite); @@ -311,7 +312,7 @@ static void ni_670x_detach(struct comedi_device *dev) static struct comedi_driver ni_670x_driver = { .driver_name = "ni_670x", .module = THIS_MODULE, - .attach = ni_670x_attach, + .attach_pci = ni_670x_attach_pci, .detach = ni_670x_detach, }; -- cgit v0.10.2 From 1cabcd3164029da5f718f0c9807bcc108b63cb7b Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:34:11 +0100 Subject: staging: comedi: ni_labpc: convert printk() to dev_...() Convert the `printk()` calls in this driver to use the `dev_...()` calls where possible, or the `pr_...()` calls otherwise. Remove the ifdefed out code that prints the EEPROM contents. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index 65d5dfc..8f835b6 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -73,9 +73,6 @@ NI manuals: */ -#undef LABPC_DEBUG -/* #define LABPC_DEBUG enable debugging messages */ - #include #include #include @@ -538,17 +535,9 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, short lsb, msb; int ret; - printk(KERN_ERR "comedi%d: ni_labpc: %s, io 0x%lx", dev->minor, - thisboard->name, - iobase); - if (irq) - printk(", irq %u", irq); - if (dma_chan) - printk(", dma %u", dma_chan); - printk("\n"); - + dev_info(dev->class_dev, "ni_labpc: %s\n", thisboard->name); if (iobase == 0) { - printk(KERN_ERR "io base address is zero!\n"); + dev_err(dev->class_dev, "io base address is zero!\n"); return -EINVAL; } /* request io regions for isa boards */ @@ -556,7 +545,7 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, /* check if io addresses are available */ if (!request_region(iobase, LABPC_SIZE, driver_labpc.driver_name)) { - printk(KERN_ERR "I/O port conflict\n"); + dev_err(dev->class_dev, "I/O port conflict\n"); return -EIO; } } @@ -589,7 +578,8 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, isr_flags |= IRQF_SHARED; if (request_irq(irq, labpc_interrupt, isr_flags, driver_labpc.driver_name, dev)) { - printk(KERN_ERR "unable to allocate irq %u\n", irq); + dev_err(dev->class_dev, "unable to allocate irq %u\n", + irq); return -EINVAL; } } @@ -598,19 +588,21 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, #ifdef CONFIG_ISA_DMA_API /* grab dma channel */ if (dma_chan > 3) { - printk(KERN_ERR " invalid dma channel %u\n", dma_chan); + dev_err(dev->class_dev, "invalid dma channel %u\n", dma_chan); return -EINVAL; } else if (dma_chan) { /* allocate dma buffer */ devpriv->dma_buffer = kmalloc(dma_buffer_size, GFP_KERNEL | GFP_DMA); if (devpriv->dma_buffer == NULL) { - printk(KERN_ERR " failed to allocate dma buffer\n"); + dev_err(dev->class_dev, + "failed to allocate dma buffer\n"); return -ENOMEM; } if (request_dma(dma_chan, driver_labpc.driver_name)) { - printk(KERN_ERR " failed to allocate dma channel %u\n", - dma_chan); + dev_err(dev->class_dev, + "failed to allocate dma channel %u\n", + dma_chan); return -EINVAL; } devpriv->dma_chan = dma_chan; @@ -706,12 +698,6 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, for (i = 0; i < EEPROM_SIZE; i++) devpriv->eeprom_data[i] = labpc_eeprom_read(dev, i); -#ifdef LABPC_DEBUG - printk(KERN_ERR " eeprom:"); - for (i = 0; i < EEPROM_SIZE; i++) - printk(" %i:0x%x ", i, devpriv->eeprom_data[i]); - printk("\n"); -#endif } else s->type = COMEDI_SUBD_UNUSED; @@ -740,8 +726,8 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it) irq = it->options[1]; dma_chan = it->options[2]; #else - printk(KERN_ERR " this driver has not been built with ISA DMA " - "support.\n"); + dev_err(dev->class_dev, + "ni_labpc driver has not been built with ISA DMA support.\n"); return -EINVAL; #endif break; @@ -756,18 +742,14 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it) iobase = (unsigned long)devpriv->mite->daq_io_addr; irq = mite_irq(devpriv->mite); #else - printk(KERN_ERR " this driver has not been built with PCI " - "support.\n"); + dev_err(dev->class_dev, + "ni_labpc driver has not been built with PCI support.\n"); return -EINVAL; #endif break; - case pcmcia_bustype: - printk - (" this driver does not support pcmcia cards, use ni_labpc_cs.o\n"); - return -EINVAL; - break; default: - printk(KERN_ERR "bug! couldn't determine board type\n"); + dev_err(dev->class_dev, + "ni_labpc: bug! couldn't determine board type\n"); return -EINVAL; break; } @@ -801,7 +783,7 @@ static int labpc_find_device(struct comedi_device *dev, int bus, int slot) } } } - printk(KERN_ERR "no device found\n"); + dev_err(dev->class_dev, "no device found\n"); mite_list_devices(); return -EIO; } @@ -872,8 +854,7 @@ static enum scan_mode labpc_ai_scan_mode(const struct comedi_cmd *cmd) if (CR_CHAN(cmd->chanlist[0]) > CR_CHAN(cmd->chanlist[1])) return MODE_MULT_CHAN_DOWN; - printk(KERN_ERR "ni_labpc: bug! this should never happen\n"); - + pr_err("ni_labpc: bug! cannot determine AI scan mode\n"); return 0; } @@ -928,7 +909,8 @@ static int labpc_ai_chanlist_invalid(const struct comedi_device *dev, } break; default: - printk(KERN_ERR "ni_labpc: bug! in chanlist check\n"); + dev_err(dev->class_dev, + "ni_labpc: bug! in chanlist check\n"); return 1; break; } @@ -1790,8 +1772,8 @@ static int labpc_eeprom_write_insn(struct comedi_device *dev, /* only allow writes to user area of eeprom */ if (channel < 16 || channel > 127) { - printk - ("eeprom writes are only allowed to channels 16 through 127 (the pointer and user areas)"); + dev_dbg(dev->class_dev, + "eeprom writes are only allowed to channels 16 through 127 (the pointer and user areas)\n"); return -EINVAL; } -- cgit v0.10.2 From 3faeeecbc85c7f4a2867bcdc65b8a598e2f4aa83 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:34:12 +0100 Subject: staging: comedi: ni_labpc: use module_comedi_pci_driver() Use the macro `module_comedi_pci_driver(comedi_driver, pci_driver)` to register the module as a Comedi PCI driver if the module supports PCI devices, otherwise use `module_comedi_driver(comedi_driver)` to register it as an ordinary Comedi driver. Rename variables and functions that have prefix `driver_` for consistency. Set the `name` member of the `struct pci_driver` variable in its initializer instead of initializing it in the module initialization function. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index 8f835b6..3b1e47e 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -492,7 +492,7 @@ static const int sample_size = 2; #define devpriv ((struct labpc_private *)dev->private) -static struct comedi_driver driver_labpc = { +static struct comedi_driver labpc_driver = { .driver_name = DRV_NAME, .module = THIS_MODULE, .attach = labpc_attach, @@ -544,7 +544,7 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, if (thisboard->bustype == isa_bustype) { /* check if io addresses are available */ if (!request_region(iobase, LABPC_SIZE, - driver_labpc.driver_name)) { + labpc_driver.driver_name)) { dev_err(dev->class_dev, "I/O port conflict\n"); return -EIO; } @@ -577,7 +577,7 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, || thisboard->bustype == pcmcia_bustype) isr_flags |= IRQF_SHARED; if (request_irq(irq, labpc_interrupt, isr_flags, - driver_labpc.driver_name, dev)) { + labpc_driver.driver_name, dev)) { dev_err(dev->class_dev, "unable to allocate irq %u\n", irq); return -EINVAL; @@ -599,7 +599,7 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, "failed to allocate dma buffer\n"); return -ENOMEM; } - if (request_dma(dma_chan, driver_labpc.driver_name)) { + if (request_dma(dma_chan, labpc_driver.driver_name)) { dev_err(dev->class_dev, "failed to allocate dma channel %u\n", dma_chan); @@ -772,7 +772,7 @@ static int labpc_find_device(struct comedi_device *dev, int bus, int slot) || slot != PCI_SLOT(mite->pcidev->devfn)) continue; } - for (i = 0; i < driver_labpc.num_names; i++) { + for (i = 0; i < labpc_driver.num_names; i++) { if (labpc_boards[i].bustype != pci_bustype) continue; if (mite_device_id(mite) == labpc_boards[i].device_id) { @@ -2123,56 +2123,26 @@ static void write_caldac(struct comedi_device *dev, unsigned int channel, } #ifdef CONFIG_COMEDI_PCI_DRIVERS -static int __devinit driver_labpc_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) +static int __devinit labpc_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, &driver_labpc); + return comedi_pci_auto_config(dev, &labpc_driver); } -static void __devexit driver_labpc_pci_remove(struct pci_dev *dev) +static void __devexit labpc_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } -static struct pci_driver driver_labpc_pci_driver = { +static struct pci_driver labpc_pci_driver = { + .name = DRV_NAME, .id_table = labpc_pci_table, - .probe = &driver_labpc_pci_probe, - .remove = __devexit_p(&driver_labpc_pci_remove) + .probe = labpc_pci_probe, + .remove = __devexit_p(labpc_pci_remove) }; - -static int __init driver_labpc_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&driver_labpc); - if (retval < 0) - return retval; - - driver_labpc_pci_driver.name = (char *)driver_labpc.driver_name; - return pci_register_driver(&driver_labpc_pci_driver); -} - -static void __exit driver_labpc_cleanup_module(void) -{ - pci_unregister_driver(&driver_labpc_pci_driver); - comedi_driver_unregister(&driver_labpc); -} - -module_init(driver_labpc_init_module); -module_exit(driver_labpc_cleanup_module); +module_comedi_pci_driver(labpc_driver, labpc_pci_driver); #else -static int __init driver_labpc_init_module(void) -{ - return comedi_driver_register(&driver_labpc); -} - -static void __exit driver_labpc_cleanup_module(void) -{ - comedi_driver_unregister(&driver_labpc); -} - -module_init(driver_labpc_init_module); -module_exit(driver_labpc_cleanup_module); +module_comedi_driver(labpc_driver); #endif -- cgit v0.10.2 From 5e51f0db14b4a2013f4f64885191076475c5b86f Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:34:13 +0100 Subject: staging: comedi: ni_labpc: move labpc_driver and labpc_pci_table Move the `labpc_driver` and `labpc_pci_table` variables nearer the module initialization code near the bottom of the module for aesthetic reasons and to avoid a forward declaration of `labpc_attach()`. As a consequence, to avoid having to add a forward declaration of the `labpc_driver` variable, change code that uses `labpc_driver.driver_name` to use `DRV_NAME` instead, and change code that uses `labpc_driver.num_names` to use `ARRAY_SIZE(labpc_boards)` instead. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index 3b1e47e..72a75a0 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -206,7 +206,6 @@ NI manuals: #define INIT_A1_BITS 0x70 #define COUNTER_B_BASE_REG 0x18 -static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it); static int labpc_cancel(struct comedi_device *dev, struct comedi_subdevice *s); static irqreturn_t labpc_interrupt(int irq, void *d); static int labpc_drain_fifo(struct comedi_device *dev); @@ -492,25 +491,6 @@ static const int sample_size = 2; #define devpriv ((struct labpc_private *)dev->private) -static struct comedi_driver labpc_driver = { - .driver_name = DRV_NAME, - .module = THIS_MODULE, - .attach = labpc_attach, - .detach = labpc_common_detach, - .num_names = ARRAY_SIZE(labpc_boards), - .board_name = &labpc_boards[0].name, - .offset = sizeof(struct labpc_board_struct), -}; - -#ifdef CONFIG_COMEDI_PCI_DRIVERS -static DEFINE_PCI_DEVICE_TABLE(labpc_pci_table) = { - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x161)}, - {0} -}; - -MODULE_DEVICE_TABLE(pci, labpc_pci_table); -#endif /* CONFIG_COMEDI_PCI_DRIVERS */ - static inline int labpc_counter_load(struct comedi_device *dev, unsigned long base_address, unsigned int counter_number, @@ -543,8 +523,7 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, /* request io regions for isa boards */ if (thisboard->bustype == isa_bustype) { /* check if io addresses are available */ - if (!request_region(iobase, LABPC_SIZE, - labpc_driver.driver_name)) { + if (!request_region(iobase, LABPC_SIZE, DRV_NAME)) { dev_err(dev->class_dev, "I/O port conflict\n"); return -EIO; } @@ -577,7 +556,7 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, || thisboard->bustype == pcmcia_bustype) isr_flags |= IRQF_SHARED; if (request_irq(irq, labpc_interrupt, isr_flags, - labpc_driver.driver_name, dev)) { + DRV_NAME, dev)) { dev_err(dev->class_dev, "unable to allocate irq %u\n", irq); return -EINVAL; @@ -599,7 +578,7 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, "failed to allocate dma buffer\n"); return -ENOMEM; } - if (request_dma(dma_chan, labpc_driver.driver_name)) { + if (request_dma(dma_chan, DRV_NAME)) { dev_err(dev->class_dev, "failed to allocate dma channel %u\n", dma_chan); @@ -772,7 +751,7 @@ static int labpc_find_device(struct comedi_device *dev, int bus, int slot) || slot != PCI_SLOT(mite->pcidev->devfn)) continue; } - for (i = 0; i < labpc_driver.num_names; i++) { + for (i = 0; i < ARRAY_SIZE(labpc_boards); i++) { if (labpc_boards[i].bustype != pci_bustype) continue; if (mite_device_id(mite) == labpc_boards[i].device_id) { @@ -2122,7 +2101,23 @@ static void write_caldac(struct comedi_device *dev, unsigned int channel, devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG); } +static struct comedi_driver labpc_driver = { + .driver_name = DRV_NAME, + .module = THIS_MODULE, + .attach = labpc_attach, + .detach = labpc_common_detach, + .num_names = ARRAY_SIZE(labpc_boards), + .board_name = &labpc_boards[0].name, + .offset = sizeof(struct labpc_board_struct), +}; + #ifdef CONFIG_COMEDI_PCI_DRIVERS +static DEFINE_PCI_DEVICE_TABLE(labpc_pci_table) = { + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x161)}, + {0} +}; +MODULE_DEVICE_TABLE(pci, labpc_pci_table); + static int __devinit labpc_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { -- cgit v0.10.2 From 7e2716cdc34778ea989093b2308bf62fc12da810 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:34:14 +0100 Subject: staging: comedi: ni_labpc: use comedi attach_pci callback Convert this PCI driver to use the comedi `attach_pci` callback instead of the `attach` callback for PCI auto-configuration. Remove support for manual attachment of PCI boards supported by this driver. The `attach` callback is still needed to manually attach ISA boards, but print an error if an attempt is made to manually attach a PCI board. Note that this driver still uses the list of PCI "mite" devices created by the "mite" module. This will be dealt with by a later patch once dynamic allocation of "mite" structures has been implemented. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index 72a75a0..7d36c2c 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -240,9 +240,6 @@ static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd); #ifdef CONFIG_ISA_DMA_API static unsigned int labpc_suggest_transfer_size(struct comedi_cmd cmd); #endif -#ifdef CONFIG_COMEDI_PCI_DRIVERS -static int labpc_find_device(struct comedi_device *dev, int bus, int slot); -#endif static int labpc_dio_mem_callback(int dir, int port, int data, unsigned long arg); static void labpc_serial_out(struct comedi_device *dev, unsigned int value, @@ -684,14 +681,66 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, } EXPORT_SYMBOL_GPL(labpc_common_attach); +static const struct labpc_board_struct * +labpc_pci_find_boardinfo(struct pci_dev *pcidev) +{ + unsigned int device_id = pcidev->device; + unsigned int n; + + for (n = 0; n < ARRAY_SIZE(labpc_boards); n++) { + const struct labpc_board_struct *board = &labpc_boards[n]; + if (board->bustype == pci_bustype && + board->device_id == device_id) + return board; + } + return NULL; +} + +/* FIXME: remove this when dynamic MITE allocation implemented. */ +static struct mite_struct *labpc_pci_find_mite(struct pci_dev *pcidev) +{ + struct mite_struct *mite; + + for (mite = mite_devices; mite; mite = mite->next) { + if (mite->used) + continue; + if (mite->pcidev == pcidev) + return mite; + } + return NULL; +} + +static int __devinit labpc_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) +{ + unsigned long iobase; + unsigned int irq; + int ret; + + if (!IS_ENABLED(CONFIG_COMEDI_PCI_DRIVERS)) + return -ENODEV; + ret = alloc_private(dev, sizeof(struct labpc_private)); + if (ret < 0) + return ret; + dev->board_ptr = labpc_pci_find_boardinfo(pcidev); + if (!dev->board_ptr) + return -ENODEV; + devpriv->mite = labpc_pci_find_mite(pcidev); + if (!devpriv->mite) + return -ENODEV; + ret = mite_setup(devpriv->mite); + if (ret < 0) + return ret; + iobase = (unsigned long)devpriv->mite->daq_io_addr; + irq = mite_irq(devpriv->mite); + return labpc_common_attach(dev, iobase, irq, 0); +} + static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it) { unsigned long iobase = 0; unsigned int irq = 0; unsigned int dma_chan = 0; -#ifdef CONFIG_COMEDI_PCI_DRIVERS - int retval; -#endif /* allocate and initialize dev->private */ if (alloc_private(dev, sizeof(struct labpc_private)) < 0) @@ -712,14 +761,10 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it) break; case pci_bustype: #ifdef CONFIG_COMEDI_PCI_DRIVERS - retval = labpc_find_device(dev, it->options[0], it->options[1]); - if (retval < 0) - return retval; - retval = mite_setup(devpriv->mite); - if (retval < 0) - return retval; - iobase = (unsigned long)devpriv->mite->daq_io_addr; - irq = mite_irq(devpriv->mite); + dev_err(dev->class_dev, + "manual configuration of PCI board '%s' is not supported\n", + thisboard->name); + return -EINVAL; #else dev_err(dev->class_dev, "ni_labpc driver has not been built with PCI support.\n"); @@ -736,38 +781,6 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it) return labpc_common_attach(dev, iobase, irq, dma_chan); } -/* adapted from ni_pcimio for finding mite based boards (pc-1200) */ -#ifdef CONFIG_COMEDI_PCI_DRIVERS -static int labpc_find_device(struct comedi_device *dev, int bus, int slot) -{ - struct mite_struct *mite; - int i; - for (mite = mite_devices; mite; mite = mite->next) { - if (mite->used) - continue; -/* if bus/slot are specified then make sure we have the right bus/slot */ - if (bus || slot) { - if (bus != mite->pcidev->bus->number - || slot != PCI_SLOT(mite->pcidev->devfn)) - continue; - } - for (i = 0; i < ARRAY_SIZE(labpc_boards); i++) { - if (labpc_boards[i].bustype != pci_bustype) - continue; - if (mite_device_id(mite) == labpc_boards[i].device_id) { - devpriv->mite = mite; -/* fixup board pointer, in case we were using the dummy "ni_labpc" entry */ - dev->board_ptr = &labpc_boards[i]; - return 0; - } - } - } - dev_err(dev->class_dev, "no device found\n"); - mite_list_devices(); - return -EIO; -} -#endif - void labpc_common_detach(struct comedi_device *dev) { struct comedi_subdevice *s; @@ -2105,6 +2118,7 @@ static struct comedi_driver labpc_driver = { .driver_name = DRV_NAME, .module = THIS_MODULE, .attach = labpc_attach, + .attach_pci = labpc_attach_pci, .detach = labpc_common_detach, .num_names = ARRAY_SIZE(labpc_boards), .board_name = &labpc_boards[0].name, -- cgit v0.10.2 From 6b26ecf0479e660e878014030b1f6e53d3787d75 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:34:15 +0100 Subject: staging: comedi: ni_pcidio: convert printk() calls Convert the `printk()` calls in this driver to use the `dev_...()` calls where possible, or the `pr_...()` calls otherwise. Combine non-line-terminated prints into single-line prints. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index 0f86506..4f76daf 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -63,9 +63,9 @@ comedi_nonfree_firmware tarball available from http://www.comedi.org #undef DPRINTK #ifdef DEBUG -#define DPRINTK(format, args...) printk(format, ## args) +#define DPRINTK(format, args...) pr_debug(format, ## args) #else -#define DPRINTK(format, args...) +#define DPRINTK(format, args...) do { } while (0) #endif #define PCI_DIO_SIZE 4096 @@ -420,18 +420,12 @@ static irqreturn_t nidio_interrupt(int irq, void *d) ni_pcidio_print_flags(flags); ni_pcidio_print_status(status); - /* printk("buf[0]=%08x\n",*(unsigned int *)async->prealloc_buf); */ - /* printk("buf[4096]=%08x\n", - *(unsigned int *)(async->prealloc_buf+4096)); */ - spin_lock(&devpriv->mite_channel_lock); if (devpriv->di_mite_chan) m_status = mite_get_status(devpriv->di_mite_chan); #ifdef MITE_DEBUG mite_print_chsr(m_status); #endif - /* printk("mite_bytes_transferred: %d\n", - mite_bytes_transferred(mite,DI_DMA_CHAN)); */ /* mite_dump_regs(mite); */ if (m_status & CHSR_INT) { @@ -526,7 +520,7 @@ static irqreturn_t nidio_interrupt(int irq, void *d) } #if 0 else { - printk("ni_pcidio: unknown interrupt\n"); + DPRINTK("ni_pcidio: unknown interrupt\n"); async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; writeb(0x00, devpriv->mite->daq_io_addr + @@ -557,38 +551,47 @@ out: } #ifdef DEBUG_FLAGS +static const char *bit_set_string(unsigned int bits, unsigned int bit, + const char *const strings[]) +{ + return (bits & (1U << bit)) ? strings[bit] : ""; +} + static const char *const flags_strings[] = { - "TransferReady", "CountExpired", "2", "3", - "4", "Waited", "PrimaryTC", "SecondaryTC", + " TransferReady", " CountExpired", " 2", " 3", + " 4", " Waited", " PrimaryTC", " SecondaryTC", }; + static void ni_pcidio_print_flags(unsigned int flags) { - int i; - - printk(KERN_INFO "group_1_flags:"); - for (i = 7; i >= 0; i--) { - if (flags & (1 << i)) - printk(" %s", flags_strings[i]); - } - printk("\n"); + pr_debug("group_1_flags:%s%s%s%s%s%s%s%s\n", + bit_set_string(flags, 7, flags_strings), + bit_set_string(flags, 6, flags_strings), + bit_set_string(flags, 5, flags_strings), + bit_set_string(flags, 4, flags_strings), + bit_set_string(flags, 3, flags_strings), + bit_set_string(flags, 2, flags_strings), + bit_set_string(flags, 1, flags_strings), + bit_set_string(flags, 0, flags_strings)); } -static char *status_strings[] = { - "DataLeft1", "Reserved1", "Req1", "StopTrig1", - "DataLeft2", "Reserved2", "Req2", "StopTrig2", +static const char *const status_strings[] = { + " DataLeft1", " Reserved1", " Req1", " StopTrig1", + " DataLeft2", " Reserved2", " Req2", " StopTrig2", }; static void ni_pcidio_print_status(unsigned int flags) { - int i; - - printk(KERN_INFO "group_status:"); - for (i = 7; i >= 0; i--) { - if (flags & (1 << i)) - printk(" %s", status_strings[i]); - } - printk("\n"); + pr_debug("group_status:%s%s%s%s%s%s%s%s\n", + bit_set_string(flags, 7, status_strings), + bit_set_string(flags, 6, status_strings), + bit_set_string(flags, 5, status_strings), + bit_set_string(flags, 4, status_strings), + bit_set_string(flags, 3, status_strings), + bit_set_string(flags, 2, status_strings), + bit_set_string(flags, 1, status_strings), + bit_set_string(flags, 0, status_strings)); } #endif @@ -988,8 +991,9 @@ static int pci_6534_load_fpga(struct comedi_device *dev, int fpga_index, udelay(1); } if (i == timeout) { - printk(KERN_WARNING "ni_pcidio: failed to load fpga %i, " - "waiting for status 0x2\n", fpga_index); + dev_warn(dev->class_dev, + "ni_pcidio: failed to load fpga %i, waiting for status 0x2\n", + fpga_index); return -EIO; } writew(0x80 | fpga_index, @@ -1000,8 +1004,9 @@ static int pci_6534_load_fpga(struct comedi_device *dev, int fpga_index, udelay(1); } if (i == timeout) { - printk(KERN_WARNING "ni_pcidio: failed to load fpga %i, " - "waiting for status 0x3\n", fpga_index); + dev_warn(dev->class_dev, + "ni_pcidio: failed to load fpga %i, waiting for status 0x3\n", + fpga_index); return -EIO; } for (j = 0; j + 1 < data_len;) { @@ -1016,8 +1021,9 @@ static int pci_6534_load_fpga(struct comedi_device *dev, int fpga_index, udelay(1); } if (i == timeout) { - printk("ni_pcidio: failed to load word into fpga %i\n", - fpga_index); + dev_warn(dev->class_dev, + "ni_pcidio: failed to load word into fpga %i\n", + fpga_index); return -EIO; } if (need_resched()) @@ -1108,7 +1114,7 @@ static int nidio_find_device(struct comedi_device *dev, int bus, int slot) } } } - printk(KERN_WARNING "no device found\n"); + dev_warn(dev->class_dev, "no device found\n"); mite_list_devices(); return -EIO; } @@ -1119,8 +1125,6 @@ static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it) int ret; unsigned int irq; - printk(KERN_INFO "comedi%d: nidio:", dev->minor); - ret = alloc_private(dev, sizeof(struct nidio96_private)); if (ret < 0) return ret; @@ -1132,7 +1136,7 @@ static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it) ret = mite_setup(devpriv->mite); if (ret < 0) { - printk(KERN_WARNING "error setting up mite\n"); + dev_warn(dev->class_dev, "error setting up mite\n"); return ret; } comedi_set_hw_dev(dev, &devpriv->mite->pcidev->dev); @@ -1142,7 +1146,6 @@ static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = this_board->name; irq = mite_irq(devpriv->mite); - printk(KERN_INFO " %s", dev->board_name); if (this_board->uses_firmware) { ret = pci_6534_upload_firmware(dev, it->options); if (ret < 0) @@ -1153,8 +1156,8 @@ static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - printk(KERN_INFO " rev=%d", - readb(devpriv->mite->daq_io_addr + Chip_Version)); + dev_info(dev->class_dev, "%s rev=%d\n", dev->board_name, + readb(devpriv->mite->daq_io_addr + Chip_Version)); s = &dev->subdevices[0]; @@ -1188,12 +1191,10 @@ static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it) ret = request_irq(irq, nidio_interrupt, IRQF_SHARED, "ni_pcidio", dev); if (ret < 0) - printk(KERN_WARNING " irq not available"); + dev_warn(dev->class_dev, "irq not available\n"); dev->irq = irq; - printk("\n"); - return 0; } -- cgit v0.10.2 From 9fb5c14ceba8841ece02b5185501e1d999a2bcf6 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:34:16 +0100 Subject: staging: comedi: ni_pcidio: use request_firmware() The PCI-6534 needs three firmware files loading to work with the driver. That is currently done by passing the firmware data using the `COMEDI_DEVCONFIG` ioctl that uses the comedi `attach()` hook in the driver. This doesn't work for auto-configured PCI devices (which also currently use the `attach()` hook in this driver, but doesn't have the firmware-loading options set in the `struct comedi_devconfig *` parameter). Change the driver to request the firmware files using `request_firmware()`, ignoring any firmware-loading options set in the `struct comedi_devconfig`. The PCI-6534 has a main FPGA which needs to be loaded first, and two "scarabs". Scarab A is loaded with firmware to support digital input mode, and scarab B is loaded with firmware to support digital output mode. I don't think the order of loading the scarab firmwares matters as long as they are loaded with the correct firmware files. This update loads scarab B first, whereas the original code loaded scarab A first. The firmware files are loaded in the following order: A) main FPGA: "ni6534a.bin" (FW_PCI_6534_MAIN) B) scarab B: "niscrb02.bin" (FW_PCI_6534_SCARAB_DO) C) scarab A: "niscrb01.bin" (FW_PCI_6534_SCARAB_DI) The required firmware files can be found in the "comedi-nonfree-firmware" tar-ball at . Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index 4f76daf..a655ab9 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -57,6 +57,7 @@ comedi_nonfree_firmware tarball available from http://www.comedi.org #include #include +#include #include "../comedidev.h" #include "mite.h" @@ -230,6 +231,14 @@ static inline unsigned secondary_DMAChannel_bits(unsigned channel) #define Protocol_Register_8 88 /* 32 bit */ #define StartDelay Protocol_Register_8 +/* Firmware files for PCI-6524 */ +#define FW_PCI_6534_MAIN "ni6534a.bin" +#define FW_PCI_6534_SCARAB_DI "niscrb01.bin" +#define FW_PCI_6534_SCARAB_DO "niscrb02.bin" +MODULE_FIRMWARE(FW_PCI_6534_MAIN); +MODULE_FIRMWARE(FW_PCI_6534_SCARAB_DI); +MODULE_FIRMWARE(FW_PCI_6534_SCARAB_DO); + enum pci_6534_firmware_registers { /* 16 bit */ Firmware_Control_Register = 0x100, Firmware_Status_Register = 0x104, @@ -977,10 +986,12 @@ static int ni_pcidio_change(struct comedi_device *dev, } static int pci_6534_load_fpga(struct comedi_device *dev, int fpga_index, - u8 *data, int data_len) + const u8 *data, size_t data_len) { static const int timeout = 1000; - int i, j; + int i; + size_t j; + writew(0x80 | fpga_index, devpriv->mite->daq_io_addr + Firmware_Control_Register); writew(0xc0 | fpga_index, @@ -1062,34 +1073,34 @@ static void pci_6534_init_main_fpga(struct comedi_device *dev) writel(0, devpriv->mite->daq_io_addr + FPGA_SCBMS_Counter_Register); } -static int pci_6534_upload_firmware(struct comedi_device *dev, int options[]) +static int pci_6534_upload_firmware(struct comedi_device *dev) { int ret; - void *main_fpga_data, *scarab_a_data, *scarab_b_data; - int main_fpga_data_len, scarab_a_data_len, scarab_b_data_len; + const struct firmware *fw; + static const char *const fw_file[3] = { + FW_PCI_6534_SCARAB_DI, /* loaded into scarab A for DI */ + FW_PCI_6534_SCARAB_DO, /* loaded into scarab B for DO */ + FW_PCI_6534_MAIN, /* loaded into main FPGA */ + }; + int n; - if (options[COMEDI_DEVCONF_AUX_DATA_LENGTH] == 0) - return 0; ret = pci_6534_reset_fpgas(dev); if (ret < 0) return ret; - main_fpga_data = comedi_aux_data(options, 0); - main_fpga_data_len = options[COMEDI_DEVCONF_AUX_DATA0_LENGTH]; - ret = pci_6534_load_fpga(dev, 2, main_fpga_data, main_fpga_data_len); - if (ret < 0) - return ret; - pci_6534_init_main_fpga(dev); - scarab_a_data = comedi_aux_data(options, 1); - scarab_a_data_len = options[COMEDI_DEVCONF_AUX_DATA1_LENGTH]; - ret = pci_6534_load_fpga(dev, 0, scarab_a_data, scarab_a_data_len); - if (ret < 0) - return ret; - scarab_b_data = comedi_aux_data(options, 2); - scarab_b_data_len = options[COMEDI_DEVCONF_AUX_DATA2_LENGTH]; - ret = pci_6534_load_fpga(dev, 1, scarab_b_data, scarab_b_data_len); - if (ret < 0) - return ret; - return 0; + /* load main FPGA first, then the two scarabs */ + for (n = 2; n >= 0; n--) { + ret = request_firmware(&fw, fw_file[n], + &devpriv->mite->pcidev->dev); + if (ret == 0) { + ret = pci_6534_load_fpga(dev, n, fw->data, fw->size); + if (ret == 0 && n == 2) + pci_6534_init_main_fpga(dev); + release_firmware(fw); + } + if (ret < 0) + break; + } + return ret; } static int nidio_find_device(struct comedi_device *dev, int bus, int slot) @@ -1147,7 +1158,7 @@ static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = this_board->name; irq = mite_irq(devpriv->mite); if (this_board->uses_firmware) { - ret = pci_6534_upload_firmware(dev, it->options); + ret = pci_6534_upload_firmware(dev); if (ret < 0) return ret; } -- cgit v0.10.2 From 21b74c2785c4bb28d42ce78ae15d06749e9bedfb Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:34:17 +0100 Subject: staging: comedi: ni_pcidio: use comedi attach_pci callback Convert this PCI driver to use the comedi `attach_pci` callback instead of the `attach` callback for PCI auto-configuration. There is no need to support manual attachment of PCI devices supported by this driver, so remove the `attach` callback altogether. Note that this driver still uses the list of PCI "mite" devices created by the "mite" module. This will be dealt with by a later patch once dynamic allocation of "mite" structures has been implemented. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index a655ab9..778a005 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -1103,34 +1103,36 @@ static int pci_6534_upload_firmware(struct comedi_device *dev) return ret; } -static int nidio_find_device(struct comedi_device *dev, int bus, int slot) +/* FIXME: remove this when dynamic MITE allocation implemented. */ +static struct mite_struct *nidio_find_mite(struct pci_dev *pcidev) { struct mite_struct *mite; - int i; for (mite = mite_devices; mite; mite = mite->next) { if (mite->used) continue; - if (bus || slot) { - if (bus != mite->pcidev->bus->number || - slot != PCI_SLOT(mite->pcidev->devfn)) - continue; - } - for (i = 0; i < n_nidio_boards; i++) { - if (mite_device_id(mite) == nidio_boards[i].dev_id) { - dev->board_ptr = nidio_boards + i; - devpriv->mite = mite; + if (mite->pcidev == pcidev) + return mite; + } + return NULL; +} - return 0; - } - } +static const struct nidio_board * +nidio_find_boardinfo(struct pci_dev *pcidev) +{ + unsigned int dev_id = pcidev->device; + unsigned int n; + + for (n = 0; n < ARRAY_SIZE(nidio_boards); n++) { + const struct nidio_board *board = &nidio_boards[n]; + if (board->dev_id == dev_id) + return board; } - dev_warn(dev->class_dev, "no device found\n"); - mite_list_devices(); - return -EIO; + return NULL; } -static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it) +static int __devinit nidio_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) { struct comedi_subdevice *s; int ret; @@ -1141,9 +1143,12 @@ static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it) return ret; spin_lock_init(&devpriv->mite_channel_lock); - ret = nidio_find_device(dev, it->options[0], it->options[1]); - if (ret < 0) - return ret; + dev->board_ptr = nidio_find_boardinfo(pcidev); + if (!dev->board_ptr) + return -ENODEV; + devpriv->mite = nidio_find_mite(pcidev); + if (!devpriv->mite) + return -ENODEV; ret = mite_setup(devpriv->mite); if (ret < 0) { @@ -1226,7 +1231,7 @@ static void nidio_detach(struct comedi_device *dev) static struct comedi_driver ni_pcidio_driver = { .driver_name = "ni_pcidio", .module = THIS_MODULE, - .attach = nidio_attach, + .attach_pci = nidio_attach_pci, .detach = nidio_detach, }; -- cgit v0.10.2 From 5b6137d8807524c9ecd9a35ff77421ab52a8e955 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:34:18 +0100 Subject: staging: comedi: ni_mio_common: don't pass config options to ni_E_init() `ni_E_init()` doesn't use the second parameter pointing to a `struct comedi_devconfig` passed from a comedi `attach` handler, so remove the parameter. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_atmio.c b/drivers/staging/comedi/drivers/ni_atmio.c index 6448373..cac2557 100644 --- a/drivers/staging/comedi/drivers/ni_atmio.c +++ b/drivers/staging/comedi/drivers/ni_atmio.c @@ -489,7 +489,7 @@ static int ni_atmio_attach(struct comedi_device *dev, /* generic E series stuff in ni_mio_common.c */ - ret = ni_E_init(dev, it); + ret = ni_E_init(dev); if (ret < 0) return ret; diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index 68f3bdd..8fd967a 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -4404,7 +4404,7 @@ static int ni_alloc_private(struct comedi_device *dev) return 0; }; -static int ni_E_init(struct comedi_device *dev, struct comedi_devconfig *it) +static int ni_E_init(struct comedi_device *dev) { struct comedi_subdevice *s; unsigned j; diff --git a/drivers/staging/comedi/drivers/ni_mio_cs.c b/drivers/staging/comedi/drivers/ni_mio_cs.c index b85765d..9acaad2 100644 --- a/drivers/staging/comedi/drivers/ni_mio_cs.c +++ b/drivers/staging/comedi/drivers/ni_mio_cs.c @@ -382,7 +382,7 @@ static int mio_cs_attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->stc_writel = &win_out2; devpriv->stc_readl = &win_in2; - ret = ni_E_init(dev, it); + ret = ni_E_init(dev); if (ret < 0) return ret; diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c index 89f4d43..fa008fa 100644 --- a/drivers/staging/comedi/drivers/ni_pcimio.c +++ b/drivers/staging/comedi/drivers/ni_pcimio.c @@ -1659,7 +1659,7 @@ static int pcimio_attach(struct comedi_device *dev, struct comedi_devconfig *it) } } - ret = ni_E_init(dev, it); + ret = ni_E_init(dev); if (ret < 0) return ret; -- cgit v0.10.2 From 9c4aef95d2ac1539c71f6637f298da75574776a9 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:34:19 +0100 Subject: staging: comedi: ni_pcimio: Add semicolon to module_comedi_pci_driver() Add a semi-colon after the macro call `module_comedi_pci_driver(ni_pcimio_driver, ni_pcimio_pci_driver)`. It compiles with or without the semicolon but it ought to have it. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c index fa008fa..3c06a00 100644 --- a/drivers/staging/comedi/drivers/ni_pcimio.c +++ b/drivers/staging/comedi/drivers/ni_pcimio.c @@ -1844,7 +1844,7 @@ static struct pci_driver ni_pcimio_pci_driver = { .probe = ni_pcimio_pci_probe, .remove = __devexit_p(ni_pcimio_pci_remove) }; -module_comedi_pci_driver(ni_pcimio_driver, ni_pcimio_pci_driver) +module_comedi_pci_driver(ni_pcimio_driver, ni_pcimio_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); -- cgit v0.10.2 From b021367487fef35f91a4fa82b2eed63149f63410 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:34:20 +0100 Subject: staging: comedi: ni_pcimio: Use comedi attach_pci callback Convert this PCI driver to use the comedi `attach_pci` callback instead of the `attach` callback for PCI auto-configuration. There is no need to support manual attachment of PCI devices supported by this driver, so remove the `attach` callback altogether. Note that this driver still uses the list of PCI "mite" devices created by the "mite" module. This will be dealt with by a later patch once dynamic allocation of "mite" structures has been implemented. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c index 3c06a00..5237346 100644 --- a/drivers/staging/comedi/drivers/ni_pcimio.c +++ b/drivers/staging/comedi/drivers/ni_pcimio.c @@ -1188,8 +1188,6 @@ static const struct ni_board_struct ni_boards[] = { }, }; -#define n_pcimio_boards ARRAY_SIZE(ni_boards) - struct ni_private { NI_PRIVATE_COMMON}; #define devpriv ((struct ni_private *)dev->private) @@ -1502,7 +1500,6 @@ static uint32_t m_series_stc_readl(struct comedi_device *dev, int reg) #include "ni_mio_common.c" -static int pcimio_find_device(struct comedi_device *dev, int bus, int slot); static int pcimio_ai_change(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long new_size); static int pcimio_ao_change(struct comedi_device *dev, @@ -1589,19 +1586,52 @@ static void pcimio_detach(struct comedi_device *dev) } } -static int pcimio_attach(struct comedi_device *dev, struct comedi_devconfig *it) +/* FIXME: remove this when dynamic MITE allocation implemented. */ +static struct mite_struct *pcimio_find_mite(struct pci_dev *pcidev) +{ + struct mite_struct *mite; + + for (mite = mite_devices; mite; mite = mite->next) { + if (mite->used) + continue; + if (mite->pcidev == pcidev) + return mite; + } + return NULL; +} + +static const struct ni_board_struct * +pcimio_find_boardinfo(struct pci_dev *pcidev) +{ + unsigned int device_id = pcidev->device; + unsigned int n; + + for (n = 0; n < ARRAY_SIZE(ni_boards); n++) { + const struct ni_board_struct *board = &ni_boards[n]; + if (board->device_id == device_id) + return board; + } + return NULL; +} + +static int __devinit pcimio_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) { int ret; - dev_info(dev->class_dev, "ni_pcimio: attach\n"); + dev_info(dev->class_dev, "ni_pcimio: attach %s\n", pci_name(pcidev)); ret = ni_alloc_private(dev); if (ret < 0) return ret; - ret = pcimio_find_device(dev, it->options[0], it->options[1]); - if (ret < 0) - return ret; + dev->board_ptr = pcimio_find_boardinfo(pcidev); + if (!dev->board_ptr) + return -ENODEV; + + devpriv->mite = pcimio_find_mite(pcidev); + if (!devpriv->mite) + return -ENODEV; dev_dbg(dev->class_dev, "%s\n", boardtype.name); dev->board_name = boardtype.name; @@ -1672,34 +1702,6 @@ static int pcimio_attach(struct comedi_device *dev, struct comedi_devconfig *it) return ret; } -static int pcimio_find_device(struct comedi_device *dev, int bus, int slot) -{ - struct mite_struct *mite; - int i; - - for (mite = mite_devices; mite; mite = mite->next) { - if (mite->used) - continue; - if (bus || slot) { - if (bus != mite->pcidev->bus->number || - slot != PCI_SLOT(mite->pcidev->devfn)) - continue; - } - - for (i = 0; i < n_pcimio_boards; i++) { - if (mite_device_id(mite) == ni_boards[i].device_id) { - dev->board_ptr = ni_boards + i; - devpriv->mite = mite; - - return 0; - } - } - } - pr_warn("no device found\n"); - mite_list_devices(); - return -EIO; -} - static int pcimio_ai_change(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long new_size) { @@ -1765,7 +1767,7 @@ static int pcimio_dio_change(struct comedi_device *dev, static struct comedi_driver ni_pcimio_driver = { .driver_name = "ni_pcimio", .module = THIS_MODULE, - .attach = pcimio_attach, + .attach_pci = pcimio_attach_pci, .detach = pcimio_detach, }; -- cgit v0.10.2 From ae0318019ff5d63d1128193731d2382823ff83a9 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:34:21 +0100 Subject: staging: comedi: mite: make internal functions static Declare some non-exported functions in "mite.c" `static` and remove their declarations from "mite.h". Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/mite.c b/drivers/staging/comedi/drivers/mite.c index a93166d..7a76791 100644 --- a/drivers/staging/comedi/drivers/mite.c +++ b/drivers/staging/comedi/drivers/mite.c @@ -64,7 +64,7 @@ EXPORT_SYMBOL(mite_devices); #define TOP_OF_PAGE(x) ((x)|(~(PAGE_MASK))) -void mite_init(void) +static void mite_init(void) { struct pci_dev *pcidev = NULL; struct mite_struct *mite; @@ -206,7 +206,7 @@ int mite_setup(struct mite_struct *mite) } EXPORT_SYMBOL(mite_setup); -void mite_cleanup(void) +static void mite_cleanup(void) { struct mite_struct *mite, *next; @@ -483,7 +483,7 @@ void mite_prep_dma(struct mite_channel *mite_chan, } EXPORT_SYMBOL(mite_prep_dma); -u32 mite_device_bytes_transferred(struct mite_channel *mite_chan) +static u32 mite_device_bytes_transferred(struct mite_channel *mite_chan) { struct mite_struct *mite = mite_chan->mite; return readl(mite->mite_io_addr + MITE_DAR(mite_chan->channel)); diff --git a/drivers/staging/comedi/drivers/mite.h b/drivers/staging/comedi/drivers/mite.h index 83f1b27..2120578 100644 --- a/drivers/staging/comedi/drivers/mite.h +++ b/drivers/staging/comedi/drivers/mite.h @@ -123,8 +123,6 @@ static inline unsigned int mite_device_id(struct mite_struct *mite) return mite->pcidev->device; }; -void mite_init(void); -void mite_cleanup(void); int mite_setup(struct mite_struct *mite); int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1); void mite_unsetup(struct mite_struct *mite); -- cgit v0.10.2 From 7d24e1ac00173a5a271bf1353d4216836dab55e6 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:34:22 +0100 Subject: staging: comedi: mite: export mite_alloc_ring() and mite_free_ring() The `mite_alloc_ring()` and `mite_free_ring()` static inline functions in "mite.h" are reasonably large. Transfer them to "mite.c" and export them. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/mite.c b/drivers/staging/comedi/drivers/mite.c index 7a76791..c67a94d 100644 --- a/drivers/staging/comedi/drivers/mite.c +++ b/drivers/staging/comedi/drivers/mite.c @@ -257,6 +257,41 @@ void mite_list_devices(void) } EXPORT_SYMBOL(mite_list_devices); +struct mite_dma_descriptor_ring *mite_alloc_ring(struct mite_struct *mite) +{ + struct mite_dma_descriptor_ring *ring = + kmalloc(sizeof(struct mite_dma_descriptor_ring), GFP_KERNEL); + + if (ring == NULL) + return ring; + ring->hw_dev = get_device(&mite->pcidev->dev); + if (ring->hw_dev == NULL) { + kfree(ring); + return NULL; + } + ring->n_links = 0; + ring->descriptors = NULL; + ring->descriptors_dma_addr = 0; + return ring; +}; +EXPORT_SYMBOL(mite_alloc_ring); + +void mite_free_ring(struct mite_dma_descriptor_ring *ring) +{ + if (ring) { + if (ring->descriptors) { + dma_free_coherent(ring->hw_dev, + ring->n_links * + sizeof(struct mite_dma_descriptor), + ring->descriptors, + ring->descriptors_dma_addr); + } + put_device(ring->hw_dev); + kfree(ring); + } +}; +EXPORT_SYMBOL(mite_free_ring); + struct mite_channel *mite_request_channel_in_range(struct mite_struct *mite, struct mite_dma_descriptor_ring diff --git a/drivers/staging/comedi/drivers/mite.h b/drivers/staging/comedi/drivers/mite.h index 2120578..1e04b09 100644 --- a/drivers/staging/comedi/drivers/mite.h +++ b/drivers/staging/comedi/drivers/mite.h @@ -77,40 +77,6 @@ struct mite_struct { spinlock_t lock; }; -static inline struct mite_dma_descriptor_ring *mite_alloc_ring(struct - mite_struct - *mite) -{ - struct mite_dma_descriptor_ring *ring = - kmalloc(sizeof(struct mite_dma_descriptor_ring), GFP_KERNEL); - if (ring == NULL) - return ring; - ring->hw_dev = get_device(&mite->pcidev->dev); - if (ring->hw_dev == NULL) { - kfree(ring); - return NULL; - } - ring->n_links = 0; - ring->descriptors = NULL; - ring->descriptors_dma_addr = 0; - return ring; -}; - -static inline void mite_free_ring(struct mite_dma_descriptor_ring *ring) -{ - if (ring) { - if (ring->descriptors) { - dma_free_coherent(ring->hw_dev, - ring->n_links * - sizeof(struct mite_dma_descriptor), - ring->descriptors, - ring->descriptors_dma_addr); - } - put_device(ring->hw_dev); - kfree(ring); - } -}; - extern struct mite_struct *mite_devices; static inline unsigned int mite_irq(struct mite_struct *mite) @@ -127,6 +93,8 @@ int mite_setup(struct mite_struct *mite); int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1); void mite_unsetup(struct mite_struct *mite); void mite_list_devices(void); +struct mite_dma_descriptor_ring *mite_alloc_ring(struct mite_struct *mite); +void mite_free_ring(struct mite_dma_descriptor_ring *ring); struct mite_channel *mite_request_channel_in_range(struct mite_struct *mite, struct mite_dma_descriptor_ring -- cgit v0.10.2 From d6f015b6ad035d465d0ab30e9a441e5e8d18d4b7 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:34:23 +0100 Subject: staging: comedi: mite: use ilog2() The static inline functions `MITE_IODWBSR_1_WSIZE_bits()` and `CR_RL()` in "mite.h" work out a base-2 logarithm using a `while` loop. Change them to use `ilog2()`. Also change `CR_RL()` to clamp the maximum value instead of printing an error. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/mite.h b/drivers/staging/comedi/drivers/mite.h index 1e04b09..0c5736c 100644 --- a/drivers/staging/comedi/drivers/mite.h +++ b/drivers/staging/comedi/drivers/mite.h @@ -25,6 +25,7 @@ #define _MITE_H_ #include +#include #include "../comedidev.h" /* #define DEBUG_MITE */ @@ -245,8 +246,9 @@ enum MITE_IODWBSR_bits { static inline unsigned MITE_IODWBSR_1_WSIZE_bits(unsigned size) { unsigned order = 0; - while (size >>= 1) - ++order; + + BUG_ON(size == 0); + order = ilog2(size); BUG_ON(order < 1); return (order - 1) & 0x1f; } @@ -393,12 +395,10 @@ static inline int CR_RL(unsigned int retry_limit) { int value = 0; - while (retry_limit) { - retry_limit >>= 1; - value++; - } + if (retry_limit) + value = 1 + ilog2(retry_limit); if (value > 0x7) - printk("comedi: bug! retry_limit too large\n"); + value = 0x7; return (value & 0x7) << 21; } -- cgit v0.10.2 From d799773f6837b44f4dca8d298c2be4d524d3331e Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:34:24 +0100 Subject: staging: comedi: mite: replace printk() calls Replace the `printk()` calls in this module with `dev_...()` calls where possible or `pr_...()` calls otherwise. Rework the normally ifdefed out (by the `DEBUG_MITE` macro) `mite_dump_regs()` to dump register offsets instead of remapped addresses. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/mite.c b/drivers/staging/comedi/drivers/mite.c index c67a94d..b63f86c 100644 --- a/drivers/staging/comedi/drivers/mite.c +++ b/drivers/staging/comedi/drivers/mite.c @@ -49,6 +49,8 @@ /* #define USE_KMALLOC */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include "mite.h" #include "comedi_fc.h" @@ -75,7 +77,7 @@ static void mite_init(void) mite = kzalloc(sizeof(*mite), GFP_KERNEL); if (!mite) { - printk(KERN_ERR "mite: allocation failed\n"); + pr_err("allocation failed\n"); pci_dev_put(pcidev); return; } @@ -94,14 +96,12 @@ static void mite_init(void) static void dump_chip_signature(u32 csigr_bits) { - printk(KERN_INFO "mite: version = %i, type = %i, mite mode = %i," - "interface mode = %i\n", - mite_csigr_version(csigr_bits), mite_csigr_type(csigr_bits), - mite_csigr_mmode(csigr_bits), mite_csigr_imode(csigr_bits)); - printk(KERN_INFO "mite: num channels = %i, write post fifo depth = %i," - "wins = %i, iowins = %i\n", - mite_csigr_dmac(csigr_bits), mite_csigr_wpdep(csigr_bits), - mite_csigr_wins(csigr_bits), mite_csigr_iowins(csigr_bits)); + pr_info("version = %i, type = %i, mite mode = %i, interface mode = %i\n", + mite_csigr_version(csigr_bits), mite_csigr_type(csigr_bits), + mite_csigr_mmode(csigr_bits), mite_csigr_imode(csigr_bits)); + pr_info("num channels = %i, write post fifo depth = %i, wins = %i, iowins = %i\n", + mite_csigr_dmac(csigr_bits), mite_csigr_wpdep(csigr_bits), + mite_csigr_wins(csigr_bits), mite_csigr_iowins(csigr_bits)); } unsigned mite_fifo_size(struct mite_struct *mite, unsigned channel) @@ -121,7 +121,8 @@ int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1) unsigned unknown_dma_burst_bits; if (comedi_pci_enable(mite->pcidev, "mite")) { - printk(KERN_ERR "error enabling mite and requesting io regions\n"); + dev_err(&mite->pcidev->dev, + "error enabling mite and requesting io regions\n"); return -EIO; } pci_set_master(mite->pcidev); @@ -130,11 +131,10 @@ int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1) mite->mite_phys_addr = addr; mite->mite_io_addr = ioremap(addr, PCI_MITE_SIZE); if (!mite->mite_io_addr) { - printk(KERN_ERR "Failed to remap mite io memory address\n"); + dev_err(&mite->pcidev->dev, + "Failed to remap mite io memory address\n"); return -ENOMEM; } - printk(KERN_INFO "MITE:0x%08llx mapped to %p ", - (unsigned long long)mite->mite_phys_addr, mite->mite_io_addr); addr = pci_resource_start(mite->pcidev, 1); mite->daq_phys_addr = addr; @@ -145,15 +145,15 @@ int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1) */ mite->daq_io_addr = ioremap(mite->daq_phys_addr, length); if (!mite->daq_io_addr) { - printk(KERN_ERR "Failed to remap daq io memory address\n"); + dev_err(&mite->pcidev->dev, + "Failed to remap daq io memory address\n"); return -ENOMEM; } - printk(KERN_INFO "DAQ:0x%08llx mapped to %p\n", - (unsigned long long)mite->daq_phys_addr, mite->daq_io_addr); if (use_iodwbsr_1) { writel(0, mite->mite_io_addr + MITE_IODWBSR); - printk(KERN_INFO "mite: using I/O Window Base Size register 1\n"); + dev_info(&mite->pcidev->dev, + "using I/O Window Base Size register 1\n"); writel(mite->daq_phys_addr | WENAB | MITE_IODWBSR_1_WSIZE_bits(length), mite->mite_io_addr + MITE_IODWBSR_1); @@ -178,9 +178,9 @@ int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1) csigr_bits = readl(mite->mite_io_addr + MITE_CSIGR); mite->num_channels = mite_csigr_dmac(csigr_bits); if (mite->num_channels > MAX_MITE_DMA_CHANNELS) { - printk(KERN_WARNING "mite: bug? chip claims to have %i dma " - "channels. Setting to %i.\n", - mite->num_channels, MAX_MITE_DMA_CHANNELS); + dev_warn(&mite->pcidev->dev, + "mite: bug? chip claims to have %i dma channels. Setting to %i.\n", + mite->num_channels, MAX_MITE_DMA_CHANNELS); mite->num_channels = MAX_MITE_DMA_CHANNELS; } dump_chip_signature(csigr_bits); @@ -193,7 +193,7 @@ int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1) mite->mite_io_addr + MITE_CHCR(i)); } mite->fifo_size = mite_fifo_size(mite, 0); - printk(KERN_INFO "mite: fifo size is %i.\n", mite->fifo_size); + dev_info(&mite->pcidev->dev, "fifo size is %i.\n", mite->fifo_size); mite->used = 1; return 0; @@ -245,15 +245,13 @@ void mite_list_devices(void) { struct mite_struct *mite, *next; - printk(KERN_INFO "Available NI device IDs:"); + pr_info("Available NI device IDs:\n"); if (mite_devices) for (mite = mite_devices; mite; mite = next) { next = mite->next; - printk(KERN_INFO " 0x%04x", mite_device_id(mite)); - if (mite->used) - printk(KERN_INFO "(used)"); + pr_info("0x%04x%s\n", mite_device_id(mite), + mite->used ? " (used)" : ""); } - printk(KERN_INFO "\n"); } EXPORT_SYMBOL(mite_list_devices); @@ -352,7 +350,7 @@ void mite_dma_arm(struct mite_channel *mite_chan) int chor; unsigned long flags; - MDPRINTK("mite_dma_arm ch%i\n", channel); + MDPRINTK("mite_dma_arm ch%i\n", mite_chan->channel); /* * memory barrier is intended to insure any twiddling with the buffer * is done before writing to the mite to arm dma transfer @@ -400,7 +398,8 @@ int mite_buf_change(struct mite_dma_descriptor_ring *ring, n_links * sizeof(struct mite_dma_descriptor), &ring->descriptors_dma_addr, GFP_KERNEL); if (!ring->descriptors) { - printk(KERN_ERR "mite: ring buffer allocation failed\n"); + dev_err(async->subdevice->device->class_dev, + "mite: ring buffer allocation failed\n"); return -ENOMEM; } ring->n_links = n_links; @@ -477,8 +476,7 @@ void mite_prep_dma(struct mite_channel *mite_chan, mcr |= CR_PSIZE32; break; default: - printk(KERN_WARNING "mite: bug! invalid mem bit width for dma " - "transfer\n"); + pr_warn("bug! invalid mem bit width for dma transfer\n"); break; } writel(mcr, mite->mite_io_addr + MITE_MCR(mite_chan->channel)); @@ -497,8 +495,7 @@ void mite_prep_dma(struct mite_channel *mite_chan, dcr |= CR_PSIZE32; break; default: - printk(KERN_WARNING "mite: bug! invalid dev bit width for dma " - "transfer\n"); + pr_warn("bug! invalid dev bit width for dma transfer\n"); break; } writel(dcr, mite->mite_io_addr + MITE_DCR(mite_chan->channel)); @@ -612,7 +609,8 @@ int mite_sync_input_dma(struct mite_channel *mite_chan, nbytes = mite_bytes_written_to_memory_lb(mite_chan); if ((int)(mite_bytes_written_to_memory_ub(mite_chan) - old_alloc_count) > 0) { - printk("mite: DMA overwrite of free area\n"); + dev_warn(async->subdevice->device->class_dev, + "mite: DMA overwrite of free area\n"); async->events |= COMEDI_CB_OVERFLOW; return -1; } @@ -656,7 +654,8 @@ int mite_sync_output_dma(struct mite_channel *mite_chan, (int)(nbytes_ub - stop_count) > 0) nbytes_ub = stop_count; if ((int)(nbytes_ub - old_alloc_count) > 0) { - printk(KERN_ERR "mite: DMA underrun\n"); + dev_warn(async->subdevice->device->class_dev, + "mite: DMA underrun\n"); async->events |= COMEDI_CB_OVERFLOW; return -1; } @@ -707,8 +706,6 @@ EXPORT_SYMBOL(mite_done); #ifdef DEBUG_MITE -static void mite_decode(char **bit_str, unsigned int bits); - /* names of bits in mite registers */ static const char *const mite_CHOR_strings[] = { @@ -778,70 +775,67 @@ static const char *const mite_CHSR_strings[] = { "28", "lpauses", "30", "int", }; -void mite_dump_regs(struct mite_channel *mite_chan) -{ - unsigned long mite_io_addr = - (unsigned long)mite_chan->mite->mite_io_addr; - unsigned long addr = 0; - unsigned long temp = 0; - - printk(KERN_DEBUG "mite_dump_regs ch%i\n", mite_chan->channel); - printk(KERN_DEBUG "mite address is =0x%08lx\n", mite_io_addr); - - addr = mite_io_addr + MITE_CHOR(channel); - printk(KERN_DEBUG "mite status[CHOR]at 0x%08lx =0x%08lx\n", addr, - temp = readl(addr)); - mite_decode(mite_CHOR_strings, temp); - addr = mite_io_addr + MITE_CHCR(channel); - printk(KERN_DEBUG "mite status[CHCR]at 0x%08lx =0x%08lx\n", addr, - temp = readl(addr)); - mite_decode(mite_CHCR_strings, temp); - addr = mite_io_addr + MITE_TCR(channel); - printk(KERN_DEBUG "mite status[TCR] at 0x%08lx =0x%08x\n", addr, - readl(addr)); - addr = mite_io_addr + MITE_MCR(channel); - printk(KERN_DEBUG "mite status[MCR] at 0x%08lx =0x%08lx\n", addr, - temp = readl(addr)); - mite_decode(mite_MCR_strings, temp); - - addr = mite_io_addr + MITE_MAR(channel); - printk(KERN_DEBUG "mite status[MAR] at 0x%08lx =0x%08x\n", addr, - readl(addr)); - addr = mite_io_addr + MITE_DCR(channel); - printk(KERN_DEBUG "mite status[DCR] at 0x%08lx =0x%08lx\n", addr, - temp = readl(addr)); - mite_decode(mite_DCR_strings, temp); - addr = mite_io_addr + MITE_DAR(channel); - printk(KERN_DEBUG "mite status[DAR] at 0x%08lx =0x%08x\n", addr, - readl(addr)); - addr = mite_io_addr + MITE_LKCR(channel); - printk(KERN_DEBUG "mite status[LKCR]at 0x%08lx =0x%08lx\n", addr, - temp = readl(addr)); - mite_decode(mite_LKCR_strings, temp); - addr = mite_io_addr + MITE_LKAR(channel); - printk(KERN_DEBUG "mite status[LKAR]at 0x%08lx =0x%08x\n", addr, - readl(addr)); - addr = mite_io_addr + MITE_CHSR(channel); - printk(KERN_DEBUG "mite status[CHSR]at 0x%08lx =0x%08lx\n", addr, - temp = readl(addr)); - mite_decode(mite_CHSR_strings, temp); - addr = mite_io_addr + MITE_FCR(channel); - printk(KERN_DEBUG "mite status[FCR] at 0x%08lx =0x%08x\n\n", addr, - readl(addr)); -} -EXPORT_SYMBOL(mite_dump_regs); - -static void mite_decode(char **bit_str, unsigned int bits) +static void mite_decode(const char *const *bit_str, unsigned int bits) { int i; for (i = 31; i >= 0; i--) { if (bits & (1 << i)) - printk(KERN_DEBUG " %s", bit_str[i]); + pr_debug(" %s\n", bit_str[i]); } - printk(KERN_DEBUG "\n"); } -EXPORT_SYMBOL(mite_decode); + +void mite_dump_regs(struct mite_channel *mite_chan) +{ + void __iomem *mite_io_addr = mite_chan->mite->mite_io_addr; + unsigned int offset; + unsigned int value; + int channel = mite_chan->channel; + + pr_debug("mite_dump_regs ch%i\n", channel); + pr_debug("mite address is =%p\n", mite_io_addr); + + offset = MITE_CHOR(channel); + value = readl(mite_io_addr + offset); + pr_debug("mite status[CHOR] at 0x%08x =0x%08x\n", offset, value); + mite_decode(mite_CHOR_strings, value); + offset = MITE_CHCR(channel); + value = readl(mite_io_addr + offset); + pr_debug("mite status[CHCR] at 0x%08x =0x%08x\n", offset, value); + mite_decode(mite_CHCR_strings, value); + offset = MITE_TCR(channel); + value = readl(mite_io_addr + offset); + pr_debug("mite status[TCR] at 0x%08x =0x%08x\n", offset, value); + offset = MITE_MCR(channel); + value = readl(mite_io_addr + offset); + pr_debug("mite status[MCR] at 0x%08x =0x%08x\n", offset, value); + mite_decode(mite_MCR_strings, value); + offset = MITE_MAR(channel); + value = readl(mite_io_addr + offset); + pr_debug("mite status[MAR] at 0x%08x =0x%08x\n", offset, value); + offset = MITE_DCR(channel); + value = readl(mite_io_addr + offset); + pr_debug("mite status[DCR] at 0x%08x =0x%08x\n", offset, value); + mite_decode(mite_DCR_strings, value); + offset = MITE_DAR(channel); + value = readl(mite_io_addr + offset); + pr_debug("mite status[DAR] at 0x%08x =0x%08x\n", offset, value); + offset = MITE_LKCR(channel); + value = readl(mite_io_addr + offset); + pr_debug("mite status[LKCR] at 0x%08x =0x%08x\n", offset, value); + mite_decode(mite_LKCR_strings, value); + offset = MITE_LKAR(channel); + value = readl(mite_io_addr + offset); + pr_debug("mite status[LKAR] at 0x%08x =0x%08x\n", offset, value); + offset = MITE_CHSR(channel); + value = readl(mite_io_addr + offset); + pr_debug("mite status[CHSR] at 0x%08x =0x%08x\n", offset, value); + mite_decode(mite_CHSR_strings, value); + offset = MITE_FCR(channel); + value = readl(mite_io_addr + offset); + pr_debug("mite status[FCR] at 0x%08x =0x%08x\n", offset, value); +} +EXPORT_SYMBOL(mite_dump_regs); #endif #ifdef MODULE diff --git a/drivers/staging/comedi/drivers/mite.h b/drivers/staging/comedi/drivers/mite.h index 0c5736c..c5157c3 100644 --- a/drivers/staging/comedi/drivers/mite.h +++ b/drivers/staging/comedi/drivers/mite.h @@ -32,9 +32,9 @@ #define PCIMIO_COMPAT #ifdef DEBUG_MITE -#define MDPRINTK(format, args...) printk(format , ## args) +#define MDPRINTK(format, args...) pr_debug(format , ## args) #else -#define MDPRINTK(format, args...) +#define MDPRINTK(format, args...) do { } while (0) #endif #define MAX_MITE_DMA_CHANNELS 8 -- cgit v0.10.2 From ca8eb8d5c8aa1a0828d381b213b14e13961f5297 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:34:25 +0100 Subject: staging: comedi: mite: add mite_alloc() and mite_free() Add `mite_alloc()` to allow drivers to allocate and initialize a `struct mite_struct` dynamically and export it. Add `mite_free()`, which is currently just an inline wrapper for `kfree()`. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/mite.c b/drivers/staging/comedi/drivers/mite.c index b63f86c..7355455 100644 --- a/drivers/staging/comedi/drivers/mite.c +++ b/drivers/staging/comedi/drivers/mite.c @@ -66,6 +66,25 @@ EXPORT_SYMBOL(mite_devices); #define TOP_OF_PAGE(x) ((x)|(~(PAGE_MASK))) +struct mite_struct *mite_alloc(struct pci_dev *pcidev) +{ + struct mite_struct *mite; + unsigned int i; + + mite = kzalloc(sizeof(*mite), GFP_KERNEL); + if (mite) { + spin_lock_init(&mite->lock); + mite->pcidev = pcidev; + for (i = 0; i < MAX_MITE_DMA_CHANNELS; ++i) { + mite->channels[i].mite = mite; + mite->channels[i].channel = i; + mite->channels[i].done = 1; + } + } + return mite; +} +EXPORT_SYMBOL(mite_alloc); + static void mite_init(void) { struct pci_dev *pcidev = NULL; @@ -73,21 +92,13 @@ static void mite_init(void) for_each_pci_dev(pcidev) { if (pcidev->vendor == PCI_VENDOR_ID_NI) { - unsigned i; - - mite = kzalloc(sizeof(*mite), GFP_KERNEL); + mite = mite_alloc(pcidev); if (!mite) { pr_err("allocation failed\n"); pci_dev_put(pcidev); return; } - spin_lock_init(&mite->lock); - mite->pcidev = pci_dev_get(pcidev); - for (i = 0; i < MAX_MITE_DMA_CHANNELS; ++i) { - mite->channels[i].mite = mite; - mite->channels[i].channel = i; - mite->channels[i].done = 1; - } + pci_dev_get(pcidev); mite->next = mite_devices; mite_devices = mite; } @@ -213,7 +224,7 @@ static void mite_cleanup(void) for (mite = mite_devices; mite; mite = next) { pci_dev_put(mite->pcidev); next = mite->next; - kfree(mite); + mite_free(mite); } } diff --git a/drivers/staging/comedi/drivers/mite.h b/drivers/staging/comedi/drivers/mite.h index c5157c3..912bae1 100644 --- a/drivers/staging/comedi/drivers/mite.h +++ b/drivers/staging/comedi/drivers/mite.h @@ -80,6 +80,13 @@ struct mite_struct { extern struct mite_struct *mite_devices; +struct mite_struct *mite_alloc(struct pci_dev *pcidev); + +static inline void mite_free(struct mite_struct *mite) +{ + kfree(mite); +} + static inline unsigned int mite_irq(struct mite_struct *mite) { return mite->pcidev->irq; -- cgit v0.10.2 From 6dc71205fc2e87ff68f5d60ffe632013587bc26c Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:34:26 +0100 Subject: staging: comedi: ni_6527: use mite_alloc() Allocate `struct mite_device` dynamically instead of searching for one on the `mite_devices` list constructed by the "mite" module. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index 170edb7..8125d50 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -353,20 +353,6 @@ static int ni6527_intr_insn_config(struct comedi_device *dev, return 2; } -/* FIXME: remove this when dynamic MITE allocation implemented. */ -static struct mite_struct *ni6527_find_mite(struct pci_dev *pcidev) -{ - struct mite_struct *mite; - - for (mite = mite_devices; mite; mite = mite->next) { - if (mite->used) - continue; - if (mite->pcidev == pcidev) - return mite; - } - return NULL; -} - static const struct ni6527_board * ni6527_find_boardinfo(struct pci_dev *pcidev) { @@ -395,9 +381,9 @@ static int __devinit ni6527_attach_pci(struct comedi_device *dev, if (!dev->board_ptr) return -ENODEV; - devpriv->mite = ni6527_find_mite(pcidev); + devpriv->mite = mite_alloc(pcidev); if (!devpriv->mite) - return -ENODEV; + return -ENOMEM; ret = mite_setup(devpriv->mite); if (ret < 0) { @@ -468,8 +454,10 @@ static void ni6527_detach(struct comedi_device *dev) devpriv->mite->daq_io_addr + Master_Interrupt_Control); if (dev->irq) free_irq(dev->irq, dev); - if (devpriv && devpriv->mite) + if (devpriv && devpriv->mite) { mite_unsetup(devpriv->mite); + mite_free(devpriv->mite); + } } static struct comedi_driver ni6527_driver = { -- cgit v0.10.2 From 2967d0ae4cd00acd764f3d6fc426a99304ef3712 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:34:27 +0100 Subject: staging: comedi: ni_65xx: use mite_alloc() Allocate `struct mite_device` dynamically instead of searching for one on the `mite_devices` list constructed by the "mite" module. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index c4174da..aab2b06 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -629,20 +629,6 @@ static int ni_65xx_intr_insn_config(struct comedi_device *dev, return 2; } -/* FIXME: remove this when dynamic MITE allocation implemented. */ -static struct mite_struct *ni_65xx_find_mite(struct pci_dev *pcidev) -{ - struct mite_struct *mite; - - for (mite = mite_devices; mite; mite = mite->next) { - if (mite->used) - continue; - if (mite->pcidev == pcidev) - return mite; - } - return NULL; -} - static const struct ni_65xx_board * ni_65xx_find_boardinfo(struct pci_dev *pcidev) { @@ -672,9 +658,9 @@ static int __devinit ni_65xx_attach_pci(struct comedi_device *dev, if (!dev->board_ptr) return -ENODEV; - private(dev)->mite = ni_65xx_find_mite(pcidev); + private(dev)->mite = mite_alloc(pcidev); if (!private(dev)->mite) - return -ENODEV; + return -ENOMEM; ret = mite_setup(private(dev)->mite); if (ret < 0) { @@ -810,8 +796,10 @@ static void ni_65xx_detach(struct comedi_device *dev) kfree(s->private); s->private = NULL; } - if (private(dev)->mite) + if (private(dev)->mite) { mite_unsetup(private(dev)->mite); + mite_free(private(dev)->mite); + } } } -- cgit v0.10.2 From 05ac0635a52836face9acadbc4ffe25ed2f6828a Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:34:28 +0100 Subject: staging: comedi: ni_660x: use mite_alloc() Allocate `struct mite_device` dynamically instead of searching for one on the `mite_devices` list constructed by the "mite" module. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 3b125a6..d3c8e6a 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -1034,20 +1034,6 @@ static void ni_660x_free_mite_rings(struct comedi_device *dev) } } -/* FIXME: remove this when dynamic MITE allocation implemented. */ -static struct mite_struct *ni_660x_find_mite(struct pci_dev *pcidev) -{ - struct mite_struct *mite; - - for (mite = mite_devices; mite; mite = mite->next) { - if (mite->used) - continue; - if (mite->pcidev == pcidev) - return mite; - } - return NULL; -} - static const struct ni_660x_board * ni_660x_find_boardinfo(struct pci_dev *pcidev) { @@ -1076,9 +1062,9 @@ static int __devinit ni_660x_attach_pci(struct comedi_device *dev, dev->board_ptr = ni_660x_find_boardinfo(pcidev); if (!dev->board_ptr) return -ENODEV; - private(dev)->mite = ni_660x_find_mite(pcidev); + private(dev)->mite = mite_alloc(pcidev); if (!private(dev)->mite) - return -ENODEV; + return -ENOMEM; dev->board_name = board(dev)->name; @@ -1196,6 +1182,7 @@ static void ni_660x_detach(struct comedi_device *dev) if (private(dev)->mite) { ni_660x_free_mite_rings(dev); mite_unsetup(private(dev)->mite); + mite_free(private(dev)->mite); } } } -- cgit v0.10.2 From 6bc42c22289bb431d613082c869193ef16112ba3 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:34:29 +0100 Subject: staging: comedi: ni_670x: use mite_alloc() Allocate `struct mite_device` dynamically instead of searching for one on the `mite_devices` list constructed by the "mite" module. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c index 1783219..fb83625 100644 --- a/drivers/staging/comedi/drivers/ni_670x.c +++ b/drivers/staging/comedi/drivers/ni_670x.c @@ -187,20 +187,6 @@ static int ni_670x_dio_insn_config(struct comedi_device *dev, return insn->n; } -/* FIXME: remove this when dynamic MITE allocation implemented. */ -static struct mite_struct *ni_670x_find_mite(struct pci_dev *pcidev) -{ - struct mite_struct *mite; - - for (mite = mite_devices; mite; mite = mite->next) { - if (mite->used) - continue; - if (mite->pcidev == pcidev) - return mite; - } - return NULL; -} - static const struct ni_670x_board * ni_670x_find_boardinfo(struct pci_dev *pcidev) { @@ -231,9 +217,9 @@ static int __devinit ni_670x_attach_pci(struct comedi_device *dev, dev->board_ptr = ni_670x_find_boardinfo(pcidev); if (!dev->board_ptr) return -ENODEV; - devpriv->mite = ni_670x_find_mite(pcidev); + devpriv->mite = mite_alloc(pcidev); if (!devpriv->mite) - return -ENODEV; + return -ENOMEM; thisboard = comedi_board(dev); ret = mite_setup(devpriv->mite); @@ -303,8 +289,10 @@ static void ni_670x_detach(struct comedi_device *dev) if (s) kfree(s->range_table_list); } - if (devpriv && devpriv->mite) + if (devpriv && devpriv->mite) { mite_unsetup(devpriv->mite); + mite_free(devpriv->mite); + } if (dev->irq) free_irq(dev->irq, dev); } -- cgit v0.10.2 From 604d66ce56ee8b31f32353006554dd6538feefb0 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:34:30 +0100 Subject: staging: comedi: ni_670x: remove spurious free_irq() call This driver's comedi `detach` handler (`ni_670x_detach()`) calls `free_irq()` but the driver doesn't call `request_irq()` anywhere. Remove the spurious call. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c index fb83625..eac6dc0 100644 --- a/drivers/staging/comedi/drivers/ni_670x.c +++ b/drivers/staging/comedi/drivers/ni_670x.c @@ -228,7 +228,6 @@ static int __devinit ni_670x_attach_pci(struct comedi_device *dev, return ret; } dev->board_name = thisboard->name; - dev->irq = mite_irq(devpriv->mite); ret = comedi_alloc_subdevices(dev, 2); if (ret) @@ -293,8 +292,6 @@ static void ni_670x_detach(struct comedi_device *dev) mite_unsetup(devpriv->mite); mite_free(devpriv->mite); } - if (dev->irq) - free_irq(dev->irq, dev); } static struct comedi_driver ni_670x_driver = { -- cgit v0.10.2 From e4ff75b58a2475c9aafe1d137aa81bcba90aa379 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:34:31 +0100 Subject: staging: comedi: ni_labpc: use mite_alloc() Allocate `struct mite_device` dynamically instead of searching for one on the `mite_devices` list constructed by the "mite" module. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index 7d36c2c..295ddbb 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -696,20 +696,6 @@ labpc_pci_find_boardinfo(struct pci_dev *pcidev) return NULL; } -/* FIXME: remove this when dynamic MITE allocation implemented. */ -static struct mite_struct *labpc_pci_find_mite(struct pci_dev *pcidev) -{ - struct mite_struct *mite; - - for (mite = mite_devices; mite; mite = mite->next) { - if (mite->used) - continue; - if (mite->pcidev == pcidev) - return mite; - } - return NULL; -} - static int __devinit labpc_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) { @@ -725,9 +711,9 @@ static int __devinit labpc_attach_pci(struct comedi_device *dev, dev->board_ptr = labpc_pci_find_boardinfo(pcidev); if (!dev->board_ptr) return -ENODEV; - devpriv->mite = labpc_pci_find_mite(pcidev); + devpriv->mite = mite_alloc(pcidev); if (!devpriv->mite) - return -ENODEV; + return -ENOMEM; ret = mite_setup(devpriv->mite); if (ret < 0) return ret; @@ -800,8 +786,10 @@ void labpc_common_detach(struct comedi_device *dev) if (thisboard->bustype == isa_bustype && dev->iobase) release_region(dev->iobase, LABPC_SIZE); #ifdef CONFIG_COMEDI_PCI_DRIVERS - if (devpriv->mite) + if (devpriv->mite) { mite_unsetup(devpriv->mite); + mite_free(devpriv->mite); + } #endif }; EXPORT_SYMBOL_GPL(labpc_common_detach); -- cgit v0.10.2 From f822a6a1a11759f0a694a4a3547c1186e1a2eaec Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:34:32 +0100 Subject: staging: comedi: ni_pcidio: use mite_alloc() Allocate `struct mite_device` dynamically instead of searching for one on the `mite_devices` list constructed by the "mite" module. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index 778a005..acbed13 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -1103,20 +1103,6 @@ static int pci_6534_upload_firmware(struct comedi_device *dev) return ret; } -/* FIXME: remove this when dynamic MITE allocation implemented. */ -static struct mite_struct *nidio_find_mite(struct pci_dev *pcidev) -{ - struct mite_struct *mite; - - for (mite = mite_devices; mite; mite = mite->next) { - if (mite->used) - continue; - if (mite->pcidev == pcidev) - return mite; - } - return NULL; -} - static const struct nidio_board * nidio_find_boardinfo(struct pci_dev *pcidev) { @@ -1146,9 +1132,9 @@ static int __devinit nidio_attach_pci(struct comedi_device *dev, dev->board_ptr = nidio_find_boardinfo(pcidev); if (!dev->board_ptr) return -ENODEV; - devpriv->mite = nidio_find_mite(pcidev); + devpriv->mite = mite_alloc(pcidev); if (!devpriv->mite) - return -ENODEV; + return -ENOMEM; ret = mite_setup(devpriv->mite); if (ret < 0) { @@ -1223,8 +1209,10 @@ static void nidio_detach(struct comedi_device *dev) mite_free_ring(devpriv->di_mite_ring); devpriv->di_mite_ring = NULL; } - if (devpriv->mite) + if (devpriv->mite) { mite_unsetup(devpriv->mite); + mite_free(devpriv->mite); + } } } -- cgit v0.10.2 From a5cf79e3ace423360126a4eeb5089c19c99ae060 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:34:33 +0100 Subject: staging: comedi: ni_pcimio: use mite_alloc() Allocate `struct mite_device` dynamically instead of searching for one on the `mite_devices` list constructed by the "mite" module. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c index 5237346..f284a90 100644 --- a/drivers/staging/comedi/drivers/ni_pcimio.c +++ b/drivers/staging/comedi/drivers/ni_pcimio.c @@ -1581,25 +1581,13 @@ static void pcimio_detach(struct comedi_device *dev) mite_free_ring(devpriv->cdo_mite_ring); mite_free_ring(devpriv->gpct_mite_ring[0]); mite_free_ring(devpriv->gpct_mite_ring[1]); - if (devpriv->mite) + if (devpriv->mite) { mite_unsetup(devpriv->mite); + mite_free(devpriv->mite); + } } } -/* FIXME: remove this when dynamic MITE allocation implemented. */ -static struct mite_struct *pcimio_find_mite(struct pci_dev *pcidev) -{ - struct mite_struct *mite; - - for (mite = mite_devices; mite; mite = mite->next) { - if (mite->used) - continue; - if (mite->pcidev == pcidev) - return mite; - } - return NULL; -} - static const struct ni_board_struct * pcimio_find_boardinfo(struct pci_dev *pcidev) { @@ -1629,9 +1617,9 @@ static int __devinit pcimio_attach_pci(struct comedi_device *dev, if (!dev->board_ptr) return -ENODEV; - devpriv->mite = pcimio_find_mite(pcidev); + devpriv->mite = mite_alloc(pcidev); if (!devpriv->mite) - return -ENODEV; + return -ENOMEM; dev_dbg(dev->class_dev, "%s\n", boardtype.name); dev->board_name = boardtype.name; -- cgit v0.10.2 From 551e2c3cf7733ac141768fc6cbdb05d6633d08a6 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:34:34 +0100 Subject: staging: comedi: mite: remove list of devices All the drivers that use the "mite" module now allocate a `struct mite_struct` dynamically instead of searching the `mite_devices` list populated during initialization of the "mite" module. Remove the list of devices and the function that prints available NI devices on the list (`mite_list_devices()`). The list node and `used` members in `struct mite_struct` are now redundant, so remove them. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/mite.c b/drivers/staging/comedi/drivers/mite.c index 7355455..873c2b7 100644 --- a/drivers/staging/comedi/drivers/mite.c +++ b/drivers/staging/comedi/drivers/mite.c @@ -61,9 +61,6 @@ #define PCI_DAQ_SIZE 4096 #define PCI_DAQ_SIZE_660X 8192 -struct mite_struct *mite_devices; -EXPORT_SYMBOL(mite_devices); - #define TOP_OF_PAGE(x) ((x)|(~(PAGE_MASK))) struct mite_struct *mite_alloc(struct pci_dev *pcidev) @@ -85,26 +82,6 @@ struct mite_struct *mite_alloc(struct pci_dev *pcidev) } EXPORT_SYMBOL(mite_alloc); -static void mite_init(void) -{ - struct pci_dev *pcidev = NULL; - struct mite_struct *mite; - - for_each_pci_dev(pcidev) { - if (pcidev->vendor == PCI_VENDOR_ID_NI) { - mite = mite_alloc(pcidev); - if (!mite) { - pr_err("allocation failed\n"); - pci_dev_put(pcidev); - return; - } - pci_dev_get(pcidev); - mite->next = mite_devices; - mite_devices = mite; - } - } -} - static void dump_chip_signature(u32 csigr_bits) { pr_info("version = %i, type = %i, mite mode = %i, interface mode = %i\n", @@ -205,8 +182,6 @@ int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1) } mite->fifo_size = mite_fifo_size(mite, 0); dev_info(&mite->pcidev->dev, "fifo size is %i.\n", mite->fifo_size); - mite->used = 1; - return 0; } EXPORT_SYMBOL(mite_setup2); @@ -217,17 +192,6 @@ int mite_setup(struct mite_struct *mite) } EXPORT_SYMBOL(mite_setup); -static void mite_cleanup(void) -{ - struct mite_struct *mite, *next; - - for (mite = mite_devices; mite; mite = next) { - pci_dev_put(mite->pcidev); - next = mite->next; - mite_free(mite); - } -} - void mite_unsetup(struct mite_struct *mite) { /* unsigned long offset, start, length; */ @@ -247,25 +211,9 @@ void mite_unsetup(struct mite_struct *mite) comedi_pci_disable(mite->pcidev); mite->mite_phys_addr = 0; } - - mite->used = 0; } EXPORT_SYMBOL(mite_unsetup); -void mite_list_devices(void) -{ - struct mite_struct *mite, *next; - - pr_info("Available NI device IDs:\n"); - if (mite_devices) - for (mite = mite_devices; mite; mite = next) { - next = mite->next; - pr_info("0x%04x%s\n", mite_device_id(mite), - mite->used ? " (used)" : ""); - } -} -EXPORT_SYMBOL(mite_list_devices); - struct mite_dma_descriptor_ring *mite_alloc_ring(struct mite_struct *mite) { struct mite_dma_descriptor_ring *ring = @@ -852,15 +800,11 @@ EXPORT_SYMBOL(mite_dump_regs); #ifdef MODULE int __init init_module(void) { - mite_init(); - mite_list_devices(); - return 0; } void __exit cleanup_module(void) { - mite_cleanup(); } #endif diff --git a/drivers/staging/comedi/drivers/mite.h b/drivers/staging/comedi/drivers/mite.h index 912bae1..255b8ba 100644 --- a/drivers/staging/comedi/drivers/mite.h +++ b/drivers/staging/comedi/drivers/mite.h @@ -62,15 +62,11 @@ struct mite_channel { }; struct mite_struct { - struct mite_struct *next; - int used; - struct pci_dev *pcidev; resource_size_t mite_phys_addr; void __iomem *mite_io_addr; resource_size_t daq_phys_addr; void __iomem *daq_io_addr; - struct mite_channel channels[MAX_MITE_DMA_CHANNELS]; short channel_allocated[MAX_MITE_DMA_CHANNELS]; int num_channels; @@ -78,8 +74,6 @@ struct mite_struct { spinlock_t lock; }; -extern struct mite_struct *mite_devices; - struct mite_struct *mite_alloc(struct pci_dev *pcidev); static inline void mite_free(struct mite_struct *mite) @@ -100,7 +94,6 @@ static inline unsigned int mite_device_id(struct mite_struct *mite) int mite_setup(struct mite_struct *mite); int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1); void mite_unsetup(struct mite_struct *mite); -void mite_list_devices(void); struct mite_dma_descriptor_ring *mite_alloc_ring(struct mite_struct *mite); void mite_free_ring(struct mite_dma_descriptor_ring *ring); struct mite_channel *mite_request_channel_in_range(struct mite_struct *mite, -- cgit v0.10.2 From a09b027882414f3e75398898905ffb1525056c55 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 14 Sep 2012 17:34:35 +0100 Subject: staging: comedi: mite: use module_init()/module_exit() Rename the standard `init_module()` and `cleanup_module()` functions and make them static. Use `module_init()` and `module_exit()` to mark the renamed functions as the module init and exit functions. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/mite.c b/drivers/staging/comedi/drivers/mite.c index 873c2b7..d4f486a 100644 --- a/drivers/staging/comedi/drivers/mite.c +++ b/drivers/staging/comedi/drivers/mite.c @@ -797,16 +797,17 @@ void mite_dump_regs(struct mite_channel *mite_chan) EXPORT_SYMBOL(mite_dump_regs); #endif -#ifdef MODULE -int __init init_module(void) +static int __init mite_module_init(void) { return 0; } -void __exit cleanup_module(void) +static void __exit mite_module_exit(void) { } -#endif + +module_init(mite_module_init); +module_exit(mite_module_exit); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); -- cgit v0.10.2 From e4c536b72fd6b25c7f4f9c6f293f43ba287b8e8f Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 14 Sep 2012 09:56:00 +0300 Subject: Staging: silicom: add some range checks to proc functions If you tried to cat more than 255 characters (the last character is for the terminator) to these proc files then it would corrupt kernel memory. Signed-off-by: Dan Carpenter Signed-off-by: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/bp_mod.c b/drivers/staging/silicom/bp_mod.c index 6e999c7..1b3f5e7 100644 --- a/drivers/staging/silicom/bp_mod.c +++ b/drivers/staging/silicom/bp_mod.c @@ -8227,6 +8227,9 @@ set_dis_bypass_pfs(struct file *file, const char *buffer, int bypass_param = 0, length = 0; + if (count >= sizeof(kbuf)) + return -EINVAL; + if (copy_from_user(&kbuf, buffer, count)) { return -1; } @@ -8256,6 +8259,9 @@ set_dis_tap_pfs(struct file *file, const char *buffer, int tap_param = 0, length = 0; + if (count >= sizeof(kbuf)) + return -EINVAL; + if (copy_from_user(&kbuf, buffer, count)) { return -1; } @@ -8285,6 +8291,9 @@ set_dis_disc_pfs(struct file *file, const char *buffer, int tap_param = 0, length = 0; + if (count >= sizeof(kbuf)) + return -EINVAL; + if (copy_from_user(&kbuf, buffer, count)) { return -1; } @@ -8374,6 +8383,9 @@ set_bypass_pwup_pfs(struct file *file, const char *buffer, int bypass_param = 0, length = 0; + if (count >= sizeof(kbuf)) + return -EINVAL; + if (copy_from_user(&kbuf, buffer, count)) { return -1; } @@ -8403,6 +8415,9 @@ set_bypass_pwoff_pfs(struct file *file, const char *buffer, int bypass_param = 0, length = 0; + if (count >= sizeof(kbuf)) + return -EINVAL; + if (copy_from_user(&kbuf, buffer, count)) { return -1; } @@ -8432,6 +8447,9 @@ set_tap_pwup_pfs(struct file *file, const char *buffer, int tap_param = 0, length = 0; + if (count >= sizeof(kbuf)) + return -EINVAL; + if (copy_from_user(&kbuf, buffer, count)) { return -1; } @@ -8461,6 +8479,9 @@ set_disc_pwup_pfs(struct file *file, const char *buffer, int tap_param = 0, length = 0; + if (count >= sizeof(kbuf)) + return -EINVAL; + if (copy_from_user(&kbuf, buffer, count)) { return -1; } @@ -8570,6 +8591,9 @@ set_std_nic_pfs(struct file *file, const char *buffer, int bypass_param = 0, length = 0; + if (count >= sizeof(kbuf)) + return -EINVAL; + if (copy_from_user(&kbuf, buffer, count)) { return -1; } -- cgit v0.10.2 From 82e6bb03983f265d06f2573e48e1cc0ae94d959a Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 14 Sep 2012 11:11:35 +0300 Subject: Staging: silicom: use kstrtoint_from_user() The main problem with the hand rolled code was that there weren't any range checks so you could corrupt memory by writing too much data to the proc file. Signed-off-by: Dan Carpenter Signed-off-by: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/bp_mod.c b/drivers/staging/silicom/bp_mod.c index 1b3f5e7..f138d29 100644 --- a/drivers/staging/silicom/bp_mod.c +++ b/drivers/staging/silicom/bp_mod.c @@ -8071,20 +8071,13 @@ int set_bypass_wd_pfs(struct file *file, const char *buffer, unsigned long count, void *data) { - - char kbuf[256]; bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; + int timeout; + int ret; - unsigned int timeout = 0; - char *timeout_ptr = kbuf; - - if (copy_from_user(&kbuf, buffer, count)) { - return -1; - } - - timeout_ptr = kbuf; - timeout = atoi(&timeout_ptr); - + ret = kstrtoint_from_user(buffer, count, 10, &timeout); + if (ret) + return ret; set_bypass_wd_fn(pbp_device_block, timeout); return count; @@ -8712,18 +8705,13 @@ int set_wd_autoreset_pfs(struct file *file, const char *buffer, unsigned long count, void *data) { - char kbuf[256]; bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data; - u32 timeout = 0; - char *timeout_ptr = kbuf; - - if (copy_from_user(&kbuf, buffer, count)) { - return -1; - } - - timeout_ptr = kbuf; - timeout = atoi(&timeout_ptr); + int timeout; + int ret; + ret = kstrtoint_from_user(buffer, count, 10, &timeout); + if (ret) + return ret; set_wd_autoreset_fn(pbp_device_block, timeout); return count; -- cgit v0.10.2 From ad139634c50999ab4007a2d83afe96cc500b0afd Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sun, 16 Sep 2012 13:49:40 -0400 Subject: staging: ft1000: replace c99 comments with c88 replace some of the c99 comments to the structures with c88 comment style no code change is done here. Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c index f8b8e71..47cc365 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c @@ -94,27 +94,27 @@ void put_request_value(struct net_device *dev, long lvalue); u16 hdr_checksum(struct pseudo_hdr *pHdr); struct dsp_file_hdr { - u32 version_id; // Version ID of this image format. - u32 package_id; // Package ID of code release. - u32 build_date; // Date/time stamp when file was built. - u32 commands_offset; // Offset to attached commands in Pseudo Hdr format. - u32 loader_offset; // Offset to bootloader code. - u32 loader_code_address; // Start address of bootloader. - u32 loader_code_end; // Where bootloader code ends. + u32 version_id; /* Version ID of this image format. */ + u32 package_id; /* Package ID of code release. */ + u32 build_date; /* Date/time stamp when file was built. */ + u32 commands_offset; /* Offset to attached commands in Pseudo Hdr format. */ + u32 loader_offset; /* Offset to bootloader code. */ + u32 loader_code_address; /* Start address of bootloader. */ + u32 loader_code_end; /* Where bootloader code ends. */ u32 loader_code_size; - u32 version_data_offset; // Offset were scrambled version data begins. - u32 version_data_size; // Size, in words, of scrambled version data. - u32 nDspImages; // Number of DSP images in file. + u32 version_data_offset; /* Offset were scrambled version data begins. */ + u32 version_data_size; /* Size, in words, of scrambled version data. */ + u32 nDspImages; /* Number of DSP images in file. */ } __attribute__ ((packed)); struct dsp_image_info { - u32 coff_date; // Date/time when DSP Coff image was built. - u32 begin_offset; // Offset in file where image begins. - u32 end_offset; // Offset in file where image begins. - u32 run_address; // On chip Start address of DSP code. - u32 image_size; // Size of image. - u32 version; // Embedded version # of DSP code. - unsigned short checksum; // Dsp File checksum + u32 coff_date; /* Date/time when DSP Coff image was built. */ + u32 begin_offset; /* Offset in file where image begins. */ + u32 end_offset; /* Offset in file where image begins. */ + u32 run_address; /* On chip Start address of DSP code. */ + u32 image_size; /* Size of image. */ + u32 version; /* Embedded version # of DSP code. */ + unsigned short checksum; /* Dsp File checksum */ unsigned short pad1; } __attribute__ ((packed)); -- cgit v0.10.2 From 0c4a9f6e0ac55db62816bfa5e584ed807540a5ee Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sun, 16 Sep 2012 12:01:59 -0400 Subject: staging: silicom: fix a comparing proc_dir_entry pointer against 0 we should be using the NULL macro, not 0 to compare against a pointer value, and also remove braces around the single if conditional after the create_proc_entry Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/bp_mod.c b/drivers/staging/silicom/bp_mod.c index f138d29..2722da9 100644 --- a/drivers/staging/silicom/bp_mod.c +++ b/drivers/staging/silicom/bp_mod.c @@ -7725,10 +7725,8 @@ bypass_proc_create_entry_sd(struct pfs_unit_sd *pfs_unit_curr, S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, parent_pfs); - if (pfs_unit_curr->proc_entry == 0) { - + if (pfs_unit_curr->proc_entry == NULL) return -1; - } pfs_unit_curr->proc_entry->read_proc = read_proc; pfs_unit_curr->proc_entry->write_proc = write_proc; -- cgit v0.10.2 From 40fe4f89671fb3c7ded94190fb267402a38b0261 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 16 Sep 2012 04:18:50 +0100 Subject: staging: speakup_soft: Fix reading of init string softsynth_read() reads a character at a time from the init string; when it finds the null terminator it sets the initialized flag but then repeats the last character. Additionally, if the read() buffer is not big enough for the init string, the next read() will start reading from the beginning again. So the caller may never progress to reading anything else. Replace the simple initialized flag with the current position in the init string, carried over between calls. Switch to reading real data once this reaches the null terminator. (This assumes that the length of the init string can't change, which seems to be the case. Really, the string and position belong together in a per-file private struct.) Tested-by: Samuel Thibault Signed-off-by: Ben Hutchings Cc: stable Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/speakup/speakup_soft.c b/drivers/staging/speakup/speakup_soft.c index 2a67610..e2f5c81 100644 --- a/drivers/staging/speakup/speakup_soft.c +++ b/drivers/staging/speakup/speakup_soft.c @@ -40,7 +40,7 @@ static int softsynth_is_alive(struct spk_synth *synth); static unsigned char get_index(void); static struct miscdevice synth_device; -static int initialized; +static int init_pos; static int misc_registered; static struct var_t vars[] = { @@ -194,7 +194,7 @@ static int softsynth_close(struct inode *inode, struct file *fp) unsigned long flags; spk_lock(flags); synth_soft.alive = 0; - initialized = 0; + init_pos = 0; spk_unlock(flags); /* Make sure we let applications go before leaving */ speakup_start_ttys(); @@ -239,13 +239,8 @@ static ssize_t softsynth_read(struct file *fp, char *buf, size_t count, ch = '\x18'; } else if (synth_buffer_empty()) { break; - } else if (!initialized) { - if (*init) { - ch = *init; - init++; - } else { - initialized = 1; - } + } else if (init[init_pos]) { + ch = init[init_pos++]; } else { ch = synth_buffer_getc(); } -- cgit v0.10.2 From 490deb7927667e384dfb75e0e41bb1f895429eef Mon Sep 17 00:00:00 2001 From: Daniel Cotey Date: Sat, 15 Sep 2012 05:59:07 -0700 Subject: Staging: silicom: bp_mod.h: checkpatch tab and space cleanup first chunk of bp_mod.h's cleanup Signed-off-by: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/bp_mod.h b/drivers/staging/silicom/bp_mod.h index 81cd97b..96c7780 100644 --- a/drivers/staging/silicom/bp_mod.h +++ b/drivers/staging/silicom/bp_mod.h @@ -277,9 +277,9 @@ static inline unsigned int jiffies_to_msecs(const unsigned long j) (pid == SILICOM_XE10G2BPILR_SSID)) #define INTEL_IF_SERIES(pid) \ - ((pid==INTEL_PEG4BPII_SSID)|| \ - (pid==INTEL_PEG4BPIIO_SSID)|| \ - (pid==INTEL_PEG4BPFII_SSID)) + ((pid == INTEL_PEG4BPII_SSID) || \ + (pid == INTEL_PEG4BPIIO_SSID) || \ + (pid == INTEL_PEG4BPFII_SSID)) #define NOKIA_SERIES(pid) \ ((pid==NOKIA_PMCXG2BPIN_SSID)|| \ -- cgit v0.10.2 From 7cdaac387c8b0d23521b18edc86933247301051b Mon Sep 17 00:00:00 2001 From: Daniel Cotey Date: Sat, 15 Sep 2012 06:00:41 -0700 Subject: Staging: silicom: bp_mod.h: checkpatch tab and space cleanup second chunk of bp_mod.h's cleanup Signed-off-by: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/bp_mod.h b/drivers/staging/silicom/bp_mod.h index 96c7780..c15d9d0 100644 --- a/drivers/staging/silicom/bp_mod.h +++ b/drivers/staging/silicom/bp_mod.h @@ -282,14 +282,14 @@ static inline unsigned int jiffies_to_msecs(const unsigned long j) (pid == INTEL_PEG4BPFII_SSID)) #define NOKIA_SERIES(pid) \ - ((pid==NOKIA_PMCXG2BPIN_SSID)|| \ - (pid==NOKIA_PMCXG4BPIN_SSID)|| \ - (pid==SILICOM_PMCX4BPI_SSID)|| \ - (pid==NOKIA_PMCXG2BPFIN_SSID)|| \ - (pid==SILICOM_PMCXG2BPFI_SSID)|| \ - (pid==NOKIA_PMCXG2BPIN2_SSID)|| \ - (pid==NOKIA_PMCXG4BPIN2_SSID)|| \ - (pid==SILICOM_PMCX2BPI_SSID)) + ((pid == NOKIA_PMCXG2BPIN_SSID) || \ + (pid == NOKIA_PMCXG4BPIN_SSID) || \ + (pid == SILICOM_PMCX4BPI_SSID) || \ + (pid == NOKIA_PMCXG2BPFIN_SSID) || \ + (pid == SILICOM_PMCXG2BPFI_SSID) || \ + (pid == NOKIA_PMCXG2BPIN2_SSID) || \ + (pid == NOKIA_PMCXG4BPIN2_SSID) || \ + (pid == SILICOM_PMCX2BPI_SSID)) #define DISCF_IF_SERIES(pid) \ (pid==SILICOM_PEG2TBFI_SSID) -- cgit v0.10.2 From c2cf19334b5d06f5391b3ab5888f67528f59e76e Mon Sep 17 00:00:00 2001 From: Daniel Cotey Date: Sat, 15 Sep 2012 06:01:40 -0700 Subject: Staging: silicom: bp_mod.h: checkpatch tab and space cleanup third chunk of bp_mod.h's cleanup Signed-off-by: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/bp_mod.h b/drivers/staging/silicom/bp_mod.h index c15d9d0..8c8cb95 100644 --- a/drivers/staging/silicom/bp_mod.h +++ b/drivers/staging/silicom/bp_mod.h @@ -292,21 +292,21 @@ static inline unsigned int jiffies_to_msecs(const unsigned long j) (pid == SILICOM_PMCX2BPI_SSID)) #define DISCF_IF_SERIES(pid) \ - (pid==SILICOM_PEG2TBFI_SSID) + (pid == SILICOM_PEG2TBFI_SSID) #define PEGF_IF_SERIES(pid) \ - ((pid==SILICOM_PEG2BPFI_SSID)|| \ - (pid==SILICOM_PEG2BPFID_SSID)|| \ - (pid==SILICOM_PEG2BPFIDLX_SSID)|| \ - (pid==SILICOM_PEG2BPFILX_SSID)|| \ - (pid==SILICOM_PEG4BPFI_SSID)|| \ - (pid==SILICOM_PXEG4BPFI_SSID)|| \ - (pid==SILICOM_MEG2BPFILN_SSID)|| \ - (pid==SILICOM_MEG2BPFINX_SSID)|| \ - (pid==SILICOM_PEG4BPFILX_SSID)|| \ - (pid==SILICOM_PEG2TBFI_SSID)|| \ - (pid==SILICOM_MEG2BPFILXLN_SSID)|| \ - (pid==SILICOM_MEG2BPFILXNX_SSID)) + ((pid == SILICOM_PEG2BPFI_SSID) || \ + (pid == SILICOM_PEG2BPFID_SSID) || \ + (pid == SILICOM_PEG2BPFIDLX_SSID) || \ + (pid == SILICOM_PEG2BPFILX_SSID) || \ + (pid == SILICOM_PEG4BPFI_SSID) || \ + (pid == SILICOM_PXEG4BPFI_SSID) || \ + (pid == SILICOM_MEG2BPFILN_SSID) || \ + (pid == SILICOM_MEG2BPFINX_SSID) || \ + (pid == SILICOM_PEG4BPFILX_SSID) || \ + (pid == SILICOM_PEG2TBFI_SSID) || \ + (pid == SILICOM_MEG2BPFILXLN_SSID) || \ + (pid == SILICOM_MEG2BPFILXNX_SSID)) #define TPL_IF_SERIES(pid) \ ((pid==SILICOM_PXG2BPFIL_SSID)|| \ -- cgit v0.10.2 From 0fe8f5d7a59f3d4d6d7dbdf624a665d11c6faf15 Mon Sep 17 00:00:00 2001 From: Daniel Cotey Date: Sat, 15 Sep 2012 06:02:22 -0700 Subject: Staging: silicom: bp_mod.h: checkpatch tab and space cleanup fourth chunk of bp_mod.h's cleanup Signed-off-by: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/bp_mod.h b/drivers/staging/silicom/bp_mod.h index 8c8cb95..61a12c2 100644 --- a/drivers/staging/silicom/bp_mod.h +++ b/drivers/staging/silicom/bp_mod.h @@ -309,23 +309,23 @@ static inline unsigned int jiffies_to_msecs(const unsigned long j) (pid == SILICOM_MEG2BPFILXNX_SSID)) #define TPL_IF_SERIES(pid) \ - ((pid==SILICOM_PXG2BPFIL_SSID)|| \ - (pid==SILICOM_PXG2BPFILLX_SSID)|| \ - (pid==SILICOM_PXG2TBFI_SSID)|| \ - (pid==SILICOM_PXG4BPFID_SSID)|| \ - (pid==SILICOM_PXG4BPFI_SSID)) + ((pid == SILICOM_PXG2BPFIL_SSID) || \ + (pid == SILICOM_PXG2BPFILLX_SSID) || \ + (pid == SILICOM_PXG2TBFI_SSID) || \ + (pid == SILICOM_PXG4BPFID_SSID) || \ + (pid == SILICOM_PXG4BPFI_SSID)) #define BP10G_IF_SERIES(pid) \ - ((pid==SILICOM_PE10G2BPISR_SSID)|| \ - (pid==SILICOM_PE10G2BPICX4_SSID)|| \ - (pid==SILICOM_PE10G2BPILR_SSID)|| \ - (pid==SILICOM_XE10G2BPIT_SSID)|| \ - (pid==SILICOM_XE10G2BPICX4_SSID)|| \ - (pid==SILICOM_XE10G2BPISR_SSID)|| \ - (pid==NOKIA_XE10G2BPIXR_SSID)|| \ - (pid==SILICOM_PE10GDBISR_SSID)|| \ - (pid==SILICOM_PE10GDBILR_SSID)|| \ - (pid==SILICOM_XE10G2BPILR_SSID)) + ((pid == SILICOM_PE10G2BPISR_SSID) || \ + (pid == SILICOM_PE10G2BPICX4_SSID) || \ + (pid == SILICOM_PE10G2BPILR_SSID) || \ + (pid == SILICOM_XE10G2BPIT_SSID) || \ + (pid == SILICOM_XE10G2BPICX4_SSID) || \ + (pid == SILICOM_XE10G2BPISR_SSID) || \ + (pid == NOKIA_XE10G2BPIXR_SSID) || \ + (pid == SILICOM_PE10GDBISR_SSID) || \ + (pid == SILICOM_PE10GDBILR_SSID) || \ + (pid == SILICOM_XE10G2BPILR_SSID)) #define BP10GB_IF_SERIES(pid) \ ((pid==SILICOM_PE10G2BPTCX4_SSID)|| \ -- cgit v0.10.2 From 2ea2ea4dab8512560aec31a9e4b6d11b6d0e3b15 Mon Sep 17 00:00:00 2001 From: Daniel Cotey Date: Sat, 15 Sep 2012 06:02:52 -0700 Subject: Staging: silicom: bp_mod.h: checkpatch tab and space cleanup fifth chunk of bp_mod.h's cleanup Signed-off-by: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/bp_mod.h b/drivers/staging/silicom/bp_mod.h index 61a12c2..425085a 100644 --- a/drivers/staging/silicom/bp_mod.h +++ b/drivers/staging/silicom/bp_mod.h @@ -328,16 +328,16 @@ static inline unsigned int jiffies_to_msecs(const unsigned long j) (pid == SILICOM_XE10G2BPILR_SSID)) #define BP10GB_IF_SERIES(pid) \ - ((pid==SILICOM_PE10G2BPTCX4_SSID)|| \ - (pid==SILICOM_PE10G2BPTSR_SSID)|| \ - (pid==SILICOM_PE10G2BPTLR_SSID)|| \ - (pid==SILICOM_PE10G2BPTT_SSID)) + ((pid == SILICOM_PE10G2BPTCX4_SSID) || \ + (pid == SILICOM_PE10G2BPTSR_SSID) || \ + (pid == SILICOM_PE10G2BPTLR_SSID) || \ + (pid == SILICOM_PE10G2BPTT_SSID)) #define BP10G_CX4_SERIES(pid) \ - (pid==SILICOM_PE10G2BPICX4_SSID) + (pid == SILICOM_PE10G2BPICX4_SSID) #define BP10GB_CX4_SERIES(pid) \ - (pid==SILICOM_PE10G2BPTCX4_SSID) + (pid == SILICOM_PE10G2BPTCX4_SSID) #define SILICOM_M2EG2BPFI6_SSID 0x0501 #define SILICOM_M2EG2BPFI6LX_SSID 0x0502 -- cgit v0.10.2 From 0118f42af24864b9451e347bc17941fd4c21cd83 Mon Sep 17 00:00:00 2001 From: Daniel Cotey Date: Sat, 15 Sep 2012 06:03:18 -0700 Subject: Staging: silicom: bp_mod.h: checkpatch tab and space cleanup sixth chunk of bp_mod.h's cleanup Signed-off-by: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/bp_mod.h b/drivers/staging/silicom/bp_mod.h index 425085a..bc5ef43 100644 --- a/drivers/staging/silicom/bp_mod.h +++ b/drivers/staging/silicom/bp_mod.h @@ -366,13 +366,13 @@ static inline unsigned int jiffies_to_msecs(const unsigned long j) #define SILICOM_PE210G2BPI9T_SSID 0x120 #define DBI_IF_SERIES(pid) \ -((pid==SILICOM_PE10GDBISR_SSID)|| \ - (pid==SILICOM_PE10GDBILR_SSID)|| \ - (pid==SILICOM_XE10G2BPILR_SSID)|| \ - (pid==SILICOM_PE210G2DBi9LR_SSID)) + ((pid == SILICOM_PE10GDBISR_SSID) || \ + (pid == SILICOM_PE10GDBILR_SSID) || \ + (pid == SILICOM_XE10G2BPILR_SSID) || \ + (pid == SILICOM_PE210G2DBi9LR_SSID)) #define PEGF5_IF_SERIES(pid) \ -((pid==SILICOM_PEG2BPFI5_SSID)|| \ + ((pid == SILICOM_PEG2BPFI5_SSID) || \ (pid==SILICOM_PEG2BPFI5LX_SSID)|| \ (pid==SILICOM_PEG4BPFI6_SSID)|| \ (pid==SILICOM_PEG4BPFI6LX_SSID)|| \ -- cgit v0.10.2 From 22f3504684b3fc4e452db60f54419f109fdb4260 Mon Sep 17 00:00:00 2001 From: Daniel Cotey Date: Sat, 15 Sep 2012 06:03:43 -0700 Subject: Staging: silicom: bp_mod.h: checkpatch tab and space cleanup seventh chunk of bp_mod.h's cleanup Signed-off-by: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/bp_mod.h b/drivers/staging/silicom/bp_mod.h index bc5ef43..a11b809 100644 --- a/drivers/staging/silicom/bp_mod.h +++ b/drivers/staging/silicom/bp_mod.h @@ -373,33 +373,33 @@ static inline unsigned int jiffies_to_msecs(const unsigned long j) #define PEGF5_IF_SERIES(pid) \ ((pid == SILICOM_PEG2BPFI5_SSID) || \ - (pid==SILICOM_PEG2BPFI5LX_SSID)|| \ - (pid==SILICOM_PEG4BPFI6_SSID)|| \ - (pid==SILICOM_PEG4BPFI6LX_SSID)|| \ - (pid==SILICOM_PEG4BPFI6ZX_SSID)|| \ - (pid==SILICOM_PEG2BPFI6_SSID)|| \ - (pid==SILICOM_PEG2BPFI6LX_SSID)|| \ - (pid==SILICOM_PEG2BPFI6ZX_SSID)|| \ - (pid==SILICOM_PEG2BPFI6FLXM_SSID)|| \ - (pid==SILICOM_PEG2DBFI6_SSID)|| \ - (pid==SILICOM_PEG2DBFI6LX_SSID)|| \ - (pid==SILICOM_PEG2DBFI6ZX_SSID)|| \ - (pid==SILICOM_PEG4BPI6FC_SSID)|| \ - (pid==SILICOM_PEG4BPFI6FCLX_SSID)|| \ - (pid==SILICOM_PEG4BPI6FC_SSID)|| \ - (pid==SILICOM_M1EG2BPFI6_SSID)|| \ - (pid==SILICOM_M1EG2BPFI6LX_SSID)|| \ - (pid==SILICOM_M1EG2BPFI6ZX_SSID)|| \ - (pid==SILICOM_M1EG4BPFI6_SSID)|| \ - (pid==SILICOM_M1EG4BPFI6LX_SSID)|| \ - (pid==SILICOM_M1EG4BPFI6ZX_SSID)|| \ - (pid==SILICOM_M2EG2BPFI6_SSID)|| \ - (pid==SILICOM_M2EG2BPFI6LX_SSID)|| \ - (pid==SILICOM_M2EG2BPFI6ZX_SSID)|| \ - (pid==SILICOM_M2EG4BPFI6_SSID)|| \ - (pid==SILICOM_M2EG4BPFI6LX_SSID)|| \ - (pid==SILICOM_M2EG4BPFI6ZX_SSID)|| \ - (pid==SILICOM_PEG4BPFI6FCZX_SSID)) + (pid == SILICOM_PEG2BPFI5LX_SSID) || \ + (pid == SILICOM_PEG4BPFI6_SSID) || \ + (pid == SILICOM_PEG4BPFI6LX_SSID) || \ + (pid == SILICOM_PEG4BPFI6ZX_SSID) || \ + (pid == SILICOM_PEG2BPFI6_SSID) || \ + (pid == SILICOM_PEG2BPFI6LX_SSID) || \ + (pid == SILICOM_PEG2BPFI6ZX_SSID) || \ + (pid == SILICOM_PEG2BPFI6FLXM_SSID) || \ + (pid == SILICOM_PEG2DBFI6_SSID) || \ + (pid == SILICOM_PEG2DBFI6LX_SSID) || \ + (pid == SILICOM_PEG2DBFI6ZX_SSID) || \ + (pid == SILICOM_PEG4BPI6FC_SSID) || \ + (pid == SILICOM_PEG4BPFI6FCLX_SSID) || \ + (pid == SILICOM_PEG4BPI6FC_SSID) || \ + (pid == SILICOM_M1EG2BPFI6_SSID) || \ + (pid == SILICOM_M1EG2BPFI6LX_SSID) || \ + (pid == SILICOM_M1EG2BPFI6ZX_SSID) || \ + (pid == SILICOM_M1EG4BPFI6_SSID) || \ + (pid == SILICOM_M1EG4BPFI6LX_SSID) || \ + (pid == SILICOM_M1EG4BPFI6ZX_SSID) || \ + (pid == SILICOM_M2EG2BPFI6_SSID) || \ + (pid == SILICOM_M2EG2BPFI6LX_SSID) || \ + (pid == SILICOM_M2EG2BPFI6ZX_SSID) || \ + (pid == SILICOM_M2EG4BPFI6_SSID) || \ + (pid == SILICOM_M2EG4BPFI6LX_SSID) || \ + (pid == SILICOM_M2EG4BPFI6ZX_SSID) || \ + (pid == SILICOM_PEG4BPFI6FCZX_SSID)) #define PEG5_IF_SERIES(pid) \ ((pid==SILICOM_PEG4BPI6_SSID)|| \ -- cgit v0.10.2 From 9088c8a99337d00dd1d52684b5ce85347940c432 Mon Sep 17 00:00:00 2001 From: Daniel Cotey Date: Sat, 15 Sep 2012 06:04:06 -0700 Subject: Staging: silicom: bp_mod.h: checkpatch tab and space cleanup eighth chunk of bp_mod.h's cleanup Signed-off-by: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/bp_mod.h b/drivers/staging/silicom/bp_mod.h index a11b809..7b01f48 100644 --- a/drivers/staging/silicom/bp_mod.h +++ b/drivers/staging/silicom/bp_mod.h @@ -402,21 +402,21 @@ static inline unsigned int jiffies_to_msecs(const unsigned long j) (pid == SILICOM_PEG4BPFI6FCZX_SSID)) #define PEG5_IF_SERIES(pid) \ -((pid==SILICOM_PEG4BPI6_SSID)|| \ -(pid==SILICOM_PEG2BPI6_SSID)|| \ -(pid==SILICOM_PEG4BPI6FC_SSID)|| \ -(pid==SILICOM_PEG6BPI6_SSID)|| \ -(pid==SILICOM_PEG2BPI6SC6_SSID)|| \ -(pid==SILICOM_MEG2BPI6_SSID)|| \ -(pid==SILICOM_XEG2BPI6_SSID)|| \ -(pid==SILICOM_MEG4BPI6_SSID)|| \ -(pid==SILICOM_M1EG2BPI6_SSID)|| \ -(pid==SILICOM_M1EG4BPI6_SSID)|| \ -(pid==SILICOM_M1EG6BPI6_SSID)|| \ -(pid==SILICOM_PEG6BPI_SSID)|| \ -(pid==SILICOM_PEG4BPIL_SSID)|| \ -(pid==SILICOM_PEG2BISC6_SSID)|| \ -(pid==SILICOM_PEG2BPI5_SSID)) + ((pid == SILICOM_PEG4BPI6_SSID) || \ + (pid == SILICOM_PEG2BPI6_SSID) || \ + (pid == SILICOM_PEG4BPI6FC_SSID) || \ + (pid == SILICOM_PEG6BPI6_SSID) || \ + (pid == SILICOM_PEG2BPI6SC6_SSID) || \ + (pid == SILICOM_MEG2BPI6_SSID) || \ + (pid == SILICOM_XEG2BPI6_SSID) || \ + (pid == SILICOM_MEG4BPI6_SSID) || \ + (pid == SILICOM_M1EG2BPI6_SSID) || \ + (pid == SILICOM_M1EG4BPI6_SSID) || \ + (pid == SILICOM_M1EG6BPI6_SSID) || \ + (pid == SILICOM_PEG6BPI_SSID) || \ + (pid == SILICOM_PEG4BPIL_SSID) || \ + (pid == SILICOM_PEG2BISC6_SSID) || \ + (pid == SILICOM_PEG2BPI5_SSID)) #define PEG80_IF_SERIES(pid) \ ((pid==SILICOM_M1E2G4BPi80_SSID)|| \ -- cgit v0.10.2 From fab85699f34293f3914f561ff6e50a2f69717cab Mon Sep 17 00:00:00 2001 From: Daniel Cotey Date: Sat, 15 Sep 2012 06:04:41 -0700 Subject: Staging: silicom: bp_mod.h: checkpatch tab and space cleanup ninth chunk of bp_mod.h's cleanup Signed-off-by: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/bp_mod.h b/drivers/staging/silicom/bp_mod.h index 7b01f48..3a97b2d 100644 --- a/drivers/staging/silicom/bp_mod.h +++ b/drivers/staging/silicom/bp_mod.h @@ -419,30 +419,30 @@ static inline unsigned int jiffies_to_msecs(const unsigned long j) (pid == SILICOM_PEG2BPI5_SSID)) #define PEG80_IF_SERIES(pid) \ -((pid==SILICOM_M1E2G4BPi80_SSID)|| \ -(pid==SILICOM_M6E2G8BPi80_SSID)|| \ -(pid==SILICOM_PE2G4BPi80L_SSID)|| \ -(pid==SILICOM_M6E2G8BPi80A_SSID)|| \ -(pid==SILICOM_PE2G2BPi35_SSID)|| \ -(pid==SILICOM_PAC1200BPi35_SSID)|| \ -(pid==SILICOM_PE2G4BPi35_SSID)|| \ -(pid==SILICOM_PE2G4BPi35L_SSID)|| \ -(pid==SILICOM_PE2G6BPi35_SSID)|| \ -(pid==SILICOM_PE2G2BPi80_SSID)|| \ -(pid==SILICOM_PE2G4BPi80_SSID)|| \ -(pid==SILICOM_PE2G4BPFi80_SSID)|| \ -(pid==SILICOM_PE2G4BPFi80LX_SSID)|| \ -(pid==SILICOM_PE2G4BPFi80ZX_SSID)|| \ -(pid==SILICOM_PE2G4BPFi80ZX_SSID)|| \ -(pid==SILICOM_PE2G2BPFi80_SSID)|| \ -(pid==SILICOM_PE2G2BPFi80LX_SSID)|| \ -(pid==SILICOM_PE2G2BPFi80ZX_SSID)|| \ -(pid==SILICOM_PE2G2BPFi35_SSID)|| \ -(pid==SILICOM_PE2G2BPFi35LX_SSID)|| \ -(pid==SILICOM_PE2G2BPFi35ZX_SSID)|| \ -(pid==SILICOM_PE2G4BPFi35_SSID)|| \ -(pid==SILICOM_PE2G4BPFi35LX_SSID)|| \ -(pid==SILICOM_PE2G4BPFi35ZX_SSID)) + ((pid == SILICOM_M1E2G4BPi80_SSID) || \ + (pid == SILICOM_M6E2G8BPi80_SSID) || \ + (pid == SILICOM_PE2G4BPi80L_SSID) || \ + (pid == SILICOM_M6E2G8BPi80A_SSID) || \ + (pid == SILICOM_PE2G2BPi35_SSID) || \ + (pid == SILICOM_PAC1200BPi35_SSID) || \ + (pid == SILICOM_PE2G4BPi35_SSID) || \ + (pid == SILICOM_PE2G4BPi35L_SSID) || \ + (pid == SILICOM_PE2G6BPi35_SSID) || \ + (pid == SILICOM_PE2G2BPi80_SSID) || \ + (pid == SILICOM_PE2G4BPi80_SSID) || \ + (pid == SILICOM_PE2G4BPFi80_SSID) || \ + (pid == SILICOM_PE2G4BPFi80LX_SSID) || \ + (pid == SILICOM_PE2G4BPFi80ZX_SSID) || \ + (pid == SILICOM_PE2G4BPFi80ZX_SSID) || \ + (pid == SILICOM_PE2G2BPFi80_SSID) || \ + (pid == SILICOM_PE2G2BPFi80LX_SSID) || \ + (pid == SILICOM_PE2G2BPFi80ZX_SSID) || \ + (pid == SILICOM_PE2G2BPFi35_SSID) || \ + (pid == SILICOM_PE2G2BPFi35LX_SSID) || \ + (pid == SILICOM_PE2G2BPFi35ZX_SSID) || \ + (pid == SILICOM_PE2G4BPFi35_SSID) || \ + (pid == SILICOM_PE2G4BPFi35LX_SSID) || \ + (pid == SILICOM_PE2G4BPFi35ZX_SSID)) #define PEGF80_IF_SERIES(pid) \ ((pid==SILICOM_PE2G4BPFi80_SSID)|| \ -- cgit v0.10.2 From 97ef0a461ba82cb641ae53314997ce44161b749a Mon Sep 17 00:00:00 2001 From: Daniel Cotey Date: Sat, 15 Sep 2012 06:05:51 -0700 Subject: Staging: silicom: bp_mod.h: checkpatch tab and space cleanup tenth chunk of bp_mod.h's cleanup Signed-off-by: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/bp_mod.h b/drivers/staging/silicom/bp_mod.h index 3a97b2d..2862c57 100644 --- a/drivers/staging/silicom/bp_mod.h +++ b/drivers/staging/silicom/bp_mod.h @@ -445,22 +445,22 @@ static inline unsigned int jiffies_to_msecs(const unsigned long j) (pid == SILICOM_PE2G4BPFi35ZX_SSID)) #define PEGF80_IF_SERIES(pid) \ -((pid==SILICOM_PE2G4BPFi80_SSID)|| \ -(pid==SILICOM_PE2G4BPFi80LX_SSID)|| \ -(pid==SILICOM_PE2G4BPFi80ZX_SSID)|| \ -(pid==SILICOM_PE2G4BPFi80ZX_SSID)|| \ -(pid==SILICOM_M1E2G4BPFi80_SSID)|| \ -(pid==SILICOM_M1E2G4BPFi80LX_SSID)|| \ -(pid==SILICOM_M1E2G4BPFi80ZX_SSID)|| \ -(pid==SILICOM_PE2G2BPFi80_SSID)|| \ -(pid==SILICOM_PE2G2BPFi80LX_SSID)|| \ -(pid==SILICOM_PE2G2BPFi80ZX_SSID)|| \ -(pid==SILICOM_PE2G2BPFi35_SSID)|| \ -(pid==SILICOM_PE2G2BPFi35LX_SSID)|| \ -(pid==SILICOM_PE2G2BPFi35ZX_SSID)|| \ -(pid==SILICOM_PE2G4BPFi35_SSID)|| \ -(pid==SILICOM_PE2G4BPFi35LX_SSID)|| \ -(pid==SILICOM_PE2G4BPFi35ZX_SSID)) + ((pid == SILICOM_PE2G4BPFi80_SSID) || \ + (pid == SILICOM_PE2G4BPFi80LX_SSID) || \ + (pid == SILICOM_PE2G4BPFi80ZX_SSID) || \ + (pid == SILICOM_PE2G4BPFi80ZX_SSID) || \ + (pid == SILICOM_M1E2G4BPFi80_SSID) || \ + (pid == SILICOM_M1E2G4BPFi80LX_SSID) || \ + (pid == SILICOM_M1E2G4BPFi80ZX_SSID) || \ + (pid == SILICOM_PE2G2BPFi80_SSID) || \ + (pid == SILICOM_PE2G2BPFi80LX_SSID) || \ + (pid == SILICOM_PE2G2BPFi80ZX_SSID) || \ + (pid == SILICOM_PE2G2BPFi35_SSID) || \ + (pid == SILICOM_PE2G2BPFi35LX_SSID) || \ + (pid == SILICOM_PE2G2BPFi35ZX_SSID) || \ + (pid == SILICOM_PE2G4BPFi35_SSID) || \ + (pid == SILICOM_PE2G4BPFi35LX_SSID) || \ + (pid == SILICOM_PE2G4BPFi35ZX_SSID)) #define BP10G9_IF_SERIES(pid) \ ((pid==INTEL_PE210G2SPI9_SSID)|| \ -- cgit v0.10.2 From d5b4f42f8f87ad2f58cea6fd8b3ce419056132ed Mon Sep 17 00:00:00 2001 From: Daniel Cotey Date: Sat, 15 Sep 2012 06:06:20 -0700 Subject: Staging: silicom: bp_mod.h: checkpatch tab and space cleanup eleventh chunk of bp_mod.h's cleanup Signed-off-by: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/bp_mod.h b/drivers/staging/silicom/bp_mod.h index 2862c57..f59c061 100644 --- a/drivers/staging/silicom/bp_mod.h +++ b/drivers/staging/silicom/bp_mod.h @@ -463,28 +463,28 @@ static inline unsigned int jiffies_to_msecs(const unsigned long j) (pid == SILICOM_PE2G4BPFi35ZX_SSID)) #define BP10G9_IF_SERIES(pid) \ -((pid==INTEL_PE210G2SPI9_SSID)|| \ -(pid==SILICOM_M1E10G2BPI9CX4_SSID)|| \ -(pid==SILICOM_M1E10G2BPI9SR_SSID)|| \ -(pid==SILICOM_M1E10G2BPI9LR_SSID)|| \ -(pid==SILICOM_M1E10G2BPI9T_SSID)|| \ -(pid==SILICOM_M2E10G2BPI9CX4_SSID)|| \ -(pid==SILICOM_M2E10G2BPI9SR_SSID)|| \ -(pid==SILICOM_M2E10G2BPI9LR_SSID)|| \ -(pid==SILICOM_M2E10G2BPI9T_SSID)|| \ -(pid==SILICOM_PE210G2BPI9CX4_SSID)|| \ -(pid==SILICOM_PE210G2BPI9SR_SSID)|| \ -(pid==SILICOM_PE210G2BPI9LR_SSID)|| \ -(pid==SILICOM_PE210G2DBi9SR_SSID)|| \ -(pid==SILICOM_PE210G2DBi9SRRB_SSID)|| \ -(pid==SILICOM_PE210G2DBi9LR_SSID)|| \ -(pid==SILICOM_PE210G2DBi9LRRB_SSID)|| \ -(pid==SILICOM_PE310G4DBi940SR_SSID)|| \ -(pid==SILICOM_PEG2BISC6_SSID)|| \ -(pid==SILICOM_PE310G4BPi9T_SSID)|| \ -(pid==SILICOM_PE310G4BPi9SR_SSID)|| \ -(pid==SILICOM_PE310G4BPi9LR_SSID)|| \ -(pid==SILICOM_PE210G2BPI9T_SSID)) + ((pid == INTEL_PE210G2SPI9_SSID) || \ + (pid == SILICOM_M1E10G2BPI9CX4_SSID) || \ + (pid == SILICOM_M1E10G2BPI9SR_SSID) || \ + (pid == SILICOM_M1E10G2BPI9LR_SSID) || \ + (pid == SILICOM_M1E10G2BPI9T_SSID) || \ + (pid == SILICOM_M2E10G2BPI9CX4_SSID) || \ + (pid == SILICOM_M2E10G2BPI9SR_SSID) || \ + (pid == SILICOM_M2E10G2BPI9LR_SSID) || \ + (pid == SILICOM_M2E10G2BPI9T_SSID) || \ + (pid == SILICOM_PE210G2BPI9CX4_SSID) || \ + (pid == SILICOM_PE210G2BPI9SR_SSID) || \ + (pid == SILICOM_PE210G2BPI9LR_SSID) || \ + (pid == SILICOM_PE210G2DBi9SR_SSID) || \ + (pid == SILICOM_PE210G2DBi9SRRB_SSID) || \ + (pid == SILICOM_PE210G2DBi9LR_SSID) || \ + (pid == SILICOM_PE210G2DBi9LRRB_SSID) || \ + (pid == SILICOM_PE310G4DBi940SR_SSID) || \ + (pid == SILICOM_PEG2BISC6_SSID) || \ + (pid == SILICOM_PE310G4BPi9T_SSID) || \ + (pid == SILICOM_PE310G4BPi9SR_SSID) || \ + (pid == SILICOM_PE310G4BPi9LR_SSID) || \ + (pid == SILICOM_PE210G2BPI9T_SSID)) /*******************************************************/ /* 1G INTERFACE ****************************************/ -- cgit v0.10.2 From 30f62902e3911616fab109e3380a1c9d74e18f33 Mon Sep 17 00:00:00 2001 From: Daniel Cotey Date: Sat, 15 Sep 2012 06:06:44 -0700 Subject: Staging: silicom: bp_mod.h: checkpatch tab and space cleanup twelfth chunk of bp_mod.h's cleanup Signed-off-by: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/bp_mod.h b/drivers/staging/silicom/bp_mod.h index f59c061..b8275f5 100644 --- a/drivers/staging/silicom/bp_mod.h +++ b/drivers/staging/silicom/bp_mod.h @@ -535,13 +535,13 @@ static inline unsigned int jiffies_to_msecs(const unsigned long j) (writel((value), (void *)(((a)->mem_map) + BPCTLI_##reg))) #define BPCTL_READ_REG(a, reg) ( \ - readl((void *)((a)->mem_map) + BPCTLI_##reg)) + readl((void *)((a)->mem_map) + BPCTLI_##reg)) #define BPCTL_WRITE_FLUSH(a) BPCTL_READ_REG(a, STATUS) #define BPCTL_BP_WRITE_REG(a, reg, value) ({ \ - BPCTL_WRITE_REG(a, reg, value); \ - BPCTL_WRITE_FLUSH(a);}) + BPCTL_WRITE_REG(a, reg, value); \ + BPCTL_WRITE_FLUSH(a); }) /**************************************************************/ /************** 82575 Interface********************************/ @@ -645,7 +645,7 @@ static inline unsigned int jiffies_to_msecs(const unsigned long j) (writel((value), (void *)(((a)->mem_map) + BP10G_##reg))) #define BP10G_READ_REG(a, reg) ( \ - readl((void *)((a)->mem_map) + BP10G_##reg)) + readl((void *)((a)->mem_map) + BP10G_##reg)) /*****BROADCOM*******************************************/ @@ -697,7 +697,7 @@ static inline unsigned int jiffies_to_msecs(const unsigned long j) (writel((value), (void *)(((a)->mem_map) + BP10GB_##reg))) #define BP10GB_READ_REG(a, reg) ( \ - readl((void *)((a)->mem_map) + BP10GB_##reg)) + readl((void *)((a)->mem_map) + BP10GB_##reg)) #endif -- cgit v0.10.2 From b2774ed427afeac28687a61e4aab63ece5f7c201 Mon Sep 17 00:00:00 2001 From: Daniel Cotey Date: Sat, 15 Sep 2012 06:08:07 -0700 Subject: Staging: silicom: bypass.h: checkpatch whitespace Remove trailing spaces, first chunk Signed-off-by: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/bypass.h b/drivers/staging/silicom/bypass.h index 28765f7..08fa7a0 100644 --- a/drivers/staging/silicom/bypass.h +++ b/drivers/staging/silicom/bypass.h @@ -37,7 +37,7 @@ #define CMND_EN_MASK 0x02 /* BIT_1 */ #define DIS_BYPASS_CAP_MASK 0x04 /* BIT_2 Bypass Cap is disable*/ #define DFLT_PWRON_MASK 0x08 /* BIT_3 */ -#define BYPASS_OFF_MASK 0x10 /* BIT_4 */ +#define BYPASS_OFF_MASK 0x10 /* BIT_4 */ #define BYPASS_FLAG_MASK 0x20 /* BIT_5 */ #define STD_NIC_MASK (DIS_BYPASS_CAP_MASK | BYPASS_OFF_MASK | DFLT_PWRON_MASK) #define WD_EXP_FLAG_MASK 0x40 /* BIT_6 */ @@ -65,7 +65,7 @@ #define STATUS_DISC_REG_ADDR 13 #define WDTE_DISC_BPN_MASK 0x01 /* BIT_0 1 when wdt expired -> TAP, 0 - Bypass */ -#define STD_NIC_ON_MASK 0x02 /* BIT_1 */ +#define STD_NIC_ON_MASK 0x02 /* BIT_1 */ #define DIS_DISC_CAP_MASK 0x04 /* BIT_2 TAP Cap is disable*/ #define DFLT_PWRON_DISC_MASK 0x08 /* BIT_3 */ #define DISC_OFF_MASK 0x10 /* BIT_4 */ -- cgit v0.10.2 From 65af0ae35a8a9d37cb8677b7afa1c0758833f99a Mon Sep 17 00:00:00 2001 From: Daniel Cotey Date: Sat, 15 Sep 2012 06:08:36 -0700 Subject: Staging: silicom: bypass.h: checkpatch whitespace Remove trailing spaces, second chunk Signed-off-by: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/libbp_sd.h b/drivers/staging/silicom/libbp_sd.h index d223a6cf..8fc4006 100644 --- a/drivers/staging/silicom/libbp_sd.h +++ b/drivers/staging/silicom/libbp_sd.h @@ -54,7 +54,7 @@ struct bp_info { * @if_index: network device index * * Output: - * 1 - if device is bypass controlling device, + * 1 - if device is bypass controlling device, * 0 - if device is bypass slave device * -1 - device not support Bypass **/ @@ -66,7 +66,7 @@ int is_bypass_sd(int if_index); * * Output: * network device index of the slave device - * -1 - on failure (device not support Bypass or it's a slave device) + * -1 - on failure (device not support Bypass or it's a slave device) **/ int get_bypass_slave_sd(int if_index); @@ -75,48 +75,48 @@ int get_bypass_slave_sd(int if_index); * @if_index: network device index * * Output: - * flags word on success;flag word is a 32-bit mask word with each bit defines different + * flags word on success;flag word is a 32-bit mask word with each bit defines different * capability as described bellow. * Value of 1 for supporting this feature. 0 for not supporting this feature. * -1 - on failure (if the device is not capable of the operation or not a Bypass device) * Bit feature description - * + * * 0 BP_CAP The interface is Bypass capable in general - * + * * 1 BP_STATUS_CAP The interface can report of the current Bypass mode - * - * 2 BP_STATUS_CHANGE_CAP The interface can report on a change to bypass mode from + * + * 2 BP_STATUS_CHANGE_CAP The interface can report on a change to bypass mode from * the last time the mode was defined - * + * * 3 SW_CTL_CAP The interface is Software controlled capable for bypass/non bypass modes. - * - * 4 BP_DIS_CAP The interface is capable of disabling the Bypass mode at all times. - * This mode will retain its mode even during power loss and also after - * power recovery. This will overcome on any bypass operation due to + * + * 4 BP_DIS_CAP The interface is capable of disabling the Bypass mode at all times. + * This mode will retain its mode even during power loss and also after + * power recovery. This will overcome on any bypass operation due to * watchdog timeout or set bypass command. - * + * * 5 BP_DIS_STATUS_CAP The interface can report of the current DIS_BP_CAP - * - * 6 STD_NIC_CAP The interface is capable to be configured to operate as standard, non Bypass, + * + * 6 STD_NIC_CAP The interface is capable to be configured to operate as standard, non Bypass, * NIC interface (have direct connection to interfaces at all power modes) - * + * * 7 BP_PWOFF_NO_CAP The interface can be in Bypass mode at power off state - * - * 8 BP_PWOFF_OFF_CAP The interface can disconnect the Bypass mode at power off state without + * + * 8 BP_PWOFF_OFF_CAP The interface can disconnect the Bypass mode at power off state without * effecting all the other states of operation - * - * 9 BP_PWOFF_CTL_CAP The behavior of the Bypass mode at Power-off state can be controlled by + * + * 9 BP_PWOFF_CTL_CAP The behavior of the Bypass mode at Power-off state can be controlled by * software without effecting any other state - * - *10 BP_PWUP_ON_CAP The interface can be in Bypass mode when power is turned on + * + *10 BP_PWUP_ON_CAP The interface can be in Bypass mode when power is turned on * (until the system take control of the bypass functionality) - * - *11 BP_PWUP_OFF_CAP The interface can disconnect from Bypass mode when power is turned on + * + *11 BP_PWUP_OFF_CAP The interface can disconnect from Bypass mode when power is turned on * (until the system take control of the bypass functionality) - * + * *12 BP_PWUP_CTL_CAP The behavior of the Bypass mode at Power-up can be controlled by software - * - *13 WD_CTL_CAP The interface has watchdog capabilities to turn to Bypass mode when not reset + * + *13 WD_CTL_CAP The interface has watchdog capabilities to turn to Bypass mode when not reset * for defined period of time. * *14 WD_STATUS_CAP The interface can report on the watchdog status (Active/inactive) -- cgit v0.10.2 From f8402b6311db6d2789e1d08af1cc0cd4953c404b Mon Sep 17 00:00:00 2001 From: Daniel Cotey Date: Sat, 15 Sep 2012 06:09:00 -0700 Subject: Staging: silicom: checkpatch cleanup: header file whitespace Whack all the line ending spaces so checkpatch.pl is happy. Signed-off-by: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/libbp_sd.h b/drivers/staging/silicom/libbp_sd.h index 8fc4006..cba9ba6 100644 --- a/drivers/staging/silicom/libbp_sd.h +++ b/drivers/staging/silicom/libbp_sd.h @@ -118,12 +118,12 @@ int get_bypass_slave_sd(int if_index); * *13 WD_CTL_CAP The interface has watchdog capabilities to turn to Bypass mode when not reset * for defined period of time. - * + * *14 WD_STATUS_CAP The interface can report on the watchdog status (Active/inactive) - * + * *15 WD_TIMEOUT_CAP The interface can report the time left till watchdog triggers to Bypass mode. - * - *16-31 RESERVED + * + *16-31 RESERVED * * **/ int get_bypass_caps_sd(int if_index); @@ -133,34 +133,34 @@ int get_bypass_caps_sd(int if_index); * @if_index: network device index * * Output: - * - * Set of numbers defining the various parameters of the watchdog capable + * + * Set of numbers defining the various parameters of the watchdog capable * to be set to as described bellow. * -1 - on failure (device not support Bypass or it's a slave device) - * + * * Bit feature description - * + * * 0-3 WD_MIN_TIME The interface WD minimal time period in 100mS units - * - * 4 WD_STEP_TIME The steps of the WD timer in + * + * 4 WD_STEP_TIME The steps of the WD timer in * 0 - for linear steps (WD_MIN_TIME * X) * 1 - for multiply by 2 from previous step (WD_MIN_TIME * 2^X) - * - * 5-8 WD_STEP_COUNT Number of steps the WD timer supports in 2^X + * + * 5-8 WD_STEP_COUNT Number of steps the WD timer supports in 2^X * (X bit available for defining the value) - * - * - * + * + * + * **/ int get_wd_set_caps_sd(int if_index); /** * set_bypass - set Bypass state * @if_index: network device index of the controlling device - * @bypass_mode: bypass mode (1=on, 0=off) + * @bypass_mode: bypass mode (1=on, 0=off) * Output: * 0 - on success - * -1 - on failure (device not support Bypass or it's a slave device) + * -1 - on failure (device not support Bypass or it's a slave device) **/ int set_bypass_sd(int if_index, int bypass_mode); @@ -169,7 +169,7 @@ int set_bypass_sd(int if_index, int bypass_mode); * @if_index: network device index of the controlling device * Output: * 0/1 - (off/on) on success - * -1 - on failure (device not support Bypass or it's a slave device) + * -1 - on failure (device not support Bypass or it's a slave device) **/ int get_bypass_sd(int if_index); @@ -178,7 +178,7 @@ int get_bypass_sd(int if_index); * @if_index: network device index of the controlling device * Output: * 0/1 - (off/on) on success - * -1 - on failure (device not support Bypass or it's a slave device) + * -1 - on failure (device not support Bypass or it's a slave device) **/ int get_bypass_change_sd(int if_index); @@ -188,8 +188,8 @@ int get_bypass_change_sd(int if_index); * @dis_bypass: disable bypass(1=dis, 0=en) * Output: * 0 - on success - * -1 - on failure (device is not capable of the operation ordevice not support Bypass - * or it's a slave device) + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) **/ int set_dis_bypass_sd(int if_index, int dis_bypass); @@ -198,8 +198,8 @@ int set_dis_bypass_sd(int if_index, int dis_bypass); * @if_index: network device index of the controlling device * Output: * 0/1 - on success (normal Bypass mode/ Disable bypass) - * -1 - on failure (device is not capable of the operation ordevice not support Bypass - * or it's a slave device) + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) **/ int get_dis_bypass_sd(int if_index); @@ -208,9 +208,9 @@ int get_dis_bypass_sd(int if_index); * @if_index: network device index of the controlling device * @bypass_mode: bypass mode setting at power off state (1=BP en, 0=BP Dis) * Output: - * 0 - on success - * -1 - on failure (device is not capable of the operation ordevice not support Bypass - * or it's a slave device) + * 0 - on success + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) **/ int set_bypass_pwoff_sd(int if_index, int bypass_mode); @@ -219,8 +219,8 @@ int set_bypass_pwoff_sd(int if_index, int bypass_mode); * @if_index: network device index of the controlling device * Output: * 0/1 - on success (Disable bypass at power off state / normal Bypass mode) - * -1 - on failure (device is not capable of the operation ordevice not support Bypass - * or it's a slave device) + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) **/ int get_bypass_pwoff_sd(int if_index); @@ -229,9 +229,9 @@ int get_bypass_pwoff_sd(int if_index); * @if_index: network device index of the controlling device * @bypass_mode: bypass mode setting at power up state (1=BP en, 0=BP Dis) * Output: - * 0 - on success - * -1 - on failure (device is not capable of the operation ordevice not support Bypass - * or it's a slave device) + * 0 - on success + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) **/ int set_bypass_pwup_sd(int if_index, int bypass_mode); @@ -240,8 +240,8 @@ int set_bypass_pwup_sd(int if_index, int bypass_mode); * @if_index: network device index of the controlling device * Output: * 0/1 - on success (Disable bypass at power up state / normal Bypass mode) - * -1 - on failure (device is not capable of the operation ordevice not support Bypass - * or it's a slave device) + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) **/ int get_bypass_pwup_sd(int if_index); @@ -249,50 +249,50 @@ int get_bypass_pwup_sd(int if_index); * set_bypass_wd - Set watchdog state * @if_index: network device index of the controlling device * @ms_timeout: requested timeout (in ms units), 0 for disabling the watchdog timer - * @ms_timeout_set(output): requested timeout (in ms units), + * @ms_timeout_set(output): requested timeout (in ms units), * that the adapter supports and will be used by the watchdog * Output: - * 0 - on success - * -1 - on failure (device is not capable of the operation ordevice not support Bypass - * or it's a slave device) + * 0 - on success + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) **/ int set_bypass_wd_sd(int if_index, int ms_timeout, int *ms_timeout_set); /** * get_bypass_wd - Get watchdog state * @if_index: network device index of the controlling device - * @ms_timeout (output): WDT timeout (in ms units), + * @ms_timeout (output): WDT timeout (in ms units), * -1 for unknown wdt status * 0 if WDT is disabled * Output: * 0 - on success - * -1 - on failure (device is not capable of the operation ordevice not support Bypass - * or it's a slave device) + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) **/ int get_bypass_wd_sd(int if_index, int *ms_timeout_set); /** * get_wd_expire_time - Get watchdog expire * @if_index: network device index of the controlling device - * @ms_time_left (output): time left till watchdog time expire, + * @ms_time_left (output): time left till watchdog time expire, * -1 if WDT has expired * 0 if WDT is disabled * Output: * 0 - on success - * -1 - on failure (device is not capable of the operation ordevice not support Bypass - * or it's a slave device or unknown wdt status) + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device or unknown wdt status) **/ int get_wd_expire_time_sd(int if_index, int *ms_time_left); /** * reset_bypass_wd_timer - Reset watchdog timer * @if_index: network device index of the controlling device - * + * * Output: * 1 - on success * 0 - watchdog is not configured - * -1 - on failure (device is not capable of the operation ordevice not support Bypass - * or it's a slave device or unknown wdt status) + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device or unknown wdt status) **/ int reset_bypass_wd_timer_sd(int if_index); @@ -300,64 +300,64 @@ int reset_bypass_wd_timer_sd(int if_index); * set_std_nic - Standard NIC mode of operation * @if_index: network device index of the controlling device * @nic_mode: 0/1 (Default Bypass mode / Standard NIC mode) - * + * * Output: * 0 - on success - * -1 - on failure (device is not capable of the operation ordevice not support Bypass - * or it's a slave device) + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) **/ int set_std_nic_sd(int if_index, int nic_mode); /** * get_std_nic - Get Standard NIC mode setting * @if_index: network device index of the controlling device - * + * * Output: * 0/1 (Default Bypass mode / Standard NIC mode) on success - * -1 - on failure (device is not capable of the operation ordevice not support Bypass - * or it's a slave device) + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) **/ int get_std_nic_sd(int if_index); /** - * set_tx - set transmitter enable/disable + * set_tx - set transmitter enable/disable * @if_index: network device index of the controlling device * @tx_state: 0/1 (Transmit Disable / Transmit Enable) - * + * * Output: * 0 - on success - * -1 - on failure (device is not capable of the operation ) + * -1 - on failure (device is not capable of the operation ) **/ int set_tx_sd(int if_index, int tx_state); /** * get_tx - get transmitter state (disable / enable) * @if_index: network device index of the controlling device - * + * * Output: * 0/1 (ransmit Disable / Transmit Enable) on success - * -1 - on failure (device is not capable of the operation ordevice not support Bypass) + * -1 - on failure (device is not capable of the operation ordevice not support Bypass) **/ int get_tx_sd(int if_index); /** - * set_tpl - set TPL enable/disable + * set_tpl - set TPL enable/disable * @if_index: network device index of the controlling device * @tx_state: 0/1 (TPL Disable / TPL Enable) - * + * * Output: * 0 - on success - * -1 - on failure (device is not capable of the operation ) + * -1 - on failure (device is not capable of the operation ) **/ int set_tpl_sd(int if_index, int tpl_state); /** * get_tpl - get TPL state (disable / enable) * @if_index: network device index of the controlling device - * + * * Output: * 0/1 (TPL Disable / TPL Enable) on success - * -1 - on failure (device is not capable of the operation) + * -1 - on failure (device is not capable of the operation) **/ int get_tpl_sd(int if_index); @@ -368,10 +368,10 @@ int set_bp_hw_reset_sd(int if_index, int status); /** * set_tap - set TAP state * @if_index: network device index of the controlling device - * @tap_mode: 1 tap mode , 0 normal nic mode + * @tap_mode: 1 tap mode , 0 normal nic mode * Output: * 0 - on success - * -1 - on failure (device not support TAP or it's a slave device) + * -1 - on failure (device not support TAP or it's a slave device) **/ int set_tap_sd(int if_index, int tap_mode); @@ -380,7 +380,7 @@ int set_tap_sd(int if_index, int tap_mode); * @if_index: network device index of the controlling device * Output: * 0/1 - (off/on) on success - * -1 - on failure (device not support TAP or it's a slave device) + * -1 - on failure (device not support TAP or it's a slave device) **/ int get_tap_sd(int if_index); @@ -389,7 +389,7 @@ int get_tap_sd(int if_index); * @if_index: network device index of the controlling device * Output: * 0/1 - (off/on) on success - * -1 - on failure (device not support TAP or it's a slave device) + * -1 - on failure (device not support TAP or it's a slave device) **/ int get_tap_change_sd(int if_index); @@ -399,8 +399,8 @@ int get_tap_change_sd(int if_index); * @dis_tap: disable tap(1=dis, 0=en) * Output: * 0 - on success - * -1 - on failure (device is not capable of the operation ordevice not support TAP - * or it's a slave device) + * -1 - on failure (device is not capable of the operation ordevice not support TAP + * or it's a slave device) **/ int set_dis_tap_sd(int if_index, int dis_tap); @@ -409,8 +409,8 @@ int set_dis_tap_sd(int if_index, int dis_tap); * @if_index: network device index of the controlling device * Output: * 0/1 - on success (normal TAP mode/ Disable TAP) - * -1 - on failure (device is not capable of the operation ordevice not support TAP - * or it's a slave device) + * -1 - on failure (device is not capable of the operation ordevice not support TAP + * or it's a slave device) **/ int get_dis_tap_sd(int if_index); @@ -419,7 +419,7 @@ int get_dis_tap_sd(int if_index); * @if_index: network device index of the controlling device * @bypass_mode: tap mode setting at power up state (1=TAP en, 0=TAP Dis) * Output: - * 0 - on success + * 0 - on success * -1 - on failure (device is not capable of the operation ordevice not support TAP * or it's a slave device) **/ -- cgit v0.10.2 From 25dd85120424d9f0d6ee1144233ce3e20930110f Mon Sep 17 00:00:00 2001 From: Daniel Cotey Date: Sat, 15 Sep 2012 06:09:26 -0700 Subject: Staging: silicom: checkpatch cleanup: header file whitespace Finish trailing spaces in libbp_sd.h Signed-off-by: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/libbp_sd.h b/drivers/staging/silicom/libbp_sd.h index cba9ba6..065277f 100644 --- a/drivers/staging/silicom/libbp_sd.h +++ b/drivers/staging/silicom/libbp_sd.h @@ -420,8 +420,8 @@ int get_dis_tap_sd(int if_index); * @bypass_mode: tap mode setting at power up state (1=TAP en, 0=TAP Dis) * Output: * 0 - on success - * -1 - on failure (device is not capable of the operation ordevice not support TAP - * or it's a slave device) + * -1 - on failure (device is not capable of the operation ordevice not support TAP + * or it's a slave device) **/ int set_tap_pwup_sd(int if_index, int tap_mode); @@ -430,18 +430,18 @@ int set_tap_pwup_sd(int if_index, int tap_mode); * @if_index: network device index of the controlling device * Output: * 0/1 - on success (Disable TAP at power up state / normal TAP mode) - * -1 - on failure (device is not capable of the operation ordevice not support TAP - * or it's a slave device) + * -1 - on failure (device is not capable of the operation ordevice not support TAP + * or it's a slave device) **/ int get_tap_pwup_sd(int if_index); /** * set_wd_exp_mode - Set adapter state when WDT expired. * @if_index: network device index of the controlling device - * @bypass_mode: adapter mode (1=tap mode, 0=bypass mode) + * @bypass_mode: adapter mode (1=tap mode, 0=bypass mode) * Output: * 0 - on success - * -1 - on failure (device not support Bypass or it's a slave device) + * -1 - on failure (device not support Bypass or it's a slave device) **/ int set_wd_exp_mode_sd(int if_index, int bypass_mode); @@ -450,38 +450,38 @@ int set_wd_exp_mode_sd(int if_index, int bypass_mode); * @if_index: network device index of the controlling device * Output: * 0/1 - (bypass/tap) on success - * -1 - on failure (device not support Bypass or it's a slave device) + * -1 - on failure (device not support Bypass or it's a slave device) **/ int get_wd_exp_mode_sd(int if_index); /** * set_wd_autoreset - reset WDT periodically. * @if_index: network device index of the controlling device - * @bypass_mode: adapter mode (1=tap mode, 0=bypass mode) + * @bypass_mode: adapter mode (1=tap mode, 0=bypass mode) * Output: * 1 - on success - * -1 - on failure (device is not capable of the operation ordevice not support Bypass - * or it's a slave device or unknown wdt status) + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device or unknown wdt status) **/ int set_wd_autoreset_sd(int if_index, int time); /** * set_wd_autoreset - reset WDT periodically. * @if_index: network device index of the controlling device - * @bypass_mode: adapter mode (1=tap mode, 0=bypass mode) + * @bypass_mode: adapter mode (1=tap mode, 0=bypass mode) * Output: * 1 - on success - * -1 - on failure (device is not capable of the operation ordevice not support Bypass - * or it's a slave device or unknown wdt status) + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device or unknown wdt status) **/ int get_wd_autoreset_sd(int if_index); /** * set_disc - set DISC state * @if_index: network device index of the controlling device - * @tap_mode: 1 DISC mode , 0 normal nic mode + * @tap_mode: 1 DISC mode , 0 normal nic mode * Output: * 0 - on success - * -1 - on failure (device not support disconnect or it's a slave device) + * -1 - on failure (device not support disconnect or it's a slave device) **/ int set_bp_disc_sd(int if_index, int disc_mode); @@ -490,7 +490,7 @@ int set_bp_disc_sd(int if_index, int disc_mode); * @if_index: network device index of the controlling device * Output: * 0/1 - (off/on) on success - * -1 - on failure (device not support disconnect or it's a slave device) + * -1 - on failure (device not support disconnect or it's a slave device) **/ int get_bp_disc_sd(int if_index); @@ -499,7 +499,7 @@ int get_bp_disc_sd(int if_index); * @if_index: network device index of the controlling device * Output: * 0/1 - (off/on) on success - * -1 - on failure (device not support disconnect or it's a slave device) + * -1 - on failure (device not support disconnect or it's a slave device) **/ int get_bp_disc_change_sd(int if_index); @@ -509,8 +509,8 @@ int get_bp_disc_change_sd(int if_index); * @dis_disc: disable disconnect(1=dis, 0=en) * Output: * 0 - on success - * -1 - on failure (device is not capable of the operation ordevice not support DISC - * or it's a slave device) + * -1 - on failure (device is not capable of the operation ordevice not support DISC + * or it's a slave device) **/ int set_bp_dis_disc_sd(int if_index, int dis_disc); @@ -519,8 +519,8 @@ int set_bp_dis_disc_sd(int if_index, int dis_disc); * @if_index: network device index of the controlling device * Output: * 0/1 - on success (normal DISC mode/ Disable DISC) - * -1 - on failure (device is not capable of the operation ordevice not support TAP - * or it's a slave device) + * -1 - on failure (device is not capable of the operation ordevice not support TAP + * or it's a slave device) **/ int get_bp_dis_disc_sd(int if_index); @@ -529,9 +529,9 @@ int get_bp_dis_disc_sd(int if_index); * @if_index: network device index of the controlling device * @disc_mode: DISC mode setting at power up state (1= en, 0= Dis) * Output: - * 0 - on success - * -1 - on failure (device is not capable of the operation ordevice not support DISC - * or it's a slave device) + * 0 - on success + * -1 - on failure (device is not capable of the operation ordevice not support DISC + * or it's a slave device) **/ int set_bp_disc_pwup_sd(int if_index, int disc_mode); @@ -540,8 +540,8 @@ int set_bp_disc_pwup_sd(int if_index, int disc_mode); * @if_index: network device index of the controlling device * Output: * 0/1 - on success (Disable DISC at power up state / normal DISC mode) - * -1 - on failure (device is not capable of the operation ordevice not support DISC - * or it's a slave device) + * -1 - on failure (device is not capable of the operation ordevice not support DISC + * or it's a slave device) **/ int get_bp_disc_pwup_sd(int if_index); -- cgit v0.10.2 From 86bc9ebb4dda92aa225fef20dd3b1f23dfd1a794 Mon Sep 17 00:00:00 2001 From: Daniel Cotey Date: Sat, 15 Sep 2012 06:09:54 -0700 Subject: Staging: silicom: checkpatch cleanup: fix includes checkpatch fixups Signed-off-by: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/bp_mod.c b/drivers/staging/silicom/bp_mod.c index 2722da9..8b7298f 100644 --- a/drivers/staging/silicom/bp_mod.c +++ b/drivers/staging/silicom/bp_mod.c @@ -10,9 +10,6 @@ /* */ /******************************************************************************/ #include -#if defined(CONFIG_SMP) && ! defined(__SMP__) -#define __SMP__ -#endif #include /* We're doing kernel work */ #include /* Specifically, a module */ @@ -24,7 +21,7 @@ #include #include -#include /* for get_user and put_user */ +#include /* for get_user and put_user */ #include #include #include -- cgit v0.10.2 From 01448bbb05abb09fa74f5d15bf7388d8ac78700d Mon Sep 17 00:00:00 2001 From: Daniel Cotey Date: Sat, 15 Sep 2012 06:10:21 -0700 Subject: Staging: silicom: checkpatch.pl cleanup: pretty pointers first chunk, straighten up the pointer notation Signed-off-by: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/bp_mod.c b/drivers/staging/silicom/bp_mod.c index 8b7298f..e133a8b 100644 --- a/drivers/staging/silicom/bp_mod.c +++ b/drivers/staging/silicom/bp_mod.c @@ -129,8 +129,8 @@ typedef struct _bpctl_dev { int bp_540; // selftest stanza - int (*hard_start_xmit_save) (struct sk_buff * skb, - struct net_device * dev); + int (*hard_start_xmit_save) (struct sk_buff *skb, + struct net_device *dev); const struct net_device_ops *old_ops; struct net_device_ops new_ops; int bp_self_test_flag; @@ -147,18 +147,18 @@ static struct semaphore bpctl_sema; static int device_num = 0; static int get_dev_idx(int ifindex); -static bpctl_dev_t *get_master_port_fn(bpctl_dev_t * pbpctl_dev); -static int disc_status(bpctl_dev_t * pbpctl_dev); -static int bypass_status(bpctl_dev_t * pbpctl_dev); -static int wdt_timer(bpctl_dev_t * pbpctl_dev, int *time_left); -static bpctl_dev_t *get_status_port_fn(bpctl_dev_t * pbpctl_dev); +static bpctl_dev_t *get_master_port_fn(bpctl_dev_t *pbpctl_dev); +static int disc_status(bpctl_dev_t *pbpctl_dev); +static int bypass_status(bpctl_dev_t *pbpctl_dev); +static int wdt_timer(bpctl_dev_t *pbpctl_dev, int *time_left); +static bpctl_dev_t *get_status_port_fn(bpctl_dev_t *pbpctl_dev); static void if_scan_init(void); -int bypass_proc_create_dev_sd(bpctl_dev_t * pbp_device_block); -int bypass_proc_remove_dev_sd(bpctl_dev_t * pbp_device_block); +int bypass_proc_create_dev_sd(bpctl_dev_t *pbp_device_block); +int bypass_proc_remove_dev_sd(bpctl_dev_t *pbp_device_block); int bp_proc_create(void); -int is_bypass_fn(bpctl_dev_t * pbpctl_dev); +int is_bypass_fn(bpctl_dev_t *pbpctl_dev); int get_dev_idx_bsf(int bus, int slot, int func); static unsigned long str_to_hex(char *p); @@ -353,10 +353,10 @@ static int device_release(struct inode *inode, struct file *file) return SUCCESS; } -int is_bypass_fn(bpctl_dev_t * pbpctl_dev); -int wdt_time_left(bpctl_dev_t * pbpctl_dev); +int is_bypass_fn(bpctl_dev_t *pbpctl_dev); +int wdt_time_left(bpctl_dev_t *pbpctl_dev); -static void write_pulse(bpctl_dev_t * pbpctl_dev, +static void write_pulse(bpctl_dev_t *pbpctl_dev, unsigned int ctrl_ext, unsigned char value, unsigned char len) { @@ -666,7 +666,7 @@ static void write_pulse(bpctl_dev_t * pbpctl_dev, } } -static int read_pulse(bpctl_dev_t * pbpctl_dev, unsigned int ctrl_ext, +static int read_pulse(bpctl_dev_t *pbpctl_dev, unsigned int ctrl_ext, unsigned char len) { unsigned char ctrl_val = 0; @@ -847,7 +847,7 @@ static int read_pulse(bpctl_dev_t * pbpctl_dev, unsigned int ctrl_ext, return ctrl_val; } -static void write_reg(bpctl_dev_t * pbpctl_dev, unsigned char value, +static void write_reg(bpctl_dev_t *pbpctl_dev, unsigned char value, unsigned char addr) { uint32_t ctrl_ext = 0, ctrl = 0; @@ -1019,12 +1019,12 @@ static void write_reg(bpctl_dev_t * pbpctl_dev, unsigned char value, } -static void write_data(bpctl_dev_t * pbpctl_dev, unsigned char value) +static void write_data(bpctl_dev_t *pbpctl_dev, unsigned char value) { write_reg(pbpctl_dev, value, CMND_REG_ADDR); } -static int read_reg(bpctl_dev_t * pbpctl_dev, unsigned char addr) +static int read_reg(bpctl_dev_t *pbpctl_dev, unsigned char addr) { uint32_t ctrl_ext = 0, ctrl = 0, ctrl_value = 0; bpctl_dev_t *pbpctl_dev_c = NULL; @@ -1298,7 +1298,7 @@ static int read_reg(bpctl_dev_t * pbpctl_dev, unsigned char addr) return ctrl_value; } -static int wdt_pulse(bpctl_dev_t * pbpctl_dev) +static int wdt_pulse(bpctl_dev_t *pbpctl_dev) { uint32_t ctrl_ext = 0, ctrl = 0; bpctl_dev_t *pbpctl_dev_c = NULL; @@ -1519,7 +1519,7 @@ static int wdt_pulse(bpctl_dev_t * pbpctl_dev) return 0; } -static void data_pulse(bpctl_dev_t * pbpctl_dev, unsigned char value) +static void data_pulse(bpctl_dev_t *pbpctl_dev, unsigned char value) { uint32_t ctrl_ext = 0; @@ -1585,7 +1585,7 @@ static void data_pulse(bpctl_dev_t * pbpctl_dev, unsigned char value) } -static int send_wdt_pulse(bpctl_dev_t * pbpctl_dev) +static int send_wdt_pulse(bpctl_dev_t *pbpctl_dev) { uint32_t ctrl_ext = 0; @@ -1619,7 +1619,7 @@ static int send_wdt_pulse(bpctl_dev_t * pbpctl_dev) return 0; } -void send_bypass_clear_pulse(bpctl_dev_t * pbpctl_dev, unsigned int value) +void send_bypass_clear_pulse(bpctl_dev_t *pbpctl_dev, unsigned int value) { uint32_t ctrl_ext = 0; @@ -1645,7 +1645,7 @@ void send_bypass_clear_pulse(bpctl_dev_t * pbpctl_dev, unsigned int value) /* #endif OLD_FW */ #ifdef BYPASS_DEBUG -int pulse_set_fn(bpctl_dev_t * pbpctl_dev, unsigned int counter) +int pulse_set_fn(bpctl_dev_t *pbpctl_dev, unsigned int counter) { uint32_t ctrl_ext = 0; @@ -1673,7 +1673,7 @@ int pulse_set_fn(bpctl_dev_t * pbpctl_dev, unsigned int counter) return 0; } -int zero_set_fn(bpctl_dev_t * pbpctl_dev) +int zero_set_fn(bpctl_dev_t *pbpctl_dev) { uint32_t ctrl_ext = 0, ctrl_value = 0; if (!pbpctl_dev) -- cgit v0.10.2 From 1bd5374ddea7a47b1ec682ee912dc36680cde939 Mon Sep 17 00:00:00 2001 From: Daniel Cotey Date: Sat, 15 Sep 2012 06:10:49 -0700 Subject: Staging: silicom: checkpatch.pl cleanup: pretty pointers More notation fixes Signed-off-by: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/bp_mod.c b/drivers/staging/silicom/bp_mod.c index e133a8b..b574c35 100644 --- a/drivers/staging/silicom/bp_mod.c +++ b/drivers/staging/silicom/bp_mod.c @@ -1698,7 +1698,7 @@ int zero_set_fn(bpctl_dev_t *pbpctl_dev) return ctrl_value; } -int pulse_get2_fn(bpctl_dev_t * pbpctl_dev) +int pulse_get2_fn(bpctl_dev_t *pbpctl_dev) { uint32_t ctrl_ext = 0, ctrl_value = 0; if (!pbpctl_dev) @@ -1713,7 +1713,7 @@ int pulse_get2_fn(bpctl_dev_t * pbpctl_dev) return ctrl_value; } -int pulse_get1_fn(bpctl_dev_t * pbpctl_dev) +int pulse_get1_fn(bpctl_dev_t *pbpctl_dev) { uint32_t ctrl_ext = 0, ctrl_value = 0; if (!pbpctl_dev) @@ -1730,7 +1730,7 @@ int pulse_get1_fn(bpctl_dev_t * pbpctl_dev) return ctrl_value; } -int gpio6_set_fn(bpctl_dev_t * pbpctl_dev) +int gpio6_set_fn(bpctl_dev_t *pbpctl_dev) { uint32_t ctrl_ext = 0; @@ -1741,7 +1741,7 @@ int gpio6_set_fn(bpctl_dev_t * pbpctl_dev) return 0; } -int gpio7_set_fn(bpctl_dev_t * pbpctl_dev) +int gpio7_set_fn(bpctl_dev_t *pbpctl_dev) { uint32_t ctrl_ext = 0; @@ -1752,7 +1752,7 @@ int gpio7_set_fn(bpctl_dev_t * pbpctl_dev) return 0; } -int gpio7_clear_fn(bpctl_dev_t * pbpctl_dev) +int gpio7_clear_fn(bpctl_dev_t *pbpctl_dev) { uint32_t ctrl_ext = 0; @@ -1763,7 +1763,7 @@ int gpio7_clear_fn(bpctl_dev_t * pbpctl_dev) return 0; } -int gpio6_clear_fn(bpctl_dev_t * pbpctl_dev) +int gpio6_clear_fn(bpctl_dev_t *pbpctl_dev) { uint32_t ctrl_ext = 0; @@ -1775,7 +1775,7 @@ int gpio6_clear_fn(bpctl_dev_t * pbpctl_dev) } #endif /*BYPASS_DEBUG */ -static bpctl_dev_t *get_status_port_fn(bpctl_dev_t * pbpctl_dev) +static bpctl_dev_t *get_status_port_fn(bpctl_dev_t *pbpctl_dev) { int idx_dev = 0; @@ -1805,7 +1805,7 @@ static bpctl_dev_t *get_status_port_fn(bpctl_dev_t * pbpctl_dev) return NULL; } -static bpctl_dev_t *get_master_port_fn(bpctl_dev_t * pbpctl_dev) +static bpctl_dev_t *get_master_port_fn(bpctl_dev_t *pbpctl_dev) { int idx_dev = 0; @@ -1839,7 +1839,7 @@ static bpctl_dev_t *get_master_port_fn(bpctl_dev_t * pbpctl_dev) /**************INTEL API***************/ /**************************************/ -static void write_data_port_int(bpctl_dev_t * pbpctl_dev, +static void write_data_port_int(bpctl_dev_t *pbpctl_dev, unsigned char ctrl_value) { uint32_t value; @@ -1864,7 +1864,7 @@ static void write_data_port_int(bpctl_dev_t * pbpctl_dev, } -static int write_data_int(bpctl_dev_t * pbpctl_dev, unsigned char value) +static int write_data_int(bpctl_dev_t *pbpctl_dev, unsigned char value) { bpctl_dev_t *pbpctl_dev_b = NULL; @@ -1878,7 +1878,7 @@ static int write_data_int(bpctl_dev_t * pbpctl_dev, unsigned char value) return 0; } -static int wdt_pulse_int(bpctl_dev_t * pbpctl_dev) +static int wdt_pulse_int(bpctl_dev_t *pbpctl_dev) { if ((atomic_read(&pbpctl_dev->wdt_busy)) == 1) @@ -1902,7 +1902,7 @@ static int wdt_pulse_int(bpctl_dev_t * pbpctl_dev) /*************************************/ /* CMND_ON 0x4 (100)*/ -int cmnd_on(bpctl_dev_t * pbpctl_dev) +int cmnd_on(bpctl_dev_t *pbpctl_dev) { int ret = BP_NOT_CAP; @@ -1919,7 +1919,7 @@ int cmnd_on(bpctl_dev_t * pbpctl_dev) } /* CMND_OFF 0x2 (10)*/ -int cmnd_off(bpctl_dev_t * pbpctl_dev) +int cmnd_off(bpctl_dev_t *pbpctl_dev) { int ret = BP_NOT_CAP; @@ -1937,7 +1937,7 @@ int cmnd_off(bpctl_dev_t * pbpctl_dev) } /* BYPASS_ON (0xa)*/ -int bypass_on(bpctl_dev_t * pbpctl_dev) +int bypass_on(bpctl_dev_t *pbpctl_dev) { int ret = BP_NOT_CAP; @@ -1958,7 +1958,7 @@ int bypass_on(bpctl_dev_t * pbpctl_dev) } /* BYPASS_OFF (0x8 111)*/ -int bypass_off(bpctl_dev_t * pbpctl_dev) +int bypass_off(bpctl_dev_t *pbpctl_dev) { int ret = BP_NOT_CAP; @@ -1981,7 +1981,7 @@ int bypass_off(bpctl_dev_t * pbpctl_dev) } /* TAP_OFF (0x9)*/ -int tap_off(bpctl_dev_t * pbpctl_dev) +int tap_off(bpctl_dev_t *pbpctl_dev) { int ret = BP_NOT_CAP; if ((pbpctl_dev->bp_caps & TAP_CAP) @@ -1994,7 +1994,7 @@ int tap_off(bpctl_dev_t * pbpctl_dev) } /* TAP_ON (0xb)*/ -int tap_on(bpctl_dev_t * pbpctl_dev) +int tap_on(bpctl_dev_t *pbpctl_dev) { int ret = BP_NOT_CAP; if ((pbpctl_dev->bp_caps & TAP_CAP) @@ -2007,7 +2007,7 @@ int tap_on(bpctl_dev_t * pbpctl_dev) } /* DISC_OFF (0x9)*/ -int disc_off(bpctl_dev_t * pbpctl_dev) +int disc_off(bpctl_dev_t *pbpctl_dev) { int ret = 0; if ((pbpctl_dev->bp_caps & DISC_CAP) && (pbpctl_dev->bp_ext_ver >= 0x8)) { @@ -2019,7 +2019,7 @@ int disc_off(bpctl_dev_t * pbpctl_dev) } /* DISC_ON (0xb)*/ -int disc_on(bpctl_dev_t * pbpctl_dev) +int disc_on(bpctl_dev_t *pbpctl_dev) { int ret = 0; if ((pbpctl_dev->bp_caps & DISC_CAP) && (pbpctl_dev->bp_ext_ver >= 0x8)) { @@ -2031,7 +2031,7 @@ int disc_on(bpctl_dev_t * pbpctl_dev) } /* DISC_PORT_ON */ -int disc_port_on(bpctl_dev_t * pbpctl_dev) +int disc_port_on(bpctl_dev_t *pbpctl_dev) { int ret = 0; bpctl_dev_t *pbpctl_dev_m; @@ -2059,7 +2059,7 @@ int disc_port_on(bpctl_dev_t * pbpctl_dev) } /* DISC_PORT_OFF */ -int disc_port_off(bpctl_dev_t * pbpctl_dev) +int disc_port_off(bpctl_dev_t *pbpctl_dev) { int ret = 0; bpctl_dev_t *pbpctl_dev_m; @@ -2084,7 +2084,7 @@ int disc_port_off(bpctl_dev_t * pbpctl_dev) } /*TWO_PORT_LINK_HW_EN (0xe)*/ -int tpl_hw_on(bpctl_dev_t * pbpctl_dev) +int tpl_hw_on(bpctl_dev_t *pbpctl_dev) { int ret = 0, ctrl = 0; bpctl_dev_t *pbpctl_dev_b = NULL; @@ -2111,7 +2111,7 @@ int tpl_hw_on(bpctl_dev_t * pbpctl_dev) } /*TWO_PORT_LINK_HW_DIS (0xc)*/ -int tpl_hw_off(bpctl_dev_t * pbpctl_dev) +int tpl_hw_off(bpctl_dev_t *pbpctl_dev) { int ret = 0, ctrl = 0; bpctl_dev_t *pbpctl_dev_b = NULL; @@ -2136,7 +2136,7 @@ int tpl_hw_off(bpctl_dev_t * pbpctl_dev) } /* WDT_OFF (0x6 110)*/ -int wdt_off(bpctl_dev_t * pbpctl_dev) +int wdt_off(bpctl_dev_t *pbpctl_dev) { int ret = BP_NOT_CAP; @@ -2159,7 +2159,7 @@ int wdt_off(bpctl_dev_t * pbpctl_dev) static unsigned int wdt_val_array[] = { 1000, 1500, 2000, 3000, 4000, 8000, 16000, 32000, 0 }; -int wdt_on(bpctl_dev_t * pbpctl_dev, unsigned int timeout) +int wdt_on(bpctl_dev_t *pbpctl_dev, unsigned int timeout) { if (pbpctl_dev->bp_caps & WD_CTL_CAP) { @@ -2211,7 +2211,7 @@ int wdt_on(bpctl_dev_t * pbpctl_dev, unsigned int timeout) return BP_NOT_CAP; } -void bp75_put_hw_semaphore_generic(bpctl_dev_t * pbpctl_dev) +void bp75_put_hw_semaphore_generic(bpctl_dev_t *pbpctl_dev) { u32 swsm; @@ -2222,7 +2222,7 @@ void bp75_put_hw_semaphore_generic(bpctl_dev_t * pbpctl_dev) BPCTL_WRITE_REG(pbpctl_dev, SWSM, swsm); } -s32 bp75_get_hw_semaphore_generic(bpctl_dev_t * pbpctl_dev) +s32 bp75_get_hw_semaphore_generic(bpctl_dev_t *pbpctl_dev) { u32 swsm; s32 ret_val = 0; @@ -2270,7 +2270,7 @@ s32 bp75_get_hw_semaphore_generic(bpctl_dev_t * pbpctl_dev) return ret_val; } -static void bp75_release_phy(bpctl_dev_t * pbpctl_dev) +static void bp75_release_phy(bpctl_dev_t *pbpctl_dev) { u16 mask = BPCTLI_SWFW_PHY0_SM; u32 swfw_sync; @@ -2288,7 +2288,7 @@ static void bp75_release_phy(bpctl_dev_t * pbpctl_dev) bp75_put_hw_semaphore_generic(pbpctl_dev); } -static s32 bp75_acquire_phy(bpctl_dev_t * pbpctl_dev) +static s32 bp75_acquire_phy(bpctl_dev_t *pbpctl_dev) { u16 mask = BPCTLI_SWFW_PHY0_SM; u32 swfw_sync; @@ -2334,7 +2334,7 @@ static s32 bp75_acquire_phy(bpctl_dev_t * pbpctl_dev) return ret_val; } -s32 bp75_read_phy_reg_mdic(bpctl_dev_t * pbpctl_dev, u32 offset, u16 * data) +s32 bp75_read_phy_reg_mdic(bpctl_dev_t *pbpctl_dev, u32 offset, u16 *data) { u32 i, mdic = 0; s32 ret_val = 0; @@ -2367,7 +2367,7 @@ s32 bp75_read_phy_reg_mdic(bpctl_dev_t * pbpctl_dev, u32 offset, u16 * data) return ret_val; } -s32 bp75_write_phy_reg_mdic(bpctl_dev_t * pbpctl_dev, u32 offset, u16 data) +s32 bp75_write_phy_reg_mdic(bpctl_dev_t *pbpctl_dev, u32 offset, u16 data) { u32 i, mdic = 0; s32 ret_val = 0; @@ -2400,7 +2400,7 @@ s32 bp75_write_phy_reg_mdic(bpctl_dev_t * pbpctl_dev, u32 offset, u16 data) return ret_val; } -static s32 bp75_read_phy_reg(bpctl_dev_t * pbpctl_dev, u32 offset, u16 * data) +static s32 bp75_read_phy_reg(bpctl_dev_t *pbpctl_dev, u32 offset, u16 *data) { s32 ret_val = 0; -- cgit v0.10.2 From 81908e8be4831e7962a8eec19bbd75389e1fa6f9 Mon Sep 17 00:00:00 2001 From: Daniel Cotey Date: Sat, 15 Sep 2012 06:11:15 -0700 Subject: Staging: silicom: checkpatch.pl cleanup: pretty pointers More pointer style cleanup Signed-off-by: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/bp_mod.c b/drivers/staging/silicom/bp_mod.c index b574c35..50bb5d3 100644 --- a/drivers/staging/silicom/bp_mod.c +++ b/drivers/staging/silicom/bp_mod.c @@ -2426,7 +2426,7 @@ static s32 bp75_read_phy_reg(bpctl_dev_t *pbpctl_dev, u32 offset, u16 *data) return ret_val; } -static s32 bp75_write_phy_reg(bpctl_dev_t * pbpctl_dev, u32 offset, u16 data) +static s32 bp75_write_phy_reg(bpctl_dev_t *pbpctl_dev, u32 offset, u16 data) { s32 ret_val = 0; @@ -2454,7 +2454,7 @@ static s32 bp75_write_phy_reg(bpctl_dev_t * pbpctl_dev, u32 offset, u16 data) } /* SET_TX (non-Bypass command :)) */ -static int set_tx(bpctl_dev_t * pbpctl_dev, int tx_state) +static int set_tx(bpctl_dev_t *pbpctl_dev, int tx_state) { int ret = 0, ctrl = 0; bpctl_dev_t *pbpctl_dev_m; @@ -2659,7 +2659,7 @@ static int set_tx(bpctl_dev_t * pbpctl_dev, int tx_state) } /* SET_FORCE_LINK (non-Bypass command :)) */ -static int set_bp_force_link(bpctl_dev_t * pbpctl_dev, int tx_state) +static int set_bp_force_link(bpctl_dev_t *pbpctl_dev, int tx_state) { int ret = 0, ctrl = 0; @@ -2683,7 +2683,7 @@ static int set_bp_force_link(bpctl_dev_t * pbpctl_dev, int tx_state) } /*RESET_CONT 0x20 */ -int reset_cont(bpctl_dev_t * pbpctl_dev) +int reset_cont(bpctl_dev_t *pbpctl_dev) { int ret = BP_NOT_CAP; @@ -2700,7 +2700,7 @@ int reset_cont(bpctl_dev_t * pbpctl_dev) } /*DIS_BYPASS_CAP 0x22 */ -int dis_bypass_cap(bpctl_dev_t * pbpctl_dev) +int dis_bypass_cap(bpctl_dev_t *pbpctl_dev) { if (pbpctl_dev->bp_caps & BP_DIS_CAP) { @@ -2719,7 +2719,7 @@ int dis_bypass_cap(bpctl_dev_t * pbpctl_dev) } /*EN_BYPASS_CAP 0x24 */ -int en_bypass_cap(bpctl_dev_t * pbpctl_dev) +int en_bypass_cap(bpctl_dev_t *pbpctl_dev) { if (pbpctl_dev->bp_caps & BP_DIS_CAP) { if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) { @@ -2735,7 +2735,7 @@ int en_bypass_cap(bpctl_dev_t * pbpctl_dev) } /* BYPASS_STATE_PWRON 0x26*/ -int bypass_state_pwron(bpctl_dev_t * pbpctl_dev) +int bypass_state_pwron(bpctl_dev_t *pbpctl_dev) { if (pbpctl_dev->bp_caps & BP_PWUP_CTL_CAP) { write_data(pbpctl_dev, BYPASS_STATE_PWRON); @@ -2749,7 +2749,7 @@ int bypass_state_pwron(bpctl_dev_t * pbpctl_dev) } /* NORMAL_STATE_PWRON 0x28*/ -int normal_state_pwron(bpctl_dev_t * pbpctl_dev) +int normal_state_pwron(bpctl_dev_t *pbpctl_dev) { if ((pbpctl_dev->bp_caps & BP_PWUP_CTL_CAP) || (pbpctl_dev->bp_caps & TAP_PWUP_CTL_CAP)) { @@ -2764,7 +2764,7 @@ int normal_state_pwron(bpctl_dev_t * pbpctl_dev) } /* BYPASS_STATE_PWROFF 0x27*/ -int bypass_state_pwroff(bpctl_dev_t * pbpctl_dev) +int bypass_state_pwroff(bpctl_dev_t *pbpctl_dev) { if (pbpctl_dev->bp_caps & BP_PWOFF_CTL_CAP) { write_data(pbpctl_dev, BYPASS_STATE_PWROFF); @@ -2775,7 +2775,7 @@ int bypass_state_pwroff(bpctl_dev_t * pbpctl_dev) } /* NORMAL_STATE_PWROFF 0x29*/ -int normal_state_pwroff(bpctl_dev_t * pbpctl_dev) +int normal_state_pwroff(bpctl_dev_t *pbpctl_dev) { if ((pbpctl_dev->bp_caps & BP_PWOFF_CTL_CAP)) { write_data(pbpctl_dev, NORMAL_STATE_PWROFF); @@ -2786,7 +2786,7 @@ int normal_state_pwroff(bpctl_dev_t * pbpctl_dev) } /*TAP_STATE_PWRON 0x2a*/ -int tap_state_pwron(bpctl_dev_t * pbpctl_dev) +int tap_state_pwron(bpctl_dev_t *pbpctl_dev) { if (pbpctl_dev->bp_caps & TAP_PWUP_CTL_CAP) { write_data(pbpctl_dev, TAP_STATE_PWRON); @@ -2797,7 +2797,7 @@ int tap_state_pwron(bpctl_dev_t * pbpctl_dev) } /*DIS_TAP_CAP 0x2c*/ -int dis_tap_cap(bpctl_dev_t * pbpctl_dev) +int dis_tap_cap(bpctl_dev_t *pbpctl_dev) { if (pbpctl_dev->bp_caps & TAP_DIS_CAP) { write_data(pbpctl_dev, DIS_TAP_CAP); @@ -2808,7 +2808,7 @@ int dis_tap_cap(bpctl_dev_t * pbpctl_dev) } /*EN_TAP_CAP 0x2e*/ -int en_tap_cap(bpctl_dev_t * pbpctl_dev) +int en_tap_cap(bpctl_dev_t *pbpctl_dev) { if (pbpctl_dev->bp_caps & TAP_DIS_CAP) { write_data(pbpctl_dev, EN_TAP_CAP); @@ -2819,7 +2819,7 @@ int en_tap_cap(bpctl_dev_t * pbpctl_dev) } /*DISC_STATE_PWRON 0x2a*/ -int disc_state_pwron(bpctl_dev_t * pbpctl_dev) +int disc_state_pwron(bpctl_dev_t *pbpctl_dev) { if (pbpctl_dev->bp_caps & DISC_PWUP_CTL_CAP) { if (pbpctl_dev->bp_ext_ver >= 0x8) { @@ -2832,7 +2832,7 @@ int disc_state_pwron(bpctl_dev_t * pbpctl_dev) } /*DIS_DISC_CAP 0x2c*/ -int dis_disc_cap(bpctl_dev_t * pbpctl_dev) +int dis_disc_cap(bpctl_dev_t *pbpctl_dev) { if (pbpctl_dev->bp_caps & DISC_DIS_CAP) { if (pbpctl_dev->bp_ext_ver >= 0x8) { @@ -2845,7 +2845,7 @@ int dis_disc_cap(bpctl_dev_t * pbpctl_dev) } /*DISC_STATE_PWRON 0x2a*/ -int disc_port_state_pwron(bpctl_dev_t * pbpctl_dev) +int disc_port_state_pwron(bpctl_dev_t *pbpctl_dev) { int ret = 0; bpctl_dev_t *pbpctl_dev_m; @@ -2871,7 +2871,7 @@ int disc_port_state_pwron(bpctl_dev_t * pbpctl_dev) return ret; } -int normal_port_state_pwron(bpctl_dev_t * pbpctl_dev) +int normal_port_state_pwron(bpctl_dev_t *pbpctl_dev) { int ret = 0; bpctl_dev_t *pbpctl_dev_m; @@ -2897,7 +2897,7 @@ int normal_port_state_pwron(bpctl_dev_t * pbpctl_dev) } /*EN_TAP_CAP 0x2e*/ -int en_disc_cap(bpctl_dev_t * pbpctl_dev) +int en_disc_cap(bpctl_dev_t *pbpctl_dev) { if (pbpctl_dev->bp_caps & DISC_DIS_CAP) { if (pbpctl_dev->bp_ext_ver >= 0x8) { @@ -2909,7 +2909,7 @@ int en_disc_cap(bpctl_dev_t * pbpctl_dev) return BP_NOT_CAP; } -int std_nic_on(bpctl_dev_t * pbpctl_dev) +int std_nic_on(bpctl_dev_t *pbpctl_dev) { if (pbpctl_dev->bp_caps & STD_NIC_CAP) { @@ -2963,7 +2963,7 @@ int std_nic_on(bpctl_dev_t * pbpctl_dev) return BP_NOT_CAP; } -int std_nic_off(bpctl_dev_t * pbpctl_dev) +int std_nic_off(bpctl_dev_t *pbpctl_dev) { if (pbpctl_dev->bp_caps & STD_NIC_CAP) { @@ -3015,7 +3015,7 @@ int std_nic_off(bpctl_dev_t * pbpctl_dev) return BP_NOT_CAP; } -int wdt_time_left(bpctl_dev_t * pbpctl_dev) +int wdt_time_left(bpctl_dev_t *pbpctl_dev) { //unsigned long curr_time=((long long)(jiffies*1000))/HZ, delta_time=0,wdt_on_time=((long long)(pbpctl_dev->bypass_wdt_on_time*1000))/HZ; @@ -3047,7 +3047,7 @@ int wdt_time_left(bpctl_dev_t * pbpctl_dev) return time_left; } -static int wdt_timer(bpctl_dev_t * pbpctl_dev, int *time_left) +static int wdt_timer(bpctl_dev_t *pbpctl_dev, int *time_left) { int ret = 0; if (pbpctl_dev->bp_caps & WD_CTL_CAP) { @@ -3063,7 +3063,7 @@ static int wdt_timer(bpctl_dev_t * pbpctl_dev, int *time_left) return ret; } -static int wdt_timer_reload(bpctl_dev_t * pbpctl_dev) +static int wdt_timer_reload(bpctl_dev_t *pbpctl_dev) { int ret = 0; @@ -3127,7 +3127,7 @@ static void wd_reset_timer(unsigned long param) //#ifdef PMC_FIX_FLAG /*WAIT_AT_PWRUP 0x80 */ -int bp_wait_at_pwup_en(bpctl_dev_t * pbpctl_dev) +int bp_wait_at_pwup_en(bpctl_dev_t *pbpctl_dev) { if (pbpctl_dev->bp_caps & SW_CTL_CAP) { @@ -3142,7 +3142,7 @@ int bp_wait_at_pwup_en(bpctl_dev_t * pbpctl_dev) } /*DIS_WAIT_AT_PWRUP 0x81 */ -int bp_wait_at_pwup_dis(bpctl_dev_t * pbpctl_dev) +int bp_wait_at_pwup_dis(bpctl_dev_t *pbpctl_dev) { if (pbpctl_dev->bp_caps & SW_CTL_CAP) { @@ -3159,7 +3159,7 @@ int bp_wait_at_pwup_dis(bpctl_dev_t * pbpctl_dev) /*EN_HW_RESET 0x82 */ -int bp_hw_reset_en(bpctl_dev_t * pbpctl_dev) +int bp_hw_reset_en(bpctl_dev_t *pbpctl_dev) { if (pbpctl_dev->bp_caps & SW_CTL_CAP) { @@ -3175,7 +3175,7 @@ int bp_hw_reset_en(bpctl_dev_t * pbpctl_dev) /*DIS_HW_RESET 0x83 */ -int bp_hw_reset_dis(bpctl_dev_t * pbpctl_dev) +int bp_hw_reset_dis(bpctl_dev_t *pbpctl_dev) { if (pbpctl_dev->bp_caps & SW_CTL_CAP) { @@ -3191,7 +3191,7 @@ int bp_hw_reset_dis(bpctl_dev_t * pbpctl_dev) //#endif /*PMC_FIX_FLAG*/ -int wdt_exp_mode(bpctl_dev_t * pbpctl_dev, int mode) +int wdt_exp_mode(bpctl_dev_t *pbpctl_dev, int mode) { uint32_t status_reg = 0, status_reg1 = 0; @@ -3242,7 +3242,7 @@ int wdt_exp_mode(bpctl_dev_t * pbpctl_dev, int mode) return BP_NOT_CAP; } -int bypass_fw_ver(bpctl_dev_t * pbpctl_dev) +int bypass_fw_ver(bpctl_dev_t *pbpctl_dev) { if (is_bypass_fn(pbpctl_dev)) return ((read_reg(pbpctl_dev, VER_REG_ADDR))); @@ -3250,7 +3250,7 @@ int bypass_fw_ver(bpctl_dev_t * pbpctl_dev) return BP_NOT_CAP; } -int bypass_sign_check(bpctl_dev_t * pbpctl_dev) +int bypass_sign_check(bpctl_dev_t *pbpctl_dev) { if (is_bypass_fn(pbpctl_dev)) @@ -3260,7 +3260,7 @@ int bypass_sign_check(bpctl_dev_t * pbpctl_dev) return BP_NOT_CAP; } -static int tx_status(bpctl_dev_t * pbpctl_dev) +static int tx_status(bpctl_dev_t *pbpctl_dev) { uint32_t ctrl = 0; bpctl_dev_t *pbpctl_dev_m; @@ -3347,7 +3347,7 @@ static int tx_status(bpctl_dev_t * pbpctl_dev) return BP_NOT_CAP; } -static int bp_force_link_status(bpctl_dev_t * pbpctl_dev) +static int bp_force_link_status(bpctl_dev_t *pbpctl_dev) { if (DBI_IF_SERIES(pbpctl_dev->subdevice)) { @@ -3361,7 +3361,7 @@ static int bp_force_link_status(bpctl_dev_t * pbpctl_dev) return BP_NOT_CAP; } -int bypass_from_last_read(bpctl_dev_t * pbpctl_dev) +int bypass_from_last_read(bpctl_dev_t *pbpctl_dev) { uint32_t ctrl_ext = 0; bpctl_dev_t *pbpctl_dev_b = NULL; -- cgit v0.10.2 From 0920af72a7db5dfcddc80474f49c6074643b230d Mon Sep 17 00:00:00 2001 From: Daniel Cotey Date: Sat, 15 Sep 2012 06:11:41 -0700 Subject: Staging: silicom: checkpatch.pl cleanup: pretty pointers more checkpatch cleanups of pointers. Signed-off-by: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/bp_mod.c b/drivers/staging/silicom/bp_mod.c index 50bb5d3..ef844c7 100644 --- a/drivers/staging/silicom/bp_mod.c +++ b/drivers/staging/silicom/bp_mod.c @@ -3379,7 +3379,7 @@ int bypass_from_last_read(bpctl_dev_t *pbpctl_dev) return BP_NOT_CAP; } -int bypass_status_clear(bpctl_dev_t * pbpctl_dev) +int bypass_status_clear(bpctl_dev_t *pbpctl_dev) { bpctl_dev_t *pbpctl_dev_b = NULL; @@ -3392,7 +3392,7 @@ int bypass_status_clear(bpctl_dev_t * pbpctl_dev) return BP_NOT_CAP; } -int bypass_flag_status(bpctl_dev_t * pbpctl_dev) +int bypass_flag_status(bpctl_dev_t *pbpctl_dev) { if ((pbpctl_dev->bp_caps & BP_CAP)) { @@ -3405,7 +3405,7 @@ int bypass_flag_status(bpctl_dev_t * pbpctl_dev) return BP_NOT_CAP; } -int bypass_flag_status_clear(bpctl_dev_t * pbpctl_dev) +int bypass_flag_status_clear(bpctl_dev_t *pbpctl_dev) { if (pbpctl_dev->bp_caps & BP_CAP) { @@ -3420,7 +3420,7 @@ int bypass_flag_status_clear(bpctl_dev_t * pbpctl_dev) return BP_NOT_CAP; } -int bypass_change_status(bpctl_dev_t * pbpctl_dev) +int bypass_change_status(bpctl_dev_t *pbpctl_dev) { int ret = BP_NOT_CAP; @@ -3439,7 +3439,7 @@ int bypass_change_status(bpctl_dev_t * pbpctl_dev) return ret; } -int bypass_off_status(bpctl_dev_t * pbpctl_dev) +int bypass_off_status(bpctl_dev_t *pbpctl_dev) { if (pbpctl_dev->bp_caps & BP_CAP) { @@ -3451,7 +3451,7 @@ int bypass_off_status(bpctl_dev_t * pbpctl_dev) return BP_NOT_CAP; } -static int bypass_status(bpctl_dev_t * pbpctl_dev) +static int bypass_status(bpctl_dev_t *pbpctl_dev) { u32 ctrl_ext = 0; if (pbpctl_dev->bp_caps & BP_CAP) { @@ -3536,7 +3536,7 @@ static int bypass_status(bpctl_dev_t * pbpctl_dev) return BP_NOT_CAP; } -int default_pwron_status(bpctl_dev_t * pbpctl_dev) +int default_pwron_status(bpctl_dev_t *pbpctl_dev) { if (pbpctl_dev->bp_caps & SW_CTL_CAP) { @@ -3554,7 +3554,7 @@ int default_pwron_status(bpctl_dev_t * pbpctl_dev) return BP_NOT_CAP; } -static int default_pwroff_status(bpctl_dev_t * pbpctl_dev) +static int default_pwroff_status(bpctl_dev_t *pbpctl_dev) { /*if ((!pbpctl_dev->bp_caps&BP_DIS_CAP)&& @@ -3568,7 +3568,7 @@ static int default_pwroff_status(bpctl_dev_t * pbpctl_dev) return BP_NOT_CAP; } -int dis_bypass_cap_status(bpctl_dev_t * pbpctl_dev) +int dis_bypass_cap_status(bpctl_dev_t *pbpctl_dev) { if (pbpctl_dev->bp_caps & BP_DIS_CAP) { @@ -3581,7 +3581,7 @@ int dis_bypass_cap_status(bpctl_dev_t * pbpctl_dev) return BP_NOT_CAP; } -int cmd_en_status(bpctl_dev_t * pbpctl_dev) +int cmd_en_status(bpctl_dev_t *pbpctl_dev) { if (pbpctl_dev->bp_caps & SW_CTL_CAP) { @@ -3593,7 +3593,7 @@ int cmd_en_status(bpctl_dev_t * pbpctl_dev) return BP_NOT_CAP; } -int wdt_en_status(bpctl_dev_t * pbpctl_dev) +int wdt_en_status(bpctl_dev_t *pbpctl_dev) { if (pbpctl_dev->bp_caps & WD_CTL_CAP) { @@ -3605,7 +3605,7 @@ int wdt_en_status(bpctl_dev_t * pbpctl_dev) return BP_NOT_CAP; } -int wdt_programmed(bpctl_dev_t * pbpctl_dev, int *timeout) +int wdt_programmed(bpctl_dev_t *pbpctl_dev, int *timeout) { int ret = 0; if (pbpctl_dev->bp_caps & WD_CTL_CAP) { @@ -3631,7 +3631,7 @@ int wdt_programmed(bpctl_dev_t * pbpctl_dev, int *timeout) return ret; } -int bypass_support(bpctl_dev_t * pbpctl_dev) +int bypass_support(bpctl_dev_t *pbpctl_dev) { int ret = 0; @@ -3648,7 +3648,7 @@ int bypass_support(bpctl_dev_t * pbpctl_dev) return ret; } -int tap_support(bpctl_dev_t * pbpctl_dev) +int tap_support(bpctl_dev_t *pbpctl_dev) { int ret = 0; @@ -3664,7 +3664,7 @@ int tap_support(bpctl_dev_t * pbpctl_dev) return ret; } -int normal_support(bpctl_dev_t * pbpctl_dev) +int normal_support(bpctl_dev_t *pbpctl_dev) { int ret = BP_NOT_CAP; @@ -3680,7 +3680,7 @@ int normal_support(bpctl_dev_t * pbpctl_dev) return ret; } -int get_bp_prod_caps(bpctl_dev_t * pbpctl_dev) +int get_bp_prod_caps(bpctl_dev_t *pbpctl_dev) { if ((pbpctl_dev->bp_caps & SW_CTL_CAP) && (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER)) @@ -3689,7 +3689,7 @@ int get_bp_prod_caps(bpctl_dev_t * pbpctl_dev) } -int tap_flag_status(bpctl_dev_t * pbpctl_dev) +int tap_flag_status(bpctl_dev_t *pbpctl_dev) { if (pbpctl_dev->bp_caps & TAP_STATUS_CAP) { @@ -3701,7 +3701,7 @@ int tap_flag_status(bpctl_dev_t * pbpctl_dev) return BP_NOT_CAP; } -int tap_flag_status_clear(bpctl_dev_t * pbpctl_dev) +int tap_flag_status_clear(bpctl_dev_t *pbpctl_dev) { uint32_t status_reg = 0; if (pbpctl_dev->bp_caps & TAP_STATUS_CAP) { @@ -3715,7 +3715,7 @@ int tap_flag_status_clear(bpctl_dev_t * pbpctl_dev) return BP_NOT_CAP; } -int tap_change_status(bpctl_dev_t * pbpctl_dev) +int tap_change_status(bpctl_dev_t *pbpctl_dev) { int ret = BP_NOT_CAP; if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) { @@ -3732,7 +3732,7 @@ int tap_change_status(bpctl_dev_t * pbpctl_dev) return ret; } -int tap_off_status(bpctl_dev_t * pbpctl_dev) +int tap_off_status(bpctl_dev_t *pbpctl_dev) { if (pbpctl_dev->bp_caps & TAP_CAP) { if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) @@ -3742,7 +3742,7 @@ int tap_off_status(bpctl_dev_t * pbpctl_dev) return BP_NOT_CAP; } -int tap_status(bpctl_dev_t * pbpctl_dev) +int tap_status(bpctl_dev_t *pbpctl_dev) { u32 ctrl_ext = 0; @@ -3781,7 +3781,7 @@ int tap_status(bpctl_dev_t * pbpctl_dev) return BP_NOT_CAP; } -int default_pwron_tap_status(bpctl_dev_t * pbpctl_dev) +int default_pwron_tap_status(bpctl_dev_t *pbpctl_dev) { if (pbpctl_dev->bp_caps & TAP_PWUP_CTL_CAP) { if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) @@ -3792,7 +3792,7 @@ int default_pwron_tap_status(bpctl_dev_t * pbpctl_dev) return BP_NOT_CAP; } -int dis_tap_cap_status(bpctl_dev_t * pbpctl_dev) +int dis_tap_cap_status(bpctl_dev_t *pbpctl_dev) { if (pbpctl_dev->bp_caps & TAP_PWUP_CTL_CAP) { if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) @@ -3803,7 +3803,7 @@ int dis_tap_cap_status(bpctl_dev_t * pbpctl_dev) return BP_NOT_CAP; } -int disc_flag_status(bpctl_dev_t * pbpctl_dev) +int disc_flag_status(bpctl_dev_t *pbpctl_dev) { if (pbpctl_dev->bp_caps & DISC_CAP) { @@ -3815,7 +3815,7 @@ int disc_flag_status(bpctl_dev_t * pbpctl_dev) return BP_NOT_CAP; } -int disc_flag_status_clear(bpctl_dev_t * pbpctl_dev) +int disc_flag_status_clear(bpctl_dev_t *pbpctl_dev) { uint32_t status_reg = 0; if (pbpctl_dev->bp_caps & DISC_CAP) { @@ -3829,7 +3829,7 @@ int disc_flag_status_clear(bpctl_dev_t * pbpctl_dev) return BP_NOT_CAP; } -int disc_change_status(bpctl_dev_t * pbpctl_dev) +int disc_change_status(bpctl_dev_t *pbpctl_dev) { int ret = BP_NOT_CAP; if (pbpctl_dev->bp_caps & DISC_CAP) { @@ -3840,7 +3840,7 @@ int disc_change_status(bpctl_dev_t * pbpctl_dev) return BP_NOT_CAP; } -int disc_off_status(bpctl_dev_t * pbpctl_dev) +int disc_off_status(bpctl_dev_t *pbpctl_dev) { bpctl_dev_t *pbpctl_dev_b = NULL; u32 ctrl_ext = 0; @@ -3930,7 +3930,7 @@ int disc_off_status(bpctl_dev_t * pbpctl_dev) return BP_NOT_CAP; } -static int disc_status(bpctl_dev_t * pbpctl_dev) +static int disc_status(bpctl_dev_t *pbpctl_dev) { int ctrl = 0; if (pbpctl_dev->bp_caps & DISC_CAP) { @@ -3943,7 +3943,7 @@ static int disc_status(bpctl_dev_t * pbpctl_dev) return BP_NOT_CAP; } -int default_pwron_disc_status(bpctl_dev_t * pbpctl_dev) +int default_pwron_disc_status(bpctl_dev_t *pbpctl_dev) { if (pbpctl_dev->bp_caps & DISC_PWUP_CTL_CAP) { if (pbpctl_dev->bp_ext_ver >= 0x8) @@ -3954,7 +3954,7 @@ int default_pwron_disc_status(bpctl_dev_t * pbpctl_dev) return BP_NOT_CAP; } -int dis_disc_cap_status(bpctl_dev_t * pbpctl_dev) +int dis_disc_cap_status(bpctl_dev_t *pbpctl_dev) { if (pbpctl_dev->bp_caps & DIS_DISC_CAP) { if (pbpctl_dev->bp_ext_ver >= 0x8) @@ -3965,7 +3965,7 @@ int dis_disc_cap_status(bpctl_dev_t * pbpctl_dev) return BP_NOT_CAP; } -int disc_port_status(bpctl_dev_t * pbpctl_dev) +int disc_port_status(bpctl_dev_t *pbpctl_dev) { int ret = BP_NOT_CAP; bpctl_dev_t *pbpctl_dev_m; @@ -3989,7 +3989,7 @@ int disc_port_status(bpctl_dev_t * pbpctl_dev) return ret; } -int default_pwron_disc_port_status(bpctl_dev_t * pbpctl_dev) +int default_pwron_disc_port_status(bpctl_dev_t *pbpctl_dev) { int ret = BP_NOT_CAP; bpctl_dev_t *pbpctl_dev_m; @@ -4013,7 +4013,7 @@ int default_pwron_disc_port_status(bpctl_dev_t * pbpctl_dev) return ret; } -int wdt_exp_mode_status(bpctl_dev_t * pbpctl_dev) +int wdt_exp_mode_status(bpctl_dev_t *pbpctl_dev) { if (pbpctl_dev->bp_caps & WD_CTL_CAP) { if (pbpctl_dev->bp_ext_ver <= PXG2BPI_VER) -- cgit v0.10.2 From 9f7a6f33e0d6462f4ae149a4cae4faed9501e80b Mon Sep 17 00:00:00 2001 From: Daniel Cotey Date: Sat, 15 Sep 2012 06:12:05 -0700 Subject: Staging: silicom: checkpatch.pl cleanup: pretty pointers pointer style cleanup Signed-off-by: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/bp_mod.c b/drivers/staging/silicom/bp_mod.c index ef844c7..0f8d2ea 100644 --- a/drivers/staging/silicom/bp_mod.c +++ b/drivers/staging/silicom/bp_mod.c @@ -4036,7 +4036,7 @@ int wdt_exp_mode_status(bpctl_dev_t *pbpctl_dev) return BP_NOT_CAP; } -int tpl2_flag_status(bpctl_dev_t * pbpctl_dev) +int tpl2_flag_status(bpctl_dev_t *pbpctl_dev) { if (pbpctl_dev->bp_caps_ex & TPL2_CAP_EX) { @@ -4047,7 +4047,7 @@ int tpl2_flag_status(bpctl_dev_t * pbpctl_dev) return BP_NOT_CAP; } -int tpl_hw_status(bpctl_dev_t * pbpctl_dev) +int tpl_hw_status(bpctl_dev_t *pbpctl_dev) { bpctl_dev_t *pbpctl_dev_b = NULL; @@ -4062,7 +4062,7 @@ int tpl_hw_status(bpctl_dev_t * pbpctl_dev) //#ifdef PMC_FIX_FLAG -int bp_wait_at_pwup_status(bpctl_dev_t * pbpctl_dev) +int bp_wait_at_pwup_status(bpctl_dev_t *pbpctl_dev) { if (pbpctl_dev->bp_caps & SW_CTL_CAP) { if (pbpctl_dev->bp_ext_ver >= 0x8) @@ -4073,7 +4073,7 @@ int bp_wait_at_pwup_status(bpctl_dev_t * pbpctl_dev) return BP_NOT_CAP; } -int bp_hw_reset_status(bpctl_dev_t * pbpctl_dev) +int bp_hw_reset_status(bpctl_dev_t *pbpctl_dev) { if (pbpctl_dev->bp_caps & SW_CTL_CAP) { @@ -4088,7 +4088,7 @@ int bp_hw_reset_status(bpctl_dev_t * pbpctl_dev) //#endif /*PMC_FIX_FLAG*/ -int std_nic_status(bpctl_dev_t * pbpctl_dev) +int std_nic_status(bpctl_dev_t *pbpctl_dev) { int status_val = 0; @@ -4136,7 +4136,7 @@ int std_nic_status(bpctl_dev_t * pbpctl_dev) /******************************************************/ /**************SW_INIT*********************************/ /******************************************************/ -void bypass_caps_init(bpctl_dev_t * pbpctl_dev) +void bypass_caps_init(bpctl_dev_t *pbpctl_dev) { u_int32_t ctrl_ext = 0; bpctl_dev_t *pbpctl_dev_m = NULL; @@ -4359,7 +4359,7 @@ void bypass_caps_init(bpctl_dev_t * pbpctl_dev) } } -int bypass_off_init(bpctl_dev_t * pbpctl_dev) +int bypass_off_init(bpctl_dev_t *pbpctl_dev) { int ret = 0; @@ -4376,7 +4376,7 @@ int bypass_off_init(bpctl_dev_t * pbpctl_dev) return 0; } -void remove_bypass_wd_auto(bpctl_dev_t * pbpctl_dev) +void remove_bypass_wd_auto(bpctl_dev_t *pbpctl_dev) { #ifdef BP_SELF_TEST bpctl_dev_t *pbpctl_dev_sl = NULL; @@ -4417,7 +4417,7 @@ void remove_bypass_wd_auto(bpctl_dev_t * pbpctl_dev) } -int init_bypass_wd_auto(bpctl_dev_t * pbpctl_dev) +int init_bypass_wd_auto(bpctl_dev_t *pbpctl_dev) { if (pbpctl_dev->bp_caps & WD_CTL_CAP) { init_timer(&pbpctl_dev->bp_timer); @@ -4464,7 +4464,7 @@ int bp_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) } #endif -int set_bypass_wd_auto(bpctl_dev_t * pbpctl_dev, unsigned int param) +int set_bypass_wd_auto(bpctl_dev_t *pbpctl_dev, unsigned int param) { if (pbpctl_dev->bp_caps & WD_CTL_CAP) { if (pbpctl_dev->reset_time != param) { @@ -4483,7 +4483,7 @@ int set_bypass_wd_auto(bpctl_dev_t * pbpctl_dev, unsigned int param) return BP_NOT_CAP; } -int get_bypass_wd_auto(bpctl_dev_t * pbpctl_dev) +int get_bypass_wd_auto(bpctl_dev_t *pbpctl_dev) { if (pbpctl_dev->bp_caps & WD_CTL_CAP) { @@ -4494,7 +4494,7 @@ int get_bypass_wd_auto(bpctl_dev_t * pbpctl_dev) #ifdef BP_SELF_TEST -int set_bp_self_test(bpctl_dev_t * pbpctl_dev, unsigned int param) +int set_bp_self_test(bpctl_dev_t *pbpctl_dev, unsigned int param) { bpctl_dev_t *pbpctl_dev_sl = NULL; @@ -4546,7 +4546,7 @@ int set_bp_self_test(bpctl_dev_t * pbpctl_dev, unsigned int param) return BP_NOT_CAP; } -int get_bp_self_test(bpctl_dev_t * pbpctl_dev) +int get_bp_self_test(bpctl_dev_t *pbpctl_dev) { if (pbpctl_dev->bp_caps & WD_CTL_CAP) { @@ -4564,7 +4564,7 @@ int get_bp_self_test(bpctl_dev_t * pbpctl_dev) /************************* API ********************************/ /**************************************************************/ -int is_bypass_fn(bpctl_dev_t * pbpctl_dev) +int is_bypass_fn(bpctl_dev_t *pbpctl_dev) { if (!pbpctl_dev) return -1; @@ -4572,7 +4572,7 @@ int is_bypass_fn(bpctl_dev_t * pbpctl_dev) return (((pbpctl_dev->func == 0) || (pbpctl_dev->func == 2)) ? 1 : 0); } -int set_bypass_fn(bpctl_dev_t * pbpctl_dev, int bypass_mode) +int set_bypass_fn(bpctl_dev_t *pbpctl_dev, int bypass_mode) { int ret = 0; @@ -4589,12 +4589,12 @@ int set_bypass_fn(bpctl_dev_t * pbpctl_dev, int bypass_mode) return ret; } -int get_bypass_fn(bpctl_dev_t * pbpctl_dev) +int get_bypass_fn(bpctl_dev_t *pbpctl_dev) { return (bypass_status(pbpctl_dev)); } -int get_bypass_change_fn(bpctl_dev_t * pbpctl_dev) +int get_bypass_change_fn(bpctl_dev_t *pbpctl_dev) { if (!pbpctl_dev) return -1; @@ -4602,7 +4602,7 @@ int get_bypass_change_fn(bpctl_dev_t * pbpctl_dev) return (bypass_change_status(pbpctl_dev)); } -int set_dis_bypass_fn(bpctl_dev_t * pbpctl_dev, int dis_param) +int set_dis_bypass_fn(bpctl_dev_t *pbpctl_dev, int dis_param) { int ret = 0; if (!pbpctl_dev) @@ -4620,7 +4620,7 @@ int set_dis_bypass_fn(bpctl_dev_t * pbpctl_dev, int dis_param) return ret; } -int get_dis_bypass_fn(bpctl_dev_t * pbpctl_dev) +int get_dis_bypass_fn(bpctl_dev_t *pbpctl_dev) { if (!pbpctl_dev) return -1; @@ -4628,7 +4628,7 @@ int get_dis_bypass_fn(bpctl_dev_t * pbpctl_dev) return (dis_bypass_cap_status(pbpctl_dev)); } -int set_bypass_pwoff_fn(bpctl_dev_t * pbpctl_dev, int bypass_mode) +int set_bypass_pwoff_fn(bpctl_dev_t *pbpctl_dev, int bypass_mode) { int ret = 0; if (!pbpctl_dev) @@ -4646,7 +4646,7 @@ int set_bypass_pwoff_fn(bpctl_dev_t * pbpctl_dev, int bypass_mode) return ret; } -int get_bypass_pwoff_fn(bpctl_dev_t * pbpctl_dev) +int get_bypass_pwoff_fn(bpctl_dev_t *pbpctl_dev) { if (!pbpctl_dev) return -1; @@ -4654,7 +4654,7 @@ int get_bypass_pwoff_fn(bpctl_dev_t * pbpctl_dev) return (default_pwroff_status(pbpctl_dev)); } -int set_bypass_pwup_fn(bpctl_dev_t * pbpctl_dev, int bypass_mode) +int set_bypass_pwup_fn(bpctl_dev_t *pbpctl_dev, int bypass_mode) { int ret = 0; if (!pbpctl_dev) @@ -4672,7 +4672,7 @@ int set_bypass_pwup_fn(bpctl_dev_t * pbpctl_dev, int bypass_mode) return ret; } -int get_bypass_pwup_fn(bpctl_dev_t * pbpctl_dev) +int get_bypass_pwup_fn(bpctl_dev_t *pbpctl_dev) { if (!pbpctl_dev) return -1; @@ -4680,7 +4680,7 @@ int get_bypass_pwup_fn(bpctl_dev_t * pbpctl_dev) return (default_pwron_status(pbpctl_dev)); } -int set_bypass_wd_fn(bpctl_dev_t * pbpctl_dev, int timeout) +int set_bypass_wd_fn(bpctl_dev_t *pbpctl_dev, int timeout) { int ret = 0; if (!pbpctl_dev) @@ -4701,7 +4701,7 @@ int set_bypass_wd_fn(bpctl_dev_t * pbpctl_dev, int timeout) return ret; } -int get_bypass_wd_fn(bpctl_dev_t * pbpctl_dev, int *timeout) +int get_bypass_wd_fn(bpctl_dev_t *pbpctl_dev, int *timeout) { if (!pbpctl_dev) return -1; @@ -4709,7 +4709,7 @@ int get_bypass_wd_fn(bpctl_dev_t * pbpctl_dev, int *timeout) return wdt_programmed(pbpctl_dev, timeout); } -int get_wd_expire_time_fn(bpctl_dev_t * pbpctl_dev, int *time_left) +int get_wd_expire_time_fn(bpctl_dev_t *pbpctl_dev, int *time_left) { if (!pbpctl_dev) return -1; @@ -4717,7 +4717,7 @@ int get_wd_expire_time_fn(bpctl_dev_t * pbpctl_dev, int *time_left) return (wdt_timer(pbpctl_dev, time_left)); } -int reset_bypass_wd_timer_fn(bpctl_dev_t * pbpctl_dev) +int reset_bypass_wd_timer_fn(bpctl_dev_t *pbpctl_dev) { if (!pbpctl_dev) return -1; @@ -4725,7 +4725,7 @@ int reset_bypass_wd_timer_fn(bpctl_dev_t * pbpctl_dev) return (wdt_timer_reload(pbpctl_dev)); } -int get_wd_set_caps_fn(bpctl_dev_t * pbpctl_dev) +int get_wd_set_caps_fn(bpctl_dev_t *pbpctl_dev) { int bp_status = 0; @@ -4749,7 +4749,7 @@ int get_wd_set_caps_fn(bpctl_dev_t * pbpctl_dev) return bp_status; } -int set_std_nic_fn(bpctl_dev_t * pbpctl_dev, int nic_mode) +int set_std_nic_fn(bpctl_dev_t *pbpctl_dev, int nic_mode) { int ret = 0; if (!pbpctl_dev) @@ -4768,7 +4768,7 @@ int set_std_nic_fn(bpctl_dev_t * pbpctl_dev, int nic_mode) return ret; } -int get_std_nic_fn(bpctl_dev_t * pbpctl_dev) +int get_std_nic_fn(bpctl_dev_t *pbpctl_dev) { if (!pbpctl_dev) return -1; @@ -4776,7 +4776,7 @@ int get_std_nic_fn(bpctl_dev_t * pbpctl_dev) return (std_nic_status(pbpctl_dev)); } -int set_tap_fn(bpctl_dev_t * pbpctl_dev, int tap_mode) +int set_tap_fn(bpctl_dev_t *pbpctl_dev, int tap_mode) { if (!pbpctl_dev) return -1; @@ -4792,7 +4792,7 @@ int set_tap_fn(bpctl_dev_t * pbpctl_dev, int tap_mode) return BP_NOT_CAP; } -int get_tap_fn(bpctl_dev_t * pbpctl_dev) +int get_tap_fn(bpctl_dev_t *pbpctl_dev) { if (!pbpctl_dev) return -1; @@ -4800,7 +4800,7 @@ int get_tap_fn(bpctl_dev_t * pbpctl_dev) return (tap_status(pbpctl_dev)); } -int set_tap_pwup_fn(bpctl_dev_t * pbpctl_dev, int tap_mode) +int set_tap_pwup_fn(bpctl_dev_t *pbpctl_dev, int tap_mode) { int ret = 0; if (!pbpctl_dev) @@ -4818,7 +4818,7 @@ int set_tap_pwup_fn(bpctl_dev_t * pbpctl_dev, int tap_mode) return ret; } -int get_tap_pwup_fn(bpctl_dev_t * pbpctl_dev) +int get_tap_pwup_fn(bpctl_dev_t *pbpctl_dev) { int ret = 0; if (!pbpctl_dev) @@ -4829,7 +4829,7 @@ int get_tap_pwup_fn(bpctl_dev_t * pbpctl_dev) return ((ret == 0) ? 1 : 0); } -int get_tap_change_fn(bpctl_dev_t * pbpctl_dev) +int get_tap_change_fn(bpctl_dev_t *pbpctl_dev) { if (!pbpctl_dev) return -1; @@ -4837,7 +4837,7 @@ int get_tap_change_fn(bpctl_dev_t * pbpctl_dev) return (tap_change_status(pbpctl_dev)); } -int set_dis_tap_fn(bpctl_dev_t * pbpctl_dev, int dis_param) +int set_dis_tap_fn(bpctl_dev_t *pbpctl_dev, int dis_param) { int ret = 0; if (!pbpctl_dev) @@ -4854,7 +4854,7 @@ int set_dis_tap_fn(bpctl_dev_t * pbpctl_dev, int dis_param) return BP_NOT_CAP; } -int get_dis_tap_fn(bpctl_dev_t * pbpctl_dev) +int get_dis_tap_fn(bpctl_dev_t *pbpctl_dev) { if (!pbpctl_dev) return -1; @@ -4862,7 +4862,7 @@ int get_dis_tap_fn(bpctl_dev_t * pbpctl_dev) return (dis_tap_cap_status(pbpctl_dev)); } -int set_disc_fn(bpctl_dev_t * pbpctl_dev, int disc_mode) +int set_disc_fn(bpctl_dev_t *pbpctl_dev, int disc_mode) { if (!pbpctl_dev) return -1; @@ -4879,7 +4879,7 @@ int set_disc_fn(bpctl_dev_t * pbpctl_dev, int disc_mode) return BP_NOT_CAP; } -int get_disc_fn(bpctl_dev_t * pbpctl_dev) +int get_disc_fn(bpctl_dev_t *pbpctl_dev) { int ret = 0; if (!pbpctl_dev) @@ -4890,7 +4890,7 @@ int get_disc_fn(bpctl_dev_t * pbpctl_dev) return ret; } -int set_disc_pwup_fn(bpctl_dev_t * pbpctl_dev, int disc_mode) +int set_disc_pwup_fn(bpctl_dev_t *pbpctl_dev, int disc_mode) { int ret = 0; if (!pbpctl_dev) @@ -4908,7 +4908,7 @@ int set_disc_pwup_fn(bpctl_dev_t * pbpctl_dev, int disc_mode) return ret; } -int get_disc_pwup_fn(bpctl_dev_t * pbpctl_dev) +int get_disc_pwup_fn(bpctl_dev_t *pbpctl_dev) { int ret = 0; if (!pbpctl_dev) -- cgit v0.10.2 From 7c014321fda993039875ff3ad961d5c579ce942d Mon Sep 17 00:00:00 2001 From: Daniel Cotey Date: Sat, 15 Sep 2012 06:12:36 -0700 Subject: Staging: silicom: checkpatch.pl cleanup: pretty pointers last of the unstylistic pointers cleaned up Signed-off-by: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/bp_mod.c b/drivers/staging/silicom/bp_mod.c index 0f8d2ea..d1cf246 100644 --- a/drivers/staging/silicom/bp_mod.c +++ b/drivers/staging/silicom/bp_mod.c @@ -4918,7 +4918,7 @@ int get_disc_pwup_fn(bpctl_dev_t *pbpctl_dev) return (ret == 0 ? 1 : (ret < 0 ? BP_NOT_CAP : 0)); } -int get_disc_change_fn(bpctl_dev_t * pbpctl_dev) +int get_disc_change_fn(bpctl_dev_t *pbpctl_dev) { int ret = 0; if (!pbpctl_dev) @@ -4928,7 +4928,7 @@ int get_disc_change_fn(bpctl_dev_t * pbpctl_dev) return ret; } -int set_dis_disc_fn(bpctl_dev_t * pbpctl_dev, int dis_param) +int set_dis_disc_fn(bpctl_dev_t *pbpctl_dev, int dis_param) { int ret = 0; if (!pbpctl_dev) @@ -4946,7 +4946,7 @@ int set_dis_disc_fn(bpctl_dev_t * pbpctl_dev, int dis_param) return BP_NOT_CAP; } -int get_dis_disc_fn(bpctl_dev_t * pbpctl_dev) +int get_dis_disc_fn(bpctl_dev_t *pbpctl_dev) { int ret = 0; if (!pbpctl_dev) @@ -4957,7 +4957,7 @@ int get_dis_disc_fn(bpctl_dev_t * pbpctl_dev) return ret; } -int set_disc_port_fn(bpctl_dev_t * pbpctl_dev, int disc_mode) +int set_disc_port_fn(bpctl_dev_t *pbpctl_dev, int disc_mode) { int ret = BP_NOT_CAP; if (!pbpctl_dev) @@ -4971,7 +4971,7 @@ int set_disc_port_fn(bpctl_dev_t * pbpctl_dev, int disc_mode) return ret; } -int get_disc_port_fn(bpctl_dev_t * pbpctl_dev) +int get_disc_port_fn(bpctl_dev_t *pbpctl_dev) { if (!pbpctl_dev) return -1; @@ -4979,7 +4979,7 @@ int get_disc_port_fn(bpctl_dev_t * pbpctl_dev) return (disc_port_status(pbpctl_dev)); } -int set_disc_port_pwup_fn(bpctl_dev_t * pbpctl_dev, int disc_mode) +int set_disc_port_pwup_fn(bpctl_dev_t *pbpctl_dev, int disc_mode) { int ret = BP_NOT_CAP; if (!pbpctl_dev) @@ -4993,7 +4993,7 @@ int set_disc_port_pwup_fn(bpctl_dev_t * pbpctl_dev, int disc_mode) return ret; } -int get_disc_port_pwup_fn(bpctl_dev_t * pbpctl_dev) +int get_disc_port_pwup_fn(bpctl_dev_t *pbpctl_dev) { int ret = 0; if (!pbpctl_dev) @@ -5004,7 +5004,7 @@ int get_disc_port_pwup_fn(bpctl_dev_t * pbpctl_dev) return ((ret == 0) ? 1 : 0); } -int get_wd_exp_mode_fn(bpctl_dev_t * pbpctl_dev) +int get_wd_exp_mode_fn(bpctl_dev_t *pbpctl_dev) { if (!pbpctl_dev) return -1; @@ -5012,7 +5012,7 @@ int get_wd_exp_mode_fn(bpctl_dev_t * pbpctl_dev) return (wdt_exp_mode_status(pbpctl_dev)); } -int set_wd_exp_mode_fn(bpctl_dev_t * pbpctl_dev, int param) +int set_wd_exp_mode_fn(bpctl_dev_t *pbpctl_dev, int param) { if (!pbpctl_dev) return -1; @@ -5020,7 +5020,7 @@ int set_wd_exp_mode_fn(bpctl_dev_t * pbpctl_dev, int param) return (wdt_exp_mode(pbpctl_dev, param)); } -int reset_cont_fn(bpctl_dev_t * pbpctl_dev) +int reset_cont_fn(bpctl_dev_t *pbpctl_dev) { int ret = 0; if (!pbpctl_dev) @@ -5031,7 +5031,7 @@ int reset_cont_fn(bpctl_dev_t * pbpctl_dev) return (reset_cont(pbpctl_dev)); } -int set_tx_fn(bpctl_dev_t * pbpctl_dev, int tx_state) +int set_tx_fn(bpctl_dev_t *pbpctl_dev, int tx_state) { bpctl_dev_t *pbpctl_dev_b = NULL; @@ -5062,7 +5062,7 @@ int set_bp_force_link_fn(int dev_num, int tx_state) return (set_bp_force_link(bpctl_dev_curr, tx_state)); } -int set_wd_autoreset_fn(bpctl_dev_t * pbpctl_dev, int param) +int set_wd_autoreset_fn(bpctl_dev_t *pbpctl_dev, int param) { if (!pbpctl_dev) return -1; @@ -5070,7 +5070,7 @@ int set_wd_autoreset_fn(bpctl_dev_t * pbpctl_dev, int param) return (set_bypass_wd_auto(pbpctl_dev, param)); } -int get_wd_autoreset_fn(bpctl_dev_t * pbpctl_dev) +int get_wd_autoreset_fn(bpctl_dev_t *pbpctl_dev) { if (!pbpctl_dev) return -1; @@ -5079,7 +5079,7 @@ int get_wd_autoreset_fn(bpctl_dev_t * pbpctl_dev) } #ifdef BP_SELF_TEST -int set_bp_self_test_fn(bpctl_dev_t * pbpctl_dev, int param) +int set_bp_self_test_fn(bpctl_dev_t *pbpctl_dev, int param) { if (!pbpctl_dev) return -1; @@ -5087,7 +5087,7 @@ int set_bp_self_test_fn(bpctl_dev_t * pbpctl_dev, int param) return (set_bp_self_test(pbpctl_dev, param)); } -int get_bp_self_test_fn(bpctl_dev_t * pbpctl_dev) +int get_bp_self_test_fn(bpctl_dev_t *pbpctl_dev) { if (!pbpctl_dev) return -1; @@ -5097,7 +5097,7 @@ int get_bp_self_test_fn(bpctl_dev_t * pbpctl_dev) #endif -int get_bypass_caps_fn(bpctl_dev_t * pbpctl_dev) +int get_bypass_caps_fn(bpctl_dev_t *pbpctl_dev) { if (!pbpctl_dev) return -1; @@ -5106,7 +5106,7 @@ int get_bypass_caps_fn(bpctl_dev_t * pbpctl_dev) } -int get_bypass_slave_fn(bpctl_dev_t * pbpctl_dev, bpctl_dev_t ** pbpctl_dev_out) +int get_bypass_slave_fn(bpctl_dev_t *pbpctl_dev, bpctl_dev_t **pbpctl_dev_out) { int idx_dev = 0; if (!pbpctl_dev) @@ -5138,7 +5138,7 @@ int get_bypass_slave_fn(bpctl_dev_t * pbpctl_dev, bpctl_dev_t ** pbpctl_dev_out) return 0; } -int is_bypass(bpctl_dev_t * pbpctl_dev) +int is_bypass(bpctl_dev_t *pbpctl_dev) { if (!pbpctl_dev) return -1; @@ -5149,7 +5149,7 @@ int is_bypass(bpctl_dev_t * pbpctl_dev) return 0; } -int get_tx_fn(bpctl_dev_t * pbpctl_dev) +int get_tx_fn(bpctl_dev_t *pbpctl_dev) { bpctl_dev_t *pbpctl_dev_b = NULL; if (!pbpctl_dev) @@ -5179,7 +5179,7 @@ int get_bp_force_link_fn(int dev_num) return (bp_force_link_status(bpctl_dev_curr)); } -static int get_bypass_link_status(bpctl_dev_t * pbpctl_dev) +static int get_bypass_link_status(bpctl_dev_t *pbpctl_dev) { if (!pbpctl_dev) return -1; @@ -5233,7 +5233,7 @@ static void bp_tpl_timer_fn(unsigned long param) mod_timer(&pbpctl_dev->bp_tpl_timer, jiffies + BP_LINK_MON_DELAY * HZ); } -void remove_bypass_tpl_auto(bpctl_dev_t * pbpctl_dev) +void remove_bypass_tpl_auto(bpctl_dev_t *pbpctl_dev) { bpctl_dev_t *pbpctl_dev_b = NULL; if (!pbpctl_dev) @@ -5251,7 +5251,7 @@ void remove_bypass_tpl_auto(bpctl_dev_t * pbpctl_dev) return; } -int init_bypass_tpl_auto(bpctl_dev_t * pbpctl_dev) +int init_bypass_tpl_auto(bpctl_dev_t *pbpctl_dev) { if (!pbpctl_dev) return -1; @@ -5264,7 +5264,7 @@ int init_bypass_tpl_auto(bpctl_dev_t * pbpctl_dev) return BP_NOT_CAP; } -int set_bypass_tpl_auto(bpctl_dev_t * pbpctl_dev, unsigned int param) +int set_bypass_tpl_auto(bpctl_dev_t *pbpctl_dev, unsigned int param) { if (!pbpctl_dev) return -1; @@ -5282,7 +5282,7 @@ int set_bypass_tpl_auto(bpctl_dev_t * pbpctl_dev, unsigned int param) return BP_NOT_CAP; } -int get_bypass_tpl_auto(bpctl_dev_t * pbpctl_dev) +int get_bypass_tpl_auto(bpctl_dev_t *pbpctl_dev) { if (!pbpctl_dev) return -1; @@ -5292,7 +5292,7 @@ int get_bypass_tpl_auto(bpctl_dev_t * pbpctl_dev) return BP_NOT_CAP; } -int set_tpl_fn(bpctl_dev_t * pbpctl_dev, int tpl_mode) +int set_tpl_fn(bpctl_dev_t *pbpctl_dev, int tpl_mode) { bpctl_dev_t *pbpctl_dev_b = NULL; @@ -5321,7 +5321,7 @@ int set_tpl_fn(bpctl_dev_t * pbpctl_dev, int tpl_mode) return BP_NOT_CAP; } -int get_tpl_fn(bpctl_dev_t * pbpctl_dev) +int get_tpl_fn(bpctl_dev_t *pbpctl_dev) { int ret = BP_NOT_CAP; if (!pbpctl_dev) @@ -5336,7 +5336,7 @@ int get_tpl_fn(bpctl_dev_t * pbpctl_dev) } //#ifdef PMC_FIX_FLAG -int set_bp_wait_at_pwup_fn(bpctl_dev_t * pbpctl_dev, int tap_mode) +int set_bp_wait_at_pwup_fn(bpctl_dev_t *pbpctl_dev, int tap_mode) { if (!pbpctl_dev) return -1; @@ -5356,7 +5356,7 @@ int set_bp_wait_at_pwup_fn(bpctl_dev_t * pbpctl_dev, int tap_mode) return BP_NOT_CAP; } -int get_bp_wait_at_pwup_fn(bpctl_dev_t * pbpctl_dev) +int get_bp_wait_at_pwup_fn(bpctl_dev_t *pbpctl_dev) { int ret = 0; if (!pbpctl_dev) @@ -5369,7 +5369,7 @@ int get_bp_wait_at_pwup_fn(bpctl_dev_t * pbpctl_dev) return ret; } -int set_bp_hw_reset_fn(bpctl_dev_t * pbpctl_dev, int tap_mode) +int set_bp_hw_reset_fn(bpctl_dev_t *pbpctl_dev, int tap_mode) { if (!pbpctl_dev) return -1; @@ -5389,7 +5389,7 @@ int set_bp_hw_reset_fn(bpctl_dev_t * pbpctl_dev, int tap_mode) return BP_NOT_CAP; } -int get_bp_hw_reset_fn(bpctl_dev_t * pbpctl_dev) +int get_bp_hw_reset_fn(bpctl_dev_t *pbpctl_dev) { int ret = 0; if (!pbpctl_dev) @@ -5405,7 +5405,7 @@ int get_bp_hw_reset_fn(bpctl_dev_t * pbpctl_dev) //#endif /*PMC_FIX_FLAG*/ -int get_bypass_info_fn(bpctl_dev_t * pbpctl_dev, char *dev_name, +int get_bypass_info_fn(bpctl_dev_t *pbpctl_dev, char *dev_name, char *add_param) { if (!pbpctl_dev) @@ -7713,8 +7713,8 @@ int bp_proc_create(void) int bypass_proc_create_entry_sd(struct pfs_unit_sd *pfs_unit_curr, char *proc_name, - write_proc_t * write_proc, - read_proc_t * read_proc, + write_proc_t *write_proc, + read_proc_t *read_proc, struct proc_dir_entry *parent_pfs, void *data) { strcpy(pfs_unit_curr->proc_name, proc_name); @@ -8811,7 +8811,7 @@ set_hw_reset_pfs(struct file *file, const char *buffer, #endif /*PMC_FIX_FLAG */ -int bypass_proc_create_dev_sd(bpctl_dev_t * pbp_device_block) +int bypass_proc_create_dev_sd(bpctl_dev_t *pbp_device_block) { struct bypass_pfs_sd *current_pfs = &(pbp_device_block->bypass_pfs_set); static struct proc_dir_entry *procfs_dir = NULL; @@ -8994,7 +8994,7 @@ int bypass_proc_create_dev_sd(bpctl_dev_t * pbp_device_block) return ret; } -int bypass_proc_remove_dev_sd(bpctl_dev_t * pbp_device_block) +int bypass_proc_remove_dev_sd(bpctl_dev_t *pbp_device_block) { struct bypass_pfs_sd *current_pfs = &pbp_device_block->bypass_pfs_set; -- cgit v0.10.2 From d084610bb1e825eb60a1ca81a801aedfd36ff332 Mon Sep 17 00:00:00 2001 From: Toshiaki Yamane Date: Sun, 16 Sep 2012 16:26:38 +0900 Subject: staging/rts_pstor: Use pr_ or dev_ printks in rtsx.c fixed some checkpatch warnings. -WARNING: Prefer pr_info(... to printk(KERN_INFO, ... -WARNING: Prefer pr_err(... to printk(KERN_ERR, ... -WARNING: quoted string split across lines And added pr_fmt. Signed-off-by: Toshiaki Yamane Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/rtsx.c b/drivers/staging/rts_pstor/rtsx.c index 5fb05a2..213829e 100644 --- a/drivers/staging/rts_pstor/rtsx.c +++ b/drivers/staging/rts_pstor/rtsx.c @@ -20,6 +20,8 @@ * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -170,14 +172,14 @@ static int queuecommand_lck(struct scsi_cmnd *srb, /* check for state-transition errors */ if (chip->srb != NULL) { - printk(KERN_ERR "Error in %s: chip->srb = %p\n", + dev_err(&dev->pci->dev, "Error in %s: chip->srb = %p\n", __func__, chip->srb); return SCSI_MLQUEUE_HOST_BUSY; } /* fail the command if we are disconnecting */ if (rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT)) { - printk(KERN_INFO "Fail command during disconnect\n"); + dev_info(&dev->pci->dev, "Fail command during disconnect\n"); srb->result = DID_NO_CONNECT << 16; done(srb); return 0; @@ -204,14 +206,14 @@ static int command_abort(struct scsi_cmnd *srb) struct rtsx_dev *dev = host_to_rtsx(host); struct rtsx_chip *chip = dev->chip; - printk(KERN_INFO "%s called\n", __func__); + dev_info(&dev->pci->dev, "%s called\n", __func__); scsi_lock(host); /* Is this command still active? */ if (chip->srb != srb) { scsi_unlock(host); - printk(KERN_INFO "-- nothing to abort\n"); + dev_info(&dev->pci->dev, "-- nothing to abort\n"); return FAILED; } @@ -230,8 +232,9 @@ static int command_abort(struct scsi_cmnd *srb) static int device_reset(struct scsi_cmnd *srb) { int result = 0; + struct rtsx_dev *dev = host_to_rtsx(srb->device->host); - printk(KERN_INFO "%s called\n", __func__); + dev_info(&dev->pci->dev, "%s called\n", __func__); return result < 0 ? FAILED : SUCCESS; } @@ -240,8 +243,9 @@ static int device_reset(struct scsi_cmnd *srb) static int bus_reset(struct scsi_cmnd *srb) { int result = 0; + struct rtsx_dev *dev = host_to_rtsx(srb->device->host); - printk(KERN_INFO "%s called\n", __func__); + dev_info(&dev->pci->dev, "%s called\n", __func__); return result < 0 ? FAILED : SUCCESS; } @@ -303,14 +307,15 @@ static int rtsx_acquire_irq(struct rtsx_dev *dev) { struct rtsx_chip *chip = dev->chip; - printk(KERN_INFO "%s: chip->msi_en = %d, pci->irq = %d\n", - __func__, chip->msi_en, dev->pci->irq); + dev_info(&dev->pci->dev, "%s: chip->msi_en = %d, pci->irq = %d\n", + __func__, chip->msi_en, dev->pci->irq); if (request_irq(dev->pci->irq, rtsx_interrupt, chip->msi_en ? 0 : IRQF_SHARED, CR_DRIVER_NAME, dev)) { - printk(KERN_ERR "rtsx: unable to grab IRQ %d, " - "disabling device\n", dev->pci->irq); + dev_err(&dev->pci->dev, + "rtsx: unable to grab IRQ %d, disabling device\n", + dev->pci->irq); return -1; } @@ -347,10 +352,10 @@ static int rtsx_suspend(struct pci_dev *pci, pm_message_t state) struct rtsx_dev *dev = (struct rtsx_dev *)pci_get_drvdata(pci); struct rtsx_chip *chip; - printk(KERN_INFO "Ready to suspend\n"); + dev_info(&dev->pci->dev, "Ready to suspend\n"); if (!dev) { - printk(KERN_ERR "Invalid memory\n"); + dev_err(&dev->pci->dev, "Invalid memory\n"); return 0; } @@ -386,10 +391,10 @@ static int rtsx_resume(struct pci_dev *pci) struct rtsx_dev *dev = (struct rtsx_dev *)pci_get_drvdata(pci); struct rtsx_chip *chip; - printk(KERN_INFO "Ready to resume\n"); + dev_info(&dev->pci->dev, "Ready to resume\n"); if (!dev) { - printk(KERN_ERR "Invalid memory\n"); + dev_err(&dev->pci->dev, "Invalid memory\n"); return 0; } @@ -401,8 +406,9 @@ static int rtsx_resume(struct pci_dev *pci) pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); if (pci_enable_device(pci) < 0) { - printk(KERN_ERR "%s: pci_enable_device failed, " - "disabling device\n", CR_DRIVER_NAME); + dev_err(&dev->pci->dev, + "%s: pci_enable_device failed, disabling device\n", + CR_DRIVER_NAME); /* unlock the device pointers */ mutex_unlock(&dev->dev_mutex); return -EIO; @@ -435,10 +441,10 @@ static void rtsx_shutdown(struct pci_dev *pci) struct rtsx_dev *dev = (struct rtsx_dev *)pci_get_drvdata(pci); struct rtsx_chip *chip; - printk(KERN_INFO "Ready to shutdown\n"); + dev_info(&dev->pci->dev, "Ready to shutdown\n"); if (!dev) { - printk(KERN_ERR "Invalid memory\n"); + dev_err(&dev->pci->dev, "Invalid memory\n"); return; } @@ -475,7 +481,7 @@ static int rtsx_control_thread(void *__dev) /* if the device has disconnected, we are free to exit */ if (rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT)) { - printk(KERN_INFO "-- rtsx-control exiting\n"); + dev_info(&dev->pci->dev, "-- rtsx-control exiting\n"); mutex_unlock(&dev->dev_mutex); break; } @@ -495,7 +501,7 @@ static int rtsx_control_thread(void *__dev) * is UNKNOWN */ if (chip->srb->sc_data_direction == DMA_BIDIRECTIONAL) { - printk(KERN_ERR "UNKNOWN data direction\n"); + dev_err(&dev->pci->dev, "UNKNOWN data direction\n"); chip->srb->result = DID_ERROR << 16; } @@ -503,14 +509,14 @@ static int rtsx_control_thread(void *__dev) * the maximum known LUN */ else if (chip->srb->device->id) { - printk(KERN_ERR "Bad target number (%d:%d)\n", + dev_err(&dev->pci->dev, "Bad target number (%d:%d)\n", chip->srb->device->id, chip->srb->device->lun); chip->srb->result = DID_BAD_TARGET << 16; } else if (chip->srb->device->lun > chip->max_lun) { - printk(KERN_ERR "Bad LUN (%d:%d)\n", + dev_err(&dev->pci->dev, "Bad LUN (%d:%d)\n", chip->srb->device->id, chip->srb->device->lun); chip->srb->result = DID_BAD_TARGET << 16; @@ -534,7 +540,7 @@ static int rtsx_control_thread(void *__dev) chip->srb->scsi_done(chip->srb); } else { SkipForAbort: - printk(KERN_ERR "scsi command aborted\n"); + dev_err(&dev->pci->dev, "scsi command aborted\n"); } if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) { @@ -594,7 +600,7 @@ static int rtsx_polling_thread(void *__dev) /* if the device has disconnected, we are free to exit */ if (rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT)) { - printk(KERN_INFO "-- rtsx-polling exiting\n"); + dev_info(&dev->pci->dev, "-- rtsx-polling exiting\n"); mutex_unlock(&dev->dev_mutex); break; } @@ -683,13 +689,13 @@ Exit: /* Release all our dynamic resources */ static void rtsx_release_resources(struct rtsx_dev *dev) { - printk(KERN_INFO "-- %s\n", __func__); + dev_info(&dev->pci->dev, "-- %s\n", __func__); /* Tell the control thread to exit. The SCSI host must * already have been removed so it won't try to queue * any more commands. */ - printk(KERN_INFO "-- sending exit command to thread\n"); + dev_info(&dev->pci->dev, "-- sending exit command to thread\n"); complete(&dev->cmnd_ready); if (dev->ctl_thread) wait_for_completion(&dev->control_exit); @@ -774,8 +780,9 @@ static int rtsx_scan_thread(void *__dev) /* Wait for the timeout to expire or for a disconnect */ if (delay_use > 0) { - printk(KERN_INFO "%s: waiting for device " - "to settle before scanning\n", CR_DRIVER_NAME); + dev_info(&dev->pci->dev, + "%s: waiting for device to settle before scanning\n", + CR_DRIVER_NAME); wait_event_interruptible_timeout(dev->delay_wait, rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT), delay_use * HZ); @@ -784,7 +791,8 @@ static int rtsx_scan_thread(void *__dev) /* If the device is still connected, perform the scanning */ if (!rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT)) { scsi_scan_host(rtsx_to_host(dev)); - printk(KERN_INFO "%s: device scan complete\n", CR_DRIVER_NAME); + dev_info(&dev->pci->dev, "%s: device scan complete\n", + CR_DRIVER_NAME); /* Should we unbind if no devices were detected? */ } @@ -906,14 +914,14 @@ static int __devinit rtsx_probe(struct pci_dev *pci, err = pci_enable_device(pci); if (err < 0) { - printk(KERN_ERR "PCI enable device failed!\n"); + dev_err(&pci->dev, "PCI enable device failed!\n"); return err; } err = pci_request_regions(pci, CR_DRIVER_NAME); if (err < 0) { - printk(KERN_ERR "PCI request regions for %s failed!\n", - CR_DRIVER_NAME); + dev_err(&pci->dev, "PCI request regions for %s failed!\n", + CR_DRIVER_NAME); pci_disable_device(pci); return err; } @@ -924,7 +932,7 @@ static int __devinit rtsx_probe(struct pci_dev *pci, */ host = scsi_host_alloc(&rtsx_host_template, sizeof(*dev)); if (!host) { - printk(KERN_ERR "Unable to allocate the scsi host\n"); + dev_err(&pci->dev, "Unable to allocate the scsi host\n"); pci_release_regions(pci); pci_disable_device(pci); return -ENOMEM; @@ -949,12 +957,12 @@ static int __devinit rtsx_probe(struct pci_dev *pci, dev->pci = pci; dev->irq = -1; - printk(KERN_INFO "Resource length: 0x%x\n", - (unsigned int)pci_resource_len(pci, 0)); + dev_info(&pci->dev, "Resource length: 0x%x\n", + (unsigned int)pci_resource_len(pci, 0)); dev->addr = pci_resource_start(pci, 0); dev->remap_addr = ioremap_nocache(dev->addr, pci_resource_len(pci, 0)); if (dev->remap_addr == NULL) { - printk(KERN_ERR "ioremap error\n"); + dev_err(&pci->dev, "ioremap error\n"); err = -ENXIO; goto errout; } @@ -963,13 +971,13 @@ static int __devinit rtsx_probe(struct pci_dev *pci, * Using "unsigned long" cast here to eliminate gcc warning in * 64-bit system */ - printk(KERN_INFO "Original address: 0x%lx, remapped address: 0x%lx\n", - (unsigned long)(dev->addr), (unsigned long)(dev->remap_addr)); + dev_info(&pci->dev, "Original address: 0x%lx, remapped address: 0x%lx\n", + (unsigned long)(dev->addr), (unsigned long)(dev->remap_addr)); dev->rtsx_resv_buf = dma_alloc_coherent(&(pci->dev), RTSX_RESV_BUF_LEN, &(dev->rtsx_resv_buf_addr), GFP_KERNEL); if (dev->rtsx_resv_buf == NULL) { - printk(KERN_ERR "alloc dma buffer fail\n"); + dev_err(&pci->dev, "alloc dma buffer fail\n"); err = -ENXIO; goto errout; } @@ -983,7 +991,7 @@ static int __devinit rtsx_probe(struct pci_dev *pci, rtsx_init_options(dev->chip); - printk(KERN_INFO "pci->irq = %d\n", pci->irq); + dev_info(&pci->dev, "pci->irq = %d\n", pci->irq); if (dev->chip->msi_en) { if (pci_enable_msi(pci) < 0) @@ -1008,7 +1016,7 @@ static int __devinit rtsx_probe(struct pci_dev *pci, /* Start up our control thread */ th = kthread_run(rtsx_control_thread, dev, CR_DRIVER_NAME); if (IS_ERR(th)) { - printk(KERN_ERR "Unable to start control thread\n"); + dev_err(&pci->dev, "Unable to start control thread\n"); err = PTR_ERR(th); goto errout; } @@ -1016,14 +1024,14 @@ static int __devinit rtsx_probe(struct pci_dev *pci, err = scsi_add_host(host, &pci->dev); if (err) { - printk(KERN_ERR "Unable to add the scsi host\n"); + dev_err(&pci->dev, "Unable to add the scsi host\n"); goto errout; } /* Start up the thread for delayed SCSI-device scanning */ th = kthread_run(rtsx_scan_thread, dev, "rtsx-scan"); if (IS_ERR(th)) { - printk(KERN_ERR "Unable to start the device-scanning thread\n"); + dev_err(&pci->dev, "Unable to start the device-scanning thread\n"); complete(&dev->scanning_done); quiesce_and_remove_host(dev); err = PTR_ERR(th); @@ -1033,7 +1041,7 @@ static int __devinit rtsx_probe(struct pci_dev *pci, /* Start up the thread for polling thread */ th = kthread_run(rtsx_polling_thread, dev, "rtsx-polling"); if (IS_ERR(th)) { - printk(KERN_ERR "Unable to start the device-polling thread\n"); + dev_err(&pci->dev, "Unable to start the device-polling thread\n"); quiesce_and_remove_host(dev); err = PTR_ERR(th); goto errout; @@ -1046,7 +1054,7 @@ static int __devinit rtsx_probe(struct pci_dev *pci, /* We come here if there are any problems */ errout: - printk(KERN_ERR "rtsx_probe() failed\n"); + dev_err(&pci->dev, "rtsx_probe() failed\n"); release_everything(dev); return err; @@ -1057,7 +1065,7 @@ static void __devexit rtsx_remove(struct pci_dev *pci) { struct rtsx_dev *dev = (struct rtsx_dev *)pci_get_drvdata(pci); - printk(KERN_INFO "rtsx_remove() called\n"); + dev_info(&pci->dev, "rtsx_remove() called\n"); quiesce_and_remove_host(dev); release_everything(dev); @@ -1090,18 +1098,18 @@ static struct pci_driver driver = { static int __init rtsx_init(void) { - printk(KERN_INFO "Initializing Realtek PCIE storage driver...\n"); + pr_info("Initializing Realtek PCIE storage driver...\n"); return pci_register_driver(&driver); } static void __exit rtsx_exit(void) { - printk(KERN_INFO "rtsx_exit() called\n"); + pr_info("rtsx_exit() called\n"); pci_unregister_driver(&driver); - printk(KERN_INFO "%s module exit\n", CR_DRIVER_NAME); + pr_info("%s module exit\n", CR_DRIVER_NAME); } module_init(rtsx_init) -- cgit v0.10.2 From 3afcb91c418a9e50cfb79d7b6e28907d782e69d9 Mon Sep 17 00:00:00 2001 From: Macpaul Lin Date: Fri, 14 Sep 2012 14:02:04 +0800 Subject: staging/gdm72xx: usb_boot: replace firmware upgrade API in em_download Replace firmware upgrade API in em_download_image(). Signed-off-by: Macpaul Lin Cc: Paul Stewart Cc: Ben Chan Cc: Sage Ahn Cc: Greg Kroah-Hartman Cc: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/gdm72xx/usb_boot.c b/drivers/staging/gdm72xx/usb_boot.c index 80870a0..0787188 100644 --- a/drivers/staging/gdm72xx/usb_boot.c +++ b/drivers/staging/gdm72xx/usb_boot.c @@ -32,8 +32,8 @@ #define MAX_IMG_CNT 16 #define FW_DIR "gdm72xx/" #define FW_UIMG "gdmuimg.bin" -#define KERN_PATH "/lib/firmware/gdm72xx/zImage" -#define FS_PATH "/lib/firmware/gdm72xx/ramdisk.jffs2" +#define FW_KERN "zImage" +#define FW_FS "ramdisk.jffs2" struct dn_header { u32 magic_num; @@ -276,38 +276,27 @@ out: return ret; } -static int em_download_image(struct usb_device *usbdev, char *path, +static int em_download_image(struct usb_device *usbdev, const char *img_name, char *type_string) { - struct file *filp; - struct inode *inode; - static mm_segment_t fs; char *buf = NULL; loff_t pos = 0; int ret = 0; - int len, readn = 0; + int len; + int img_len; + const struct firmware *firm; #if defined(GDM7205_PADDING) const int pad_size = GDM7205_PADDING; #else const int pad_size = 0; #endif - fs = get_fs(); - set_fs(get_ds()); - - filp = filp_open(path, O_RDONLY | O_LARGEFILE, 0); - if (IS_ERR(filp)) { - printk(KERN_ERR "Can't find %s.\n", path); - set_fs(fs); - ret = -ENOENT; - goto restore_fs; - } - - inode = filp->f_dentry->d_inode; - if (!S_ISREG(inode->i_mode)) { - printk(KERN_ERR "Invalid file type: %s\n", path); - ret = -EINVAL; - goto out; + ret = request_firmware(&firm, img_name, &usbdev->dev); + if (ret < 0) { + printk(KERN_ERR + "requesting firmware %s failed with error %d\n", + img_name, ret); + return ret; } buf = kmalloc(DOWNLOAD_CHUCK + pad_size, GFP_KERNEL); @@ -321,18 +310,28 @@ static int em_download_image(struct usb_device *usbdev, char *path, if (ret < 0) goto out; - while ((len = filp->f_op->read(filp, buf+pad_size, DOWNLOAD_CHUCK, - &pos))) { - if (len < 0) { - ret = -1; - goto out; - } - readn += len; + img_len = firm->size; + if (img_len <= 0) { + ret = -1; + goto out; + } + + while (img_len > 0) { + if (img_len > DOWNLOAD_CHUCK) + len = DOWNLOAD_CHUCK; + else + len = img_len; /* the last chunk of data */ + + memcpy(buf+pad_size, firm->data + pos, len); ret = gdm_wibro_send(usbdev, buf, len+pad_size); + if (ret < 0) goto out; + img_len -= DOWNLOAD_CHUCK; + pos += DOWNLOAD_CHUCK; + ret = em_wait_ack(usbdev, ((len+pad_size) % 512 == 0)); if (ret < 0) goto out; @@ -343,11 +342,7 @@ static int em_download_image(struct usb_device *usbdev, char *path, goto out; out: - filp_close(filp, NULL); - -restore_fs: - set_fs(fs); - + release_firmware(firm); kfree(buf); return ret; @@ -365,18 +360,20 @@ static int em_fw_reset(struct usb_device *usbdev) int usb_emergency(struct usb_device *usbdev) { int ret; + const char *kern_name = FW_DIR FW_KERN; + const char *fs_name = FW_DIR FW_FS; - ret = em_download_image(usbdev, KERN_PATH, KERNEL_TYPE_STRING); + ret = em_download_image(usbdev, kern_name, KERNEL_TYPE_STRING); if (ret < 0) - goto out; + return ret; printk(KERN_INFO "GCT Emergency: Kernel download success.\n"); - ret = em_download_image(usbdev, FS_PATH, FS_TYPE_STRING); + ret = em_download_image(usbdev, fs_name, FS_TYPE_STRING); if (ret < 0) - goto out; + return ret; printk(KERN_INFO "GCT Emergency: Filesystem download success.\n"); ret = em_fw_reset(usbdev); -out: + return ret; } -- cgit v0.10.2 From b2b79ffa40d7ae40115631660ff8b6da3cf989b6 Mon Sep 17 00:00:00 2001 From: "Kim, Milo" Date: Mon, 17 Sep 2012 09:44:00 +0100 Subject: iio: inkern: add error case in iio_channel_get() The datasheet name is defined in the IIO driver. On the other hand, the adc_channel_label is configured in the platform side. If the datasheet name is not matched with any adc_channel_label, the iio_channel_get() should be returned as error for preventing invalid channel data access. This can be handled either way. (a) checking null data when using it : in the xxx_read_raw() or (b) error returns when the channel is requested : this patch The IIO consumer can't use the channel with invalid channel spec. Therefore case (b) is more reasonable. Signed-off-by: Milo(Woogyom) Kim Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index 028c657..d539e1e 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -136,12 +136,21 @@ struct iio_channel *iio_channel_get(const char *name, const char *channel_name) channel->indio_dev = c->indio_dev; - if (c->map->adc_channel_label) + if (c->map->adc_channel_label) { channel->channel = iio_chan_spec_from_name(channel->indio_dev, c->map->adc_channel_label); + if (channel->channel == NULL) + goto error_no_chan; + } + return channel; + +error_no_chan: + iio_device_put(c->indio_dev); + kfree(channel); + return ERR_PTR(-EINVAL); } EXPORT_SYMBOL_GPL(iio_channel_get); -- cgit v0.10.2 From c499d029d80534a01e858ce9fd1687f2042f7a86 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 17 Sep 2012 10:24:00 +0100 Subject: iio:dac: Add ad5755 driver This patch adds support for the AD5755, AD5755-1, AD5757, AD5735, AD5737 16 and 14 bit quad-channel DACs. The AD5757/AD5737 only have current outputs, but for the AD5755/AD5757 each of the outputs can be configured to either be a voltage or a current output. We only allow to configure this at device probe time since usually this needs to match the external circuitry and should not be changed on the fly. A few trivial formatting changes on merge. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig index 7845263..b1c0ee5 100644 --- a/drivers/iio/dac/Kconfig +++ b/drivers/iio/dac/Kconfig @@ -77,6 +77,17 @@ config AD5504 To compile this driver as a module, choose M here: the module will be called ad5504. +config AD5755 + tristate "Analog Devices AD5755/AD5755-1/AD5757/AD5735/AD5737 DAC driver" + depends on SPI_MASTER + help + Say yes here to build support for Analog Devices AD5755, AD5755-1, + AD5757, AD5735, AD5737 quad channel Digital to + Analog Converter. + + To compile this driver as a module, choose M here: the + module will be called ad5755. + config AD5764 tristate "Analog Devices AD5764/64R/44/44R DAC driver" depends on SPI_MASTER diff --git a/drivers/iio/dac/Makefile b/drivers/iio/dac/Makefile index 9ea3cee..c0d333b 100644 --- a/drivers/iio/dac/Makefile +++ b/drivers/iio/dac/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_AD5624R_SPI) += ad5624r_spi.o obj-$(CONFIG_AD5064) += ad5064.o obj-$(CONFIG_AD5504) += ad5504.o obj-$(CONFIG_AD5446) += ad5446.o +obj-$(CONFIG_AD5755) += ad5755.o obj-$(CONFIG_AD5764) += ad5764.o obj-$(CONFIG_AD5791) += ad5791.o obj-$(CONFIG_AD5686) += ad5686.o diff --git a/drivers/iio/dac/ad5755.c b/drivers/iio/dac/ad5755.c new file mode 100644 index 0000000..e6dbe5f --- /dev/null +++ b/drivers/iio/dac/ad5755.c @@ -0,0 +1,650 @@ +/* + * AD5755, AD5755-1, AD5757, AD5735, AD5737 Digital to analog converters driver + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define AD5755_NUM_CHANNELS 4 + +#define AD5755_ADDR(x) ((x) << 16) + +#define AD5755_WRITE_REG_DATA(chan) (chan) +#define AD5755_WRITE_REG_GAIN(chan) (0x08 | (chan)) +#define AD5755_WRITE_REG_OFFSET(chan) (0x10 | (chan)) +#define AD5755_WRITE_REG_CTRL(chan) (0x1c | (chan)) + +#define AD5755_READ_REG_DATA(chan) (chan) +#define AD5755_READ_REG_CTRL(chan) (0x4 | (chan)) +#define AD5755_READ_REG_GAIN(chan) (0x8 | (chan)) +#define AD5755_READ_REG_OFFSET(chan) (0xc | (chan)) +#define AD5755_READ_REG_CLEAR(chan) (0x10 | (chan)) +#define AD5755_READ_REG_SLEW(chan) (0x14 | (chan)) +#define AD5755_READ_REG_STATUS 0x18 +#define AD5755_READ_REG_MAIN 0x19 +#define AD5755_READ_REG_DC_DC 0x1a + +#define AD5755_CTRL_REG_SLEW 0x0 +#define AD5755_CTRL_REG_MAIN 0x1 +#define AD5755_CTRL_REG_DAC 0x2 +#define AD5755_CTRL_REG_DC_DC 0x3 +#define AD5755_CTRL_REG_SW 0x4 + +#define AD5755_READ_FLAG 0x800000 + +#define AD5755_NOOP 0x1CE000 + +#define AD5755_DAC_INT_EN BIT(8) +#define AD5755_DAC_CLR_EN BIT(7) +#define AD5755_DAC_OUT_EN BIT(6) +#define AD5755_DAC_INT_CURRENT_SENSE_RESISTOR BIT(5) +#define AD5755_DAC_DC_DC_EN BIT(4) +#define AD5755_DAC_VOLTAGE_OVERRANGE_EN BIT(3) + +#define AD5755_DC_DC_MAXV 0 +#define AD5755_DC_DC_FREQ_SHIFT 2 +#define AD5755_DC_DC_PHASE_SHIFT 4 +#define AD5755_EXT_DC_DC_COMP_RES BIT(6) + +#define AD5755_SLEW_STEP_SIZE_SHIFT 0 +#define AD5755_SLEW_RATE_SHIFT 3 +#define AD5755_SLEW_ENABLE BIT(12) + +/** + * struct ad5755_chip_info - chip specific information + * @channel_template: channel specification + * @calib_shift: shift for the calibration data registers + * @has_voltage_out: whether the chip has voltage outputs + */ +struct ad5755_chip_info { + const struct iio_chan_spec channel_template; + unsigned int calib_shift; + bool has_voltage_out; +}; + +/** + * struct ad5755_state - driver instance specific data + * @spi: spi device the driver is attached to + * @chip_info: chip model specific constants, available modes etc + * @pwr_down: bitmask which contains hether a channel is powered down or not + * @ctrl: software shadow of the channel ctrl registers + * @channels: iio channel spec for the device + * @data: spi transfer buffers + */ +struct ad5755_state { + struct spi_device *spi; + const struct ad5755_chip_info *chip_info; + unsigned int pwr_down; + unsigned int ctrl[AD5755_NUM_CHANNELS]; + struct iio_chan_spec channels[AD5755_NUM_CHANNELS]; + + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + */ + + union { + u32 d32; + u8 d8[4]; + } data[2] ____cacheline_aligned; +}; + +enum ad5755_type { + ID_AD5755, + ID_AD5757, + ID_AD5735, + ID_AD5737, +}; + +static int ad5755_write_unlocked(struct iio_dev *indio_dev, + unsigned int reg, unsigned int val) +{ + struct ad5755_state *st = iio_priv(indio_dev); + + st->data[0].d32 = cpu_to_be32((reg << 16) | val); + + return spi_write(st->spi, &st->data[0].d8[1], 3); +} + +static int ad5755_write_ctrl_unlocked(struct iio_dev *indio_dev, + unsigned int channel, unsigned int reg, unsigned int val) +{ + return ad5755_write_unlocked(indio_dev, + AD5755_WRITE_REG_CTRL(channel), (reg << 13) | val); +} + +static int ad5755_write(struct iio_dev *indio_dev, unsigned int reg, + unsigned int val) +{ + int ret; + + mutex_lock(&indio_dev->mlock); + ret = ad5755_write_unlocked(indio_dev, reg, val); + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static int ad5755_write_ctrl(struct iio_dev *indio_dev, unsigned int channel, + unsigned int reg, unsigned int val) +{ + int ret; + + mutex_lock(&indio_dev->mlock); + ret = ad5755_write_ctrl_unlocked(indio_dev, channel, reg, val); + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static int ad5755_read(struct iio_dev *indio_dev, unsigned int addr) +{ + struct ad5755_state *st = iio_priv(indio_dev); + struct spi_message m; + int ret; + struct spi_transfer t[] = { + { + .tx_buf = &st->data[0].d8[1], + .len = 3, + .cs_change = 1, + }, { + .tx_buf = &st->data[1].d8[1], + .rx_buf = &st->data[1].d8[1], + .len = 3, + }, + }; + + spi_message_init(&m); + spi_message_add_tail(&t[0], &m); + spi_message_add_tail(&t[1], &m); + + mutex_lock(&indio_dev->mlock); + + st->data[0].d32 = cpu_to_be32(AD5755_READ_FLAG | (addr << 16)); + st->data[1].d32 = cpu_to_be32(AD5755_NOOP); + + ret = spi_sync(st->spi, &m); + if (ret >= 0) + ret = be32_to_cpu(st->data[1].d32) & 0xffff; + + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static int ad5755_update_dac_ctrl(struct iio_dev *indio_dev, + unsigned int channel, unsigned int set, unsigned int clr) +{ + struct ad5755_state *st = iio_priv(indio_dev); + int ret; + + st->ctrl[channel] |= set; + st->ctrl[channel] &= ~clr; + + ret = ad5755_write_ctrl_unlocked(indio_dev, channel, + AD5755_CTRL_REG_DAC, st->ctrl[channel]); + + return ret; +} + +static int ad5755_set_channel_pwr_down(struct iio_dev *indio_dev, + unsigned int channel, bool pwr_down) +{ + struct ad5755_state *st = iio_priv(indio_dev); + unsigned int mask = BIT(channel); + + mutex_lock(&indio_dev->mlock); + + if ((bool)(st->pwr_down & mask) == pwr_down) + goto out_unlock; + + if (!pwr_down) { + st->pwr_down &= ~mask; + ad5755_update_dac_ctrl(indio_dev, channel, + AD5755_DAC_INT_EN | AD5755_DAC_DC_DC_EN, 0); + udelay(200); + ad5755_update_dac_ctrl(indio_dev, channel, + AD5755_DAC_OUT_EN, 0); + } else { + st->pwr_down |= mask; + ad5755_update_dac_ctrl(indio_dev, channel, + 0, AD5755_DAC_INT_EN | AD5755_DAC_OUT_EN | + AD5755_DAC_DC_DC_EN); + } + +out_unlock: + mutex_unlock(&indio_dev->mlock); + + return 0; +} + +static const int ad5755_min_max_table[][2] = { + [AD5755_MODE_VOLTAGE_0V_5V] = { 0, 5000 }, + [AD5755_MODE_VOLTAGE_0V_10V] = { 0, 10000 }, + [AD5755_MODE_VOLTAGE_PLUSMINUS_5V] = { -5000, 5000 }, + [AD5755_MODE_VOLTAGE_PLUSMINUS_10V] = { -10000, 10000 }, + [AD5755_MODE_CURRENT_4mA_20mA] = { 4, 20 }, + [AD5755_MODE_CURRENT_0mA_20mA] = { 0, 20 }, + [AD5755_MODE_CURRENT_0mA_24mA] = { 0, 24 }, +}; + +static void ad5755_get_min_max(struct ad5755_state *st, + struct iio_chan_spec const *chan, int *min, int *max) +{ + enum ad5755_mode mode = st->ctrl[chan->channel] & 7; + *min = ad5755_min_max_table[mode][0]; + *max = ad5755_min_max_table[mode][1]; +} + +static inline int ad5755_get_offset(struct ad5755_state *st, + struct iio_chan_spec const *chan) +{ + int min, max; + + ad5755_get_min_max(st, chan, &min, &max); + return (min * (1 << chan->scan_type.realbits)) / (max - min); +} + +static inline int ad5755_get_scale(struct ad5755_state *st, + struct iio_chan_spec const *chan) +{ + int min, max; + + ad5755_get_min_max(st, chan, &min, &max); + return ((max - min) * 1000000000ULL) >> chan->scan_type.realbits; +} + +static int ad5755_chan_reg_info(struct ad5755_state *st, + struct iio_chan_spec const *chan, long info, bool write, + unsigned int *reg, unsigned int *shift, unsigned int *offset) +{ + switch (info) { + case IIO_CHAN_INFO_RAW: + if (write) + *reg = AD5755_WRITE_REG_DATA(chan->address); + else + *reg = AD5755_READ_REG_DATA(chan->address); + *shift = chan->scan_type.shift; + *offset = 0; + break; + case IIO_CHAN_INFO_CALIBBIAS: + if (write) + *reg = AD5755_WRITE_REG_OFFSET(chan->address); + else + *reg = AD5755_READ_REG_OFFSET(chan->address); + *shift = st->chip_info->calib_shift; + *offset = 32768; + break; + case IIO_CHAN_INFO_CALIBSCALE: + if (write) + *reg = AD5755_WRITE_REG_GAIN(chan->address); + else + *reg = AD5755_READ_REG_GAIN(chan->address); + *shift = st->chip_info->calib_shift; + *offset = 0; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int ad5755_read_raw(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, int *val, int *val2, long info) +{ + struct ad5755_state *st = iio_priv(indio_dev); + unsigned int reg, shift, offset; + int ret; + + switch (info) { + case IIO_CHAN_INFO_SCALE: + *val = 0; + *val2 = ad5755_get_scale(st, chan); + return IIO_VAL_INT_PLUS_NANO; + case IIO_CHAN_INFO_OFFSET: + *val = ad5755_get_offset(st, chan); + return IIO_VAL_INT; + default: + ret = ad5755_chan_reg_info(st, chan, info, false, + ®, &shift, &offset); + if (ret) + return ret; + + ret = ad5755_read(indio_dev, reg); + if (ret < 0) + return ret; + + *val = (ret - offset) >> shift; + + return IIO_VAL_INT; + } + + return -EINVAL; +} + +static int ad5755_write_raw(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, int val, int val2, long info) +{ + struct ad5755_state *st = iio_priv(indio_dev); + unsigned int shift, reg, offset; + int ret; + + ret = ad5755_chan_reg_info(st, chan, info, true, + ®, &shift, &offset); + if (ret) + return ret; + + val <<= shift; + val += offset; + + if (val < 0 || val > 0xffff) + return -EINVAL; + + return ad5755_write(indio_dev, reg, val); +} + +static ssize_t ad5755_read_powerdown(struct iio_dev *indio_dev, uintptr_t priv, + const struct iio_chan_spec *chan, char *buf) +{ + struct ad5755_state *st = iio_priv(indio_dev); + + return sprintf(buf, "%d\n", + (bool)(st->pwr_down & (1 << chan->channel))); +} + +static ssize_t ad5755_write_powerdown(struct iio_dev *indio_dev, uintptr_t priv, + struct iio_chan_spec const *chan, const char *buf, size_t len) +{ + bool pwr_down; + int ret; + + ret = strtobool(buf, &pwr_down); + if (ret) + return ret; + + ret = ad5755_set_channel_pwr_down(indio_dev, chan->channel, pwr_down); + return ret ? ret : len; +} + +static const struct iio_info ad5755_info = { + .read_raw = ad5755_read_raw, + .write_raw = ad5755_write_raw, + .driver_module = THIS_MODULE, +}; + +static const struct iio_chan_spec_ext_info ad5755_ext_info[] = { + { + .name = "powerdown", + .read = ad5755_read_powerdown, + .write = ad5755_write_powerdown, + }, + { }, +}; + +#define AD5755_CHANNEL(_bits) { \ + .indexed = 1, \ + .output = 1, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SEPARATE_BIT | \ + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | \ + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | \ + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, \ + .scan_type = IIO_ST('u', (_bits), 16, 16 - (_bits)), \ + .ext_info = ad5755_ext_info, \ +} + +static const struct ad5755_chip_info ad5755_chip_info_tbl[] = { + [ID_AD5735] = { + .channel_template = AD5755_CHANNEL(14), + .has_voltage_out = true, + .calib_shift = 4, + }, + [ID_AD5737] = { + .channel_template = AD5755_CHANNEL(14), + .has_voltage_out = false, + .calib_shift = 4, + }, + [ID_AD5755] = { + .channel_template = AD5755_CHANNEL(16), + .has_voltage_out = true, + .calib_shift = 0, + }, + [ID_AD5757] = { + .channel_template = AD5755_CHANNEL(16), + .has_voltage_out = false, + .calib_shift = 0, + }, +}; + +static bool ad5755_is_valid_mode(struct ad5755_state *st, enum ad5755_mode mode) +{ + switch (mode) { + case AD5755_MODE_VOLTAGE_0V_5V: + case AD5755_MODE_VOLTAGE_0V_10V: + case AD5755_MODE_VOLTAGE_PLUSMINUS_5V: + case AD5755_MODE_VOLTAGE_PLUSMINUS_10V: + return st->chip_info->has_voltage_out; + case AD5755_MODE_CURRENT_4mA_20mA: + case AD5755_MODE_CURRENT_0mA_20mA: + case AD5755_MODE_CURRENT_0mA_24mA: + return true; + default: + return false; + } +} + +static int __devinit ad5755_setup_pdata(struct iio_dev *indio_dev, + const struct ad5755_platform_data *pdata) +{ + struct ad5755_state *st = iio_priv(indio_dev); + unsigned int ret; + unsigned int val; + unsigned int i; + + if (pdata->dc_dc_phase > AD5755_DC_DC_PHASE_90_DEGREE || + pdata->dc_dc_freq > AD5755_DC_DC_FREQ_650kHZ || + pdata->dc_dc_maxv > AD5755_DC_DC_MAXV_29V5) + return -EINVAL; + + val = pdata->dc_dc_maxv << AD5755_DC_DC_MAXV; + val |= pdata->dc_dc_freq << AD5755_DC_DC_FREQ_SHIFT; + val |= pdata->dc_dc_phase << AD5755_DC_DC_PHASE_SHIFT; + if (pdata->ext_dc_dc_compenstation_resistor) + val |= AD5755_EXT_DC_DC_COMP_RES; + + ret = ad5755_write_ctrl(indio_dev, 0, AD5755_CTRL_REG_DC_DC, val); + if (ret < 0) + return ret; + + for (i = 0; i < ARRAY_SIZE(pdata->dac); ++i) { + val = pdata->dac[i].slew.step_size << + AD5755_SLEW_STEP_SIZE_SHIFT; + val |= pdata->dac[i].slew.rate << + AD5755_SLEW_RATE_SHIFT; + if (pdata->dac[i].slew.enable) + val |= AD5755_SLEW_ENABLE; + + ret = ad5755_write_ctrl(indio_dev, i, + AD5755_CTRL_REG_SLEW, val); + if (ret < 0) + return ret; + } + + for (i = 0; i < ARRAY_SIZE(pdata->dac); ++i) { + if (!ad5755_is_valid_mode(st, pdata->dac[i].mode)) + return -EINVAL; + + val = 0; + if (!pdata->dac[i].ext_current_sense_resistor) + val |= AD5755_DAC_INT_CURRENT_SENSE_RESISTOR; + if (pdata->dac[i].enable_voltage_overrange) + val |= AD5755_DAC_VOLTAGE_OVERRANGE_EN; + val |= pdata->dac[i].mode; + + ret = ad5755_update_dac_ctrl(indio_dev, i, val, 0); + if (ret < 0) + return ret; + } + + return 0; +} + +static bool __devinit ad5755_is_voltage_mode(enum ad5755_mode mode) +{ + switch (mode) { + case AD5755_MODE_VOLTAGE_0V_5V: + case AD5755_MODE_VOLTAGE_0V_10V: + case AD5755_MODE_VOLTAGE_PLUSMINUS_5V: + case AD5755_MODE_VOLTAGE_PLUSMINUS_10V: + return true; + default: + return false; + } +} + +static int __devinit ad5755_init_channels(struct iio_dev *indio_dev, + const struct ad5755_platform_data *pdata) +{ + struct ad5755_state *st = iio_priv(indio_dev); + struct iio_chan_spec *channels = st->channels; + unsigned int i; + + for (i = 0; i < AD5755_NUM_CHANNELS; ++i) { + channels[i] = st->chip_info->channel_template; + channels[i].channel = i; + channels[i].address = i; + if (pdata && ad5755_is_voltage_mode(pdata->dac[i].mode)) + channels[i].type = IIO_VOLTAGE; + else + channels[i].type = IIO_CURRENT; + } + + indio_dev->channels = channels; + + return 0; +} + +#define AD5755_DEFAULT_DAC_PDATA { \ + .mode = AD5755_MODE_CURRENT_4mA_20mA, \ + .ext_current_sense_resistor = true, \ + .enable_voltage_overrange = false, \ + .slew = { \ + .enable = false, \ + .rate = AD5755_SLEW_RATE_64k, \ + .step_size = AD5755_SLEW_STEP_SIZE_1, \ + }, \ + } + +static const struct ad5755_platform_data ad5755_default_pdata = { + .ext_dc_dc_compenstation_resistor = false, + .dc_dc_phase = AD5755_DC_DC_PHASE_ALL_SAME_EDGE, + .dc_dc_freq = AD5755_DC_DC_FREQ_410kHZ, + .dc_dc_maxv = AD5755_DC_DC_MAXV_23V, + .dac = { + [0] = AD5755_DEFAULT_DAC_PDATA, + [1] = AD5755_DEFAULT_DAC_PDATA, + [2] = AD5755_DEFAULT_DAC_PDATA, + [3] = AD5755_DEFAULT_DAC_PDATA, + }, +}; + +static int __devinit ad5755_probe(struct spi_device *spi) +{ + enum ad5755_type type = spi_get_device_id(spi)->driver_data; + const struct ad5755_platform_data *pdata = dev_get_platdata(&spi->dev); + struct iio_dev *indio_dev; + struct ad5755_state *st; + int ret; + + indio_dev = iio_device_alloc(sizeof(*st)); + if (indio_dev == NULL) { + dev_err(&spi->dev, "Failed to allocate iio device\n"); + return -ENOMEM; + } + + st = iio_priv(indio_dev); + spi_set_drvdata(spi, indio_dev); + + st->chip_info = &ad5755_chip_info_tbl[type]; + st->spi = spi; + st->pwr_down = 0xf; + + indio_dev->dev.parent = &spi->dev; + indio_dev->name = spi_get_device_id(spi)->name; + indio_dev->info = &ad5755_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->num_channels = AD5755_NUM_CHANNELS; + + if (!pdata) + pdata = &ad5755_default_pdata; + + ret = ad5755_init_channels(indio_dev, pdata); + if (ret) + goto error_free; + + ret = ad5755_setup_pdata(indio_dev, pdata); + if (ret) + goto error_free; + + ret = iio_device_register(indio_dev); + if (ret) { + dev_err(&spi->dev, "Failed to register iio device: %d\n", ret); + goto error_free; + } + + return 0; + +error_free: + iio_device_free(indio_dev); + + return ret; +} + +static int __devexit ad5755_remove(struct spi_device *spi) +{ + struct iio_dev *indio_dev = spi_get_drvdata(spi); + + iio_device_unregister(indio_dev); + iio_device_free(indio_dev); + + return 0; +} + +static const struct spi_device_id ad5755_id[] = { + { "ad5755", ID_AD5755 }, + { "ad5755-1", ID_AD5755 }, + { "ad5757", ID_AD5757 }, + { "ad5735", ID_AD5735 }, + { "ad5737", ID_AD5737 }, + {} +}; +MODULE_DEVICE_TABLE(spi, ad5755_id); + +static struct spi_driver ad5755_driver = { + .driver = { + .name = "ad5755", + .owner = THIS_MODULE, + }, + .probe = ad5755_probe, + .remove = __devexit_p(ad5755_remove), + .id_table = ad5755_id, +}; +module_spi_driver(ad5755_driver); + +MODULE_AUTHOR("Lars-Peter Clausen "); +MODULE_DESCRIPTION("Analog Devices AD5755/55-1/57/35/37 DAC"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/platform_data/ad5755.h b/include/linux/platform_data/ad5755.h new file mode 100644 index 0000000..a5a1cb7 --- /dev/null +++ b/include/linux/platform_data/ad5755.h @@ -0,0 +1,103 @@ +/* + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ +#ifndef __LINUX_PLATFORM_DATA_AD5755_H__ +#define __LINUX_PLATFORM_DATA_AD5755_H__ + +enum ad5755_mode { + AD5755_MODE_VOLTAGE_0V_5V = 0, + AD5755_MODE_VOLTAGE_0V_10V = 1, + AD5755_MODE_VOLTAGE_PLUSMINUS_5V = 2, + AD5755_MODE_VOLTAGE_PLUSMINUS_10V = 3, + AD5755_MODE_CURRENT_4mA_20mA = 4, + AD5755_MODE_CURRENT_0mA_20mA = 5, + AD5755_MODE_CURRENT_0mA_24mA = 6, +}; + +enum ad5755_dc_dc_phase { + AD5755_DC_DC_PHASE_ALL_SAME_EDGE = 0, + AD5755_DC_DC_PHASE_A_B_SAME_EDGE_C_D_OPP_EDGE = 1, + AD5755_DC_DC_PHASE_A_C_SAME_EDGE_B_D_OPP_EDGE = 2, + AD5755_DC_DC_PHASE_90_DEGREE = 3, +}; + +enum ad5755_dc_dc_freq { + AD5755_DC_DC_FREQ_250kHZ = 0, + AD5755_DC_DC_FREQ_410kHZ = 1, + AD5755_DC_DC_FREQ_650kHZ = 2, +}; + +enum ad5755_dc_dc_maxv { + AD5755_DC_DC_MAXV_23V = 0, + AD5755_DC_DC_MAXV_24V5 = 1, + AD5755_DC_DC_MAXV_27V = 2, + AD5755_DC_DC_MAXV_29V5 = 3, +}; + +enum ad5755_slew_rate { + AD5755_SLEW_RATE_64k = 0, + AD5755_SLEW_RATE_32k = 1, + AD5755_SLEW_RATE_16k = 2, + AD5755_SLEW_RATE_8k = 3, + AD5755_SLEW_RATE_4k = 4, + AD5755_SLEW_RATE_2k = 5, + AD5755_SLEW_RATE_1k = 6, + AD5755_SLEW_RATE_500 = 7, + AD5755_SLEW_RATE_250 = 8, + AD5755_SLEW_RATE_125 = 9, + AD5755_SLEW_RATE_64 = 10, + AD5755_SLEW_RATE_32 = 11, + AD5755_SLEW_RATE_16 = 12, + AD5755_SLEW_RATE_8 = 13, + AD5755_SLEW_RATE_4 = 14, + AD5755_SLEW_RATE_0_5 = 15, +}; + +enum ad5755_slew_step_size { + AD5755_SLEW_STEP_SIZE_1 = 0, + AD5755_SLEW_STEP_SIZE_2 = 1, + AD5755_SLEW_STEP_SIZE_4 = 2, + AD5755_SLEW_STEP_SIZE_8 = 3, + AD5755_SLEW_STEP_SIZE_16 = 4, + AD5755_SLEW_STEP_SIZE_32 = 5, + AD5755_SLEW_STEP_SIZE_64 = 6, + AD5755_SLEW_STEP_SIZE_128 = 7, + AD5755_SLEW_STEP_SIZE_256 = 8, +}; + +/** + * struct ad5755_platform_data - AD5755 DAC driver platform data + * @ext_dc_dc_compenstation_resistor: Whether an external DC-DC converter + * compensation register is used. + * @dc_dc_phase: DC-DC converter phase. + * @dc_dc_freq: DC-DC converter frequency. + * @dc_dc_maxv: DC-DC maximum allowed boost voltage. + * @dac.mode: The mode to be used for the DAC output. + * @dac.ext_current_sense_resistor: Whether an external current sense resistor + * is used. + * @dac.enable_voltage_overrange: Whether to enable 20% voltage output overrange. + * @dac.slew.enable: Whether to enable digital slew. + * @dac.slew.rate: Slew rate of the digital slew. + * @dac.slew.step_size: Slew step size of the digital slew. + **/ +struct ad5755_platform_data { + bool ext_dc_dc_compenstation_resistor; + enum ad5755_dc_dc_phase dc_dc_phase; + enum ad5755_dc_dc_freq dc_dc_freq; + enum ad5755_dc_dc_maxv dc_dc_maxv; + + struct { + enum ad5755_mode mode; + bool ext_current_sense_resistor; + bool enable_voltage_overrange; + struct { + bool enable; + enum ad5755_slew_rate rate; + enum ad5755_slew_step_size step_size; + } slew; + } dac[4]; +}; + +#endif -- cgit v0.10.2 From 45f010baa0292c367168b1f62d5494965b905b5d Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 17 Sep 2012 13:17:00 +0100 Subject: iio: consumer.h: Fix kernel doc incosistency For the iio_read_channel_raw and iio_read_channel_scale the kerneldoc comment refers to an argument called "channel", while the argument is called "chan" in the function signature. This leads to the following warnings from kerneldoc: Warning(include/linux/iio/consumer.h:71): No description found for parameter 'chan' Warning(include/linux/iio/consumer.h:71): Excess function parameter 'channel' description in 'iio_read_channel_raw' Warning(include/linux/iio/consumer.h:109): No description found for parameter 'chan' Warning(include/linux/iio/consumer.h:109): Excess function parameter 'channel' description in 'iio_read_channel_scale' This patch fixes the warnings by naming them consistently. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h index 06ab4ec..62118dd 100644 --- a/include/linux/iio/consumer.h +++ b/include/linux/iio/consumer.h @@ -61,7 +61,7 @@ void iio_channel_release_all(struct iio_channel *chan); /** * iio_read_channel_raw() - read from a given channel - * @channel: The channel being queried. + * @chan: The channel being queried. * @val: Value read back. * * Note raw reads from iio channels are in adc counts and hence @@ -82,7 +82,7 @@ int iio_get_channel_type(struct iio_channel *channel, /** * iio_read_channel_scale() - read the scale value for a channel - * @channel: The channel being queried. + * @chan: The channel being queried. * @val: First part of value read back. * @val2: Second part of value read back. * -- cgit v0.10.2 From 48e44ce0f8810b530fc83a4f5eb67149280d9b82 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 17 Sep 2012 13:17:00 +0100 Subject: iio:inkern: Add function to read the processed value Add a function to read a processed value from a channel. The function will first attempt to read the IIO_CHAN_INFO_PROCESSED attribute. If that fails it will read the IIO_CHAN_INFO_RAW attribute and convert the result from a raw value to a processed value. The patch also introduces a function to convert raw value to a processed value and exports it, in case a user needs or wants to do the conversion by itself. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index d539e1e..25b0076 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -238,9 +238,21 @@ void iio_channel_release_all(struct iio_channel *channels) } EXPORT_SYMBOL_GPL(iio_channel_release_all); +static int iio_channel_read(struct iio_channel *chan, int *val, int *val2, + enum iio_chan_info_enum info) +{ + int unused; + + if (val2 == NULL) + val2 = &unused; + + return chan->indio_dev->info->read_raw(chan->indio_dev, chan->channel, + val, val2, info); +} + int iio_read_channel_raw(struct iio_channel *chan, int *val) { - int val2, ret; + int ret; mutex_lock(&chan->indio_dev->info_exist_lock); if (chan->indio_dev->info == NULL) { @@ -248,10 +260,7 @@ int iio_read_channel_raw(struct iio_channel *chan, int *val) goto err_unlock; } - ret = chan->indio_dev->info->read_raw(chan->indio_dev, - chan->channel, - val, &val2, - IIO_CHAN_INFO_RAW); + ret = iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_RAW); err_unlock: mutex_unlock(&chan->indio_dev->info_exist_lock); @@ -259,6 +268,100 @@ err_unlock: } EXPORT_SYMBOL_GPL(iio_read_channel_raw); +static int iio_convert_raw_to_processed_unlocked(struct iio_channel *chan, + int raw, int *processed, unsigned int scale) +{ + int scale_type, scale_val, scale_val2, offset; + s64 raw64 = raw; + int ret; + + ret = iio_channel_read(chan, &offset, NULL, IIO_CHAN_INFO_SCALE); + if (ret == 0) + raw64 += offset; + + scale_type = iio_channel_read(chan, &scale_val, &scale_val2, + IIO_CHAN_INFO_SCALE); + if (scale_type < 0) + return scale_type; + + switch (scale_type) { + case IIO_VAL_INT: + *processed = raw64 * scale_val; + break; + case IIO_VAL_INT_PLUS_MICRO: + if (scale_val2 < 0) + *processed = -raw64 * scale_val; + else + *processed = raw64 * scale_val; + *processed += div_s64(raw64 * (s64)scale_val2 * scale, + 1000000LL); + break; + case IIO_VAL_INT_PLUS_NANO: + if (scale_val2 < 0) + *processed = -raw64 * scale_val; + else + *processed = raw64 * scale_val; + *processed += div_s64(raw64 * (s64)scale_val2 * scale, + 1000000000LL); + break; + case IIO_VAL_FRACTIONAL: + *processed = div_s64(raw64 * (s64)scale_val * scale, + scale_val2); + break; + default: + return -EINVAL; + } + + return 0; +} + +int iio_convert_raw_to_processed(struct iio_channel *chan, int raw, + int *processed, unsigned int scale) +{ + int ret; + + mutex_lock(&chan->indio_dev->info_exist_lock); + if (chan->indio_dev->info == NULL) { + ret = -ENODEV; + goto err_unlock; + } + + ret = iio_convert_raw_to_processed_unlocked(chan, raw, processed, + scale); +err_unlock: + mutex_unlock(&chan->indio_dev->info_exist_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(iio_convert_raw_to_processed); + +int iio_read_channel_processed(struct iio_channel *chan, int *val) +{ + int ret; + + mutex_lock(&chan->indio_dev->info_exist_lock); + if (chan->indio_dev->info == NULL) { + ret = -ENODEV; + goto err_unlock; + } + + if (iio_channel_has_info(chan->channel, IIO_CHAN_INFO_PROCESSED)) { + ret = iio_channel_read(chan, val, NULL, + IIO_CHAN_INFO_PROCESSED); + } else { + ret = iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_RAW); + if (ret < 0) + goto err_unlock; + ret = iio_convert_raw_to_processed_unlocked(chan, *val, val, 1); + } + +err_unlock: + mutex_unlock(&chan->indio_dev->info_exist_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(iio_read_channel_processed); + int iio_read_channel_scale(struct iio_channel *chan, int *val, int *val2) { int ret; @@ -269,10 +372,7 @@ int iio_read_channel_scale(struct iio_channel *chan, int *val, int *val2) goto err_unlock; } - ret = chan->indio_dev->info->read_raw(chan->indio_dev, - chan->channel, - val, val2, - IIO_CHAN_INFO_SCALE); + ret = iio_channel_read(chan, val, val2, IIO_CHAN_INFO_SCALE); err_unlock: mutex_unlock(&chan->indio_dev->info_exist_lock); diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h index 62118dd..e875bcf 100644 --- a/include/linux/iio/consumer.h +++ b/include/linux/iio/consumer.h @@ -71,6 +71,21 @@ int iio_read_channel_raw(struct iio_channel *chan, int *val); /** + * iio_read_channel_processed() - read processed value from a given channel + * @chan: The channel being queried. + * @val: Value read back. + * + * Returns an error code or 0. + * + * This function will read a processed value from a channel. A processed value + * means that this value will have the correct unit and not some device internal + * representation. If the device does not support reporting a processed value + * the function will query the raw value and the channels scale and offset and + * do the appropriate transformation. + */ +int iio_read_channel_processed(struct iio_channel *chan, int *val); + +/** * iio_get_channel_type() - get the type of a channel * @channel: The channel being queried. * @type: The type of the channel. @@ -93,4 +108,27 @@ int iio_get_channel_type(struct iio_channel *channel, int iio_read_channel_scale(struct iio_channel *chan, int *val, int *val2); +/** + * iio_convert_raw_to_processed() - Converts a raw value to a processed value + * @chan: The channel being queried + * @raw: The raw IIO to convert + * @processed: The result of the conversion + * @scale: Scale factor to apply during the conversion + * + * Returns an error code or 0. + * + * This function converts a raw value to processed value for a specific channel. + * A raw value is the device internal representation of a sample and the value + * returned by iio_read_channel_raw, so the unit of that value is device + * depended. A processed value on the other hand is value has a normed unit + * according with the IIO specification. + * + * The scale factor allows to increase the precession of the returned value. For + * a scale factor of 1 the function will return the result in the normal IIO + * unit for the channel type. E.g. millivolt for voltage channels, if you want + * nanovolts instead pass 1000 as the scale factor. + */ +int iio_convert_raw_to_processed(struct iio_channel *chan, int raw, + int *processed, unsigned int scale); + #endif diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 30affa5..c0ae76a 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -40,6 +40,8 @@ enum iio_chan_info_enum { #define IIO_CHAN_INFO_SHARED_BIT(type) BIT(type*2) #define IIO_CHAN_INFO_SEPARATE_BIT(type) BIT(type*2 + 1) +#define IIO_CHAN_INFO_BITS(type) (IIO_CHAN_INFO_SHARED_BIT(type) | \ + IIO_CHAN_INFO_SEPARATE_BIT(type)) #define IIO_CHAN_INFO_RAW_SEPARATE_BIT \ IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_RAW) @@ -261,6 +263,21 @@ struct iio_chan_spec { unsigned differential:1; }; + +/** + * iio_channel_has_info() - Checks whether a channel supports a info attribute + * @chan: The channel to be queried + * @type: Type of the info attribute to be checked + * + * Returns true if the channels supports reporting values for the given info + * attribute type, false otherwise. + */ +static inline bool iio_channel_has_info(const struct iio_chan_spec *chan, + enum iio_chan_info_enum type) +{ + return chan->info_mask & IIO_CHAN_INFO_BITS(type); +} + #define IIO_ST(si, rb, sb, sh) \ { .sign = si, .realbits = rb, .storagebits = sb, .shift = sh } -- cgit v0.10.2 From a0e545e0e75006a7de0e9bc5397f6b44c61990b2 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 17 Sep 2012 13:17:00 +0100 Subject: staging:iio:hwmon bridge: Use iio_read_channel_processed Use the iio_read_channel_processed function to read the sample value in the proper unit instead of using iio_read_channel_raw and iio_read_channel_scale and doing the unit conversion manually. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/iio_hwmon.c b/drivers/staging/iio/iio_hwmon.c index 69d4a3b..5d49122 100644 --- a/drivers/staging/iio/iio_hwmon.c +++ b/drivers/staging/iio/iio_hwmon.c @@ -42,40 +42,17 @@ static ssize_t iio_hwmon_read_val(struct device *dev, struct device_attribute *attr, char *buf) { - long result; - int val, ret, scaleint, scalepart; + int result; + int ret; struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); struct iio_hwmon_state *state = dev_get_drvdata(dev); - /* - * No locking between this pair, so theoretically possible - * the scale has changed. - */ - ret = iio_read_channel_raw(&state->channels[sattr->index], - &val); + ret = iio_read_channel_processed(&state->channels[sattr->index], + &result); if (ret < 0) return ret; - ret = iio_read_channel_scale(&state->channels[sattr->index], - &scaleint, &scalepart); - if (ret < 0) - return ret; - switch (ret) { - case IIO_VAL_INT: - result = val * scaleint; - break; - case IIO_VAL_INT_PLUS_MICRO: - result = (s64)val * (s64)scaleint + - div_s64((s64)val * (s64)scalepart, 1000000LL); - break; - case IIO_VAL_INT_PLUS_NANO: - result = (s64)val * (s64)scaleint + - div_s64((s64)val * (s64)scalepart, 1000000000LL); - break; - default: - return -EINVAL; - } - return sprintf(buf, "%ld\n", result); + return sprintf(buf, "%d\n", result); } static void iio_hwmon_free_attrs(struct iio_hwmon_state *st) -- cgit v0.10.2 From 37812d2e10e5790f3cc3319055aac0647080c4af Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 17 Sep 2012 13:26:00 +0100 Subject: staging:iio:trigger:bfintmr: Avoid divide by zero If the timer frequency has not been configured yet get_gptimer_period() will return 0. Handle this case instead of blindly dividing by the returned value. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c index ce6a7b1..2772ea2 100644 --- a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c +++ b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c @@ -99,9 +99,15 @@ static ssize_t iio_bfin_tmr_frequency_show(struct device *dev, { struct iio_trigger *trig = to_iio_trigger(dev); struct bfin_tmr_state *st = trig->private_data; + unsigned int period = get_gptimer_period(st->t->id); + unsigned long val; - return sprintf(buf, "%lu\n", - get_sclk() / get_gptimer_period(st->t->id)); + if (period == 0) + val = 0; + else + val = get_sclk() / get_gptimer_period(st->t->id); + + return sprintf(buf, "%lu\n", val); } static DEVICE_ATTR(frequency, S_IRUGO | S_IWUSR, iio_bfin_tmr_frequency_show, -- cgit v0.10.2 From 2aecc5b95cdb17d7b80463e9c1a542f389403cbb Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 17 Sep 2012 13:26:00 +0100 Subject: staging:iio:trigger:bfintmr: Only enable timer when necessary This patch hooks up the set_trigger_state callback for the blackfin timer trigger driver and only enables the timer when a trigger consumer requests it to be enabled. There really is no reason to keep the timer running and generate interrupts if nobody is listening to them. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c index 2772ea2..d9d3dc9 100644 --- a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c +++ b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c @@ -57,12 +57,28 @@ struct bfin_tmr_state { int irq; }; +static int iio_bfin_tmr_set_state(struct iio_trigger *trig, bool state) +{ + struct bfin_tmr_state *st = trig->private_data; + + if (get_gptimer_period(st->t->id) == 0) + return -EINVAL; + + if (state) + enable_gptimers(st->t->bit); + else + disable_gptimers(st->t->bit); + + return 0; +} + static ssize_t iio_bfin_tmr_frequency_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct iio_trigger *trig = to_iio_trigger(dev); struct bfin_tmr_state *st = trig->private_data; long val; + bool enabled; int ret; ret = strict_strtoul(buf, 10, &val); @@ -74,7 +90,10 @@ static ssize_t iio_bfin_tmr_frequency_store(struct device *dev, goto error_ret; } - disable_gptimers(st->t->bit); + enabled = get_enabled_gptimers() & st->t->bit; + + if (enabled) + disable_gptimers(st->t->bit); if (!val) goto error_ret; @@ -87,7 +106,9 @@ static ssize_t iio_bfin_tmr_frequency_store(struct device *dev, set_gptimer_period(st->t->id, val); set_gptimer_pwidth(st->t->id, 1); - enable_gptimers(st->t->bit); + + if (enabled) + enable_gptimers(st->t->bit); error_ret: return ret ? ret : count; @@ -127,7 +148,6 @@ static const struct attribute_group *iio_bfin_tmr_trigger_attr_groups[] = { NULL }; - static irqreturn_t iio_bfin_tmr_trigger_isr(int irq, void *devid) { struct bfin_tmr_state *st = devid; @@ -151,6 +171,7 @@ static int iio_bfin_tmr_get_number(int irq) static const struct iio_trigger_ops iio_bfin_tmr_trigger_ops = { .owner = THIS_MODULE, + .set_trigger_state = iio_bfin_tmr_set_state, }; static int __devinit iio_bfin_tmr_trigger_probe(struct platform_device *pdev) -- cgit v0.10.2 From 587a51241c5d74a1e262d34e990f85dc4e5318c5 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 17 Sep 2012 13:26:00 +0100 Subject: staging:iio:trigger:bfintmr Add output support Some converters require an external signal to start the conversion. This patch adds support to the bfintmr trigger driver to generate such a signal. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c index d9d3dc9..52062d7 100644 --- a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c +++ b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c @@ -14,14 +14,18 @@ #include #include +#include #include #include +#include "iio-trig-bfin-timer.h" + struct bfin_timer { unsigned short id, bit; unsigned long irqbit; int irq; + int pin; }; /* @@ -30,22 +34,22 @@ struct bfin_timer { */ static struct bfin_timer iio_bfin_timer_code[MAX_BLACKFIN_GPTIMERS] = { - {TIMER0_id, TIMER0bit, TIMER_STATUS_TIMIL0, IRQ_TIMER0}, - {TIMER1_id, TIMER1bit, TIMER_STATUS_TIMIL1, IRQ_TIMER1}, - {TIMER2_id, TIMER2bit, TIMER_STATUS_TIMIL2, IRQ_TIMER2}, + {TIMER0_id, TIMER0bit, TIMER_STATUS_TIMIL0, IRQ_TIMER0, P_TMR0}, + {TIMER1_id, TIMER1bit, TIMER_STATUS_TIMIL1, IRQ_TIMER1, P_TMR1}, + {TIMER2_id, TIMER2bit, TIMER_STATUS_TIMIL2, IRQ_TIMER2, P_TMR2}, #if (MAX_BLACKFIN_GPTIMERS > 3) - {TIMER3_id, TIMER3bit, TIMER_STATUS_TIMIL3, IRQ_TIMER3}, - {TIMER4_id, TIMER4bit, TIMER_STATUS_TIMIL4, IRQ_TIMER4}, - {TIMER5_id, TIMER5bit, TIMER_STATUS_TIMIL5, IRQ_TIMER5}, - {TIMER6_id, TIMER6bit, TIMER_STATUS_TIMIL6, IRQ_TIMER6}, - {TIMER7_id, TIMER7bit, TIMER_STATUS_TIMIL7, IRQ_TIMER7}, + {TIMER3_id, TIMER3bit, TIMER_STATUS_TIMIL3, IRQ_TIMER3, P_TMR3}, + {TIMER4_id, TIMER4bit, TIMER_STATUS_TIMIL4, IRQ_TIMER4, P_TMR4}, + {TIMER5_id, TIMER5bit, TIMER_STATUS_TIMIL5, IRQ_TIMER5, P_TMR5}, + {TIMER6_id, TIMER6bit, TIMER_STATUS_TIMIL6, IRQ_TIMER6, P_TMR6}, + {TIMER7_id, TIMER7bit, TIMER_STATUS_TIMIL7, IRQ_TIMER7, P_TMR7}, #endif #if (MAX_BLACKFIN_GPTIMERS > 8) - {TIMER8_id, TIMER8bit, TIMER_STATUS_TIMIL8, IRQ_TIMER8}, - {TIMER9_id, TIMER9bit, TIMER_STATUS_TIMIL9, IRQ_TIMER9}, - {TIMER10_id, TIMER10bit, TIMER_STATUS_TIMIL10, IRQ_TIMER10}, + {TIMER8_id, TIMER8bit, TIMER_STATUS_TIMIL8, IRQ_TIMER8, P_TMR8}, + {TIMER9_id, TIMER9bit, TIMER_STATUS_TIMIL9, IRQ_TIMER9, P_TMR9}, + {TIMER10_id, TIMER10bit, TIMER_STATUS_TIMIL10, IRQ_TIMER10, P_TMR10}, #if (MAX_BLACKFIN_GPTIMERS > 11) - {TIMER11_id, TIMER11bit, TIMER_STATUS_TIMIL11, IRQ_TIMER11}, + {TIMER11_id, TIMER11bit, TIMER_STATUS_TIMIL11, IRQ_TIMER11, P_TMR11}, #endif #endif }; @@ -54,6 +58,8 @@ struct bfin_tmr_state { struct iio_trigger *trig; struct bfin_timer *t; unsigned timer_num; + bool output_enable; + unsigned int duty; int irq; }; @@ -77,7 +83,7 @@ static ssize_t iio_bfin_tmr_frequency_store(struct device *dev, { struct iio_trigger *trig = to_iio_trigger(dev); struct bfin_tmr_state *st = trig->private_data; - long val; + unsigned long val; bool enabled; int ret; @@ -99,13 +105,13 @@ static ssize_t iio_bfin_tmr_frequency_store(struct device *dev, goto error_ret; val = get_sclk() / val; - if (val <= 4) { + if (val <= 4 || val <= st->duty) { ret = -EINVAL; goto error_ret; } set_gptimer_period(st->t->id, val); - set_gptimer_pwidth(st->t->id, 1); + set_gptimer_pwidth(st->t->id, val - st->duty); if (enabled) enable_gptimers(st->t->bit); @@ -176,7 +182,9 @@ static const struct iio_trigger_ops iio_bfin_tmr_trigger_ops = { static int __devinit iio_bfin_tmr_trigger_probe(struct platform_device *pdev) { + struct iio_bfin_timer_trigger_pdata *pdata = pdev->dev.platform_data; struct bfin_tmr_state *st; + unsigned int config; int ret; st = kzalloc(sizeof(*st), GFP_KERNEL); @@ -220,13 +228,43 @@ static int __devinit iio_bfin_tmr_trigger_probe(struct platform_device *pdev) goto out4; } - set_gptimer_config(st->t->id, OUT_DIS | PWM_OUT | PERIOD_CNT | IRQ_ENA); + config = PWM_OUT | PERIOD_CNT | IRQ_ENA; + + if (pdata && pdata->output_enable) { + unsigned long long val; + + st->output_enable = true; + + ret = peripheral_request(st->t->pin, st->trig->name); + if (ret) + goto out_free_irq; + + val = (unsigned long long)get_sclk() * pdata->duty_ns; + do_div(val, NSEC_PER_SEC); + st->duty = val; + + /** + * The interrupt will be generated at the end of the period, + * since we want the interrupt to be generated at end of the + * pulse we invert both polarity and duty cycle, so that the + * pulse will be generated directly before the interrupt. + */ + if (pdata->active_low) + config |= PULSE_HI; + } else { + st->duty = 1; + config |= OUT_DIS; + } + + set_gptimer_config(st->t->id, config); dev_info(&pdev->dev, "iio trigger Blackfin TMR%d, IRQ-%d", st->timer_num, st->irq); platform_set_drvdata(pdev, st); return 0; +out_free_irq: + free_irq(st->irq, st); out4: iio_trigger_unregister(st->trig); out2: @@ -242,6 +280,8 @@ static int __devexit iio_bfin_tmr_trigger_remove(struct platform_device *pdev) struct bfin_tmr_state *st = platform_get_drvdata(pdev); disable_gptimers(st->t->bit); + if (st->output_enable) + peripheral_free(st->t->pin); free_irq(st->irq, st); iio_trigger_unregister(st->trig); iio_trigger_put(st->trig); diff --git a/drivers/staging/iio/trigger/iio-trig-bfin-timer.h b/drivers/staging/iio/trigger/iio-trig-bfin-timer.h new file mode 100644 index 0000000..c07321f --- /dev/null +++ b/drivers/staging/iio/trigger/iio-trig-bfin-timer.h @@ -0,0 +1,24 @@ +#ifndef __IIO_BFIN_TIMER_TRIGGER_H__ +#define __IIO_BFIN_TIMER_TRIGGER_H__ + +/** + * struct iio_bfin_timer_trigger_pdata - timer trigger platform data + * @output_enable: Enable external trigger pulse generation. + * @active_low: Whether the trigger pulse is active low. + * @duty_ns: Length of the trigger pulse in nanoseconds. + * + * This struct is used to configure the output pulse generation of the blackfin + * timer trigger. If output_enable is set to true an external trigger signal + * will generated on the pin corresponding to the timer. This is useful for + * converters which needs an external signal to start conversion. active_low and + * duty_ns are used to configure the type of the trigger pulse. If output_enable + * is set to false no external trigger pulse will be generated and active_low + * and duty_ns are ignored. + **/ +struct iio_bfin_timer_trigger_pdata { + bool output_enable; + bool active_low; + unsigned int duty_ns; +}; + +#endif -- cgit v0.10.2 From 87c5b10fd97937796dbf0769e8790a5f275b4a37 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 17 Sep 2012 13:26:00 +0100 Subject: iio: ad7476: Add support for the ad7091r Add support for the ad7091r 12 bit ADC to the ad7476 driver. Although the ad7091r is not really related to any of the other devices supported by this driver, luckily for us there are not so many ways (which are not totally insane) how sampling a single channel ADC via SPI can be implemented and support for the ad7091r can be added to the driver with just a few adjustments. The ad7091r requires an external "conversion start" pulse to start a sample conversion. After the conversion has finished the result can be read via SPI. We depend on a IIO trigger to generate this signal, as a result only sampling in buffered mode and not in manual mode is available. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/adc/ad7476.c b/drivers/iio/adc/ad7476.c index be2098d..7f2f45a 100644 --- a/drivers/iio/adc/ad7476.c +++ b/drivers/iio/adc/ad7476.c @@ -23,9 +23,12 @@ #define RES_MASK(bits) ((1 << (bits)) - 1) +struct ad7476_state; + struct ad7476_chip_info { unsigned int int_vref_uv; struct iio_chan_spec channel[2]; + void (*reset)(struct ad7476_state *); }; struct ad7476_state { @@ -45,6 +48,7 @@ struct ad7476_state { }; enum ad7476_supported_device_ids { + ID_AD7091R, ID_AD7276, ID_AD7277, ID_AD7278, @@ -79,6 +83,12 @@ done: return IRQ_HANDLED; } +static void ad7091_reset(struct ad7476_state *st) +{ + /* Any transfers with 8 scl cycles will reset the device */ + spi_read(st->spi, st->data, 1); +} + static int ad7476_scan_direct(struct ad7476_state *st) { int ret; @@ -130,11 +140,11 @@ static int ad7476_read_raw(struct iio_dev *indio_dev, return -EINVAL; } -#define _AD7476_CHAN(bits, _shift) \ +#define _AD7476_CHAN(bits, _shift, _info_mask) \ { \ .type = IIO_VOLTAGE, \ .indexed = 1, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + .info_mask = _info_mask | \ IIO_CHAN_INFO_SCALE_SHARED_BIT, \ .scan_type = { \ .sign = 'u', \ @@ -145,10 +155,18 @@ static int ad7476_read_raw(struct iio_dev *indio_dev, }, \ } -#define AD7476_CHAN(bits) _AD7476_CHAN((bits), 13 - (bits)) -#define AD7940_CHAN(bits) _AD7476_CHAN((bits), 15 - (bits)) +#define AD7476_CHAN(bits) _AD7476_CHAN((bits), 13 - (bits), \ + IIO_CHAN_INFO_RAW_SEPARATE_BIT) +#define AD7940_CHAN(bits) _AD7476_CHAN((bits), 15 - (bits), \ + IIO_CHAN_INFO_RAW_SEPARATE_BIT) +#define AD7091R_CHAN(bits) _AD7476_CHAN((bits), 16 - (bits), 0) static const struct ad7476_chip_info ad7476_chip_info_tbl[] = { + [ID_AD7091R] = { + .channel[0] = AD7091R_CHAN(12), + .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), + .reset = ad7091_reset, + }, [ID_AD7276] = { .channel[0] = AD7940_CHAN(12), .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), @@ -238,6 +256,9 @@ static int __devinit ad7476_probe(struct spi_device *spi) if (ret) goto error_disable_reg; + if (st->chip_info->reset) + st->chip_info->reset(st); + ret = iio_device_register(indio_dev); if (ret) goto error_ring_unregister; @@ -271,6 +292,7 @@ static int __devexit ad7476_remove(struct spi_device *spi) } static const struct spi_device_id ad7476_id[] = { + {"ad7091r", ID_AD7091R}, {"ad7273", ID_AD7277}, {"ad7274", ID_AD7276}, {"ad7276", ID_AD7276}, -- cgit v0.10.2 From 8ab92cbdb37b87d4fda4c2cb1c0f586856c6c64a Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 17 Sep 2012 10:33:18 -0700 Subject: staging: fix csr printk format warning Fix printk format warning on i386/X86_32 by using 't' for ptrdiff_t. Also builds cleanly on x86_64. drivers/staging/csr/csr_wifi_hip_udi.c: In function 'unifi_print_status': drivers/staging/csr/csr_wifi_hip_udi.c:151:27: warning: format '%ld' expects type 'long int', but argument 5 has type 'int' Signed-off-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/csr/csr_wifi_hip_udi.c b/drivers/staging/csr/csr_wifi_hip_udi.c index 31a27cc..a65b822 100644 --- a/drivers/staging/csr/csr_wifi_hip_udi.c +++ b/drivers/staging/csr/csr_wifi_hip_udi.c @@ -146,7 +146,7 @@ s32 unifi_print_status(card_t *card, char *str, s32 *remain) (u16)card->to_host_signals_w); UNIFI_SNPRINTF_RET(p, remaining, written); written = scnprintf(p, remaining, - "fh buffer contains: %d signals, %ld bytes\n", + "fh buffer contains: %d signals, %td bytes\n", card->fh_buffer.count, card->fh_buffer.ptr - card->fh_buffer.buf); UNIFI_SNPRINTF_RET(p, remaining, written); -- cgit v0.10.2 From 2b5d20db81276149d70db02be876511137a64b7f Mon Sep 17 00:00:00 2001 From: Lauri Hintsala Date: Mon, 17 Sep 2012 16:26:31 +0300 Subject: staging: csr: wait for the exec in usermodehelper The order of wait values has been changed by commit 9d944ef32e. Fix the wait parameter and start to use a define instead of "magic number". Signed-off-by: Lauri Hintsala Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/csr/firmware.c b/drivers/staging/csr/firmware.c index dc6a04d..b6d8a6e 100644 --- a/drivers/staging/csr/firmware.c +++ b/drivers/staging/csr/firmware.c @@ -286,7 +286,7 @@ uf_run_unifihelper(unifi_priv_t *priv) unifi_trace(priv, UDBG2, "running %s %s %s\n", argv[0], argv[1], argv[2]); - r = call_usermodehelper(argv[0], argv, envp, 0); + r = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC); return r; #else -- cgit v0.10.2 From 6d3616bb1902eaf9f096731fe06f9e5c033914b6 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 17 Sep 2012 08:20:24 -0700 Subject: staging: "wlags49_h25" Fix typos. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlags49_h25/Kconfig b/drivers/staging/wlags49_h25/Kconfig index bf5664a..dd8dc4d 100644 --- a/drivers/staging/wlags49_h25/Kconfig +++ b/drivers/staging/wlags49_h25/Kconfig @@ -8,4 +8,4 @@ config WLAGS49_H25 Driver for wireless cards using Agere's HERMES II.5 chipset which are identified with Manufacture ID: 0156,0004 The software is a modified version of wl_lkm_722_abg.tar.gz - from the Agere Systems website, addapted for Ubuntu 9.04. + from the Agere Systems website, adapted for Ubuntu 9.04. diff --git a/drivers/staging/wlags49_h25/TODO b/drivers/staging/wlags49_h25/TODO index 94032b6..ec71ad3 100644 --- a/drivers/staging/wlags49_h25/TODO +++ b/drivers/staging/wlags49_h25/TODO @@ -1,4 +1,4 @@ -First of all, the best thing would be that this driver becomes obsolte by +First of all, the best thing would be that this driver becomes obsolete by adding support for Hermes II and Hermes II.5 cards to the existing orinoco driver. The orinoco driver currently only supports Hermes I based cards. Since this will not happen by magic and has not happened until now this @@ -10,11 +10,11 @@ list. TODO: - verify against a Hermes II.5 card - - verify with WPA encription (both with H2 and H2.5 cards) + - verify with WPA encryption (both with H2 and H2.5 cards) - sometimes the card does not initialize correctly, retry mechanisms are build in to catch most cases but not all - once the driver runs it is very stable, but I have the impression - some the crittical sections take to long + some the critical sections take to long - the driver is split into a Hermes II and a Hermes II.5 part, it would be nice to handle both with one module instead of two - review by the wireless developer community @@ -25,7 +25,7 @@ TODO: DONE: - verified against a Hermes II card (Thomson Speedtouch 110 PCMCIA card) - - verified with WEP encription + - verified with WEP encryption Please send any patches or complaints about this driver to Greg Kroah-Hartman and Cc: Henk de Groot -- cgit v0.10.2 From d459a03b90ae2895d0726b9a6f5147efa30ca11f Mon Sep 17 00:00:00 2001 From: "Javier M. Mellid" Date: Mon, 17 Sep 2012 16:12:47 +0200 Subject: staging: sm7xxfb: clean fb_fix_screeninfo and fb_var_screeninfo initialization Part of fb_fix_screeninfo and fb_var_screeninfo initialization happens in smtc_alloc_fb_info. It duplicates code while hiding the real functionality of smtc_alloc_fb_info. This patch groups initialization together. Signed-off-by: Javier M. Mellid Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/sm7xxfb/sm7xxfb.c b/drivers/staging/sm7xxfb/sm7xxfb.c index d935c23..b809e2c 100644 --- a/drivers/staging/sm7xxfb/sm7xxfb.c +++ b/drivers/staging/sm7xxfb/sm7xxfb.c @@ -72,6 +72,8 @@ static struct fb_var_screeninfo smtcfb_var = { .height = -1, .width = -1, .vmode = FB_VMODE_NONINTERLACED, + .nonstd = 0, + .accel_flags = FB_ACCELF_TEXT, }; static struct fb_fix_screeninfo smtcfb_fix = { @@ -80,6 +82,10 @@ static struct fb_fix_screeninfo smtcfb_fix = { .visual = FB_VISUAL_TRUECOLOR, .line_length = 800 * 3, .accel = FB_ACCEL_SMI_LYNX, + .type_aux = 0, + .xpanstep = 0, + .ypanstep = 0, + .ywrapstep = 0, }; struct vesa_mode { @@ -694,20 +700,7 @@ static struct smtcfb_info *smtc_alloc_fb_info(struct pci_dev *pdev, char *name) sfb->fb.fix = smtcfb_fix; strcpy(sfb->fb.fix.id, name); - sfb->fb.fix.type = FB_TYPE_PACKED_PIXELS; - sfb->fb.fix.type_aux = 0; - sfb->fb.fix.xpanstep = 0; - sfb->fb.fix.ypanstep = 0; - sfb->fb.fix.ywrapstep = 0; - sfb->fb.fix.accel = FB_ACCEL_SMI_LYNX; - - sfb->fb.var = smtcfb_var; - sfb->fb.var.nonstd = 0; - sfb->fb.var.activate = FB_ACTIVATE_NOW; - sfb->fb.var.height = -1; - sfb->fb.var.width = -1; - sfb->fb.var.accel_flags = FB_ACCELF_TEXT; - sfb->fb.var.vmode = FB_VMODE_NONINTERLACED; + sfb->fb.var = smtcfb_var; sfb->fb.pseudo_palette = sfb->colreg; -- cgit v0.10.2 From 9f6fe04326da5036ab0d01553eacabe9b21d47ae Mon Sep 17 00:00:00 2001 From: "Javier M. Mellid" Date: Mon, 17 Sep 2012 16:12:48 +0200 Subject: staging: sm7xxfb: clean smtcfb_fix's id initialization Setting up smtcfb_fix's id happens through smtc_alloc_fb_info. It adds complexity and unnecesary code. Signed-off-by: Javier M. Mellid Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/sm7xxfb/sm7xxfb.c b/drivers/staging/sm7xxfb/sm7xxfb.c index b809e2c..f6ecac3 100644 --- a/drivers/staging/sm7xxfb/sm7xxfb.c +++ b/drivers/staging/sm7xxfb/sm7xxfb.c @@ -77,7 +77,7 @@ static struct fb_var_screeninfo smtcfb_var = { }; static struct fb_fix_screeninfo smtcfb_fix = { - .id = "sm712fb", + .id = "smXXXfb", .type = FB_TYPE_PACKED_PIXELS, .visual = FB_VISUAL_TRUECOLOR, .line_length = 800 * 3, @@ -681,7 +681,7 @@ static struct fb_ops smtcfb_ops = { /* * alloc struct smtcfb_info and assign the default value */ -static struct smtcfb_info *smtc_alloc_fb_info(struct pci_dev *pdev, char *name) +static struct smtcfb_info *smtc_alloc_fb_info(struct pci_dev *pdev) { struct smtcfb_info *sfb; @@ -698,7 +698,6 @@ static struct smtcfb_info *smtc_alloc_fb_info(struct pci_dev *pdev, char *name) sfb->fb.fbops = &smtcfb_ops; sfb->fb.fix = smtcfb_fix; - strcpy(sfb->fb.fix.id, name); sfb->fb.var = smtcfb_var; @@ -781,7 +780,6 @@ static int __devinit smtcfb_pci_probe(struct pci_dev *pdev, { struct smtcfb_info *sfb; u_long smem_size = 0x00800000; /* default 8MB */ - char name[16]; int err; unsigned long pFramebufferPhysical; @@ -791,9 +789,9 @@ static int __devinit smtcfb_pci_probe(struct pci_dev *pdev, if (err) return err; - sprintf(name, "sm%Xfb", ent->device); + sprintf(smtcfb_fix.id, "sm%Xfb", ent->device); - sfb = smtc_alloc_fb_info(pdev, name); + sfb = smtc_alloc_fb_info(pdev); if (!sfb) { err = -ENOMEM; -- cgit v0.10.2 From 20d471c447d5fede8d0d2b3618450d9ab8d82da9 Mon Sep 17 00:00:00 2001 From: "Javier M. Mellid" Date: Mon, 17 Sep 2012 16:12:49 +0200 Subject: staging: sm7xxfb: cleanup on smtc_alloc_fb_info This patch improves code legibility after last changes. Signed-off-by: Javier M. Mellid Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/sm7xxfb/sm7xxfb.c b/drivers/staging/sm7xxfb/sm7xxfb.c index f6ecac3..5ad52b9 100644 --- a/drivers/staging/sm7xxfb/sm7xxfb.c +++ b/drivers/staging/sm7xxfb/sm7xxfb.c @@ -679,7 +679,7 @@ static struct fb_ops smtcfb_ops = { }; /* - * alloc struct smtcfb_info and assign the default value + * alloc struct smtcfb_info and assign default values */ static struct smtcfb_info *smtc_alloc_fb_info(struct pci_dev *pdev) { @@ -692,18 +692,12 @@ static struct smtcfb_info *smtc_alloc_fb_info(struct pci_dev *pdev) sfb->pdev = pdev; - /* init sfb->fb with default value */ - - sfb->fb.flags = FBINFO_FLAG_DEFAULT; - sfb->fb.fbops = &smtcfb_ops; - - sfb->fb.fix = smtcfb_fix; - - sfb->fb.var = smtcfb_var; - - sfb->fb.pseudo_palette = sfb->colreg; - - sfb->fb.par = sfb; + sfb->fb.flags = FBINFO_FLAG_DEFAULT; + sfb->fb.fbops = &smtcfb_ops; + sfb->fb.fix = smtcfb_fix; + sfb->fb.var = smtcfb_var; + sfb->fb.pseudo_palette = sfb->colreg; + sfb->fb.par = sfb; return sfb; } -- cgit v0.10.2 From 5d0c77026be682141eef24fdb10e4f2d39df7ccb Mon Sep 17 00:00:00 2001 From: "Javier M. Mellid" Date: Mon, 17 Sep 2012 16:12:50 +0200 Subject: staging: sm7xxfb: annotate iomem pointers This patch annotates iomem pointers. Signed-off-by: Javier M. Mellid Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/sm7xxfb/sm7xx.h b/drivers/staging/sm7xxfb/sm7xx.h index 333f33c..8599861 100644 --- a/drivers/staging/sm7xxfb/sm7xx.h +++ b/drivers/staging/sm7xxfb/sm7xx.h @@ -29,7 +29,7 @@ #define dac_reg (0x3c8) #define dac_val (0x3c9) -extern char __iomem *smtc_RegBaseAddress; +extern void __iomem *smtc_RegBaseAddress; #define smtc_mmiowb(dat, reg) writeb(dat, smtc_RegBaseAddress + reg) #define smtc_mmioww(dat, reg) writew(dat, smtc_RegBaseAddress + reg) #define smtc_mmiowl(dat, reg) writel(dat, smtc_RegBaseAddress + reg) diff --git a/drivers/staging/sm7xxfb/sm7xxfb.c b/drivers/staging/sm7xxfb/sm7xxfb.c index 5ad52b9..3fa55a8 100644 --- a/drivers/staging/sm7xxfb/sm7xxfb.c +++ b/drivers/staging/sm7xxfb/sm7xxfb.c @@ -43,11 +43,11 @@ struct smtcfb_info { u16 chip_id; u8 chip_rev_id; - unsigned char __iomem *m_pMMIO; - char __iomem *m_pLFB; - char *m_pDPR; - char *m_pVPR; - char *m_pCPR; + void __iomem *m_pMMIO; + void __iomem *m_pLFB; + void __iomem *m_pDPR; + void __iomem *m_pVPR; + void __iomem *m_pCPR; u_int width; u_int height; @@ -56,8 +56,8 @@ struct smtcfb_info { u32 colreg[17]; }; -char __iomem *smtc_RegBaseAddress; /* Memory Map IO starting address */ -char __iomem *smtc_VRAMBaseAddress; /* video memory starting address */ +void __iomem *smtc_RegBaseAddress; /* Memory Map IO starting address */ +void __iomem *smtc_VRAMBaseAddress; /* video memory starting address */ static struct fb_var_screeninfo smtcfb_var = { .xres = 1024, -- cgit v0.10.2 From 3da53b141616dd856ae2c232e126483975891382 Mon Sep 17 00:00:00 2001 From: "Javier M. Mellid" Date: Mon, 17 Sep 2012 16:12:51 +0200 Subject: staging: sm7xxfb: rename some smtcfb_info fields This patch improves naming style and comments on smtcfb_info fields. Signed-off-by: Javier M. Mellid Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/sm7xxfb/sm7xxfb.c b/drivers/staging/sm7xxfb/sm7xxfb.c index 3fa55a8..1358fc7 100644 --- a/drivers/staging/sm7xxfb/sm7xxfb.c +++ b/drivers/staging/sm7xxfb/sm7xxfb.c @@ -43,11 +43,11 @@ struct smtcfb_info { u16 chip_id; u8 chip_rev_id; - void __iomem *m_pMMIO; - void __iomem *m_pLFB; - void __iomem *m_pDPR; - void __iomem *m_pVPR; - void __iomem *m_pCPR; + void __iomem *lfb; /* linear frame buffer */ + void __iomem *dp_regs; /* drawing processor control regs */ + void __iomem *vp_regs; /* video processor control regs */ + void __iomem *cp_regs; /* capture processor control regs */ + void __iomem *mmio; /* memory map IO port */ u_int width; u_int height; @@ -551,28 +551,28 @@ static void sm7xx_set_timing(struct smtcfb_info *sfb) smtc_mmiowb(0x67, 0x3c2); /* set VPR registers */ - writel(0x0, sfb->m_pVPR + 0x0C); - writel(0x0, sfb->m_pVPR + 0x40); + writel(0x0, sfb->vp_regs + 0x0C); + writel(0x0, sfb->vp_regs + 0x40); /* set data width */ m_nScreenStride = (sfb->width * sfb->fb.var.bits_per_pixel) / 64; switch (sfb->fb.var.bits_per_pixel) { case 8: - writel(0x0, sfb->m_pVPR + 0x0); + writel(0x0, sfb->vp_regs + 0x0); break; case 16: - writel(0x00020000, sfb->m_pVPR + 0x0); + writel(0x00020000, sfb->vp_regs + 0x0); break; case 24: - writel(0x00040000, sfb->m_pVPR + 0x0); + writel(0x00040000, sfb->vp_regs + 0x0); break; case 32: - writel(0x00030000, sfb->m_pVPR + 0x0); + writel(0x00030000, sfb->vp_regs + 0x0); break; } writel((u32) (((m_nScreenStride + 2) << 16) | m_nScreenStride), - sfb->m_pVPR + 0x10); + sfb->vp_regs + 0x10); } @@ -825,23 +825,23 @@ static int __devinit smtcfb_pci_probe(struct pci_dev *pdev, sfb->fb.fix.mmio_len = 0x00400000; smem_size = SM712_VIDEOMEMORYSIZE; #ifdef __BIG_ENDIAN - sfb->m_pLFB = (smtc_VRAMBaseAddress = + sfb->lfb = (smtc_VRAMBaseAddress = ioremap(pFramebufferPhysical, 0x00c00000)); #else - sfb->m_pLFB = (smtc_VRAMBaseAddress = + sfb->lfb = (smtc_VRAMBaseAddress = ioremap(pFramebufferPhysical, 0x00800000)); #endif - sfb->m_pMMIO = (smtc_RegBaseAddress = + sfb->mmio = (smtc_RegBaseAddress = smtc_VRAMBaseAddress + 0x00700000); - sfb->m_pDPR = smtc_VRAMBaseAddress + 0x00408000; - sfb->m_pVPR = sfb->m_pLFB + 0x0040c000; + sfb->dp_regs = smtc_VRAMBaseAddress + 0x00408000; + sfb->vp_regs = sfb->lfb + 0x0040c000; #ifdef __BIG_ENDIAN if (sfb->fb.var.bits_per_pixel == 32) { smtc_VRAMBaseAddress += 0x800000; - sfb->m_pLFB += 0x800000; + sfb->lfb += 0x800000; dev_info(&pdev->dev, - "smtc_VRAMBaseAddress=%p sfb->m_pLFB=%p", - smtc_VRAMBaseAddress, sfb->m_pLFB); + "smtc_VRAMBaseAddress=%p sfb->lfb=%p", + smtc_VRAMBaseAddress, sfb->lfb); } #endif if (!smtc_RegBaseAddress) { @@ -868,12 +868,12 @@ static int __devinit smtcfb_pci_probe(struct pci_dev *pdev, sfb->fb.fix.mmio_start = pFramebufferPhysical; sfb->fb.fix.mmio_len = 0x00200000; smem_size = SM722_VIDEOMEMORYSIZE; - sfb->m_pDPR = ioremap(pFramebufferPhysical, 0x00a00000); - sfb->m_pLFB = (smtc_VRAMBaseAddress = - sfb->m_pDPR + 0x00200000); - sfb->m_pMMIO = (smtc_RegBaseAddress = - sfb->m_pDPR + 0x000c0000); - sfb->m_pVPR = sfb->m_pDPR + 0x800; + sfb->dp_regs = ioremap(pFramebufferPhysical, 0x00a00000); + sfb->lfb = (smtc_VRAMBaseAddress = + sfb->dp_regs + 0x00200000); + sfb->mmio = (smtc_RegBaseAddress = + sfb->dp_regs + 0x000c0000); + sfb->vp_regs = sfb->dp_regs + 0x800; smtc_seqw(0x62, 0xff); smtc_seqw(0x6a, 0x0d); -- cgit v0.10.2 From 3f28ed174198f210addf77b126573e29a0b75478 Mon Sep 17 00:00:00 2001 From: "Javier M. Mellid" Date: Mon, 17 Sep 2012 16:12:52 +0200 Subject: staging: sm7xxfb: rename pFramebufferPhysical to mmio_base This patch renames pFramebufferPhysical name to mmio_base. Signed-off-by: Javier M. Mellid Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/sm7xxfb/sm7xxfb.c b/drivers/staging/sm7xxfb/sm7xxfb.c index 1358fc7..11fb9f5 100644 --- a/drivers/staging/sm7xxfb/sm7xxfb.c +++ b/drivers/staging/sm7xxfb/sm7xxfb.c @@ -775,7 +775,7 @@ static int __devinit smtcfb_pci_probe(struct pci_dev *pdev, struct smtcfb_info *sfb; u_long smem_size = 0x00800000; /* default 8MB */ int err; - unsigned long pFramebufferPhysical; + unsigned long mmio_base; dev_info(&pdev->dev, "Silicon Motion display driver."); @@ -815,21 +815,21 @@ static int __devinit smtcfb_pci_probe(struct pci_dev *pdev, sfb->fb.var.bits_per_pixel = (smtc_scr_info.lfb_depth = 32); #endif /* Map address and memory detection */ - pFramebufferPhysical = pci_resource_start(pdev, 0); + mmio_base = pci_resource_start(pdev, 0); pci_read_config_byte(pdev, PCI_REVISION_ID, &sfb->chip_rev_id); switch (sfb->chip_id) { case 0x710: case 0x712: - sfb->fb.fix.mmio_start = pFramebufferPhysical + 0x00400000; + sfb->fb.fix.mmio_start = mmio_base + 0x00400000; sfb->fb.fix.mmio_len = 0x00400000; smem_size = SM712_VIDEOMEMORYSIZE; #ifdef __BIG_ENDIAN sfb->lfb = (smtc_VRAMBaseAddress = - ioremap(pFramebufferPhysical, 0x00c00000)); + ioremap(mmio_base, 0x00c00000)); #else sfb->lfb = (smtc_VRAMBaseAddress = - ioremap(pFramebufferPhysical, 0x00800000)); + ioremap(mmio_base, 0x00800000)); #endif sfb->mmio = (smtc_RegBaseAddress = smtc_VRAMBaseAddress + 0x00700000); @@ -865,10 +865,10 @@ static int __devinit smtcfb_pci_probe(struct pci_dev *pdev, #endif break; case 0x720: - sfb->fb.fix.mmio_start = pFramebufferPhysical; + sfb->fb.fix.mmio_start = mmio_base; sfb->fb.fix.mmio_len = 0x00200000; smem_size = SM722_VIDEOMEMORYSIZE; - sfb->dp_regs = ioremap(pFramebufferPhysical, 0x00a00000); + sfb->dp_regs = ioremap(mmio_base, 0x00a00000); sfb->lfb = (smtc_VRAMBaseAddress = sfb->dp_regs + 0x00200000); sfb->mmio = (smtc_RegBaseAddress = -- cgit v0.10.2 From 87765b97718a301eeefcaca8867b48bea96b1727 Mon Sep 17 00:00:00 2001 From: "Javier M. Mellid" Date: Mon, 17 Sep 2012 16:12:53 +0200 Subject: staging: sm7xxfb: remove smtc_VRAMBaseAddress This patch erases smtc_VRAMBaseAddress variable. Signed-off-by: Javier M. Mellid Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/sm7xxfb/sm7xxfb.c b/drivers/staging/sm7xxfb/sm7xxfb.c index 11fb9f5..f27182d 100644 --- a/drivers/staging/sm7xxfb/sm7xxfb.c +++ b/drivers/staging/sm7xxfb/sm7xxfb.c @@ -57,7 +57,6 @@ struct smtcfb_info { }; void __iomem *smtc_RegBaseAddress; /* Memory Map IO starting address */ -void __iomem *smtc_VRAMBaseAddress; /* video memory starting address */ static struct fb_var_screeninfo smtcfb_var = { .xres = 1024, @@ -737,7 +736,7 @@ static int smtc_map_smem(struct smtcfb_info *sfb, sfb->fb.fix.smem_len = smem_len; - sfb->fb.screen_base = smtc_VRAMBaseAddress; + sfb->fb.screen_base = sfb->lfb; if (!sfb->fb.screen_base) { dev_err(&pdev->dev, @@ -825,23 +824,18 @@ static int __devinit smtcfb_pci_probe(struct pci_dev *pdev, sfb->fb.fix.mmio_len = 0x00400000; smem_size = SM712_VIDEOMEMORYSIZE; #ifdef __BIG_ENDIAN - sfb->lfb = (smtc_VRAMBaseAddress = - ioremap(mmio_base, 0x00c00000)); + sfb->lfb = ioremap(mmio_base, 0x00c00000); #else - sfb->lfb = (smtc_VRAMBaseAddress = - ioremap(mmio_base, 0x00800000)); + sfb->lfb = ioremap(mmio_base, 0x00800000); #endif sfb->mmio = (smtc_RegBaseAddress = - smtc_VRAMBaseAddress + 0x00700000); - sfb->dp_regs = smtc_VRAMBaseAddress + 0x00408000; + sfb->lfb + 0x00700000); + sfb->dp_regs = sfb->lfb + 0x00408000; sfb->vp_regs = sfb->lfb + 0x0040c000; #ifdef __BIG_ENDIAN if (sfb->fb.var.bits_per_pixel == 32) { - smtc_VRAMBaseAddress += 0x800000; sfb->lfb += 0x800000; - dev_info(&pdev->dev, - "smtc_VRAMBaseAddress=%p sfb->lfb=%p", - smtc_VRAMBaseAddress, sfb->lfb); + dev_info(&pdev->dev, "sfb->lfb=%p", sfb->lfb); } #endif if (!smtc_RegBaseAddress) { @@ -869,8 +863,7 @@ static int __devinit smtcfb_pci_probe(struct pci_dev *pdev, sfb->fb.fix.mmio_len = 0x00200000; smem_size = SM722_VIDEOMEMORYSIZE; sfb->dp_regs = ioremap(mmio_base, 0x00a00000); - sfb->lfb = (smtc_VRAMBaseAddress = - sfb->dp_regs + 0x00200000); + sfb->lfb = sfb->dp_regs + 0x00200000; sfb->mmio = (smtc_RegBaseAddress = sfb->dp_regs + 0x000c0000); sfb->vp_regs = sfb->dp_regs + 0x800; -- cgit v0.10.2 From 3e76c95107a3423e3dc9d6df09ad802f0e237e9b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 17 Sep 2012 13:13:12 -0700 Subject: staging: comedi: comedi_fops: make internal function static The function do_become_nonbusy() is only referenced in this file. Make it static. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index fb2ed2f..00d8d1f 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -2023,7 +2023,8 @@ done: /* This function restores a subdevice to an idle state. */ -void do_become_nonbusy(struct comedi_device *dev, struct comedi_subdevice *s) +static void do_become_nonbusy(struct comedi_device *dev, + struct comedi_subdevice *s) { struct comedi_async *async = s->async; -- cgit v0.10.2 From 29aba763060a2c44a7449dff1579f0fed52ea567 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 17 Sep 2012 13:13:32 -0700 Subject: staging: comedi: ni_mio_common: make internal functions static The functions ni_release_gpct_mite_channel() and ni_prime_channelgain_list() are only referenced in this file. Make it static. The function ni_release_gpct_mite_channel() is also only called when PCIDMA is enabled. Move the #ifdef to quite a sparse warning about the function not being used. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index 8fd967a..87995da 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -644,10 +644,10 @@ static void ni_release_ao_mite_channel(struct comedi_device *dev) #endif /* PCIDMA */ } -void ni_release_gpct_mite_channel(struct comedi_device *dev, - unsigned gpct_index) -{ #ifdef PCIDMA +static void ni_release_gpct_mite_channel(struct comedi_device *dev, + unsigned gpct_index) +{ unsigned long flags; BUG_ON(gpct_index >= NUM_GPCT); @@ -663,8 +663,8 @@ void ni_release_gpct_mite_channel(struct comedi_device *dev, mite_release_channel(mite_chan); } spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); -#endif /* PCIDMA */ } +#endif /* PCIDMA */ static void ni_release_cdo_mite_channel(struct comedi_device *dev) { @@ -1881,7 +1881,7 @@ static int ni_ai_insn_read(struct comedi_device *dev, return insn->n; } -void ni_prime_channelgain_list(struct comedi_device *dev) +static void ni_prime_channelgain_list(struct comedi_device *dev) { int i; devpriv->stc_writew(dev, AI_CONVERT_Pulse, AI_Command_1_Register); -- cgit v0.10.2 From 135f8a5e031db8ef4031fb3c815ef7ace876f9b1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 17 Sep 2012 13:13:48 -0700 Subject: staging: comedi: jr3_pci.h: remove vect_bits_t and warning_bits_t Leave the enum's but remove their names. The names are not used anywhere in the driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/jr3_pci.h b/drivers/staging/comedi/drivers/jr3_pci.h index a146961..9c42653 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.h +++ b/drivers/staging/comedi/drivers/jr3_pci.h @@ -97,7 +97,7 @@ enum { mz = 0x0020, changeV2 = 0x0040, changeV1 = 0x0080 -} vect_bits_t; +}; /* WARNING_BITS */ /* The warning_bits structure shows the bit pattern for the warning @@ -116,7 +116,7 @@ enum { mx_near_sat = 0x0008, my_near_sat = 0x0010, mz_near_sat = 0x0020 -} warning_bits_t; +}; /* ERROR_BITS */ /* XX_SAT */ -- cgit v0.10.2 From 2ca9bc2e69b66f98ff41c06700333cb544f91211 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 17 Sep 2012 13:14:08 -0700 Subject: staging: comedi: jr3_pci: local functions should not be exported The function read_idm_word() is only referenced in this file. Make it static. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index 93f94cd..4b7cfe3 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -362,7 +362,8 @@ static int jr3_pci_open(struct comedi_device *dev) return 0; } -int read_idm_word(const u8 * data, size_t size, int *pos, unsigned int *val) +static int read_idm_word(const u8 *data, size_t size, int *pos, + unsigned int *val) { int result = 0; if (pos != 0 && val != 0) { -- cgit v0.10.2 From ce48a91139eaafba2ed0f917e5ca744f20c28c47 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 17 Sep 2012 13:14:24 -0700 Subject: staging: comedi: ni_660x: local functions should not be exported The function ni_660x_release_mite_channel() is only referenced in this file. Make it static. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index d3c8e6a..df2f3b0 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -865,8 +865,8 @@ static int ni_660x_request_mite_channel(struct comedi_device *dev, return 0; } -void ni_660x_release_mite_channel(struct comedi_device *dev, - struct ni_gpct *counter) +static void ni_660x_release_mite_channel(struct comedi_device *dev, + struct ni_gpct *counter) { unsigned long flags; -- cgit v0.10.2 From 08ebfcd205e30a8c42651b00d8c6722d03d9a2ae Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 17 Sep 2012 13:14:41 -0700 Subject: staging: comedi: ni_pcidio: local functions should not be exported The function ni_pcidio_event() is only referenced in this file. Make it static. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index acbed13..6a70e266 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -370,7 +370,8 @@ static void ni_pcidio_release_di_mite_channel(struct comedi_device *dev) spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); } -void ni_pcidio_event(struct comedi_device *dev, struct comedi_subdevice *s) +static void ni_pcidio_event(struct comedi_device *dev, + struct comedi_subdevice *s) { if (s-> async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | -- cgit v0.10.2 From 3786d4fb4d40a4e06f21c37cae7f15dbfb9fb777 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 17 Sep 2012 13:14:59 -0700 Subject: staging: comedi: ni_daq_dio24: local symbols should not be exported The symbol dio24_cs_driver is only referenced in this file. Make it static. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_daq_dio24.c b/drivers/staging/comedi/drivers/ni_daq_dio24.c index 5f713c9..0ca222b 100644 --- a/drivers/staging/comedi/drivers/ni_daq_dio24.c +++ b/drivers/staging/comedi/drivers/ni_daq_dio24.c @@ -308,7 +308,7 @@ MODULE_DESCRIPTION("Comedi driver for National Instruments " "PCMCIA DAQ-Card DIO-24"); MODULE_LICENSE("GPL"); -struct pcmcia_driver dio24_cs_driver = { +static struct pcmcia_driver dio24_cs_driver = { .probe = dio24_cs_attach, .remove = dio24_cs_detach, .suspend = dio24_cs_suspend, -- cgit v0.10.2 From 0dcee6fec87325e455ffb720d1ed8cb98289d99f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 17 Sep 2012 13:15:15 -0700 Subject: staging: comedi: ni_labpc_cs: local symbols should not be exported The symbol labpc_cs_driver and the functions labpc_init_module() and labpc_exit_module() are only referenced in this file. Make them static. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_labpc_cs.c b/drivers/staging/comedi/drivers/ni_labpc_cs.c index dbb61b6..eb0417e 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_cs.c +++ b/drivers/staging/comedi/drivers/ni_labpc_cs.c @@ -270,7 +270,7 @@ MODULE_AUTHOR("Frank Mori Hess "); MODULE_DESCRIPTION("Comedi driver for National Instruments Lab-PC"); MODULE_LICENSE("GPL"); -struct pcmcia_driver labpc_cs_driver = { +static struct pcmcia_driver labpc_cs_driver = { .probe = labpc_cs_attach, .remove = labpc_cs_detach, .suspend = labpc_cs_suspend, @@ -291,7 +291,7 @@ static void __exit exit_labpc_cs(void) pcmcia_unregister_driver(&labpc_cs_driver); } -int __init labpc_init_module(void) +static int __init labpc_init_module(void) { int ret; @@ -302,7 +302,7 @@ int __init labpc_init_module(void) return comedi_driver_register(&driver_labpc_cs); } -void __exit labpc_exit_module(void) +static void __exit labpc_exit_module(void) { exit_labpc_cs(); comedi_driver_unregister(&driver_labpc_cs); -- cgit v0.10.2 From 3243785c39836fdded4ad76797941fad7e504227 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 17 Sep 2012 13:15:32 -0700 Subject: staging: comedi: ni_mio_cs: local symbols should not be exported The symbol ni_mio_cs_driver is only referenced in this file. Make it static. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_mio_cs.c b/drivers/staging/comedi/drivers/ni_mio_cs.c index 9acaad2..ca4f8e0 100644 --- a/drivers/staging/comedi/drivers/ni_mio_cs.c +++ b/drivers/staging/comedi/drivers/ni_mio_cs.c @@ -421,7 +421,7 @@ MODULE_AUTHOR("David A. Schleef "); MODULE_DESCRIPTION("Comedi driver for National Instruments DAQCard E series"); MODULE_LICENSE("GPL"); -struct pcmcia_driver ni_mio_cs_driver = { +static struct pcmcia_driver ni_mio_cs_driver = { .probe = &cs_attach, .remove = &cs_detach, .suspend = &mio_cs_suspend, -- cgit v0.10.2 From 2ad1d2e1ad789b878ca3c79c62d015d7cefd6b71 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 17 Sep 2012 13:16:05 -0700 Subject: staging: comedi: mite: local symbols should not be exported The function mite_fifo_size() is only referenced in this file. Make it static. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/mite.c b/drivers/staging/comedi/drivers/mite.c index d4f486a..e27850f 100644 --- a/drivers/staging/comedi/drivers/mite.c +++ b/drivers/staging/comedi/drivers/mite.c @@ -92,7 +92,7 @@ static void dump_chip_signature(u32 csigr_bits) mite_csigr_wins(csigr_bits), mite_csigr_iowins(csigr_bits)); } -unsigned mite_fifo_size(struct mite_struct *mite, unsigned channel) +static unsigned mite_fifo_size(struct mite_struct *mite, unsigned channel) { unsigned fcr_bits = readl(mite->mite_io_addr + MITE_FCR(channel)); unsigned empty_count = (fcr_bits >> 16) & 0xff; -- cgit v0.10.2 From 765c3c64f76a786cd01f3b479ee63b79cb9343d0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 17 Sep 2012 13:16:45 -0700 Subject: staging: comedi: pcmmio: remove kernel messages about IRQ These messages are just added noise. They also cause some sparse warnings due to MAX_ASICS evaluating as 1. This causes the local variable 'irq' to be 'unsigned int irq[1]', which makes the 'irq[1]' access invalid. Just remove the messages. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c index 9a9af0b..a10bf0a 100644 --- a/drivers/staging/comedi/drivers/pcmmio.c +++ b/drivers/staging/comedi/drivers/pcmmio.c @@ -1197,15 +1197,6 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) * multiple irqs.. */ - if (irq[0]) { - printk(KERN_DEBUG "comedi%d: irq: %u\n", dev->minor, irq[0]); - if (board->dio_num_asics == 2 && irq[1]) - printk(KERN_DEBUG "comedi%d: second ASIC irq: %u\n", - dev->minor, irq[1]); - } else { - printk(KERN_INFO "comedi%d: (IRQ mode disabled)\n", dev->minor); - } - printk(KERN_INFO "comedi%d: attached\n", dev->minor); return 1; -- cgit v0.10.2 From 920e2ffbe243fb0555b2c238e26fe7dbc03db98c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 17 Sep 2012 13:17:03 -0700 Subject: staging: comedi: pcmuio: pointers should be cleared with NULL Pointer variables should be cleared with NULL on 0. This quiets some sparse warnings about: warning: Using plain integer as NULL pointer Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c index aba6b45..0e32119 100644 --- a/drivers/staging/comedi/drivers/pcmuio.c +++ b/drivers/staging/comedi/drivers/pcmuio.c @@ -442,7 +442,7 @@ static void pcmuio_stop_intr(struct comedi_device *dev, subpriv->intr.enabled_mask = 0; subpriv->intr.active = 0; - s->async->inttrig = 0; + s->async->inttrig = NULL; nports = subpriv->intr.num_asic_chans / CHANS_PER_PORT; firstport = subpriv->intr.asic_chan / CHANS_PER_PORT; switch_page(dev, asic, PAGE_ENAB); @@ -683,7 +683,7 @@ pcmuio_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s, return -EINVAL; spin_lock_irqsave(&subpriv->intr.spinlock, flags); - s->async->inttrig = 0; + s->async->inttrig = NULL; if (subpriv->intr.active) event = pcmuio_start_intr(dev, s); -- cgit v0.10.2 From 57991b6bfc2b0faafb7d42edbd1673903d76b853 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 17 Sep 2012 13:17:19 -0700 Subject: staging: comedi: jr3_pci: quiet "Using plain interger as NULL pointer" noise Quiet some sparse warnings about: warning: Using plain integer as NULL pointer Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index 4b7cfe3..360107c 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -366,7 +366,7 @@ static int read_idm_word(const u8 *data, size_t size, int *pos, unsigned int *val) { int result = 0; - if (pos != 0 && val != 0) { + if (pos && val) { /* Skip over non hex */ for (; *pos < size && !isxdigit(data[*pos]); (*pos)++) { } @@ -876,7 +876,7 @@ static int jr3_pci_attach(struct comedi_device *dev, p->maxdata_list[56] = 0xffff; p->maxdata_list[57] = 0xffff; /* Channel specific range and maxdata */ - dev->subdevices[i].range_table = 0; + dev->subdevices[i].range_table = NULL; dev->subdevices[i].range_table_list = p->range_table_list; dev->subdevices[i].maxdata = 0; -- cgit v0.10.2 From 2eae6bdc12f4e49b7f94f032b82d664dcf3881bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alois=20Schl=C3=B6gl?= Date: Mon, 17 Sep 2012 19:22:52 -0700 Subject: Staging: add ced1401 USB driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This was imported from the http://pub.ist.ac.at/~schloegl/src/ced1401/.git git repo at the request of Alois. The driver originally came from Cambridge Electronic Design Ltd and was authored by Greg P Smith and others, but Alois did the maintance work to get it into a semi-building state and pushed to get it into the main kernel tree here. Cc: Alois Schlögl Cc: Greg P. Smith Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ced1401/Makefile b/drivers/staging/ced1401/Makefile new file mode 100644 index 0000000..6acb031 --- /dev/null +++ b/drivers/staging/ced1401/Makefile @@ -0,0 +1,12 @@ +obj-m := cedusb.o +cedusb-objs := usb1401.o ced_ioc.o +KDIR := /lib/modules/$(shell uname -r)/build +PWD := $(shell pwd) +KBUILD_EXTRA_SYMBOLS := $(PWD) +EXTRA_CFLAGS = -I$(HOME)/src/ced1401 +all: + $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules + +clean: + $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean + diff --git a/drivers/staging/ced1401/ced_ioc.c b/drivers/staging/ced1401/ced_ioc.c new file mode 100644 index 0000000..4a13c10 --- /dev/null +++ b/drivers/staging/ced1401/ced_ioc.c @@ -0,0 +1,1461 @@ +/* ced_ioc.c + ioctl part of the 1401 usb device driver for linux. + Copyright (C) 2010 Cambridge Electronic Design Ltd + Author Greg P Smith (greg@ced.co.uk) + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "usb1401.h" + +/**************************************************************************** +** FlushOutBuff +** +** Empties the Output buffer and sets int lines. Used from user level only +****************************************************************************/ +void FlushOutBuff(DEVICE_EXTENSION *pdx) +{ + dev_dbg(&pdx->interface->dev, "%s currentState=%d", __func__, pdx->sCurrentState); + if (pdx->sCurrentState == U14ERR_TIME) /* Do nothing if hardware in trouble */ + return; +// CharSend_Cancel(pdx); /* Kill off any pending I/O */ + spin_lock_irq(&pdx->charOutLock); + pdx->dwNumOutput = 0; + pdx->dwOutBuffGet = 0; + pdx->dwOutBuffPut = 0; + spin_unlock_irq(&pdx->charOutLock); +} + +/**************************************************************************** +** +** FlushInBuff +** +** Empties the input buffer and sets int lines +****************************************************************************/ +void FlushInBuff(DEVICE_EXTENSION *pdx) +{ + dev_dbg(&pdx->interface->dev, "%s currentState=%d", __func__, pdx->sCurrentState); + if (pdx->sCurrentState == U14ERR_TIME) /* Do nothing if hardware in trouble */ + return; +// CharRead_Cancel(pDevObject); /* Kill off any pending I/O */ + spin_lock_irq(&pdx->charInLock); + pdx->dwNumInput = 0; + pdx->dwInBuffGet = 0; + pdx->dwInBuffPut = 0; + spin_unlock_irq(&pdx->charInLock); +} + +/**************************************************************************** +** PutChars +** +** Utility routine to copy chars into the output buffer and fire them off. +** called from user mode, holds charOutLock. +****************************************************************************/ +static int PutChars(DEVICE_EXTENSION* pdx, const char* pCh, unsigned int uCount) +{ + int iReturn; + spin_lock_irq(&pdx->charOutLock); // get the output spin lock + if ((OUTBUF_SZ - pdx->dwNumOutput) >= uCount) + { + unsigned int u; + for (u=0; uoutputBuffer[pdx->dwOutBuffPut++] = pCh[u]; + if (pdx->dwOutBuffPut >= OUTBUF_SZ) + pdx->dwOutBuffPut = 0; + } + pdx->dwNumOutput += uCount; + spin_unlock_irq(&pdx->charOutLock); + iReturn = SendChars(pdx); // ...give a chance to transmit data + } + else + { + iReturn = U14ERR_NOOUT; // no room at the out (ha-ha) + spin_unlock_irq(&pdx->charOutLock); + } + return iReturn; +} + +/***************************************************************************** +** Add the data in pData (local pointer) of length n to the output buffer, and +** trigger an output transfer if this is appropriate. User mode. +** Holds the io_mutex +*****************************************************************************/ +int SendString(DEVICE_EXTENSION* pdx, const char __user* pData, unsigned int n) +{ + int iReturn = U14ERR_NOERROR; // assume all will be well + char buffer[OUTBUF_SZ+1]; // space in our address space for characters + if (n > OUTBUF_SZ) // check space in local buffer... + return U14ERR_NOOUT; // ...too many characters + if (copy_from_user(buffer, pData, n)) + return -ENOMEM; // could not copy + buffer[n] = 0; // terminate for debug purposes + + mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o + if (n > 0) // do nothing if nowt to do! + { + dev_dbg(&pdx->interface->dev, "%s n=%d>%s<", __func__, n, buffer); + iReturn = PutChars(pdx, buffer, n); + } + + Allowi(pdx, false); // make sure we have input int + mutex_unlock(&pdx->io_mutex); + + return iReturn; +} + +/**************************************************************************** +** SendChar +** +** Sends a single character to the 1401. User mode, holds io_mutex. +****************************************************************************/ +int SendChar(DEVICE_EXTENSION *pdx, char c) +{ + int iReturn; + mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o + iReturn = PutChars(pdx, &c, 1); + dev_dbg(&pdx->interface->dev,"SendChar >%c< (0x%02x)", c, c); + Allowi(pdx, false); // Make sure char reads are running + mutex_unlock(&pdx->io_mutex); + return iReturn; +} + +/*************************************************************************** +** +** Get1401State +** +** Retrieves state information from the 1401, adjusts the 1401 state held +** in the device extension to indicate the current 1401 type. +** +** *state is updated with information about the 1401 state as returned by the +** 1401. The low byte is a code for what 1401 is doing: +** +** 0 normal 1401 operation +** 1 sending chars to host +** 2 sending block data to host +** 3 reading block data from host +** 4 sending an escape sequence to the host +** 0x80 1401 is executing self-test, in which case the upper word +** is the last error code seen (or zero for no new error). +** +** *error is updated with error information if a self-test error code +** is returned in the upper word of state. +** +** both state and error are set to -1 if there are comms problems, and +** to zero if there is a simple failure. +** +** return error code (U14ERR_NOERROR for OK) +*/ +int Get1401State(DEVICE_EXTENSION* pdx, __u32* state, __u32* error) +{ + int nGot; + dev_dbg(&pdx->interface->dev, "Get1401State() entry"); + + *state = 0xFFFFFFFF; // Start off with invalid state + nGot = usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0), + GET_STATUS, (D_TO_H|VENDOR|DEVREQ), 0,0, + pdx->statBuf, sizeof(pdx->statBuf), HZ); + if (nGot != sizeof(pdx->statBuf)) + { + dev_err(&pdx->interface->dev, "Get1401State() FAILED, return code %d", nGot); + pdx->sCurrentState = U14ERR_TIME; // Indicate that things are very wrong indeed + *state = 0; // Force status values to a known state + *error = 0; + } + else + { + int nDevice; + dev_dbg(&pdx->interface->dev, "Get1401State() Success, state: 0x%x, 0x%x", + pdx->statBuf[0], pdx->statBuf[1]); + + *state = pdx->statBuf[0]; // Return the state values to the calling code + *error = pdx->statBuf[1]; + + nDevice = pdx->udev->descriptor.bcdDevice >> 8; // 1401 type code value + switch (nDevice) // so we can clean up current state + { + case 0: + pdx->sCurrentState = U14ERR_U1401; + break; + + default: // allow lots of device codes for future 1401s + if ((nDevice >= 1) && (nDevice <= 23)) + pdx->sCurrentState = (short)(nDevice + 6); + else + pdx->sCurrentState = U14ERR_ILL; + break; + } + } + + return pdx->sCurrentState >= 0 ? U14ERR_NOERROR : pdx->sCurrentState; +} + +/**************************************************************************** +** ReadWrite_Cancel +** +** Kills off staged read\write request from the USB if one is pending. +****************************************************************************/ +int ReadWrite_Cancel(DEVICE_EXTENSION *pdx) +{ + dev_dbg(&pdx->interface->dev, "ReadWrite_Cancel entry %d", pdx->bStagedUrbPending); +#ifdef NOT_WRITTEN_YET + int ntStatus = STATUS_SUCCESS; + bool bResult = false; + unsigned int i; + // We can fill this in when we know how we will implement the staged transfer stuff + spin_lock_irq(&pdx->stagedLock); + + if (pdx->bStagedUrbPending) // anything to be cancelled? May need more... + { + dev_info(&pdx->interface-dev, "ReadWrite_Cancel about to cancel Urb"); + + // KeClearEvent(&pdx->StagingDoneEvent); // Clear the staging done flag + USB_ASSERT(pdx->pStagedIrp != NULL); + + // Release the spinlock first otherwise the completion routine may hang + // on the spinlock while this function hands waiting for the event. + spin_unlock_irq(&pdx->stagedLock); + bResult = IoCancelIrp(pdx->pStagedIrp); // Actually do the cancel + if (bResult) + { + LARGE_INTEGER timeout; + timeout.QuadPart = -10000000; // Use a timeout of 1 second + dev_info(&pdx->interface-dev, "ReadWrite_Cancel about to wait till done"); + ntStatus = KeWaitForSingleObject(&pdx->StagingDoneEvent, Executive, + KernelMode, FALSE, &timeout); + } + else + { + dev_info(&pdx->interface-dev, "ReadWrite_Cancel, cancellation failed"); + ntStatus = U14ERR_FAIL; + } + USB_KdPrint(DBGLVL_DEFAULT, ("ReadWrite_Cancel ntStatus = 0x%x decimal %d\n", ntStatus, ntStatus)); + } + else + spin_unlock_irq(&pdx->stagedLock); + + dev_info(&pdx->interface-dev, "ReadWrite_Cancel done"); + return ntStatus; +#else + return U14ERR_NOERROR; +#endif + +} + +/*************************************************************************** +** InSelfTest - utility to check in self test. Return 1 for ST, 0 for not or +** a -ve error code if we failed for some reason. +***************************************************************************/ +static int InSelfTest(DEVICE_EXTENSION* pdx, unsigned int* pState) +{ + unsigned int state, error; + int iReturn = Get1401State(pdx, &state, &error); // see if in self-test + if (iReturn == U14ERR_NOERROR) // if all still OK + iReturn = (state == (unsigned int)-1) || // TX problem or... + ((state & 0xff) == 0x80); // ...self test + *pState = state; // return actual state + return iReturn; +} + +/*************************************************************************** +** Is1401 - ALWAYS CALLED HOLDING THE io_mutex +** +** Tests for the current state of the 1401. Sets sCurrentState: +** +** U14ERR_NOIF 1401 i/f card not installed (not done here) +** U14ERR_OFF 1401 apparently not switched on +** U14ERR_NC 1401 appears to be not connected +** U14ERR_ILL 1401 if it is there its not very well at all +** U14ERR_TIME 1401 appears OK, but doesn't communicate - very bad +** U14ERR_STD 1401 OK and ready for use +** U14ERR_PLUS 1401+ OK and ready for use +** U14ERR_U1401 Micro1401 OK and ready for use +** U14ERR_POWER Power1401 OK and ready for use +** U14ERR_U14012 Micro1401 mkII OK and ready for use +** +** Returns TRUE if a 1401 detected and OK, else FALSE +****************************************************************************/ +bool Is1401(DEVICE_EXTENSION* pdx) +{ + int iReturn; + dev_dbg(&pdx->interface->dev, "%s", __func__); + + ced_draw_down(pdx); // wait for, then kill outstanding Urbs + FlushInBuff(pdx); // Clear out input buffer & pipe + FlushOutBuff(pdx); // Clear output buffer & pipe + + // The next call returns 0 if OK, but has returned 1 in the past, meaning that + // usb_unlock_device() is needed... now it always is + iReturn = usb_lock_device_for_reset(pdx->udev, pdx->interface); + + // release the io_mutex because if we don't, we will deadlock due to system + // calls back into the driver. + mutex_unlock(&pdx->io_mutex); // locked, so we will not get system calls + if (iReturn >= 0) // if we failed + { + iReturn = usb_reset_device(pdx->udev); // try to do the reset + usb_unlock_device(pdx->udev); // undo the lock + } + + mutex_lock(&pdx->io_mutex); // hold stuff off while we wait + pdx->dwDMAFlag = MODE_CHAR; // Clear DMA mode flag regardless! + if (iReturn == 0) // if all is OK still + { + unsigned int state; + iReturn = InSelfTest(pdx, &state); // see if likely in self test + if (iReturn > 0) // do we need to wait for self-test? + { + unsigned long ulTimeOut = jiffies + 30*HZ; // when to give up + while((iReturn > 0) && time_before(jiffies, ulTimeOut)) + { + schedule(); // let other stuff run + iReturn = InSelfTest(pdx, &state); // see if done yet + } + } + + if (iReturn == 0) // if all is OK... + iReturn = state == 0; // then sucess is that the state is 0 + } + else + iReturn = 0; // we failed + pdx->bForceReset = false; // Clear forced reset flag now + + return iReturn > 0; +} + +/**************************************************************************** +** QuickCheck - ALWAYS CALLED HOLDING THE io_mutex +** This is used to test for a 1401. It will try to do a quick check if all is +** OK, that is the 1401 was OK the last time it was asked, and there is no DMA +** in progress, and if the bTestBuff flag is set, the character buffers must be +** empty too. If the quick check shows that the state is still the same, then +** all is OK. +** +** If any of the above conditions are not met, or if the state or type of the +** 1401 has changed since the previous test, the full Is1401 test is done, but +** only if bCanReset is also TRUE. +** +** The return value is TRUE if a useable 1401 is found, FALSE if not +*/ +bool QuickCheck(DEVICE_EXTENSION* pdx, bool bTestBuff, bool bCanReset) +{ + bool bRet = false; // assume it will fail and we will reset + bool bShortTest; + + bShortTest = ((pdx->dwDMAFlag == MODE_CHAR) && // no DMA running + (!pdx->bForceReset) && // Not had a real reset forced + (pdx->sCurrentState >= U14ERR_STD)); // No 1401 errors stored + + dev_dbg(&pdx->interface->dev, "%s DMAFlag:%d, state:%d, force:%d, testBuff:%d, short:%d", + __func__, pdx->dwDMAFlag, pdx->sCurrentState, pdx->bForceReset, bTestBuff, bShortTest); + + if ((bTestBuff) && // Buffer check requested, and... + (pdx->dwNumInput || pdx->dwNumOutput)) // ...characters were in the buffer? + { + bShortTest = false; // Then do the full test + dev_dbg(&pdx->interface->dev, "%s will reset as buffers not empty", __func__); + } + + if (bShortTest || !bCanReset) // Still OK to try the short test? + { // Always test if no reset - we want state update + unsigned int state, error; + dev_dbg(&pdx->interface->dev, "%s->Get1401State", __func__); + if (Get1401State(pdx, &state, &error) == U14ERR_NOERROR) // Check on the 1401 state + { + if ((state & 0xFF) == 0) // If call worked, check the status value + bRet = true; // If that was zero, all is OK, no reset needed + } + } + + if (!bRet && bCanReset) // If all not OK, then + { + dev_info(&pdx->interface->dev, "%s->Is1401 %d %d %d %d", + __func__, bShortTest, pdx->sCurrentState, bTestBuff, pdx->bForceReset); + bRet = Is1401(pdx); // do full test + } + + return bRet; +} + +/**************************************************************************** +** Reset1401 +** +** Resets the 1401 and empties the i/o buffers +*****************************************************************************/ +int Reset1401(DEVICE_EXTENSION *pdx) +{ + mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o + dev_dbg(&pdx->interface->dev,"ABout to call QuickCheck"); + QuickCheck(pdx, true, true); // Check 1401, reset if not OK + mutex_unlock(&pdx->io_mutex); + return U14ERR_NOERROR; +} + +/**************************************************************************** +** GetChar +** +** Gets a single character from the 1401 +****************************************************************************/ +int GetChar(DEVICE_EXTENSION *pdx) +{ + int iReturn = U14ERR_NOIN; // assume we will get nothing + mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o + + dev_dbg(&pdx->interface->dev, "GetChar"); + + Allowi(pdx, false); // Make sure char reads are running + SendChars(pdx); // and send any buffered chars + + spin_lock_irq(&pdx->charInLock); + if (pdx->dwNumInput > 0) // worth looking + { + iReturn = pdx->inputBuffer[pdx->dwInBuffGet++]; + if (pdx->dwInBuffGet >= INBUF_SZ) + pdx->dwInBuffGet = 0; + pdx->dwNumInput--; + } + else + iReturn = U14ERR_NOIN; // no input data to read + spin_unlock_irq(&pdx->charInLock); + + Allowi(pdx, false); // Make sure char reads are running + + mutex_unlock(&pdx->io_mutex); // Protect disconnect from new i/o + return iReturn; +} + +/**************************************************************************** +** GetString +** +** Gets a string from the 1401. Returns chars up to the next CR or when +** there are no more to read or nowhere to put them. CR is translated to +** 0 and counted as a character. If the string does not end in a 0, we will +** add one, if there is room, but it is not counted as a character. +** +** returns the count of characters (including the terminator, or 0 if none +** or a negative error code. +****************************************************************************/ +int GetString(DEVICE_EXTENSION *pdx, char __user* pUser, int n) +{ + int nAvailable; // character in the buffer + int iReturn = U14ERR_NOIN; + if (n <= 0) + return -ENOMEM; + + mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o + Allowi(pdx, false); // Make sure char reads are running + SendChars(pdx); // and send any buffered chars + + spin_lock_irq(&pdx->charInLock); + nAvailable = pdx->dwNumInput; // characters available now + if (nAvailable > n) // read max of space in pUser... + nAvailable = n; // ...or input characters + + if (nAvailable > 0) // worth looking? + { + char buffer[INBUF_SZ+1]; // space for a linear copy of data + int nGot = 0; + int nCopyToUser; // number to copy to user + char cData; + do + { + cData = pdx->inputBuffer[pdx->dwInBuffGet++]; + if (cData == CR_CHAR) // replace CR with zero + cData = (char)0; + + if (pdx->dwInBuffGet >= INBUF_SZ) + pdx->dwInBuffGet = 0; // wrap buffer pointer + + buffer[nGot++] = cData; // save the output + } + while((nGot < nAvailable) && cData); + + nCopyToUser = nGot; // what to copy... + if (cData) // do we need null + { + buffer[nGot] = (char)0; // make it tidy + if (nGot < n) // if space in user buffer... + ++nCopyToUser; // ...copy the 0 as well. + } + + pdx->dwNumInput -= nGot; + spin_unlock_irq(&pdx->charInLock); + + dev_dbg(&pdx->interface->dev,"GetString read %d characters >%s<", nGot, buffer); + copy_to_user(pUser, buffer, nCopyToUser); + + iReturn = nGot; // report characters read + } + else + spin_unlock_irq(&pdx->charInLock); + + Allowi(pdx, false); // Make sure char reads are running + mutex_unlock(&pdx->io_mutex); // Protect disconnect from new i/o + + return iReturn; +} + +/******************************************************************************* +** Get count of characters in the inout buffer. +*******************************************************************************/ +int Stat1401(DEVICE_EXTENSION *pdx) +{ + int iReturn; + mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o + Allowi(pdx, false); // make sure we allow pending chars + SendChars(pdx); // in both directions + iReturn = pdx->dwNumInput; // no lock as single read + mutex_unlock(&pdx->io_mutex); // Protect disconnect from new i/o + return iReturn; +} + +/**************************************************************************** +** LineCount +** +** Returns the number of newline chars in the buffer. There is no need for +** any fancy interlocks as we only read the interrupt routine data, and the +** system is arranged so nothing can be destroyed. +****************************************************************************/ +int LineCount(DEVICE_EXTENSION *pdx) +{ + int iReturn = 0; // will be count of line ends + + mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o + Allowi(pdx, false); // Make sure char reads are running + SendChars(pdx); // and send any buffered chars + spin_lock_irq(&pdx->charInLock); // Get protection + + if (pdx->dwNumInput > 0) // worth looking? + { + unsigned int dwIndex = pdx->dwInBuffGet;// start at first available + unsigned int dwEnd = pdx->dwInBuffPut; // Position for search end + do + { + if (pdx->inputBuffer[dwIndex++] == CR_CHAR) + ++iReturn; // inc count if CR + + if (dwIndex >= INBUF_SZ) // see if we fall off buff + dwIndex = 0; + } + while (dwIndex != dwEnd); // go to last avaliable + } + + spin_unlock_irq(&pdx->charInLock); + dev_dbg(&pdx->interface->dev,"LineCount returned %d", iReturn); + mutex_unlock(&pdx->io_mutex); // Protect disconnect from new i/o + return iReturn; +} + +/**************************************************************************** +** GetOutBufSpace +** +** Gets the space in the output buffer. Called from user code. +*****************************************************************************/ +int GetOutBufSpace(DEVICE_EXTENSION *pdx) +{ + int iReturn; + mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o + SendChars(pdx); // send any buffered chars + iReturn = (int)(OUTBUF_SZ - pdx->dwNumOutput); // no lock needed for single read + dev_dbg(&pdx->interface->dev,"OutBufSpace %d", iReturn); + mutex_unlock(&pdx->io_mutex); // Protect disconnect from new i/o + return iReturn; +} + +/**************************************************************************** +** +** ClearArea +** +** Clears up a transfer area. This is always called in the context of a user +** request, never from a call-back. +****************************************************************************/ +int ClearArea(DEVICE_EXTENSION *pdx, int nArea) +{ + int iReturn = U14ERR_NOERROR; + + if ((nArea < 0) || (nArea >= MAX_TRANSAREAS)) + { + iReturn = U14ERR_BADAREA; + dev_err(&pdx->interface->dev, "%s Attempt to clear area %d", __func__, nArea); + } + else + { + TRANSAREA *pTA = &pdx->rTransDef[nArea]; // to save typing + if (!pTA->bUsed) // if not used... + iReturn = U14ERR_NOTSET; // ...nothing to be done + else + { + // We must save the memory we return as we shouldn't mess with memory while + // holding a spin lock. + struct page **pPages = 0; // save page address list + int nPages = 0; // and number of pages + int np; + + dev_dbg(&pdx->interface->dev, "%s area %d", __func__, nArea); + spin_lock_irq(&pdx->stagedLock); + if ((pdx->StagedId == nArea) && (pdx->dwDMAFlag > MODE_CHAR)) + { + iReturn = U14ERR_UNLOCKFAIL; // cannot delete as in use + dev_err(&pdx->interface->dev, "%s call on area %d while active", __func__, nArea); + } + else + { + pPages = pTA->pPages; // save page address list + nPages = pTA->nPages; // and page count + if (pTA->dwEventSz) // if events flagging in use + wake_up_interruptible(&pTA->wqEvent); // release anything that was waiting + + if (pdx->bXFerWaiting && (pdx->rDMAInfo.wIdent == nArea)) + pdx->bXFerWaiting = false; // Cannot have pending xfer if area cleared + + // Clean out the TRANSAREA except for the wait queue, which is at the end + // This sets bUsed to false and dwEventSz to 0 to say area not used and no events. + memset(pTA, 0, sizeof(TRANSAREA)-sizeof(wait_queue_head_t)); + } + spin_unlock_irq(&pdx->stagedLock); + + if (pPages) // if we decided to release the memory + { + // Now we must undo the pinning down of the pages. We will assume the worst and mark + // all the pages as dirty. Don't be tempted to move this up above as you must not be + // holding a spin lock to do this stuff as it is not atomic. + dev_dbg(&pdx->interface->dev, "%s nPages=%d", __func__, nPages); + + for (np = 0; np < nPages; ++np) + { + if (pPages[np]) + { + SetPageDirty(pPages[np]); + page_cache_release(pPages[np]); + } + } + + kfree(pPages); + dev_dbg(&pdx->interface->dev, "%s kfree(pPages) done", __func__); + } + } + } + + return iReturn; +} + +/**************************************************************************** +** SetArea +** +** Sets up a transfer area - the functional part. Called by both +** SetTransfer and SetCircular. +****************************************************************************/ +static int SetArea(DEVICE_EXTENSION *pdx, int nArea, char __user* puBuf, + unsigned int dwLength, bool bCircular, bool bCircToHost) +{ + // Start by working out the page aligned start of the area and the size + // of the area in pages, allowing for the start not being aligned and the + // end needing to be rounded up to a page boundary. + unsigned long ulStart = ((unsigned long)puBuf) & PAGE_MASK; + unsigned int ulOffset = ((unsigned long)puBuf) & (PAGE_SIZE-1); + int len = (dwLength + ulOffset+PAGE_SIZE - 1) >> PAGE_SHIFT; + + TRANSAREA *pTA = &pdx->rTransDef[nArea]; // to save typing + struct page **pPages = 0; // space for page tables + int nPages = 0; // and number of pages + + int iReturn = ClearArea(pdx, nArea); // see if OK to use this area + if ((iReturn != U14ERR_NOTSET) && // if not area unused and... + (iReturn != U14ERR_NOERROR)) // ...not all OK, then... + return iReturn; // ...we cannot use this area + + if (!access_ok(VERIFY_WRITE, puBuf, dwLength)) // if we cannot access the memory... + return -EFAULT; // ...then we are done + + // Now allocate space to hold the page pointer and virtual address pointer tables + pPages = (struct page **)kmalloc(len*sizeof(struct page *), GFP_KERNEL); + if (!pPages) + { + iReturn = U14ERR_NOMEMORY; + goto error; + } + dev_dbg(&pdx->interface->dev, "%s %p, length=%06x, circular %d", __func__, puBuf, dwLength, bCircular); + + // To pin down user pages we must first acquire the mapping semaphore. + down_read(¤t->mm->mmap_sem); // get memory map semaphore + nPages = get_user_pages(current, current->mm, ulStart, len, 1, 0, pPages, 0); + up_read(¤t->mm->mmap_sem); // release the semaphore + dev_dbg(&pdx->interface->dev, "%s nPages = %d", __func__, nPages); + + if (nPages > 0) // if we succeeded + { + // If you are tempted to use page_address (form LDD3), forget it. You MUST use + // kmap() or kmap_atomic() to get a virtual address. page_address will give you + // (null) or at least it does in this context with an x86 machine. + spin_lock_irq(&pdx->stagedLock); + pTA->lpvBuff = puBuf; // keep start of region (user address) + pTA->dwBaseOffset = ulOffset; // save offset in first page to start of xfer + pTA->dwLength = dwLength; // Size if the region in bytes + pTA->pPages = pPages; // list of pages that are used by buffer + pTA->nPages = nPages; // number of pages + + pTA->bCircular = bCircular; + pTA->bCircToHost = bCircToHost; + + pTA->aBlocks[0].dwOffset = 0; + pTA->aBlocks[0].dwSize = 0; + pTA->aBlocks[1].dwOffset = 0; + pTA->aBlocks[1].dwSize = 0; + pTA->bUsed = true; // This is now a used block + + spin_unlock_irq(&pdx->stagedLock); + iReturn = U14ERR_NOERROR; // say all was well + } + else + { + iReturn = U14ERR_LOCKFAIL; + goto error; + } + + return iReturn; + +error: + kfree(pPages); + return iReturn; +} + +/**************************************************************************** +** SetTransfer +** +** Sets up a transfer area record. If the area is already set, we attempt to +** unset it. Unsetting will fail if the area is booked, and a transfer to that +** area is in progress. Otherwise, we will release the area and re-assign it. +****************************************************************************/ +int SetTransfer(DEVICE_EXTENSION *pdx, TRANSFERDESC __user *pTD) +{ + int iReturn; + TRANSFERDESC td; + copy_from_user(&td, pTD, sizeof(td)); + mutex_lock(&pdx->io_mutex); + dev_dbg(&pdx->interface->dev,"%s area:%d, size:%08x", __func__, td.wAreaNum, td.dwLength); + // The strange cast is done so that we don't get warnings in 32-bit linux about the size of the + // pointer. The pointer is always passed as a 64-bit object so that we don't have problems using + // a 32-bit program on a 64-bit system. unsigned long is 64-bits on a 64-bit system. + iReturn = SetArea(pdx, td.wAreaNum, (char __user *)((unsigned long)td.lpvBuff), td.dwLength, false, false); + mutex_unlock(&pdx->io_mutex); + return iReturn; +} + +/**************************************************************************** +** UnSetTransfer +** Erases a transfer area record +****************************************************************************/ +int UnsetTransfer(DEVICE_EXTENSION *pdx, int nArea) +{ + int iReturn; + mutex_lock(&pdx->io_mutex); + iReturn = ClearArea(pdx, nArea); + mutex_unlock(&pdx->io_mutex); + return iReturn; +} + +/**************************************************************************** +** SetEvent +** Creates an event that we can test for based on a transfer to/from an area. +** The area must be setup for a transfer. We attempt to simulate the Windows +** driver behavior for events (as we don't actually use them), which is to +** pretend that whatever the user asked for was achieved, so we return 1 if +** try to create one, and 0 if they ask to remove (assuming all else was OK). +****************************************************************************/ +int SetEvent(DEVICE_EXTENSION *pdx, TRANSFEREVENT __user*pTE) +{ + int iReturn = U14ERR_NOERROR; + TRANSFEREVENT te; + copy_from_user(&te, pTE, sizeof(te)); // get a local copy of the data + if (te.wAreaNum >= MAX_TRANSAREAS) // the area must exist + return U14ERR_BADAREA; + else + { + TRANSAREA *pTA = &pdx->rTransDef[te.wAreaNum]; + mutex_lock(&pdx->io_mutex); // make sure we have no competitor + spin_lock_irq(&pdx->stagedLock); + if (pTA->bUsed) // area must be in use + { + pTA->dwEventSt = te.dwStart; // set area regions + pTA->dwEventSz = te.dwLength; // set size (0 cancels it) + pTA->bEventToHost = te.wFlags & 1; // set the direction + pTA->iWakeUp = 0; // zero the wake up count + } + else + iReturn = U14ERR_NOTSET; + spin_unlock_irq(&pdx->stagedLock); + mutex_unlock(&pdx->io_mutex); + } + return iReturn == U14ERR_NOERROR ? (te.iSetEvent ? 1 : U14ERR_NOERROR) : iReturn; +} + +/**************************************************************************** +** WaitEvent +** Sleep the process with a timeout waiting for an event. Returns the number +** of times that a block met the event condition since we last cleared it or +** 0 if timed out, or -ve error (bad area or not set, or signal). +****************************************************************************/ +int WaitEvent(DEVICE_EXTENSION *pdx, int nArea, int msTimeOut) +{ + int iReturn; + if ((unsigned)nArea > MAX_TRANSAREAS) + return U14ERR_BADAREA; + else + { + int iWait; + TRANSAREA *pTA = &pdx->rTransDef[nArea]; + msTimeOut = (msTimeOut * HZ + 999)/1000; // convert timeout to jiffies + + // We cannot wait holding the mutex, but we check the flags while holding + // it. This may well be pointless as another thread could get in between + // releasing it and the wait call. However, this would have to clear the + // iWakeUp flag. However, the !pTA-bUsed may help us in this case. + mutex_lock(&pdx->io_mutex); // make sure we have no competitor + if (!pTA->bUsed || !pTA->dwEventSz) // check something to wait for... + return U14ERR_NOTSET; // ...else we do nothing + mutex_unlock(&pdx->io_mutex); + + if (msTimeOut) + iWait = wait_event_interruptible_timeout(pTA->wqEvent, pTA->iWakeUp || !pTA->bUsed, msTimeOut); + else + iWait = wait_event_interruptible(pTA->wqEvent, pTA->iWakeUp || !pTA->bUsed); + if (iWait) + iReturn = -ERESTARTSYS; // oops - we have had a SIGNAL + else + iReturn = pTA->iWakeUp; // else the wakeup count + + spin_lock_irq(&pdx->stagedLock); + pTA->iWakeUp = 0; // clear the flag + spin_unlock_irq(&pdx->stagedLock); + } + return iReturn; +} + +/**************************************************************************** +** TestEvent +** Test the event to see if a WaitEvent would return immediately. Returns the +** number of times a block completed since the last call, or 0 if none or a +** negative error. +****************************************************************************/ +int TestEvent(DEVICE_EXTENSION *pdx, int nArea) +{ + int iReturn; + if ((unsigned)nArea > MAX_TRANSAREAS) + iReturn = U14ERR_BADAREA; + else + { + TRANSAREA *pTA = &pdx->rTransDef[nArea]; + mutex_lock(&pdx->io_mutex); // make sure we have no competitor + spin_lock_irq(&pdx->stagedLock); + iReturn = pTA->iWakeUp; // get wakeup count since last call + pTA->iWakeUp = 0; // clear the count + spin_unlock_irq(&pdx->stagedLock); + mutex_unlock(&pdx->io_mutex); + } + return iReturn; +} + +/**************************************************************************** +** GetTransferInfo +** Puts the current state of the 1401 in a TGET_TX_BLOCK. +*****************************************************************************/ +int GetTransfer(DEVICE_EXTENSION *pdx, TGET_TX_BLOCK __user *pTX) +{ + int iReturn = U14ERR_NOERROR; + unsigned int dwIdent; + + mutex_lock(&pdx->io_mutex); + dwIdent = pdx->StagedId; // area ident for last xfer + if (dwIdent >= MAX_TRANSAREAS) + iReturn = U14ERR_BADAREA; + else + { + // Return the best information we have - we don't have physical addresses + TGET_TX_BLOCK tx; + memset(&tx, 0, sizeof(tx)); // clean out local work structure + tx.size = pdx->rTransDef[dwIdent].dwLength; + tx.linear = (long long)((long)pdx->rTransDef[dwIdent].lpvBuff); + tx.avail = GET_TX_MAXENTRIES; // how many blocks we could return + tx.used = 1; // number we actually return + tx.entries[0].physical = (long long)(tx.linear+pdx->StagedOffset); + tx.entries[0].size = tx.size; + copy_to_user(pTX, &tx, sizeof(tx)); + } + mutex_unlock(&pdx->io_mutex); + return iReturn; +} + +/**************************************************************************** +** KillIO1401 +** +** Empties the host i/o buffers +****************************************************************************/ +int KillIO1401(DEVICE_EXTENSION *pdx) +{ + dev_dbg(&pdx->interface->dev, "%s", __func__); + mutex_lock(&pdx->io_mutex); + FlushOutBuff(pdx); + FlushInBuff(pdx); + mutex_unlock(&pdx->io_mutex); + return U14ERR_NOERROR; +} + +/**************************************************************************** +** BlkTransState +** Returns a 0 or a 1 for whether DMA is happening. No point holding a mutex +** for this as it only does one read. +*****************************************************************************/ +int BlkTransState(DEVICE_EXTENSION *pdx) +{ + int iReturn = pdx->dwDMAFlag != MODE_CHAR; + dev_dbg(&pdx->interface->dev, "%s = %d", __func__, iReturn); + return iReturn; +} + +/**************************************************************************** +** StateOf1401 +** +** Puts the current state of the 1401 in the Irp return buffer. +*****************************************************************************/ +int StateOf1401(DEVICE_EXTENSION *pdx) +{ + int iReturn; + mutex_lock(&pdx->io_mutex); + + QuickCheck(pdx, false, false); // get state up to date, no reset + iReturn = pdx->sCurrentState; + + mutex_unlock(&pdx->io_mutex); + dev_dbg(&pdx->interface->dev, "%s = %d", __func__, iReturn); + + return iReturn; +} +/**************************************************************************** +** StartSelfTest +** +** Initiates a self-test cycle. The assumption is that we have no interrupts +** active, so we should make sure that this is the case. +*****************************************************************************/ +int StartSelfTest(DEVICE_EXTENSION *pdx) +{ + int nGot; + mutex_lock(&pdx->io_mutex); + dev_dbg(&pdx->interface->dev, "%s", __func__); + + ced_draw_down(pdx); // wait for, then kill outstanding Urbs + FlushInBuff(pdx); // Clear out input buffer & pipe + FlushOutBuff(pdx); // Clear output buffer & pipe +// ReadWrite_Cancel(pDeviceObject); /* so things stay tidy */ + pdx->dwDMAFlag = MODE_CHAR; /* Clear DMA mode flags here */ + + nGot = usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0), + DB_SELFTEST, (H_TO_D|VENDOR|DEVREQ), 0, 0, + 0, 0, HZ); // allow 1 second timeout + pdx->ulSelfTestTime = jiffies + HZ*30; // 30 seconds into the future + + mutex_unlock(&pdx->io_mutex); + if (nGot < 0) + dev_err(&pdx->interface->dev, "%s err=%d", __func__, nGot); + return nGot < 0 ? U14ERR_FAIL : U14ERR_NOERROR; +} + + +/**************************************************************************** +** CheckSelfTest +** +** Check progress of a self-test cycle +****************************************************************************/ +int CheckSelfTest(DEVICE_EXTENSION *pdx, TGET_SELFTEST __user *pGST) +{ + unsigned int state, error; + int iReturn; + TGET_SELFTEST gst; // local work space + memset(&gst, 0, sizeof(gst)); // clear out the space (sets code 0) + + mutex_lock(&pdx->io_mutex); + + dev_dbg(&pdx->interface->dev, "%s", __func__); + iReturn = Get1401State(pdx, &state, &error); + if (iReturn == U14ERR_NOERROR) // Only accept zero if it happens twice + iReturn = Get1401State(pdx, &state, &error); + + if (iReturn != U14ERR_NOERROR) // Self-test can cause comms errors + { // so we assume still testing + dev_err(&pdx->interface->dev, "%s Get1401State=%d, assuming still testing", __func__, iReturn); + state = 0x80; // Force still-testing, no error + error = 0; + iReturn = U14ERR_NOERROR; + } + + if ((state == -1) && (error == -1)) // If Get1401State had problems + { + dev_err(&pdx->interface->dev, "%s Get1401State failed, assuming still testing", __func__); + state = 0x80; // Force still-testing, no error + error = 0; + } + + if ((state & 0xFF) == 0x80) // If we are still in self-test + { + if (state & 0x00FF0000) // Have we got an error? + { + gst.code = (state & 0x00FF0000) >> 16; // read the error code + gst.x = error & 0x0000FFFF; // Error data X + gst.y = (error & 0xFFFF0000) >> 16; // and data Y + dev_dbg(&pdx->interface->dev,"Self-test error code %d", gst.code); + } + else // No error, check for timeout + { + unsigned long ulNow = jiffies; // get current time + if (time_after(ulNow, pdx->ulSelfTestTime)) + { + gst.code = -2; // Flag the timeout + dev_dbg(&pdx->interface->dev, "Self-test timed-out"); + } + else + dev_dbg(&pdx->interface->dev, "Self-test on-going"); + } + } + else + { + gst.code = -1; // Flag the test is done + dev_dbg(&pdx->interface->dev, "Self-test done"); + } + + if (gst.code < 0) // If we have a problem or finished + { // If using the 2890 we should reset properly + if ((pdx->nPipes == 4) && (pdx->s1401Type <= TYPEPOWER)) + Is1401(pdx); // Get 1401 reset and OK + else + QuickCheck(pdx, true, true); // Otherwise check without reset unless problems + } + mutex_unlock(&pdx->io_mutex); + + copy_to_user(pGST, &gst, sizeof(gst)); // copy result to user space + return iReturn; +} + +/**************************************************************************** +** TypeOf1401 +** +** Returns code for standard, plus, micro1401, power1401 or none +****************************************************************************/ +int TypeOf1401(DEVICE_EXTENSION *pdx) +{ + int iReturn = TYPEUNKNOWN; + mutex_lock(&pdx->io_mutex); + dev_dbg(&pdx->interface->dev, "%s", __func__); + + switch (pdx->s1401Type) + { + case TYPE1401: iReturn = U14ERR_STD; break; // Handle these types directly + case TYPEPLUS: iReturn = U14ERR_PLUS; break; + case TYPEU1401:iReturn = U14ERR_U1401;break; + default: + if ((pdx->s1401Type >= TYPEPOWER) && + (pdx->s1401Type <= 25)) + iReturn = pdx->s1401Type + 4; // We can calculate types + else // for up-coming 1401 designs + iReturn = TYPEUNKNOWN; // Don't know or not there + } + dev_dbg(&pdx->interface->dev, "%s %d", __func__, iReturn); + mutex_unlock(&pdx->io_mutex); + + return iReturn; +} + +/**************************************************************************** +** TransferFlags +** +** Returns flags on block transfer abilities +****************************************************************************/ +int TransferFlags(DEVICE_EXTENSION *pdx) +{ + int iReturn = U14TF_MULTIA | U14TF_DIAG | // we always have multiple DMA area + U14TF_NOTIFY | U14TF_CIRCTH; // diagnostics, notify and circular + dev_dbg(&pdx->interface->dev, "%s", __func__); + mutex_lock(&pdx->io_mutex); + if (pdx->bIsUSB2) // Set flag for USB2 if appropriate + iReturn |= U14TF_USB2; + mutex_unlock(&pdx->io_mutex); + + return iReturn; +} + +/*************************************************************************** +** DbgCmd1401 +** Issues a debug\diagnostic command to the 1401 along with a 32-bit datum +** This is a utility command used for dbg operations. +*/ +static int DbgCmd1401(DEVICE_EXTENSION *pdx, unsigned char cmd, unsigned int data) +{ + int iReturn; + dev_dbg(&pdx->interface->dev, "%s entry", __func__); + iReturn = usb_control_msg(pdx->udev, usb_sndctrlpipe(pdx->udev, 0), + cmd, (H_TO_D|VENDOR|DEVREQ), + (unsigned short)data, (unsigned short)(data >> 16), + 0, 0, HZ); // allow 1 second timeout + if (iReturn < 0) + dev_err(&pdx->interface->dev, "%s fail code=%d", __func__, iReturn); + + return iReturn; +} + +/**************************************************************************** +** DbgPeek +** +** Execute the diagnostic peek operation. Uses address, width and repeats. +****************************************************************************/ +int DbgPeek(DEVICE_EXTENSION *pdx, TDBGBLOCK __user* pDB) +{ + int iReturn; + TDBGBLOCK db; + copy_from_user(&db, pDB, sizeof(db)); // get the data + + mutex_lock(&pdx->io_mutex); + dev_dbg(&pdx->interface->dev, "%s @ %08x", __func__, db.iAddr); + + iReturn = DbgCmd1401(pdx, DB_SETADD, db.iAddr); + if (iReturn == U14ERR_NOERROR) + iReturn = DbgCmd1401(pdx, DB_WIDTH, db.iWidth); + if (iReturn == U14ERR_NOERROR) + iReturn = DbgCmd1401(pdx, DB_REPEATS, db.iRepeats); + if (iReturn == U14ERR_NOERROR) + iReturn = DbgCmd1401(pdx, DB_PEEK, 0); + mutex_unlock(&pdx->io_mutex); + + return iReturn; +} + + +/**************************************************************************** +** DbgPoke +** +** Execute the diagnostic poke operation. Parameters are in the CSBLOCK struct +** in order address, size, repeats and value to poke. +****************************************************************************/ +int DbgPoke(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB) +{ + int iReturn; + TDBGBLOCK db; + copy_from_user(&db, pDB, sizeof(db)); // get the data + + mutex_lock(&pdx->io_mutex); + dev_dbg(&pdx->interface->dev, "%s @ %08x", __func__, db.iAddr); + + iReturn = DbgCmd1401(pdx, DB_SETADD, db.iAddr); + if (iReturn == U14ERR_NOERROR) + iReturn = DbgCmd1401(pdx, DB_WIDTH, db.iWidth); + if (iReturn == U14ERR_NOERROR) + iReturn = DbgCmd1401(pdx, DB_REPEATS, db.iRepeats); + if (iReturn == U14ERR_NOERROR) + iReturn = DbgCmd1401(pdx, DB_POKE, db.iData); + mutex_unlock(&pdx->io_mutex); + + return iReturn; +} + + +/**************************************************************************** +** DbgRampData +** +** Execute the diagnostic ramp data operation. Parameters are in the CSBLOCK struct +** in order address, default, enable mask, size and repeats. +****************************************************************************/ +int DbgRampData(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB) +{ + int iReturn; + TDBGBLOCK db; + copy_from_user(&db, pDB, sizeof(db)); // get the data + + mutex_lock(&pdx->io_mutex); + dev_dbg(&pdx->interface->dev, "%s @ %08x", __func__, db.iAddr); + + iReturn = DbgCmd1401(pdx, DB_SETADD, db.iAddr); + if (iReturn == U14ERR_NOERROR) + iReturn = DbgCmd1401(pdx, DB_SETDEF, db.iDefault); + if (iReturn == U14ERR_NOERROR) + iReturn = DbgCmd1401(pdx, DB_SETMASK, db.iMask); + if (iReturn == U14ERR_NOERROR) + iReturn = DbgCmd1401(pdx, DB_WIDTH, db.iWidth); + if (iReturn == U14ERR_NOERROR) + iReturn = DbgCmd1401(pdx, DB_REPEATS, db.iRepeats); + if (iReturn == U14ERR_NOERROR) + iReturn = DbgCmd1401(pdx, DB_RAMPD, 0); + mutex_unlock(&pdx->io_mutex); + + return iReturn; +} + + +/**************************************************************************** +** DbgRampAddr +** +** Execute the diagnostic ramp address operation +****************************************************************************/ +int DbgRampAddr(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB) +{ + int iReturn; + TDBGBLOCK db; + copy_from_user(&db, pDB, sizeof(db)); // get the data + + mutex_lock(&pdx->io_mutex); + dev_dbg(&pdx->interface->dev, "%s", __func__); + + iReturn = DbgCmd1401(pdx, DB_SETDEF, db.iDefault); + if (iReturn == U14ERR_NOERROR) + iReturn = DbgCmd1401(pdx, DB_SETMASK, db.iMask); + if (iReturn == U14ERR_NOERROR) + iReturn = DbgCmd1401(pdx, DB_WIDTH, db.iWidth); + if (iReturn == U14ERR_NOERROR) + iReturn = DbgCmd1401(pdx, DB_REPEATS, db.iRepeats); + if (iReturn == U14ERR_NOERROR) + iReturn = DbgCmd1401(pdx, DB_RAMPA, 0); + mutex_unlock(&pdx->io_mutex); + + return iReturn; +} + + +/**************************************************************************** +** DbgGetData +** +** Retrieve the data resulting from the last debug Peek operation +****************************************************************************/ +int DbgGetData(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB) +{ + int iReturn; + TDBGBLOCK db; + memset(&db, 0, sizeof(db)); // fill returned block with 0s + + mutex_lock(&pdx->io_mutex); + dev_dbg(&pdx->interface->dev, "%s", __func__); + + // Read back the last peeked value from the 1401. + iReturn = usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0), + DB_DATA, (D_TO_H|VENDOR|DEVREQ), 0,0, + &db.iData, sizeof(db.iData), HZ); + if (iReturn == sizeof(db.iData)) + { + copy_to_user(pDB, &db, sizeof(db)); + iReturn = U14ERR_NOERROR; + } + else + dev_err(&pdx->interface->dev, "%s failed, code %d", __func__, iReturn); + + mutex_unlock(&pdx->io_mutex); + + return iReturn; +} + +/**************************************************************************** +** DbgStopLoop +** +** Stop any never-ending debug loop, we just call Get1401State for USB +** +****************************************************************************/ +int DbgStopLoop(DEVICE_EXTENSION *pdx) +{ + int iReturn; + unsigned int uState, uErr; + + mutex_lock(&pdx->io_mutex); + dev_dbg(&pdx->interface->dev, "%s", __func__); + iReturn = Get1401State(pdx, &uState, &uErr); + mutex_unlock(&pdx->io_mutex); + + return iReturn; +} + + +/**************************************************************************** +** SetCircular +** +** Sets up a transfer area record for circular transfers. If the area is +** already set, we attempt to unset it. Unsetting will fail if the area is +** booked and a transfer to that area is in progress. Otherwise, we will +** release the area and re-assign it. +****************************************************************************/ +int SetCircular(DEVICE_EXTENSION *pdx, TRANSFERDESC __user *pTD) +{ + int iReturn; + bool bToHost; + TRANSFERDESC td; + copy_from_user(&td, pTD, sizeof(td)); + mutex_lock(&pdx->io_mutex); + dev_dbg(&pdx->interface->dev,"%s area:%d, size:%08x", __func__, td.wAreaNum, td.dwLength); + bToHost = td.eSize != 0; // this is used as the tohost flag + + // The strange cast is done so that we don't get warnings in 32-bit linux about the size of the + // pointer. The pointer is always passed as a 64-bit object so that we don't have problems using + // a 32-bit program on a 64-bit system. unsigned long is 64-bits on a 64-bit system. + iReturn = SetArea(pdx, td.wAreaNum, (char __user *)((unsigned long)td.lpvBuff), td.dwLength, true, bToHost); + mutex_unlock(&pdx->io_mutex); + return iReturn; +} + +/**************************************************************************** +** GetCircBlock +** +** Return the next available block of circularly-transferred data. +****************************************************************************/ +int GetCircBlock(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user* pCB) +{ + int iReturn = U14ERR_NOERROR; + unsigned int nArea; + TCIRCBLOCK cb; + dev_dbg(&pdx->interface->dev, "%s", __func__); + copy_from_user(&cb, pCB, sizeof(cb)); + mutex_lock(&pdx->io_mutex); + + nArea = cb.nArea; // Retrieve parameters first + cb.dwOffset = 0; // set default result (nothing) + cb.dwSize = 0; + + if (nArea < MAX_TRANSAREAS) // The area number must be OK + { + TRANSAREA* pArea = &pdx->rTransDef[nArea]; // Pointer to relevant info + spin_lock_irq(&pdx->stagedLock); // Lock others out + + if ((pArea->bUsed) && (pArea->bCircular) && // Must be circular area + (pArea->bCircToHost)) // For now at least must be to host + { + if (pArea->aBlocks[0].dwSize > 0) // Got anything? + { + cb.dwOffset = pArea->aBlocks[0].dwOffset; + cb.dwSize = pArea->aBlocks[0].dwSize; + dev_dbg(&pdx->interface->dev, "%s return block 0: %d bytes at %d", __func__, cb.dwSize, cb.dwOffset); + } + } + else + iReturn = U14ERR_NOTSET; + + spin_unlock_irq(&pdx->stagedLock); + } + else + iReturn = U14ERR_BADAREA; + + copy_to_user(pCB, &cb, sizeof(cb)); + mutex_unlock(&pdx->io_mutex); + return iReturn; +} + + +/**************************************************************************** +** FreeCircBlock +** +** Frees a block of circularly-transferred data and returns the next one. +****************************************************************************/ +int FreeCircBlock(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user* pCB) +{ + int iReturn = U14ERR_NOERROR; + unsigned int nArea, uStart, uSize; + TCIRCBLOCK cb; + dev_dbg(&pdx->interface->dev, "%s", __func__); + copy_from_user(&cb, pCB, sizeof(cb)); + mutex_lock(&pdx->io_mutex); + + nArea = cb.nArea; // Retrieve parameters first + uStart = cb.dwOffset; + uSize = cb.dwSize; + cb.dwOffset = 0; // then set default result (nothing) + cb.dwSize = 0; + + if (nArea < MAX_TRANSAREAS) // The area number must be OK + { + TRANSAREA* pArea = &pdx->rTransDef[nArea]; // Pointer to relevant info + spin_lock_irq(&pdx->stagedLock); // Lock others out + + if ((pArea->bUsed) && (pArea->bCircular) && // Must be circular area + (pArea->bCircToHost)) // For now at least must be to host + { + bool bWaiting = false; + + if ((pArea->aBlocks[0].dwSize >= uSize) && // Got anything? + (pArea->aBlocks[0].dwOffset == uStart)) // Must be legal data + { + pArea->aBlocks[0].dwSize -= uSize; + pArea->aBlocks[0].dwOffset += uSize; + if (pArea->aBlocks[0].dwSize == 0) // Have we emptied this block? + { + if (pArea->aBlocks[1].dwSize) // Is there a second block? + { + pArea->aBlocks[0] = pArea->aBlocks[1]; // Copy down block 2 data + pArea->aBlocks[1].dwSize = 0; // and mark the second block as unused + pArea->aBlocks[1].dwOffset = 0; + } + else + pArea->aBlocks[0].dwOffset = 0; + } + + dev_dbg(&pdx->interface->dev, "%s free %d bytes at %d, return %d bytes at %d, wait=%d", + __func__, uSize, uStart, pArea->aBlocks[0].dwSize, pArea->aBlocks[0].dwOffset, pdx->bXFerWaiting); + + // Return the next available block of memory as well + if (pArea->aBlocks[0].dwSize > 0) // Got anything? + { + cb.dwOffset = pArea->aBlocks[0].dwOffset; + cb.dwSize = pArea->aBlocks[0].dwSize; + } + + bWaiting = pdx->bXFerWaiting; + if (bWaiting && pdx->bStagedUrbPending) + { + dev_err(&pdx->interface->dev, "%s ERROR: waiting xfer and staged Urb pending!", __func__); + bWaiting = false; + } + } + else + { + dev_err(&pdx->interface->dev, "%s ERROR: freeing %d bytes at %d, block 0 is %d bytes at %d", + __func__, uSize, uStart, pArea->aBlocks[0].dwSize, pArea->aBlocks[0].dwOffset); + iReturn = U14ERR_NOMEMORY; + } + + // If we have one, kick off pending transfer + if (bWaiting) // Got a block xfer waiting? + { + int RWMStat = ReadWriteMem(pdx, !pdx->rDMAInfo.bOutWard, + pdx->rDMAInfo.wIdent, pdx->rDMAInfo.dwOffset, pdx->rDMAInfo.dwSize); + if (RWMStat != U14ERR_NOERROR) + dev_err(&pdx->interface->dev, "%s rw setup failed %d", __func__, RWMStat); + } + } + else + iReturn = U14ERR_NOTSET; + + spin_unlock_irq(&pdx->stagedLock); + } + else + iReturn = U14ERR_BADAREA; + + copy_to_user(pCB, &cb, sizeof(cb)); + mutex_unlock(&pdx->io_mutex); + return iReturn; +} + + + diff --git a/drivers/staging/ced1401/ced_ioctl.h b/drivers/staging/ced1401/ced_ioctl.h new file mode 100644 index 0000000..075ecad --- /dev/null +++ b/drivers/staging/ced1401/ced_ioctl.h @@ -0,0 +1,232 @@ +/* ced_ioctl.h + IOCTL calls for the CED1401 driver + Copyright (C) 2010 Cambridge Electronic Design Ltd + Author Greg P Smith (greg@ced.co.uk) + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ +#ifndef __CED_IOCTL_H__ +#define __CED_IOCTL_H__ +#include + +/// dma modes, only MODE_CHAR and MODE_LINEAR are used in this driver +#define MODE_CHAR 0 +#define MODE_LINEAR 1 + +/**************************************************************************** +** TypeDefs +*****************************************************************************/ + +typedef unsigned short TBLOCKENTRY; // index the blk transfer table 0-7 + +typedef struct TransferDesc +{ + long long lpvBuff; // address of transfer area (for 64 or 32 bit) + unsigned int dwLength; // length of the area + TBLOCKENTRY wAreaNum; // number of transfer area to set up + short eSize; // element size - is tohost flag for circular +} TRANSFERDESC; + +typedef TRANSFERDESC* LPTRANSFERDESC; + +typedef struct TransferEvent +{ + unsigned int dwStart; // offset into the area + unsigned int dwLength; // length of the region + unsigned short wAreaNum; // the area number + unsigned short wFlags; // bit 0 set for toHost + int iSetEvent; // could be dummy in LINUX +} TRANSFEREVENT; + +#define MAX_TRANSFER_SIZE 0x4000 /* Maximum data bytes per IRP */ +#define MAX_AREA_LENGTH 0x100000 /* Maximum size of transfer area */ +#define MAX_TRANSAREAS 8 /* definitions for dma set up */ + +typedef struct TGetSelfTest +{ + int code; // self-test error code + int x,y; // additional information +} TGET_SELFTEST; + +/// Debug block used for several commands. Not all fields are used for all commands. +typedef struct TDbgBlock +{ + int iAddr; // the address in the 1401 + int iRepeats; // number of repeats + int iWidth; // width in bytes 1, 2, 4 + int iDefault; // default value + int iMask; // mask to apply + int iData; // data for poke, result for peek +} TDBGBLOCK; + +/// Used to collect information about a circular block from the device driver +typedef struct TCircBlock +{ + unsigned int nArea; // the area to collect information from + unsigned int dwOffset; // offset into the area to the available block + unsigned int dwSize; // size of the area +} TCIRCBLOCK; + +/// Used to clollect the 1401 status +typedef struct TCSBlock +{ + unsigned int uiState; + unsigned int uiError; +} TCSBLOCK; + +// As seen by the user, an ioctl call looks like: +// int ioctl(int fd, unsigned long cmd, char* argp); +// We will then have all sorts of variants on this that can be used +// to pass stuff to our driver. We will generate macros for each type +// of call so as to provide some sort of type safety in the calling: +#define CED_MAGIC_IOC 0xce + +// NBNB: READ and WRITE are from the point of view of the device, not user. +typedef struct ced_ioc_string +{ + int nChars; + char buffer[256]; +} CED_IOC_STRING; + +#define IOCTL_CED_SENDSTRING(n) _IOC(_IOC_WRITE, CED_MAGIC_IOC, 2, n) + +#define IOCTL_CED_RESET1401 _IO(CED_MAGIC_IOC, 3) +#define IOCTL_CED_GETCHAR _IO(CED_MAGIC_IOC, 4) +#define IOCTL_CED_SENDCHAR _IO(CED_MAGIC_IOC, 5) +#define IOCTL_CED_STAT1401 _IO(CED_MAGIC_IOC, 6) +#define IOCTL_CED_LINECOUNT _IO(CED_MAGIC_IOC, 7) +#define IOCTL_CED_GETSTRING(nMax) _IOC(_IOC_READ, CED_MAGIC_IOC, 8, nMax) + +#define IOCTL_CED_SETTRANSFER _IOW(CED_MAGIC_IOC, 11, TRANSFERDESC) +#define IOCTL_CED_UNSETTRANSFER _IO(CED_MAGIC_IOC, 12) +#define IOCTL_CED_SETEVENT _IOW(CED_MAGIC_IOC,13, TRANSFEREVENT) +#define IOCTL_CED_GETOUTBUFSPACE _IO(CED_MAGIC_IOC, 14) +#define IOCTL_CED_GETBASEADDRESS _IO(CED_MAGIC_IOC, 15) +#define IOCTL_CED_GETDRIVERREVISION _IO(CED_MAGIC_IOC, 16) + +#define IOCTL_CED_GETTRANSFER _IOR(CED_MAGIC_IOC,17, TGET_TX_BLOCK) +#define IOCTL_CED_KILLIO1401 _IO(CED_MAGIC_IOC,18) +#define IOCTL_CED_BLKTRANSSTATE _IO(CED_MAGIC_IOC,19) + +#define IOCTL_CED_STATEOF1401 _IO(CED_MAGIC_IOC,23) +#define IOCTL_CED_GRAB1401 _IO(CED_MAGIC_IOC,25) +#define IOCTL_CED_FREE1401 _IO(CED_MAGIC_IOC,26) +#define IOCTL_CED_STARTSELFTEST _IO(CED_MAGIC_IOC,31) +#define IOCTL_CED_CHECKSELFTEST _IOR(CED_MAGIC_IOC,32, TGET_SELFTEST) +#define IOCTL_CED_TYPEOF1401 _IO(CED_MAGIC_IOC,33) +#define IOCTL_CED_TRANSFERFLAGS _IO(CED_MAGIC_IOC,34) + +#define IOCTL_CED_DBGPEEK _IOW(CED_MAGIC_IOC,35, TDBGBLOCK) +#define IOCTL_CED_DBGPOKE _IOW(CED_MAGIC_IOC,36, TDBGBLOCK) +#define IOCTL_CED_DBGRAMPDATA _IOW(CED_MAGIC_IOC,37, TDBGBLOCK) +#define IOCTL_CED_DBGRAMPADDR _IOW(CED_MAGIC_IOC,38, TDBGBLOCK) +#define IOCTL_CED_DBGGETDATA _IOR(CED_MAGIC_IOC,39, TDBGBLOCK) +#define IOCTL_CED_DBGSTOPLOOP _IO(CED_MAGIC_IOC,40) +#define IOCTL_CED_FULLRESET _IO(CED_MAGIC_IOC,41) +#define IOCTL_CED_SETCIRCULAR _IOW(CED_MAGIC_IOC,42, TRANSFERDESC) +#define IOCTL_CED_GETCIRCBLOCK _IOWR(CED_MAGIC_IOC,43, TCIRCBLOCK) +#define IOCTL_CED_FREECIRCBLOCK _IOWR(CED_MAGIC_IOC,44, TCIRCBLOCK) +#define IOCTL_CED_WAITEVENT _IO(CED_MAGIC_IOC, 45) +#define IOCTL_CED_TESTEVENT _IO(CED_MAGIC_IOC, 46) + +#ifndef __KERNEL__ +// If nothing said about return value, it is a U14ERR_... error code (U14ERR_NOERROR for none) +inline int CED_SendString(int fh, const char* szText, int n){return ioctl(fh, IOCTL_CED_SENDSTRING(n), szText);} + +inline int CED_Reset1401(int fh){return ioctl(fh, IOCTL_CED_RESET1401);} + +inline int CED_GetChar(int fh){return ioctl(fh, IOCTL_CED_GETCHAR);} +// Return the singe character or a -ve error code. + +inline int CED_Stat1401(int fh){return ioctl(fh, IOCTL_CED_STAT1401);} +// Return character count in input buffer + +inline int CED_SendChar(int fh, char c){return ioctl(fh, IOCTL_CED_SENDCHAR, c);} + +inline int CED_LineCount(int fh){return ioctl(fh, IOCTL_CED_LINECOUNT);} + +inline int CED_GetString(int fh, char* szText, int nMax){return ioctl(fh, IOCTL_CED_GETSTRING(nMax), szText);} +// return the count of characters returned. If the string was terminated by CR or 0, then the 0 is part +// of the count. Otherwise, we will add a zero if there is room, but it is not included in the count. +// The return value is 0 if there was nothing to read. + +inline int CED_GetOutBufSpace(int fh){return ioctl(fh, IOCTL_CED_GETOUTBUFSPACE);} +// returns space in the output buffer. + +inline int CED_GetBaseAddress(int fh){return ioctl(fh, IOCTL_CED_GETBASEADDRESS);} +// This always returns -1 as not implemented. + +inline int CED_GetDriverRevision(int fh){return ioctl(fh, IOCTL_CED_GETDRIVERREVISION);} +// returns the major revision <<16 | minor revision. + +inline int CED_SetTransfer(int fh, TRANSFERDESC* pTD){return ioctl(fh, IOCTL_CED_SETTRANSFER, pTD);} + +inline int CED_UnsetTransfer(int fh, int nArea){return ioctl(fh, IOCTL_CED_UNSETTRANSFER, nArea);} + +inline int CED_SetEvent(int fh, TRANSFEREVENT* pTE){return ioctl(fh, IOCTL_CED_SETEVENT, pTE);} + +inline int CED_GetTransfer(int fh, TGET_TX_BLOCK* pTX){return ioctl(fh, IOCTL_CED_GETTRANSFER, pTX);} + +inline int CED_KillIO1401(int fh){return ioctl(fh, IOCTL_CED_KILLIO1401);} + +inline int CED_BlkTransState(int fh){return ioctl(fh, IOCTL_CED_BLKTRANSSTATE);} +// returns 0 if no active DMA, 1 if active + +inline int CED_StateOf1401(int fh){return ioctl(fh, IOCTL_CED_STATEOF1401);} + +inline int CED_Grab1401(int fh){return ioctl(fh, IOCTL_CED_GRAB1401);} +inline int CED_Free1401(int fh){return ioctl(fh, IOCTL_CED_FREE1401);} + +inline int CED_StartSelfTest(int fh){return ioctl(fh, IOCTL_CED_STARTSELFTEST);} +inline int CED_CheckSelfTest(int fh, TGET_SELFTEST* pGST){return ioctl(fh, IOCTL_CED_CHECKSELFTEST, pGST);} + +inline int CED_TypeOf1401(int fh){return ioctl(fh, IOCTL_CED_TYPEOF1401);} +inline int CED_TransferFlags(int fh){return ioctl(fh, IOCTL_CED_TRANSFERFLAGS);} + +inline int CED_DbgPeek(int fh, TDBGBLOCK* pDB){return ioctl(fh, IOCTL_CED_DBGPEEK, pDB);} +inline int CED_DbgPoke(int fh, TDBGBLOCK* pDB){return ioctl(fh, IOCTL_CED_DBGPOKE, pDB);} +inline int CED_DbgRampData(int fh, TDBGBLOCK* pDB){return ioctl(fh, IOCTL_CED_DBGRAMPDATA, pDB);} +inline int CED_DbgRampAddr(int fh, TDBGBLOCK* pDB){return ioctl(fh, IOCTL_CED_DBGRAMPADDR, pDB);} +inline int CED_DbgGetData(int fh, TDBGBLOCK* pDB){return ioctl(fh, IOCTL_CED_DBGGETDATA, pDB);} +inline int CED_DbgStopLoop(int fh){return ioctl(fh, IOCTL_CED_DBGSTOPLOOP);} + +inline int CED_FullReset(int fh){return ioctl(fh, IOCTL_CED_FULLRESET);} + +inline int CED_SetCircular(int fh, TRANSFERDESC* pTD){return ioctl(fh, IOCTL_CED_SETCIRCULAR, pTD);} +inline int CED_GetCircBlock(int fh, TCIRCBLOCK* pCB){return ioctl(fh, IOCTL_CED_GETCIRCBLOCK, pCB);} +inline int CED_FreeCircBlock(int fh, TCIRCBLOCK* pCB){return ioctl(fh, IOCTL_CED_FREECIRCBLOCK, pCB);} + +inline int CED_WaitEvent(int fh, int nArea, int msTimeOut){return ioctl(fh, IOCTL_CED_WAITEVENT, (nArea & 0xff)|(msTimeOut << 8));} +inline int CED_TestEvent(int fh, int nArea){return ioctl(fh, IOCTL_CED_TESTEVENT, nArea);} +#endif + +#ifdef NOTWANTEDYET +#define IOCTL_CED_REGCALLBACK _IO(CED_MAGIC_IOC,9) // Not used +#define IOCTL_CED_GETMONITORBUF _IO(CED_MAGIC_IOC,10) // Not used + +#define IOCTL_CED_BYTECOUNT _IO(CED_MAGIC_IOC,20) // Not used +#define IOCTL_CED_ZEROBLOCKCOUNT _IO(CED_MAGIC_IOC,21) // Not used +#define IOCTL_CED_STOPCIRCULAR _IO(CED_MAGIC_IOC,22) // Not used + +#define IOCTL_CED_REGISTERS1401 _IO(CED_MAGIC_IOC,24) // Not used +#define IOCTL_CED_STEP1401 _IO(CED_MAGIC_IOC,27) // Not used +#define IOCTL_CED_SET1401REGISTERS _IO(CED_MAGIC_IOC,28) // Not used +#define IOCTL_CED_STEPTILL1401 _IO(CED_MAGIC_IOC,29) // Not used +#define IOCTL_CED_SETORIN _IO(CED_MAGIC_IOC,30) // Not used + +#endif + +// __CED_IOCTL_H__ +#endif diff --git a/drivers/staging/ced1401/machine.h b/drivers/staging/ced1401/machine.h new file mode 100644 index 0000000..af07379 --- /dev/null +++ b/drivers/staging/ced1401/machine.h @@ -0,0 +1,127 @@ +/***************************************************************************** +** +** machine.h +** +** Copyright (c) Cambridge Electronic Design Limited 1991,1992,2010 +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +** +** Contact CED: Cambridge Electronic Design Limited, Science Park, Milton Road +** Cambridge, CB6 0FE. +** www.ced.co.uk +** greg@ced.co.uk +** +** This file is included at the start of 'C' or 'C++' source file to define +** things for cross-platform/compiler interoperability. This used to deal with +** MSDOS/16-bit stuff, but this was all removed in Decemeber 2010. There are +** three things to consider: Windows, LINUX, mac OSX (BSD Unix) and 32 vs 64 +** bit. At the time of writing (DEC 2010) there is a consensus on the following +** and their unsigned equivalents: +** +** type bits +** char 8 +** short 16 +** int 32 +** long long 64 +** +** long is a problem as it is always 64 bits on linux/unix and is always 32 bits +** on windows. +** On windows, we define _IS_WINDOWS_ and one of WIN32 or WIN64. +** On linux we define LINUX +** On Max OSX we define MACOSX +** +*/ + +#ifndef __MACHINE_H__ +#define __MACHINE_H__ +#ifndef __KERNEL__ +#include +#include +#endif + +/* +** The initial section is to identify the operating system +*/ +#if (defined(__linux__) || defined(_linux) || defined(__linux)) && !defined(LINUX) +#define LINUX 1 +#endif + +#if (defined(__WIN32__) || defined(_WIN32)) && !defined(WIN32) +#define WIN32 1 +#endif + +#if defined(__APPLE__) +#define MACOSX +#endif + +#if defined(_WIN64) +#undef WIN32 +#undef WIN64 +#define WIN64 1 +#endif + +#if defined(WIN32) || defined(WIN64) +#define _IS_WINDOWS_ 1 +#endif + +#if defined(LINUX) || defined(MAXOSX) + #define FAR + + typedef int BOOL; // To match Windows + typedef char * LPSTR; + typedef const char * LPCSTR; + typedef unsigned short WORD; + typedef unsigned int DWORD; + typedef unsigned char BYTE; + typedef BYTE BOOLEAN; + typedef unsigned char UCHAR; + #define __packed __attribute__((packed)) + typedef BYTE * LPBYTE; + #define HIWORD(x) (WORD)(((x)>>16) & 0xffff) + #define LOWORD(x) (WORD)((x) & 0xffff) +#endif + +#ifdef _IS_WINDOWS_ +#include +#define __packed +#endif + +/* +** Sort out the DllExport and DllImport macros. The GCC compiler has its own +** syntax for this, though it also supports the MS specific __declspec() as +** a synonym. +*/ +#ifdef GNUC + #define DllExport __attribute__((dllexport)) + #define DllImport __attribute__((dllimport)) +#endif + +#ifndef DllExport +#ifdef _IS_WINDOWS_ + #define DllExport __declspec(dllexport) + #define DllImport __declspec(dllimport) +#else + #define DllExport + #define DllImport +#endif +#endif /* _IS_WINDOWS_ */ + + +#ifndef TRUE + #define TRUE 1 + #define FALSE 0 +#endif + +#endif diff --git a/drivers/staging/ced1401/usb1401.c b/drivers/staging/ced1401/usb1401.c new file mode 100644 index 0000000..54595b8 --- /dev/null +++ b/drivers/staging/ced1401/usb1401.c @@ -0,0 +1,1597 @@ +/*********************************************************************************** + CED1401 usb driver. This basic loading is based on the usb-skeleton.c code that is: + Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com) + Copyright (C) 2012 Alois Schloegl + There is not a great deal of the skeleton left. + + All the remainder dealing specifically with the CED1401 is based on drivers written + by CED for other systems (mainly Windows) and is: + Copyright (C) 2010 Cambridge Electronic Design Ltd + Author Greg P Smith (greg@ced.co.uk) + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + +Endpoints +********* +There are 4 endpoints plus the control endpoint in the standard interface +provided by most 1401s. The control endpoint is used for standard USB requests, +plus various CED-specific transactions such as start self test, debug and get +the 1401 status. The other endpoints are: + + 1 Characters to the 1401 + 2 Characters from the 1401 + 3 Block data to the 1401 + 4 Block data to the host. + +inside the driver these are indexed as an array from 0 to 3, transactions +over the control endpoint are carried out using a separate mechanism. The +use of the endpoints is mostly straightforward, with the driver issuing +IO request packets (IRPs) as required to transfer data to and from the 1401. +The handling of endpoint 2 is different because it is used for characters +from the 1401, which can appear spontaneously and without any other driver +activity - for example to repeatedly request DMA transfers in Spike2. The +desired effect is achieved by using an interrupt endpoint which can be +polled to see if it has data available, and writing the driver so that it +always maintains a pending read IRP from that endpoint which will read the +character data and terminate as soon as the 1401 makes data available. This +works very well, some care is taken with when you kick off this character +read IRP to avoid it being active when it is not wanted but generally it +is running all the time. + +In the 2270, there are only three endpoints plus the control endpoint. In +addition to the transactions mentioned above, the control endpoint is used +to transfer character data to the 1401. The other endpoints are used as: + + 1 Characters from the 1401 + 2 Block data to the 1401 + 3 Block data to the host. + +The type of interface available is specified by the interface subclass field +in the interface descriptor provided by the 1401. See the USB_INT_ constants +for the values that this field can hold. + +**************************************************************************** +Linux implementation + +Although Linux Device Drivers (3rd Edition) was a major source of information, +it is very out of date. A lot of information was gleaned from the latest +usb_skeleton.c code (you need to download the kernel sources to get this). + +To match the Windows version, everything is done using ioctl calls. All the +device state is held in the DEVICE_EXTENSION (named to match Windows use). +Block transfers are done by using get_user_pages() to pin down a list of +pages that we hold a pointer to in the device driver. We also allocate a +coherent transfer buffer of size STAGED_SZ (this must be a multiple of the +bulk endpoint size so that the 1401 does not realise that we break large +transfers down into smaller pieces). We use kmap_atomic() to get a kernel +va for each page, as it is required, for copying; see CopyUserSpace(). + +All character and data transfers are done using asynchronous IO. All Urbs are +tracked by anchoring them. Status and debug ioctls are implemented with the +synchronous non-Urb based transfers. +*/ + +#include +#include +#include +#include +#include +#include +#include +#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) ) + #include + #include + #include + #include + #include +#endif + + +#include "usb1401.h" + +/* Define these values to match your devices */ +#define USB_CED_VENDOR_ID 0x0525 +#define USB_CED_PRODUCT_ID 0xa0f0 + +/* table of devices that work with this driver */ +static const struct usb_device_id ced_table[] = +{ + { USB_DEVICE(USB_CED_VENDOR_ID, USB_CED_PRODUCT_ID) }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE(usb, ced_table); + + +/* Get a minor range for your devices from the usb maintainer */ +#define USB_CED_MINOR_BASE 192 + +/* our private defines. if this grows any larger, use your own .h file */ +#define MAX_TRANSFER (PAGE_SIZE - 512) +/* MAX_TRANSFER is chosen so that the VM is not stressed by + allocations > PAGE_SIZE and the number of packets in a page + is an integer 512 is the largest possible packet on EHCI */ +#define WRITES_IN_FLIGHT 8 +/* arbitrarily chosen */ + +/* +The cause for these errors is that the driver makes use of the functions usb_buffer_alloc() and usb_buffer_free() which got renamed in kernel 2.6.35. This is stated in the Changelog: USB: rename usb_buffer_alloc() and usb_buffer_free() users + For more clearance what the functions actually do, + usb_buffer_alloc() is renamed to usb_alloc_coherent() + usb_buffer_free() is renamed to usb_free_coherent() + This is needed on Debian 2.6.32-5-amd64 +*/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) ) + #define usb_alloc_coherent usb_buffer_alloc + #define usb_free_coherent usb_buffer_free + #define noop_llseek NULL +#endif + +static struct usb_driver ced_driver; + +static void ced_delete(struct kref *kref) +{ + DEVICE_EXTENSION *pdx = to_DEVICE_EXTENSION(kref); + + // Free up the output buffer, then free the output urb. Note that the interface member + // of pdx will probably be NULL, so cannot be used to get to dev. + usb_free_coherent(pdx->udev, OUTBUF_SZ, pdx->pCoherCharOut, pdx->pUrbCharOut->transfer_dma); + usb_free_urb(pdx->pUrbCharOut); + + // Do the same for chan input + usb_free_coherent(pdx->udev, INBUF_SZ, pdx->pCoherCharIn, pdx->pUrbCharIn->transfer_dma); + usb_free_urb(pdx->pUrbCharIn); + + // Do the same for the block transfers + usb_free_coherent(pdx->udev, STAGED_SZ, pdx->pCoherStagedIO, pdx->pStagedUrb->transfer_dma); + usb_free_urb(pdx->pStagedUrb); + + usb_put_dev(pdx->udev); + kfree(pdx); +} + +// This is the driver end of the open() call from user space. +static int ced_open(struct inode *inode, struct file *file) +{ + DEVICE_EXTENSION *pdx; + int retval = 0; + int subminor = iminor(inode); + struct usb_interface* interface = usb_find_interface(&ced_driver, subminor); + if (!interface) + { + err("%s - error, can't find device for minor %d", __func__, subminor); + retval = -ENODEV; + goto exit; + } + + pdx = usb_get_intfdata(interface); + if (!pdx) + { + retval = -ENODEV; + goto exit; + } + + dev_dbg(&interface->dev, "%s got pdx", __func__); + + /* increment our usage count for the device */ + kref_get(&pdx->kref); + + /* lock the device to allow correctly handling errors + * in resumption */ + mutex_lock(&pdx->io_mutex); + + if (!pdx->open_count++) + { + retval = usb_autopm_get_interface(interface); + if (retval) + { + pdx->open_count--; + mutex_unlock(&pdx->io_mutex); + kref_put(&pdx->kref, ced_delete); + goto exit; + } + } + else + { //uncomment this block if you want exclusive open + dev_err(&interface->dev, "%s fail: already open", __func__); + retval = -EBUSY; + pdx->open_count--; + mutex_unlock(&pdx->io_mutex); + kref_put(&pdx->kref, ced_delete); + goto exit; + } + /* prevent the device from being autosuspended */ + + /* save our object in the file's private structure */ + file->private_data = pdx; + mutex_unlock(&pdx->io_mutex); + +exit: + return retval; +} + +static int ced_release(struct inode *inode, struct file *file) +{ + DEVICE_EXTENSION *pdx = file->private_data; + if (pdx == NULL) + return -ENODEV; + + dev_dbg(&pdx->interface->dev,"%s called", __func__); + mutex_lock(&pdx->io_mutex); + if (!--pdx->open_count && pdx->interface) // Allow autosuspend + usb_autopm_put_interface(pdx->interface); + mutex_unlock(&pdx->io_mutex); + + kref_put(&pdx->kref, ced_delete); // decrement the count on our device + return 0; +} + +static int ced_flush(struct file *file, fl_owner_t id) +{ + int res; + DEVICE_EXTENSION *pdx = file->private_data; + if (pdx == NULL) + return -ENODEV; + + dev_dbg(&pdx->interface->dev,"%s char in pend=%d", __func__, pdx->bReadCharsPending); + + /* wait for io to stop */ + mutex_lock(&pdx->io_mutex); + dev_dbg(&pdx->interface->dev,"%s got io_mutex", __func__); + ced_draw_down(pdx); + + /* read out errors, leave subsequent opens a clean slate */ + spin_lock_irq(&pdx->err_lock); + res = pdx->errors ? (pdx->errors == -EPIPE ? -EPIPE : -EIO) : 0; + pdx->errors = 0; + spin_unlock_irq(&pdx->err_lock); + + mutex_unlock(&pdx->io_mutex); + dev_dbg(&pdx->interface->dev,"%s exit reached", __func__); + + return res; +} + + +static ssize_t ced_read(struct file *file, char *buffer, size_t count, + loff_t *ppos) +{ + DEVICE_EXTENSION *pdx = file->private_data; + dev_err(&pdx->interface->dev, "%s called: use ioctl for cedusb", __func__); + return 0; // as we do not do reads this way +} + +static ssize_t ced_write(struct file *file, const char *user_buffer, + size_t count, loff_t *ppos) +{ + DEVICE_EXTENSION *pdx = file->private_data; + dev_err(&pdx->interface->dev, "%s called: use ioctl for cedusb", __func__); + return 0; +} + +/*************************************************************************** +** CanAcceptIoRequests +** If the device is removed, interface is set NULL. We also clear our pointer +** from the interface, so we should make sure that pdx is not NULL. This will +** not help with a device extension held by a file. +** return true if can accept new io requests, else false +*/ +static bool CanAcceptIoRequests(DEVICE_EXTENSION* pdx) +{ + return pdx && pdx->interface; // Can we accept IO requests +} + +/**************************************************************************** +** Callback routine to complete writes. This may need to fire off another +** urb to complete the transfer. +****************************************************************************/ +static void ced_writechar_callback(struct urb* pUrb) +{ + DEVICE_EXTENSION *pdx = pUrb->context; + int nGot = pUrb->actual_length; // what we transferred + + if (pUrb->status) + { // sync/async unlink faults aren't errors + if (!(pUrb->status == -ENOENT || pUrb->status == -ECONNRESET || pUrb->status == -ESHUTDOWN)) + { + dev_err(&pdx->interface->dev, "%s - nonzero write bulk status received: %d", __func__, pUrb->status); + } + + spin_lock(&pdx->err_lock); + pdx->errors = pUrb->status; + spin_unlock(&pdx->err_lock); + nGot = 0; // and tidy up again if so + + spin_lock(&pdx->charOutLock); // already at irq level + pdx->dwOutBuffGet = 0; // Reset the output buffer + pdx->dwOutBuffPut = 0; + pdx->dwNumOutput = 0; // Clear the char count + pdx->bPipeError[0] = 1; // Flag an error for later + pdx->bSendCharsPending = false; // Allow other threads again + spin_unlock(&pdx->charOutLock); // already at irq level + dev_dbg(&pdx->interface->dev, "%s - char out done, 0 chars sent", __func__); + } + else + { + dev_dbg(&pdx->interface->dev, "%s - char out done, %d chars sent", __func__, nGot); + spin_lock(&pdx->charOutLock); // already at irq level + pdx->dwNumOutput -= nGot; // Now adjust the char send buffer + pdx->dwOutBuffGet += nGot; // to match what we did + if (pdx->dwOutBuffGet >= OUTBUF_SZ) // Can't do this any earlier as data could be overwritten + pdx->dwOutBuffGet = 0; + + if (pdx->dwNumOutput > 0) // if more to be done... + { + int nPipe = 0; // The pipe number to use + int iReturn; + char* pDat = &pdx->outputBuffer[pdx->dwOutBuffGet]; + unsigned int dwCount = pdx->dwNumOutput; // maximum to send + if ((pdx->dwOutBuffGet+dwCount) > OUTBUF_SZ) // does it cross buffer end? + dwCount = OUTBUF_SZ - pdx->dwOutBuffGet; + spin_unlock(&pdx->charOutLock); // we are done with stuff that changes + memcpy(pdx->pCoherCharOut, pDat, dwCount); // copy output data to the buffer + usb_fill_bulk_urb(pdx->pUrbCharOut, pdx->udev, + usb_sndbulkpipe(pdx->udev, pdx->epAddr[0]), + pdx->pCoherCharOut, dwCount, ced_writechar_callback, pdx); + pdx->pUrbCharOut->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + usb_anchor_urb(pdx->pUrbCharOut, &pdx->submitted); // in case we need to kill it + iReturn = usb_submit_urb(pdx->pUrbCharOut, GFP_ATOMIC); + dev_dbg(&pdx->interface->dev, "%s n=%d>%s<", __func__, dwCount, pDat); + spin_lock(&pdx->charOutLock); // grab lock for errors + if (iReturn) + { + pdx->bPipeError[nPipe] = 1; // Flag an error to be handled later + pdx->bSendCharsPending = false; // Allow other threads again + usb_unanchor_urb(pdx->pUrbCharOut); + dev_err(&pdx->interface->dev, "%s usb_submit_urb() returned %d", __func__, iReturn); + } + } + else + pdx->bSendCharsPending = false; // Allow other threads again + spin_unlock(&pdx->charOutLock); // already at irq level + } +} + +/**************************************************************************** +** SendChars +** Transmit the characters in the output buffer to the 1401. This may need +** breaking down into multiple transfers. +****************************************************************************/ +int SendChars(DEVICE_EXTENSION* pdx) +{ + int iReturn = U14ERR_NOERROR; + + spin_lock_irq(&pdx->charOutLock); // Protect ourselves + + if ((!pdx->bSendCharsPending) && // Not currently sending + (pdx->dwNumOutput > 0) && // has characters to output + (CanAcceptIoRequests(pdx))) // and current activity is OK + { + unsigned int dwCount = pdx->dwNumOutput; // Get a copy of the character count + pdx->bSendCharsPending = true; // Set flag to lock out other threads + + dev_dbg(&pdx->interface->dev, "Send %d chars to 1401, EP0 flag %d\n", dwCount, pdx->nPipes == 3); + // If we have only 3 end points we must send the characters to the 1401 using EP0. + if (pdx->nPipes == 3) + { + // For EP0 character transmissions to the 1401, we have to hang about until they + // are gone, as otherwise without more character IO activity they will never go. + unsigned int count = dwCount; // Local char counter + unsigned int index = 0; // The index into the char buffer + + spin_unlock_irq(&pdx->charOutLock); // Free spinlock as we call USBD + + while ((count > 0) && (iReturn == U14ERR_NOERROR)) + { + // We have to break the transfer up into 64-byte chunks because of a 2270 problem + int n = count > 64 ? 64 : count; // Chars for this xfer, max of 64 + int nSent = usb_control_msg(pdx->udev, + usb_sndctrlpipe(pdx->udev,0), // use end point 0 + DB_CHARS, // bRequest + (H_TO_D|VENDOR|DEVREQ), // to the device, vendor request to the device + 0,0, // value and index are both 0 + &pdx->outputBuffer[index], // where to send from + n, // how much to send + 1000); // timeout in jiffies + if (nSent <= 0) + { + iReturn = nSent ? nSent : -ETIMEDOUT; // if 0 chars says we timed out + dev_err(&pdx->interface->dev, "Send %d chars by EP0 failed: %d", n, iReturn); + } + else + { + dev_dbg(&pdx->interface->dev, "Sent %d chars by EP0", n); + count -= nSent; + index += nSent; + } + } + + spin_lock_irq(&pdx->charOutLock); // Protect pdx changes, released by general code + pdx->dwOutBuffGet = 0; // so reset the output buffer + pdx->dwOutBuffPut = 0; + pdx->dwNumOutput = 0; // and clear the buffer count + pdx->bSendCharsPending = false; // Allow other threads again + } + else + { // Here for sending chars normally - we hold the spin lock + int nPipe = 0; // The pipe number to use + char* pDat = &pdx->outputBuffer[pdx->dwOutBuffGet]; + + if ((pdx->dwOutBuffGet+dwCount) > OUTBUF_SZ) // does it cross buffer end? + dwCount = OUTBUF_SZ - pdx->dwOutBuffGet; + spin_unlock_irq(&pdx->charOutLock); // we are done with stuff that changes + memcpy(pdx->pCoherCharOut, pDat, dwCount); // copy output data to the buffer + usb_fill_bulk_urb(pdx->pUrbCharOut, pdx->udev, + usb_sndbulkpipe(pdx->udev, pdx->epAddr[0]), + pdx->pCoherCharOut, dwCount, ced_writechar_callback, pdx); + pdx->pUrbCharOut->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + usb_anchor_urb(pdx->pUrbCharOut, &pdx->submitted); + iReturn = usb_submit_urb(pdx->pUrbCharOut, GFP_KERNEL); + spin_lock_irq(&pdx->charOutLock); // grab lock for errors + if (iReturn) + { + pdx->bPipeError[nPipe] = 1; // Flag an error to be handled later + pdx->bSendCharsPending = false; // Allow other threads again + usb_unanchor_urb(pdx->pUrbCharOut); // remove from list of active urbs + } + } + } + else + if (pdx->bSendCharsPending && (pdx->dwNumOutput > 0)) + dev_dbg(&pdx->interface->dev, "SendChars bSendCharsPending:true"); + + + dev_dbg(&pdx->interface->dev, "SendChars exit code: %d", iReturn); + spin_unlock_irq(&pdx->charOutLock); // Now let go of the spinlock + return iReturn; +} + +/*************************************************************************** +** CopyUserSpace +** This moves memory between pinned down user space and the pCoherStagedIO +** memory buffer we use for transfers. Copy n bytes in the directions that +** is defined by pdx->StagedRead. The user space is determined by the area +** in pdx->StagedId and the offset in pdx->StagedDone. The user +** area may well not start on a page boundary, so allow for that. +** +** We have a table of physical pages that describe the area, so we can use +** this to get a virtual address that the kernel can use. +** +** pdx Is our device extension which holds all we know about the transfer. +** n The number of bytes to move one way or the other. +***************************************************************************/ +static void CopyUserSpace(DEVICE_EXTENSION *pdx, int n) +{ + unsigned int nArea = pdx->StagedId; + if (nArea < MAX_TRANSAREAS) + { + TRANSAREA *pArea = &pdx->rTransDef[nArea]; // area to be used + unsigned int dwOffset = pdx->StagedDone + pdx->StagedOffset + pArea->dwBaseOffset; + char* pCoherBuf = pdx->pCoherStagedIO; // coherent buffer + if (!pArea->bUsed) + { + dev_err(&pdx->interface->dev, "%s area %d unused", __func__, nArea); + return; + } + + while (n) + { + int nPage = dwOffset >> PAGE_SHIFT; // page number in table + if (nPage < pArea->nPages) + { + char *pvAddress = (char*)kmap_atomic(pArea->pPages[nPage], KM_IRQ0); + if (pvAddress) + { + unsigned int uiPageOff = dwOffset & (PAGE_SIZE-1); // offset into the page + size_t uiXfer = PAGE_SIZE - uiPageOff; // max to transfer on this page + if (uiXfer > n) // limit byte count if too much + uiXfer = n; // for the page + if (pdx->StagedRead) + memcpy(pvAddress+uiPageOff, pCoherBuf, uiXfer); + else + memcpy(pCoherBuf, pvAddress+uiPageOff, uiXfer); + kunmap_atomic(pvAddress, KM_IRQ0); + dwOffset += uiXfer; + pCoherBuf += uiXfer; + n -= uiXfer; + } + else + { + dev_err(&pdx->interface->dev, "%s did not map page %d", __func__, nPage); + return; + } + + } + else + { + dev_err(&pdx->interface->dev, "%s exceeded pages %d", __func__, nPage); + return; + } + } + } + else + dev_err(&pdx->interface->dev, "%s bad area %d", __func__, nArea); +} + +// Forward declarations for stuff used circularly +static int StageChunk(DEVICE_EXTENSION *pdx); +/*************************************************************************** +** ReadWrite_Complete +** +** Completion routine for our staged read/write Irps +*/ +static void staged_callback(struct urb* pUrb) +{ + DEVICE_EXTENSION *pdx = pUrb->context; + unsigned int nGot = pUrb->actual_length; // what we transferred + bool bCancel = false; + bool bRestartCharInput; // used at the end + + spin_lock(&pdx->stagedLock); // stop ReadWriteMem() action while this routine is running + pdx->bStagedUrbPending = false; // clear the flag for staged IRP pending + + if (pUrb->status) + { // sync/async unlink faults aren't errors + if (!(pUrb->status == -ENOENT || pUrb->status == -ECONNRESET || pUrb->status == -ESHUTDOWN)) + { + dev_err(&pdx->interface->dev, "%s - nonzero write bulk status received: %d", __func__, pUrb->status); + } + else + dev_info(&pdx->interface->dev, "%s - staged xfer cancelled", __func__); + + spin_lock(&pdx->err_lock); + pdx->errors = pUrb->status; + spin_unlock(&pdx->err_lock); + nGot = 0; // and tidy up again if so + bCancel = true; + } + else + { + dev_dbg(&pdx->interface->dev, "%s %d chars xferred", __func__, nGot); + if (pdx->StagedRead) // if reading, save to user space + CopyUserSpace(pdx, nGot); // copy from buffer to user + if (nGot == 0) + dev_dbg(&pdx->interface->dev, "%s ZLP", __func__); + } + + // Update the transfer length based on the TransferBufferLength value in the URB + pdx->StagedDone += nGot; + + dev_dbg(&pdx->interface->dev, "%s, done %d bytes of %d", __func__, pdx->StagedDone, pdx->StagedLength); + + if ((pdx->StagedDone == pdx->StagedLength) || // If no more to do + (bCancel)) // or this IRP was cancelled + { + TRANSAREA* pArea = &pdx->rTransDef[pdx->StagedId]; // Transfer area info + dev_dbg(&pdx->interface->dev, "%s transfer done, bytes %d, cancel %d", __func__, pdx->StagedDone, bCancel); + + // Here is where we sort out what to do with this transfer if using a circular buffer. We have + // a completed transfer that can be assumed to fit into the transfer area. We should be able to + // add this to the end of a growing block or to use it to start a new block unless the code + // that calculates the offset to use (in ReadWriteMem) is totally duff. + if ((pArea->bCircular) && (pArea->bCircToHost) && (!bCancel) && // Time to sort out circular buffer info? + (pdx->StagedRead)) // Only for tohost transfers for now + { + if (pArea->aBlocks[1].dwSize > 0) // If block 1 is in use we must append to it + { + if (pdx->StagedOffset == (pArea->aBlocks[1].dwOffset + pArea->aBlocks[1].dwSize)) + { + pArea->aBlocks[1].dwSize += pdx->StagedLength; + dev_dbg(&pdx->interface->dev, "RWM_Complete, circ block 1 now %d bytes at %d", + pArea->aBlocks[1].dwSize, pArea->aBlocks[1].dwOffset); + } + else + { + // Here things have gone very, very, wrong, but I cannot see how this can actually be achieved + pArea->aBlocks[1].dwOffset = pdx->StagedOffset; + pArea->aBlocks[1].dwSize = pdx->StagedLength; + dev_err(&pdx->interface->dev, "%s ERROR, circ block 1 re-started %d bytes at %d", + __func__, pArea->aBlocks[1].dwSize, pArea->aBlocks[1].dwOffset); + } + } + else // If block 1 is not used, we try to add to block 0 + { + if (pArea->aBlocks[0].dwSize > 0) // Got stored block 0 information? + { // Must append onto the existing block 0 + if (pdx->StagedOffset == (pArea->aBlocks[0].dwOffset + pArea->aBlocks[0].dwSize)) + { + pArea->aBlocks[0].dwSize += pdx->StagedLength; // Just add this transfer in + dev_dbg(&pdx->interface->dev, "RWM_Complete, circ block 0 now %d bytes at %d", + pArea->aBlocks[0].dwSize, pArea->aBlocks[0].dwOffset); + } + else // If it doesn't append, put into new block 1 + { + pArea->aBlocks[1].dwOffset = pdx->StagedOffset; + pArea->aBlocks[1].dwSize = pdx->StagedLength; + dev_dbg(&pdx->interface->dev, "RWM_Complete, circ block 1 started %d bytes at %d", + pArea->aBlocks[1].dwSize, pArea->aBlocks[1].dwOffset); + } + } + else // No info stored yet, just save in block 0 + { + pArea->aBlocks[0].dwOffset = pdx->StagedOffset; + pArea->aBlocks[0].dwSize = pdx->StagedLength; + dev_dbg(&pdx->interface->dev, "RWM_Complete, circ block 0 started %d bytes at %d", + pArea->aBlocks[0].dwSize, pArea->aBlocks[0].dwOffset); + } + } + } + + if (!bCancel) // Don't generate an event if cancelled + { + dev_dbg(&pdx->interface->dev, "RWM_Complete, bCircular %d, bToHost %d, eStart %d, eSize %d", + pArea->bCircular, pArea->bEventToHost, pArea->dwEventSt, pArea->dwEventSz); + if ((pArea->dwEventSz) && // Set a user-mode event... + (pdx->StagedRead == pArea->bEventToHost)) // ...on transfers in this direction? + { + int iWakeUp = 0; // assume + // If we have completed the right sort of DMA transfer then set the event to notify + // the user code to wake up anyone that is waiting. + if ((pArea->bCircular) && // Circular areas use a simpler test + (pArea->bCircToHost)) // only in supported direction + { // Is total data waiting up to size limit? + unsigned int dwTotal = pArea->aBlocks[0].dwSize + pArea->aBlocks[1].dwSize; + iWakeUp = (dwTotal >= pArea->dwEventSz); + } + else + { + unsigned int transEnd = pdx->StagedOffset + pdx->StagedLength; + unsigned int eventEnd = pArea->dwEventSt + pArea->dwEventSz; + iWakeUp = (pdx->StagedOffset < eventEnd) && (transEnd > pArea->dwEventSt); + } + + if (iWakeUp) + { + dev_dbg(&pdx->interface->dev, "About to set event to notify app"); + wake_up_interruptible(&pArea->wqEvent); // wake up waiting processes + ++pArea->iWakeUp; // increment wakeup count + } + } + } + + pdx->dwDMAFlag = MODE_CHAR; // Switch back to char mode before ReadWriteMem call + + if (!bCancel) // Don't look for waiting transfer if cancelled + { + // If we have a transfer waiting, kick it off + if (pdx->bXFerWaiting) // Got a block xfer waiting? + { + int iReturn; + dev_info(&pdx->interface->dev, "*** RWM_Complete *** pending transfer will now be set up!!!"); + iReturn = ReadWriteMem(pdx, !pdx->rDMAInfo.bOutWard, pdx->rDMAInfo.wIdent, pdx->rDMAInfo.dwOffset, pdx->rDMAInfo.dwSize); + + if (iReturn) + dev_err(&pdx->interface->dev, "RWM_Complete rw setup failed %d", iReturn); + } + } + + } + else // Here for more to do + StageChunk(pdx); // fire off the next bit + + // While we hold the stagedLock, see if we should reallow character input ints + // Don't allow if cancelled, or if a new block has started or if there is a waiting block. + // This feels wrong as we should ask which spin lock protects dwDMAFlag. + bRestartCharInput = !bCancel && (pdx->dwDMAFlag == MODE_CHAR) && !pdx->bXFerWaiting; + + spin_unlock(&pdx->stagedLock); // Finally release the lock again + + // This is not correct as dwDMAFlag is protected by the staged lock, but it is treated + // in Allowi as if it were protected by the char lock. In any case, most systems will + // not be upset by char input during DMA... sigh. Needs sorting out. + if (bRestartCharInput) // may be out of date, but... + Allowi(pdx, true); // ...Allowi tests a lock too. + dev_dbg(&pdx->interface->dev, "%s done", __func__); +} + +/**************************************************************************** +** StageChunk +** +** Generates the next chunk of data making up a staged transfer. +** +** The calling code must have acquired the staging spinlock before calling +** this function, and is responsible for releasing it. We are at callback level. +****************************************************************************/ +static int StageChunk(DEVICE_EXTENSION *pdx) +{ + int iReturn = U14ERR_NOERROR; + unsigned int ChunkSize; + int nPipe = pdx->StagedRead ? 3 : 2; // The pipe number to use for reads or writes + if (pdx->nPipes == 3) nPipe--; // Adjust for the 3-pipe case + if (nPipe < 0) // and trap case that should never happen + return U14ERR_FAIL; + + if (!CanAcceptIoRequests(pdx)) // got sudden remove? + { + dev_info(&pdx->interface->dev, "%s sudden remove, giving up", __func__); + return U14ERR_FAIL; // could do with a better error + } + + ChunkSize = (pdx->StagedLength - pdx->StagedDone); // transfer length remaining + if (ChunkSize > STAGED_SZ) // make sure to keep legal + ChunkSize = STAGED_SZ; // limit to max allowed + + if (!pdx->StagedRead) // if writing... + CopyUserSpace(pdx, ChunkSize); // ...copy data into the buffer + + usb_fill_bulk_urb(pdx->pStagedUrb, pdx->udev, + pdx->StagedRead ? usb_rcvbulkpipe(pdx->udev, pdx->epAddr[nPipe]): + usb_sndbulkpipe(pdx->udev, pdx->epAddr[nPipe]), + pdx->pCoherStagedIO, ChunkSize, staged_callback, pdx); + pdx->pStagedUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + usb_anchor_urb(pdx->pStagedUrb, &pdx->submitted); // in case we need to kill it + iReturn = usb_submit_urb(pdx->pStagedUrb, GFP_ATOMIC); + if (iReturn) + { + usb_unanchor_urb(pdx->pStagedUrb); // kill it + pdx->bPipeError[nPipe] = 1; // Flag an error to be handled later + dev_err(&pdx->interface->dev, "%s submit urb failed, code %d", __func__, iReturn); + } + else + pdx->bStagedUrbPending = true; // Set the flag for staged URB pending + dev_dbg(&pdx->interface->dev, "%s done so far:%d, this size:%d", __func__, pdx->StagedDone, ChunkSize); + + return iReturn; +} + +/*************************************************************************** +** ReadWriteMem +** +** This routine is used generally for block read and write operations. +** Breaks up a read or write in to specified sized chunks, as specified by pipe +** information on maximum transfer size. +** +** Any code that calls this must be holding the stagedLock +** +** Arguments: +** DeviceObject - pointer to our FDO (Functional Device Object) +** Read - TRUE for read, FALSE for write. This is from POV of the driver +** wIdent - the transfer area number - defines memory area and more. +** dwOffs - the start offset within the transfer area of the start of this +** transfer. +** dwLen - the number of bytes to transfer. +*/ +int ReadWriteMem(DEVICE_EXTENSION *pdx, bool Read, unsigned short wIdent, + unsigned int dwOffs, unsigned int dwLen) +{ + TRANSAREA* pArea = &pdx->rTransDef[wIdent]; // Transfer area info + + if (!CanAcceptIoRequests(pdx)) // Are we in a state to accept new requests? + { + dev_err(&pdx->interface->dev, "%s can't accept requests", __func__); + return U14ERR_FAIL; + } + + dev_dbg(&pdx->interface->dev, "%s xfer %d bytes to %s, offset %d, area %d", + __func__, dwLen, Read ? "host" : "1401", dwOffs, wIdent); + + // Amazingly, we can get an escape sequence back before the current staged Urb is done, so we + // have to check for this situation and, if so, wait until all is OK. + if (pdx->bStagedUrbPending) + { + pdx->bXFerWaiting = true; // Flag we are waiting + dev_info(&pdx->interface->dev, "%s xfer is waiting, as previous staged pending", __func__); + return U14ERR_NOERROR; + } + + if (dwLen == 0) // allow 0-len read or write; just return success + { + dev_dbg(&pdx->interface->dev, "%s OK; zero-len read/write request", __func__); + return U14ERR_NOERROR; + } + + if ((pArea->bCircular) && // Circular transfer? + (pArea->bCircToHost) && (Read)) // In a supported direction + { // If so, we sort out offset ourself + bool bWait = false; // Flag for transfer having to wait + + dev_dbg(&pdx->interface->dev, "Circular buffers are %d at %d and %d at %d", + pArea->aBlocks[0].dwSize, pArea->aBlocks[0].dwOffset, pArea->aBlocks[1].dwSize, pArea->aBlocks[1].dwOffset); + if (pArea->aBlocks[1].dwSize > 0) // Using the second block already? + { + dwOffs = pArea->aBlocks[1].dwOffset + pArea->aBlocks[1].dwSize; // take offset from that + bWait = (dwOffs + dwLen) > pArea->aBlocks[0].dwOffset; // Wait if will overwrite block 0? + bWait |= (dwOffs + dwLen) > pArea->dwLength; // or if it overflows the buffer + } + else // Area 1 not in use, try to use area 0 + { + if (pArea->aBlocks[0].dwSize == 0) // Reset block 0 if not in use + pArea->aBlocks[0].dwOffset = 0; + dwOffs = pArea->aBlocks[0].dwOffset + pArea->aBlocks[0].dwSize; + if ((dwOffs+dwLen) > pArea->dwLength) // Off the end of the buffer? + { + pArea->aBlocks[1].dwOffset = 0; // Set up to use second block + dwOffs = 0; + bWait = (dwOffs + dwLen) > pArea->aBlocks[0].dwOffset; // Wait if will overwrite block 0? + bWait |= (dwOffs + dwLen) > pArea->dwLength; // or if it overflows the buffer + } + } + + if (bWait) // This transfer will have to wait? + { + pdx->bXFerWaiting = true; // Flag we are waiting + dev_dbg(&pdx->interface->dev, "%s xfer waiting for circular buffer space", __func__); + return U14ERR_NOERROR; + } + + dev_dbg(&pdx->interface->dev, "%s circular xfer, %d bytes starting at %d", __func__, dwLen, dwOffs); + } + + // Save the parameters for the read\write transfer + pdx->StagedRead = Read; // Save the parameters for this read + pdx->StagedId = wIdent; // ID allows us to get transfer area info + pdx->StagedOffset = dwOffs; // The area within the transfer area + pdx->StagedLength = dwLen; + pdx->StagedDone = 0; // Initialise the byte count + pdx->dwDMAFlag = MODE_LINEAR; // Set DMA mode flag at this point + pdx->bXFerWaiting = false; // Clearly not a transfer waiting now + +// KeClearEvent(&pdx->StagingDoneEvent); // Clear the transfer done event + StageChunk(pdx); // fire off the first chunk + + return U14ERR_NOERROR; +} + +/**************************************************************************** +** +** ReadChar +** +** Reads a character a buffer. If there is no more +** data we return FALSE. Used as part of decoding a DMA request. +** +****************************************************************************/ +static bool ReadChar(unsigned char* pChar, char* pBuf, unsigned int* pdDone, unsigned int dGot) +{ + bool bRead = false; + unsigned int dDone = *pdDone; + + if (dDone < dGot) // If there is more data + { + *pChar = (unsigned char)pBuf[dDone];// Extract the next char + dDone++; // Increment the done count + *pdDone = dDone; + bRead = true; // and flag success + } + + return bRead; +} + +#ifdef NOTUSED +/**************************************************************************** +** +** ReadWord +** +** Reads a word from the 1401, just uses ReadChar twice; passes on any error +** +*****************************************************************************/ +static bool ReadWord(unsigned short* pWord, char* pBuf, unsigned int* pdDone, unsigned int dGot) +{ + if (ReadChar((unsigned char*)pWord, pBuf, pdDone, dGot)) + return ReadChar(((unsigned char*)pWord)+1, pBuf, pdDone, dGot); + else + return false; +} +#endif + +/**************************************************************************** +** ReadHuff +** +** Reads a coded number in and returns it, Code is: +** If data is in range 0..127 we recieve 1 byte. If data in range 128-16383 +** we recieve two bytes, top bit of first indicates another on its way. If +** data in range 16383-4194303 we get three bytes, top two bits of first set +** to indicate three byte total. +** +*****************************************************************************/ +static bool ReadHuff(volatile unsigned int* pDWord, char* pBuf, unsigned int* pdDone, unsigned int dGot) +{ + unsigned char ucData; /* for each read to ReadChar */ + bool bReturn = true; /* assume we will succeed */ + unsigned int dwData = 0; /* Accumulator for the data */ + + if (ReadChar(&ucData, pBuf, pdDone, dGot)) + { + dwData = ucData; /* copy the data */ + if ((dwData & 0x00000080) != 0) /* Bit set for more data ? */ + { + dwData &= 0x0000007F; /* Clear the relevant bit */ + if (ReadChar(&ucData, pBuf, pdDone, dGot)) + { + dwData = (dwData << 8) | ucData; + if ((dwData & 0x00004000) != 0) /* three byte sequence ? */ + { + dwData &= 0x00003FFF; /* Clear the relevant bit */ + if (ReadChar(&ucData, pBuf, pdDone, dGot)) + dwData = (dwData << 8) | ucData; + else + bReturn = false; + } + } + else + bReturn = false; /* couldn't read data */ + } + } + else + bReturn = false; + + *pDWord = dwData; /* return the data */ + return bReturn; +} + +/*************************************************************************** +** +** ReadDMAInfo +** +** Tries to read info about the dma request from the 1401 and decode it into +** the dma descriptor block. We have at this point had the escape character +** from the 1401 and now we must read in the rest of the information about +** the transfer request. Returns FALSE if 1401 fails to respond or obselete +** code from 1401 or bad parameters. +** +** The pBuf char pointer does not include the initial escape character, so +** we start handling the data at offset zero. +** +*****************************************************************************/ +static bool ReadDMAInfo(volatile DMADESC* pDmaDesc, DEVICE_EXTENSION *pdx, + char* pBuf, unsigned int dwCount) +{ + bool bResult = false; // assume we won't succeed + unsigned char ucData; + unsigned int dDone = 0; // We haven't parsed anything so far + + dev_dbg(&pdx->interface->dev, "%s", __func__); + + if (ReadChar(&ucData, pBuf, &dDone, dwCount)) + { + unsigned char ucTransCode = (ucData & 0x0F); // get code for transfer type + unsigned short wIdent = ((ucData >> 4) & 0x07); // and area identifier + + // fill in the structure we were given + pDmaDesc->wTransType = ucTransCode; // type of transfer + pDmaDesc->wIdent = wIdent; // area to use + pDmaDesc->dwSize = 0; // initialise other bits + pDmaDesc->dwOffset = 0; + + dev_dbg(&pdx->interface->dev, "%s type: %d ident: %d", __func__, pDmaDesc->wTransType, pDmaDesc->wIdent); + + pDmaDesc->bOutWard = (ucTransCode != TM_EXTTOHOST); // set transfer direction + + switch (ucTransCode) + { + case TM_EXTTOHOST: // Extended linear transfer modes (the only ones!) + case TM_EXTTO1401: + { + bResult = ReadHuff(&(pDmaDesc->dwOffset), pBuf, &dDone, dwCount) && + ReadHuff(&(pDmaDesc->dwSize), pBuf, &dDone, dwCount); + if (bResult) + { + dev_dbg(&pdx->interface->dev, "%s xfer offset & size %d %d", + __func__, pDmaDesc->dwOffset, pDmaDesc->dwSize); + + if ((wIdent >= MAX_TRANSAREAS) || // Illegal area number, or... + (!pdx->rTransDef[wIdent].bUsed) || // area not set up, or... + (pDmaDesc->dwOffset > pdx->rTransDef[wIdent].dwLength) || // range/size + ((pDmaDesc->dwOffset + pDmaDesc->dwSize) > (pdx->rTransDef[wIdent].dwLength))) + { + bResult = false; // bad parameter(s) + dev_dbg(&pdx->interface->dev, "%s bad param - id %d, bUsed %d, offset %d, size %d, area length %d", + __func__, wIdent, pdx->rTransDef[wIdent].bUsed, pDmaDesc->dwOffset, pDmaDesc->dwSize, + pdx->rTransDef[wIdent].dwLength); + } + } + break; + } + default: + break; + } + } + else + bResult = false; + + if (!bResult) // now check parameters for validity + dev_err(&pdx->interface->dev, "%s error reading Esc sequence", __func__); + + return bResult; +} + +/**************************************************************************** +** +** Handle1401Esc +** +** Deals with an escape sequence coming from the 1401. This can either be +** a DMA transfer request of various types or a response to an escape sequence +** sent to the 1401. This is called from a callback. +** +** Parameters are +** +** dwCount - the number of characters in the device extension char in buffer, +** this is known to be at least 2 or we will not be called. +** +****************************************************************************/ +static int Handle1401Esc(DEVICE_EXTENSION* pdx, char* pCh, unsigned int dwCount) +{ + int iReturn = U14ERR_FAIL; + + // I have no idea what this next test is about. '?' is 0x3f, which is area 3, code + // 15. At the moment, this is not used, so it does no harm, but unless someone can + // tell me what this is for, it should be removed from this and the Windows driver. + if (pCh[0] == '?') // Is this an information response + { // Parse and save the information + } + else + { + spin_lock(&pdx->stagedLock); // Lock others out + + if (ReadDMAInfo(&pdx->rDMAInfo, pdx, pCh, dwCount)) // Get DMA parameters + { + unsigned short wTransType = pdx->rDMAInfo.wTransType; // check transfer type + + dev_dbg(&pdx->interface->dev, "%s xfer to %s, offset %d, length %d", __func__, + pdx->rDMAInfo.bOutWard ? "1401" : "host", + pdx->rDMAInfo.dwOffset, pdx->rDMAInfo.dwSize); + + if (pdx->bXFerWaiting) // Check here for badly out of kilter... + { // This can never happen, really + dev_err(&pdx->interface->dev, "ERROR: DMA setup while transfer still waiting"); + spin_unlock(&pdx->stagedLock); + } + else + { + if ((wTransType == TM_EXTTOHOST) || (wTransType == TM_EXTTO1401)) + { + iReturn = ReadWriteMem(pdx, !pdx->rDMAInfo.bOutWard, pdx->rDMAInfo.wIdent, pdx->rDMAInfo.dwOffset, pdx->rDMAInfo.dwSize); + if (iReturn != U14ERR_NOERROR) + dev_err(&pdx->interface->dev, "%s ReadWriteMem() failed %d", __func__, iReturn); + } + else // This covers non-linear transfer setup + dev_err(&pdx->interface->dev, "%s Unknown block xfer type %d", __func__, wTransType); + } + } + else // Failed to read parameters + dev_err(&pdx->interface->dev, "%s ReadDMAInfo() fail", __func__); + + spin_unlock(&pdx->stagedLock); // OK here + } + + dev_dbg(&pdx->interface->dev, "%s returns %d", __func__, iReturn); + + return iReturn; +} + +/**************************************************************************** +** Callback for the character read complete or error +****************************************************************************/ +static void ced_readchar_callback(struct urb* pUrb) +{ + DEVICE_EXTENSION *pdx = pUrb->context; + int nGot = pUrb->actual_length; // what we transferred + + if (pUrb->status) // Do we have a problem to handle? + { + int nPipe = pdx->nPipes == 4 ? 1 : 0; // The pipe number to use for error + // sync/async unlink faults aren't errors... just saying device removed or stopped + if (!(pUrb->status == -ENOENT || pUrb->status == -ECONNRESET || pUrb->status == -ESHUTDOWN)) + { + dev_err(&pdx->interface->dev, "%s - nonzero write bulk status received: %d", __func__, pUrb->status); + } + else + dev_dbg(&pdx->interface->dev, "%s - 0 chars pUrb->status=%d (shutdown?)", __func__, pUrb->status); + + spin_lock(&pdx->err_lock); + pdx->errors = pUrb->status; + spin_unlock(&pdx->err_lock); + nGot = 0; // and tidy up again if so + + spin_lock(&pdx->charInLock); // already at irq level + pdx->bPipeError[nPipe] = 1; // Flag an error for later + } + else + { + if ((nGot > 1) && ((pdx->pCoherCharIn[0] & 0x7f) == 0x1b)) // Esc sequence? + { + Handle1401Esc(pdx, &pdx->pCoherCharIn[1], nGot-1); // handle it + spin_lock(&pdx->charInLock); // already at irq level + } + else + { + spin_lock(&pdx->charInLock); // already at irq level + if (nGot > 0) + { + unsigned int i; + if (nGot < INBUF_SZ) + { + pdx->pCoherCharIn[nGot] = 0; // tidy the string + dev_dbg(&pdx->interface->dev, "%s got %d chars >%s<", __func__, nGot, pdx->pCoherCharIn); + } + + // We know that whatever we read must fit in the input buffer + for (i = 0; i < nGot; i++) + { + pdx->inputBuffer[pdx->dwInBuffPut++] = pdx->pCoherCharIn[i] & 0x7F; + if (pdx->dwInBuffPut >= INBUF_SZ) + pdx->dwInBuffPut = 0; + } + + if ((pdx->dwNumInput + nGot) <= INBUF_SZ) + pdx->dwNumInput += nGot; // Adjust the buffer count accordingly + } + else + dev_dbg(&pdx->interface->dev, "%s read ZLP", __func__); + } + } + + pdx->bReadCharsPending = false; // No longer have a pending read + spin_unlock(&pdx->charInLock); // already at irq level + + Allowi(pdx, true); // see if we can do the next one +} + +/**************************************************************************** +** Allowi +** +** This is used to make sure that there is always a pending input transfer so +** we can pick up any inward transfers. This can be called in multiple contexts +** so we use the irqsave version of the spinlock. +****************************************************************************/ +int Allowi(DEVICE_EXTENSION* pdx, bool bInCallback) +{ + int iReturn = U14ERR_NOERROR; + unsigned long flags; + spin_lock_irqsave(&pdx->charInLock, flags); // can be called in multiple contexts + + // We don't want char input running while DMA is in progress as we know that this + // can cause sequencing problems for the 2270. So don't. It will also allow the + // ERR response to get back to the host code too early on some PCs, even if there + // is no actual driver failure, so we don't allow this at all. + if (!pdx->bInDrawDown && // stop input if + !pdx->bReadCharsPending && // If no read request outstanding + (pdx->dwNumInput < (INBUF_SZ/2)) && // and there is some space + (pdx->dwDMAFlag == MODE_CHAR) && // not doing any DMA + (!pdx->bXFerWaiting) && // no xfer waiting to start + (CanAcceptIoRequests(pdx))) // and activity is generally OK + { // then off we go + unsigned int nMax = INBUF_SZ-pdx->dwNumInput; // max we could read + int nPipe = pdx->nPipes == 4 ? 1 : 0; // The pipe number to use + + dev_dbg(&pdx->interface->dev, "%s %d chars in input buffer", __func__, pdx->dwNumInput); + + usb_fill_int_urb(pdx->pUrbCharIn, pdx->udev, + usb_rcvintpipe(pdx->udev, pdx->epAddr[nPipe]), + pdx->pCoherCharIn, nMax, ced_readchar_callback, + pdx, pdx->bInterval); + pdx->pUrbCharIn->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; // short xfers are OK by default + usb_anchor_urb(pdx->pUrbCharIn, &pdx->submitted); // in case we need to kill it + iReturn = usb_submit_urb(pdx->pUrbCharIn, bInCallback ? GFP_ATOMIC : GFP_KERNEL); + if (iReturn) + { + usb_unanchor_urb(pdx->pUrbCharIn); // remove from list of active Urbs + pdx->bPipeError[nPipe] = 1; // Flag an error to be handled later + dev_err(&pdx->interface->dev,"%s submit urb failed: %d", __func__, iReturn); + } + else + pdx->bReadCharsPending = true; // Flag that we are active here + } + + spin_unlock_irqrestore(&pdx->charInLock, flags); + + return iReturn; + +} + +/***************************************************************************** +** The ioctl entry point to the driver that is used by us to talk to it. +** inode The device node (no longer in 3.0.0 kernels) +** file The file that is open, which holds our pdx pointer +** ulArg The argument passed in. Note that long is 64-bits in 64-bit system, i.e. it is big +** enough for a 64-bit pointer. +*****************************************************************************/ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36) +static int ced_ioctl(struct file * file, unsigned int cmd, unsigned long ulArg) +#else +static int ced_ioctl(struct inode * node, struct file * file, unsigned int cmd, unsigned long ulArg) +#endif +{ + int err = 0; + DEVICE_EXTENSION *pdx = file->private_data; + if (!CanAcceptIoRequests(pdx)) // check we still exist + return -ENODEV; + + // Check that access is allowed, where is is needed. Anything that would have an indeterminate + // size will be checked by the specific command. + if (_IOC_DIR(cmd) & _IOC_READ) // read from point of view of user... + err = !access_ok(VERIFY_WRITE, (void __user *)ulArg, _IOC_SIZE(cmd)); // is kernel write + else if (_IOC_DIR(cmd) & _IOC_WRITE) // and write from point of view of user... + err = !access_ok(VERIFY_READ, (void __user *)ulArg, _IOC_SIZE(cmd)); // is kernel read + if (err) + return -EFAULT; + + switch (_IOC_NR(cmd)) + { + case _IOC_NR(IOCTL_CED_SENDSTRING(0)): + return SendString(pdx, (const char __user*)ulArg, _IOC_SIZE(cmd)); + + case _IOC_NR(IOCTL_CED_RESET1401): + return Reset1401(pdx); + + case _IOC_NR(IOCTL_CED_GETCHAR): + return GetChar(pdx); + + case _IOC_NR(IOCTL_CED_SENDCHAR): + return SendChar(pdx, (char)ulArg); + + case _IOC_NR(IOCTL_CED_STAT1401): + return Stat1401(pdx); + + case _IOC_NR(IOCTL_CED_LINECOUNT): + return LineCount(pdx); + + case _IOC_NR(IOCTL_CED_GETSTRING(0)): + return GetString(pdx, (char __user*)ulArg, _IOC_SIZE(cmd)); + + case _IOC_NR(IOCTL_CED_SETTRANSFER): + return SetTransfer(pdx, (TRANSFERDESC __user*)ulArg); + + case _IOC_NR(IOCTL_CED_UNSETTRANSFER): + return UnsetTransfer(pdx, (int)ulArg); + + case _IOC_NR(IOCTL_CED_SETEVENT): + return SetEvent(pdx, (TRANSFEREVENT __user*)ulArg); + + case _IOC_NR(IOCTL_CED_GETOUTBUFSPACE): + return GetOutBufSpace(pdx); + + case _IOC_NR(IOCTL_CED_GETBASEADDRESS): + return -1; + + case _IOC_NR(IOCTL_CED_GETDRIVERREVISION): + return (2<<24)|(DRIVERMAJREV<<16) | DRIVERMINREV; // USB | MAJOR | MINOR + + case _IOC_NR(IOCTL_CED_GETTRANSFER): + return GetTransfer(pdx, (TGET_TX_BLOCK __user*)ulArg); + + case _IOC_NR(IOCTL_CED_KILLIO1401): + return KillIO1401(pdx); + + case _IOC_NR(IOCTL_CED_STATEOF1401): + return StateOf1401(pdx); + + case _IOC_NR(IOCTL_CED_GRAB1401): + case _IOC_NR(IOCTL_CED_FREE1401): + return U14ERR_NOERROR; + + case _IOC_NR(IOCTL_CED_STARTSELFTEST): + return StartSelfTest(pdx); + + case _IOC_NR(IOCTL_CED_CHECKSELFTEST): + return CheckSelfTest(pdx, (TGET_SELFTEST __user*)ulArg); + + case _IOC_NR(IOCTL_CED_TYPEOF1401): + return TypeOf1401(pdx); + + case _IOC_NR(IOCTL_CED_TRANSFERFLAGS): + return TransferFlags(pdx); + + case _IOC_NR(IOCTL_CED_DBGPEEK): + return DbgPeek(pdx, (TDBGBLOCK __user*)ulArg); + + case _IOC_NR(IOCTL_CED_DBGPOKE): + return DbgPoke(pdx, (TDBGBLOCK __user*)ulArg); + + case _IOC_NR(IOCTL_CED_DBGRAMPDATA): + return DbgRampData(pdx, (TDBGBLOCK __user*)ulArg); + + case _IOC_NR(IOCTL_CED_DBGRAMPADDR): + return DbgRampAddr(pdx, (TDBGBLOCK __user*)ulArg); + + case _IOC_NR(IOCTL_CED_DBGGETDATA): + return DbgGetData(pdx, (TDBGBLOCK __user*)ulArg); + + case _IOC_NR(IOCTL_CED_DBGSTOPLOOP): + return DbgStopLoop(pdx); + + case _IOC_NR(IOCTL_CED_FULLRESET): + pdx->bForceReset = true; // Set a flag for a full reset + break; + + case _IOC_NR(IOCTL_CED_SETCIRCULAR): + return SetCircular(pdx, (TRANSFERDESC __user*)ulArg); + + case _IOC_NR(IOCTL_CED_GETCIRCBLOCK): + return GetCircBlock(pdx, (TCIRCBLOCK __user*)ulArg); + + case _IOC_NR(IOCTL_CED_FREECIRCBLOCK): + return FreeCircBlock(pdx, (TCIRCBLOCK __user*)ulArg); + + case _IOC_NR(IOCTL_CED_WAITEVENT): + return WaitEvent(pdx, (int)(ulArg & 0xff), (int)(ulArg >> 8)); + + case _IOC_NR(IOCTL_CED_TESTEVENT): + return TestEvent(pdx, (int)ulArg); + + default: + return U14ERR_NO_SUCH_FN; + } + return U14ERR_NOERROR; +} + +static const struct file_operations ced_fops = +{ + .owner = THIS_MODULE, + .read = ced_read, + .write = ced_write, + .open = ced_open, + .release = ced_release, + .flush = ced_flush, + .llseek = noop_llseek, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36) + .unlocked_ioctl = ced_ioctl, +#else + .ioctl = ced_ioctl, +#endif +}; + +/* + * usb class driver info in order to get a minor number from the usb core, + * and to have the device registered with the driver core + */ +static struct usb_class_driver ced_class = +{ + .name = "cedusb%d", + .fops = &ced_fops, + .minor_base = USB_CED_MINOR_BASE, +}; + +// Check that the device that matches a 1401 vendor and product ID is OK to use and +// initialise our DEVICE_EXTENSION. +static int ced_probe(struct usb_interface *interface, const struct usb_device_id *id) +{ + DEVICE_EXTENSION *pdx; + struct usb_host_interface *iface_desc; + struct usb_endpoint_descriptor *endpoint; + int i, bcdDevice; + int retval = -ENOMEM; + + // allocate memory for our device extension and initialize it + pdx = kzalloc(sizeof(*pdx), GFP_KERNEL); + if (!pdx) + { + err("Out of memory"); + goto error; + } + + for (i=0; irTransDef[i].wqEvent); + } + + // Put initialises for our stuff here. Note that all of *pdx is zero, so + // no need to explicitly zero it. + spin_lock_init(&pdx->charOutLock); + spin_lock_init(&pdx->charInLock); + spin_lock_init(&pdx->stagedLock); + + // Initialises from the skeleton stuff + kref_init(&pdx->kref); + mutex_init(&pdx->io_mutex); + spin_lock_init(&pdx->err_lock); + init_usb_anchor(&pdx->submitted); + + pdx->udev = usb_get_dev(interface_to_usbdev(interface)); + pdx->interface = interface; + + // Attempt to identify the device + bcdDevice = pdx->udev->descriptor.bcdDevice; + i = (bcdDevice >> 8); + if (i == 0) + pdx->s1401Type = TYPEU1401; + else if ((i>=1) && (i<=23)) + pdx->s1401Type = i+2; + else + { + dev_err(&interface->dev, "%s Unknown device. bcdDevice = %d", __func__, bcdDevice); + goto error; + } + // set up the endpoint information. We only care about the number of EP as + // we know that we are dealing with a 1401 device. + iface_desc = interface->cur_altsetting; + pdx->nPipes = iface_desc->desc.bNumEndpoints; + dev_info(&interface->dev, "1401Type=%d with %d End Points", pdx->s1401Type, pdx->nPipes); + if ((pdx->nPipes < 3) || (pdx->nPipes > 4)) + goto error; + + // Allocate the URBs we hold for performing transfers + pdx->pUrbCharOut = usb_alloc_urb(0, GFP_KERNEL); // character output URB + pdx->pUrbCharIn = usb_alloc_urb(0, GFP_KERNEL); // character input URB + pdx->pStagedUrb = usb_alloc_urb(0, GFP_KERNEL); // block transfer URB + if (!pdx->pUrbCharOut || !pdx->pUrbCharIn || !pdx->pStagedUrb) + { + dev_err(&interface->dev, "%s URB alloc failed", __func__); + goto error; + } + + pdx->pCoherStagedIO = usb_alloc_coherent(pdx->udev, STAGED_SZ, GFP_KERNEL, &pdx->pStagedUrb->transfer_dma); + pdx->pCoherCharOut = usb_alloc_coherent(pdx->udev, OUTBUF_SZ, GFP_KERNEL, &pdx->pUrbCharOut->transfer_dma); + pdx->pCoherCharIn = usb_alloc_coherent(pdx->udev, INBUF_SZ, GFP_KERNEL, &pdx->pUrbCharIn->transfer_dma); + if (!pdx->pCoherCharOut || !pdx->pCoherCharIn || !pdx->pCoherStagedIO) + { + dev_err(&interface->dev, "%s Coherent buffer alloc failed", __func__); + goto error; + } + + for (i = 0; i < pdx->nPipes; ++i) + { + endpoint = &iface_desc->endpoint[i].desc; + pdx->epAddr[i] = endpoint->bEndpointAddress; + dev_info(&interface->dev, "Pipe %d, ep address %02x", i, pdx->epAddr[i]); + if (((pdx->nPipes==3) && (i==0)) || // if char input end point + ((pdx->nPipes==4) && (i==1))) + { + pdx->bInterval = endpoint->bInterval; // save the endpoint interrupt interval + dev_info(&interface->dev, "Pipe %d, bInterval = %d", i, pdx->bInterval); + } + + // Detect USB2 by checking last ep size (64 if USB1) + if (i == pdx->nPipes-1) // if this is the last ep (bulk) + { + pdx->bIsUSB2 = le16_to_cpu(endpoint->wMaxPacketSize) > 64; + dev_info(&pdx->interface->dev, "USB%d", pdx->bIsUSB2 + 1); + } + } + + /* save our data pointer in this interface device */ + usb_set_intfdata(interface, pdx); + + /* we can register the device now, as it is ready */ + retval = usb_register_dev(interface, &ced_class); + if (retval) + { + /* something prevented us from registering this driver */ + err("Not able to get a minor for this device."); + usb_set_intfdata(interface, NULL); + goto error; + } + + /* let the user know what node this device is now attached to */ + dev_info(&interface->dev, + "USB CEDUSB device now attached to cedusb #%d", + interface->minor); + return 0; + +error: + if (pdx) + kref_put(&pdx->kref, ced_delete); // frees allocated memory + return retval; +} + +static void ced_disconnect(struct usb_interface *interface) +{ + DEVICE_EXTENSION *pdx = usb_get_intfdata(interface); + int minor = interface->minor; // save for message at the end + int i; + + usb_set_intfdata(interface, NULL); // remove the pdx from the interface + usb_deregister_dev(interface, &ced_class); // give back our minor device number + + mutex_lock(&pdx->io_mutex); // stop more I/O starting while... + ced_draw_down(pdx); // ...wait for then kill any io + for (i=0; iinterface->dev, "%s Area %d was in used", __func__, i); + } + pdx->interface = NULL; // ...we kill off link to interface + mutex_unlock(&pdx->io_mutex); + + usb_kill_anchored_urbs(&pdx->submitted); + + kref_put(&pdx->kref, ced_delete); // decrement our usage count + + dev_info(&interface->dev, "USB cedusb #%d now disconnected", minor); +} + +// Wait for all the urbs we know of to be done with, then kill off any that +// are left. NBNB we will need to have a mechanism to stop circular xfers +// from trying to fire off more urbs. We will wait up to 3 seconds for Urbs +// to be done. +void ced_draw_down(DEVICE_EXTENSION *pdx) +{ + int time; + dev_dbg(&pdx->interface->dev,"%s called", __func__); + + pdx->bInDrawDown = true; + time = usb_wait_anchor_empty_timeout(&pdx->submitted, 3000); + if (!time) // if we timed out we kill the urbs + { + usb_kill_anchored_urbs(&pdx->submitted); + dev_err(&pdx->interface->dev,"%s timed out", __func__); + } + pdx->bInDrawDown = false; + } + +static int ced_suspend(struct usb_interface *intf, pm_message_t message) +{ + DEVICE_EXTENSION *pdx = usb_get_intfdata(intf); + if (!pdx) + return 0; + ced_draw_down(pdx); + + dev_dbg(&pdx->interface->dev,"%s called", __func__); + return 0; +} + +static int ced_resume(struct usb_interface *intf) +{ + DEVICE_EXTENSION *pdx = usb_get_intfdata(intf); + if (!pdx) + return 0; + dev_dbg(&pdx->interface->dev,"%s called", __func__); + return 0; +} + +static int ced_pre_reset(struct usb_interface *intf) +{ + DEVICE_EXTENSION *pdx = usb_get_intfdata(intf); + dev_dbg(&pdx->interface->dev, "%s", __func__); + mutex_lock(&pdx->io_mutex); + ced_draw_down(pdx); + return 0; +} + +static int ced_post_reset(struct usb_interface *intf) +{ + DEVICE_EXTENSION *pdx = usb_get_intfdata(intf); + dev_dbg(&pdx->interface->dev, "%s", __func__); + + /* we are sure no URBs are active - no locking needed */ + pdx->errors = -EPIPE; + mutex_unlock(&pdx->io_mutex); + + return 0; +} + +static struct usb_driver ced_driver = +{ + .name = "cedusb", + .probe = ced_probe, + .disconnect = ced_disconnect, + .suspend = ced_suspend, + .resume = ced_resume, + .pre_reset = ced_pre_reset, + .post_reset = ced_post_reset, + .id_table = ced_table, + .supports_autosuspend = 1, +}; + +static int __init usb_skel_init(void) +{ + /* register this driver with the USB subsystem */ + int result = usb_register(&ced_driver); + if (result) + err("usb_register failed. Error number %d", result); + + return result; +} + +static void __exit usb_skel_exit(void) +{ + /* deregister this driver with the USB subsystem */ + usb_deregister(&ced_driver); +} + +module_init(usb_skel_init); +module_exit(usb_skel_exit); + +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/ced1401/usb1401.h b/drivers/staging/ced1401/usb1401.h new file mode 100644 index 0000000..331ca98 --- /dev/null +++ b/drivers/staging/ced1401/usb1401.h @@ -0,0 +1,249 @@ +/* usb1401.h + Header file for the CED 1401 USB device driver for Linux + Copyright (C) 2010 Cambridge Electronic Design Ltd + Author Greg P Smith (greg@ced.co.uk) + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ +#ifndef __USB1401_H__ +#define __USB1401_H__ +#include "use1401.h" +#include "ced_ioctl.h" + +#ifndef UINT +#define UINT unsigned int +#endif + +/// Device type codes, but these don't need to be extended - a succession is assumed +/// These are set for usb from the bcdDevice field (suitably mangled). Future devices +/// will be added in order of device creation to the list, so the names here are just +/// to help use remember which device is which. The U14ERR_... values follow the same +/// pattern for modern devices. +#define TYPEUNKNOWN -1 // dont know +#define TYPE1401 0 // standard 1401 +#define TYPEPLUS 1 // 1401 plus +#define TYPEU1401 2 // u1401 +#define TYPEPOWER 3 // Power1401 +#define TYPEU14012 4 // u1401 mkII +#define TYPEPOWER2 5 // Power1401 mk II +#define TYPEMICRO3 6 // Micro1401-3 +#define TYPEPOWER3 7 // Power1401-3 + +/// Some useful defines of constants. DONT FORGET to change the version in the +/// resources whenever you change it here!. +#define DRIVERMAJREV 2 // driver revision level major (match windows) +#define DRIVERMINREV 0 // driver revision level minor + +/// Definitions of the various block transfer command codes +#define TM_EXTTOHOST 8 // extended tohost +#define TM_EXTTO1401 9 // extended to1401 + +/// Definitions of values in usbReqtype. Used in sorting out setup actions +#define H_TO_D 0x00 +#define D_TO_H 0x80 +#define VENDOR 0x40 +#define DEVREQ 0x00 +#define INTREQ 0x01 +#define ENDREQ 0x02 + +/// Definition of values in usbRequest, again used to sort out setup +#define GET_STATUS 0x00 +#define CLEAR_FEATURE 0x01 +#define SET_FEATURE 0x03 +#define SET_ADDRESS 0x05 +#define GET_DESC 0x06 +#define SET_DESC 0x07 +#define GET_CONF 0x08 +#define SET_CONF 0x09 +#define GET_INTERFACE 0x0a +#define SET_INTERFACE 0x0b +#define SYNCH_FRAME 0x0c + +/// Definitions of the various debug command codes understood by the 1401. These +/// are used in various vendor-specific commands to achieve the desired effect +#define DB_GRAB 0x50 /* Grab is a NOP for USB */ +#define DB_FREE 0x51 /* Free is a NOP for the USB */ +#define DB_SETADD 0x52 /* Set debug address (double) */ +#define DB_SELFTEST 0x53 /* Start self test */ +#define DB_SETMASK 0x54 /* Set enable mask (double) */ +#define DB_SETDEF 0x55 /* Set default mask (double) */ +#define DB_PEEK 0x56 /* Peek address, save result */ +#define DB_POKE 0x57 /* Poke address with data (double) */ +#define DB_RAMPD 0x58 /* Ramp data at debug address */ +#define DB_RAMPA 0x59 /* Ramp address bus */ +#define DB_REPEATS 0x5A /* Set repeats for operations (double) */ +#define DB_WIDTH 0x5B /* Set width for operations (byte) */ +#define DB_DATA 0x5C /* Get 4-byte data read by PEEK */ +#define DB_CHARS 0x5D /* Send chars via EP0 control write */ + +#define CR_CHAR 0x0D /* The carriage return character */ +#define CR_CHAR_80 0x8d /* and with bit 7 set */ + +/// A structure holding information about a block of memory for use in circular transfers +typedef struct circBlk +{ + volatile UINT dwOffset; /* Offset within area of block start */ + volatile UINT dwSize; /* Size of the block, in bytes (0 = unused) */ +} CIRCBLK; + +/// A structure holding all of the information about a transfer area - an area of +/// memory set up for use either as a source or destination in DMA transfers. +typedef struct transarea +{ + void* lpvBuff; // User address of xfer area saved for completeness + UINT dwBaseOffset; // offset to start of xfer area in first page + UINT dwLength; // Length of xfer area, in bytes + struct page **pPages; // Points at array of locked down pages + int nPages; // number of pages that are locked down + bool bUsed; // Is this structure in use? + bool bCircular; // Is this area for circular transfers? + bool bCircToHost; // Flag for direction of circular transfer + bool bEventToHost; // Set event on transfer to host? + int iWakeUp; // Set 1 on event, cleared by TestEvent() + UINT dwEventSt; // Defines section within xfer area for... + UINT dwEventSz; // ...notification by the event SZ is 0 if unset + CIRCBLK aBlocks[2]; // Info on a pair of circular blocks + wait_queue_head_t wqEvent; // The wait queue for events in this area MUST BE LAST +} TRANSAREA; + +/// The DMADESC structure is used to hold information on the transfer in progress. It +/// is set up by ReadDMAInfo, using information sent by the 1401 in an escape sequence. +typedef struct dmadesc +{ + unsigned short wTransType; /* transfer type as TM_xxx above */ + unsigned short wIdent; /* identifier word */ + unsigned int dwSize; /* bytes to transfer */ + unsigned int dwOffset; /* offset into transfer area for trans */ + bool bOutWard; /* true when data is going TO 1401 */ +} DMADESC; + +#define INBUF_SZ 256 /* input buffer size */ +#define OUTBUF_SZ 256 /* output buffer size */ +#define STAGED_SZ 0x10000 // size of coherent buffer for staged transfers + +/// Structure to hold all of our device specific stuff. We are making this as similar as we +/// can to the Windows driver to help in our understanding of what is going on. +typedef struct _DEVICE_EXTENSION +{ + char inputBuffer[INBUF_SZ]; /* The two buffers */ + char outputBuffer[OUTBUF_SZ]; /* accessed by the host functions */ + volatile unsigned int dwNumInput; /* num of chars in input buffer */ + volatile unsigned int dwInBuffGet; /* where to get from input buffer */ + volatile unsigned int dwInBuffPut; /* where to put into input buffer */ + volatile unsigned int dwNumOutput; /* num of chars in output buffer */ + volatile unsigned int dwOutBuffGet; /* where to get from output buffer*/ + volatile unsigned int dwOutBuffPut; /* where to put into output buffer*/ + + volatile bool bSendCharsPending; /* Flag to indicate sendchar active */ + volatile bool bReadCharsPending; /* Flag to indicate a read is primed */ + char* pCoherCharOut; /* special aligned buffer for chars to 1401 */ + struct urb* pUrbCharOut; /* urb used for chars to 1401 */ + char* pCoherCharIn; /* special aligned buffer for chars to host */ + struct urb* pUrbCharIn; /* urb used for chars to host */ + + spinlock_t charOutLock; /* to protect the outputBuffer and outputting */ + spinlock_t charInLock; /* to protect the inputBuffer and char reads */ + __u8 bInterval; /* Interrupt end point interval */ + + volatile unsigned int dwDMAFlag; /* state of DMA */ + TRANSAREA rTransDef[MAX_TRANSAREAS];/* transfer area info */ + volatile DMADESC rDMAInfo; // info on current DMA transfer + volatile bool bXFerWaiting; // Flag set if DMA transfer stalled + volatile bool bInDrawDown; // Flag that we want to halt transfers + + // Parameters relating to a block read\write that is in progress. Some of these values + // are equivalent to values in rDMAInfo. The values here are those in use, while those + // in rDMAInfo are those recieved from the 1401 via an escape sequence. If another + // escape sequence arrives before the previous xfer ends, rDMAInfo values are updated while these + // are used to finish off the current transfer. + volatile short StagedId; // The transfer area id for this transfer + volatile bool StagedRead; // Flag TRUE for read from 1401, FALSE for write + volatile unsigned int StagedLength; // Total length of this transfer + volatile unsigned int StagedOffset; // Offset within memory area for transfer start + volatile unsigned int StagedDone; // Bytes transferred so far + volatile bool bStagedUrbPending; // Flag to indicate active + char* pCoherStagedIO; // buffer used for block transfers + struct urb* pStagedUrb; // The URB to use + spinlock_t stagedLock; // protects ReadWriteMem() and circular buffer stuff + + short s1401Type; // type of 1401 attached + short sCurrentState; // current error state + bool bIsUSB2; // type of the interface we connect to + bool bForceReset; // Flag to make sure we get a real reset + __u32 statBuf[2]; // buffer for 1401 state info + + unsigned long ulSelfTestTime; // used to timeout self test + + int nPipes; // Should be 3 or 4 depending on 1401 usb chip + int bPipeError[4]; // set non-zero if an error on one of the pipe + __u8 epAddr[4]; // addresses of the 3/4 end points + + struct usb_device *udev; // the usb device for this device + struct usb_interface *interface; // the interface for this device, NULL if removed + struct usb_anchor submitted; // in case we need to retract our submissions + struct mutex io_mutex; // synchronize I/O with disconnect, one user-mode caller at a time + + int errors; // the last request tanked + int open_count; // count the number of openers + spinlock_t err_lock; // lock for errors + struct kref kref; +}DEVICE_EXTENSION, *PDEVICE_EXTENSION; +#define to_DEVICE_EXTENSION(d) container_of(d, DEVICE_EXTENSION, kref) + +/// Definitions of routimes used between compilation object files +// in usb1401.c +extern int Allowi(DEVICE_EXTENSION* pdx, bool bInCallback); +extern int SendChars(DEVICE_EXTENSION* pdx); +extern void ced_draw_down(DEVICE_EXTENSION *pdx); +extern int ReadWriteMem(DEVICE_EXTENSION *pdx, bool Read, unsigned short wIdent, + unsigned int dwOffs, unsigned int dwLen); + +// in ced_ioc.c +extern int ClearArea(DEVICE_EXTENSION *pdx, int nArea); +extern int SendString(DEVICE_EXTENSION* pdx, const char __user* pData, unsigned int n); +extern int SendChar(DEVICE_EXTENSION *pdx, char c); +extern int Get1401State(DEVICE_EXTENSION* pdx, __u32* state, __u32* error); +extern int ReadWrite_Cancel(DEVICE_EXTENSION *pdx); +extern bool Is1401(DEVICE_EXTENSION* pdx); +extern bool QuickCheck(DEVICE_EXTENSION* pdx, bool bTestBuff, bool bCanReset); +extern int Reset1401(DEVICE_EXTENSION *pdx); +extern int GetChar(DEVICE_EXTENSION *pdx); +extern int GetString(DEVICE_EXTENSION *pdx, char __user* pUser, int n); +extern int SetTransfer(DEVICE_EXTENSION *pdx, TRANSFERDESC __user *pTD); +extern int UnsetTransfer(DEVICE_EXTENSION *pdx, int nArea); +extern int SetEvent(DEVICE_EXTENSION *pdx, TRANSFEREVENT __user*pTE); +extern int Stat1401(DEVICE_EXTENSION *pdx); +extern int LineCount(DEVICE_EXTENSION *pdx); +extern int GetOutBufSpace(DEVICE_EXTENSION *pdx); +extern int GetTransfer(DEVICE_EXTENSION *pdx, TGET_TX_BLOCK __user *pGTB); +extern int KillIO1401(DEVICE_EXTENSION *pdx); +extern int BlkTransState(DEVICE_EXTENSION *pdx); +extern int StateOf1401(DEVICE_EXTENSION *pdx); +extern int StartSelfTest(DEVICE_EXTENSION *pdx); +extern int CheckSelfTest(DEVICE_EXTENSION *pdx, TGET_SELFTEST __user *pGST); +extern int TypeOf1401(DEVICE_EXTENSION *pdx); +extern int TransferFlags(DEVICE_EXTENSION *pdx); +extern int DbgPeek(DEVICE_EXTENSION *pdx, TDBGBLOCK __user* pDB); +extern int DbgPoke(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB); +extern int DbgRampData(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB); +extern int DbgRampAddr(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB); +extern int DbgGetData(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB); +extern int DbgStopLoop(DEVICE_EXTENSION *pdx); +extern int SetCircular(DEVICE_EXTENSION *pdx, TRANSFERDESC __user *pTD); +extern int GetCircBlock(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user* pCB); +extern int FreeCircBlock(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user* pCB); +extern int WaitEvent(DEVICE_EXTENSION *pdx, int nArea, int msTimeOut); +extern int TestEvent(DEVICE_EXTENSION *pdx, int nArea); +#endif diff --git a/drivers/staging/ced1401/use1401.h b/drivers/staging/ced1401/use1401.h new file mode 100644 index 0000000..86294e2 --- /dev/null +++ b/drivers/staging/ced1401/use1401.h @@ -0,0 +1,287 @@ +/**************************************************************************** +** use1401.h +** Copyright (C) Cambridge Electronic Design Ltd, 1992-2010 +** Authors: Paul Cox, Tim Bergel, Greg Smith +** See CVS for revisions. +** +** Because the size of a long is different between 32-bit and 64-bit on some +** systems, we avoid this in this interface. +****************************************************************************/ +#ifndef __USE1401_H__ +#define __USE1401_H__ +#include "machine.h" + +// Some definitions to make things compatible. If you want to use Use1401 directly +// from a Windows program you should define U14_NOT_DLL, in which case you also +// MUST make sure that your application startup code calls U14InitLib(). +// DLL_USE1401 is defined when you are building the Use1401 dll, not otherwise. +#ifdef _IS_WINDOWS_ +#ifndef U14_NOT_DLL +#ifdef DLL_USE1401 +#define U14API(retType) retType DllExport __stdcall +#else +#define U14API(retType) retType DllImport __stdcall +#endif +#endif + +#define U14ERRBASE -500 +#define U14LONG long +#endif + +#ifdef LINUX +#define U14ERRBASE -1000 +#define U14LONG int +#endif + +#ifdef _QT +#ifndef U14_NOT_DLL +#undef U14API +#define U14API(retType) retType __declspec(dllimport) __stdcall +#endif +#undef U14LONG +#define U14LONG int +#endif + +#ifndef U14API +#define U14API(retType) retType +#endif + +#ifndef U14LONG +#define U14LONG long +#endif + +/// Error codes: We need them here as user space can see them. +#define U14ERR_NOERROR 0 // no problems + +/// Device error codes, but these don't need to be extended - a succession is assumed +#define U14ERR_STD 4 // standard 1401 connected +#define U14ERR_U1401 5 // u1401 connected +#define U14ERR_PLUS 6 // 1401 plus connected +#define U14ERR_POWER 7 // Power1401 connected +#define U14ERR_U14012 8 // u1401 mkII connected +#define U14ERR_POWER2 9 +#define U14ERR_U14013 10 +#define U14ERR_POWER3 11 + +/// NBNB Error numbers need shifting as some linux error codes start at 512 +#define U14ERR(n) (n+U14ERRBASE) +#define U14ERR_OFF U14ERR(0) /* 1401 there but switched off */ +#define U14ERR_NC U14ERR(-1) /* 1401 not connected */ +#define U14ERR_ILL U14ERR(-2) /* if present it is ill */ +#define U14ERR_NOIF U14ERR(-3) /* I/F card missing */ +#define U14ERR_TIME U14ERR(-4) /* 1401 failed to come ready */ +#define U14ERR_BADSW U14ERR(-5) /* I/F card bad switches */ +#define U14ERR_PTIME U14ERR(-6) /* 1401plus failed to come ready */ +#define U14ERR_NOINT U14ERR(-7) /* couldn't grab the int vector */ +#define U14ERR_INUSE U14ERR(-8) /* 1401 is already in use */ +#define U14ERR_NODMA U14ERR(-9) /* couldn't get DMA channel */ +#define U14ERR_BADHAND U14ERR(-10) /* handle provided was bad */ +#define U14ERR_BAD1401NUM U14ERR(-11) /* 1401 number provided was bad */ + +#define U14ERR_NO_SUCH_FN U14ERR(-20) /* no such function */ +#define U14ERR_NO_SUCH_SUBFN U14ERR(-21) /* no such sub function */ +#define U14ERR_NOOUT U14ERR(-22) /* no room in output buffer */ +#define U14ERR_NOIN U14ERR(-23) /* no input in buffer */ +#define U14ERR_STRLEN U14ERR(-24) /* string longer than buffer */ +#define U14ERR_ERR_STRLEN U14ERR(-24) /* string longer than buffer */ +#define U14ERR_LOCKFAIL U14ERR(-25) /* failed to lock memory */ +#define U14ERR_UNLOCKFAIL U14ERR(-26) /* failed to unlock memory */ +#define U14ERR_ALREADYSET U14ERR(-27) /* area already set up */ +#define U14ERR_NOTSET U14ERR(-28) /* area not set up */ +#define U14ERR_BADAREA U14ERR(-29) /* illegal area number */ +#define U14ERR_FAIL U14ERR(-30) /* we failed for some other reason*/ + +#define U14ERR_NOFILE U14ERR(-40) /* command file not found */ +#define U14ERR_READERR U14ERR(-41) /* error reading command file */ +#define U14ERR_UNKNOWN U14ERR(-42) /* unknown command */ +#define U14ERR_HOSTSPACE U14ERR(-43) /* not enough host space to load */ +#define U14ERR_LOCKERR U14ERR(-44) /* could not lock resource/command*/ +#define U14ERR_CLOADERR U14ERR(-45) /* CLOAD command failed */ + +#define U14ERR_TOXXXERR U14ERR(-60) /* tohost/1401 failed */ +#define U14ERR_NO386ENH U14ERR(-80) /* not 386 enhanced mode */ +#define U14ERR_NO1401DRIV U14ERR(-81) /* no device driver */ +#define U14ERR_DRIVTOOOLD U14ERR(-82) /* device driver too old */ + +#define U14ERR_TIMEOUT U14ERR(-90) /* timeout occurred */ + +#define U14ERR_BUFF_SMALL U14ERR(-100) /* buffer for getstring too small */ +#define U14ERR_CBALREADY U14ERR(-101) /* there is already a callback */ +#define U14ERR_BADDEREG U14ERR(-102) /* bad parameter to deregcallback */ +#define U14ERR_NOMEMORY U14ERR(-103) /* no memory for allocation */ + +#define U14ERR_DRIVCOMMS U14ERR(-110) /* failed talking to driver */ +#define U14ERR_OUTOFMEMORY U14ERR(-111) /* needed memory and couldnt get it*/ + +/// 1401 type codes. +#define U14TYPE1401 0 /* standard 1401 */ +#define U14TYPEPLUS 1 /* 1401 plus */ +#define U14TYPEU1401 2 /* u1401 */ +#define U14TYPEPOWER 3 /* power1401 */ +#define U14TYPEU14012 4 /* u1401 mk II */ +#define U14TYPEPOWER2 5 /* power1401 mk II */ +#define U14TYPEU14013 6 /* u1401-3 */ +#define U14TYPEPOWER3 7 /* power1401-3 */ +#define U14TYPEUNKNOWN -1 /* dont know */ + +/// Transfer flags to allow driver capabilities to be interrogated + +/// Constants for transfer flags +#define U14TF_USEDMA 1 /* Transfer flag for use DMA */ +#define U14TF_MULTIA 2 /* Transfer flag for multi areas */ +#define U14TF_FIFO 4 /* for FIFO interface card */ +#define U14TF_USB2 8 /* for USB2 interface and 1401 */ +#define U14TF_NOTIFY 16 /* for event notifications */ +#define U14TF_SHORT 32 /* for PCI can short cycle */ +#define U14TF_PCI2 64 /* for new PCI card 1401-70 */ +#define U14TF_CIRCTH 128 /* Circular-mode to host */ +#define U14TF_DIAG 256 /* Diagnostics/debug functions */ +#define U14TF_CIRC14 512 /* Circular-mode to 1401 */ + +/// Definitions of element sizes for DMA transfers - to allow byte-swapping +#define ESZBYTES 0 /* BYTE element size value */ +#define ESZWORDS 1 /* WORD element size value */ +#define ESZLONGS 2 /* long element size value */ +#define ESZUNKNOWN 0 /* unknown element size value */ + +/// These define required access types for the debug/diagnostics function +#define BYTE_SIZE 1 /* 8-bit access */ +#define WORD_SIZE 2 /* 16-bit access */ +#define LONG_SIZE 3 /* 32-bit access */ + +/// Stuff used by U14_GetTransfer +#define GET_TX_MAXENTRIES 257 /* (max length / page size + 1) */ + +#ifdef _IS_WINDOWS_ +#pragma pack(1) + +typedef struct /* used for U14_GetTransfer results */ +{ /* Info on a single mapped block */ + U14LONG physical; + U14LONG size; +} TXENTRY; + +typedef struct TGetTxBlock /* used for U14_GetTransfer results */ +{ /* matches structure in VXD */ + U14LONG size; + U14LONG linear; + short seg; + short reserved; + short avail; /* number of available entries */ + short used; /* number of used entries */ + TXENTRY entries[GET_TX_MAXENTRIES]; /* Array of mapped block info */ +} TGET_TX_BLOCK; + +typedef TGET_TX_BLOCK *LPGET_TX_BLOCK; + +#pragma pack() +#endif + +#ifdef LINUX +typedef struct /* used for U14_GetTransfer results */ +{ /* Info on a single mapped block */ + long long physical; + long size; +} TXENTRY; + +typedef struct TGetTxBlock /* used for U14_GetTransfer results */ +{ /* matches structure in VXD */ + long long linear; /* linear address */ + long size; /* total size of the mapped area, holds id when called */ + short seg; /* segment of the address for Win16 */ + short reserved; + short avail; /* number of available entries */ + short used; /* number of used entries */ + TXENTRY entries[GET_TX_MAXENTRIES]; /* Array of mapped block info */ +} TGET_TX_BLOCK; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +U14API(int) U14WhenToTimeOut(short hand); // when to timeout in ms +U14API(short) U14PassedTime(int iTime); // non-zero if iTime passed + +U14API(short) U14LastErrCode(short hand); + +U14API(short) U14Open1401(short n1401); +U14API(short) U14Close1401(short hand); +U14API(short) U14Reset1401(short hand); +U14API(short) U14ForceReset(short hand); +U14API(short) U14TypeOf1401(short hand); +U14API(short) U14NameOf1401(short hand, char* pBuf, WORD wMax); + +U14API(short) U14Stat1401(short hand); +U14API(short) U14CharCount(short hand); +U14API(short) U14LineCount(short hand); + +U14API(short) U14SendString(short hand, const char* pString); +U14API(short) U14GetString(short hand, char* pBuffer, WORD wMaxLen); +U14API(short) U14SendChar(short hand, char cChar); +U14API(short) U14GetChar(short hand, char* pcChar); + +U14API(short) U14LdCmd(short hand, const char* command); +U14API(DWORD) U14Ld(short hand, const char* vl, const char* str); + +U14API(short) U14SetTransArea(short hand, WORD wArea, void *pvBuff, + DWORD dwLength, short eSz); +U14API(short) U14UnSetTransfer(short hand, WORD wArea); +U14API(short) U14SetTransferEvent(short hand, WORD wArea, BOOL bEvent, + BOOL bToHost, DWORD dwStart, DWORD dwLength); +U14API(int) U14TestTransferEvent(short hand, WORD wArea); +U14API(int) U14WaitTransferEvent(short hand, WORD wArea, int msTimeOut); +U14API(short) U14GetTransfer(short hand, TGET_TX_BLOCK *pTransBlock); + +U14API(short) U14ToHost(short hand, char* pAddrHost,DWORD dwSize,DWORD dw1401, + short eSz); +U14API(short) U14To1401(short hand, const char* pAddrHost,DWORD dwSize,DWORD dw1401, + short eSz); + +U14API(short) U14SetCircular(short hand, WORD wArea, BOOL bToHost, void *pvBuff, + DWORD dwLength); + +U14API(int) U14GetCircBlk(short hand, WORD wArea, DWORD *pdwOffs); +U14API(int) U14FreeCircBlk(short hand, WORD wArea, DWORD dwOffs, DWORD dwSize, + DWORD *pdwOffs); + +U14API(short) U14StrToLongs(const char* pszBuff, U14LONG *palNums, short sMaxLongs); +U14API(short) U14LongsFrom1401(short hand, U14LONG *palBuff, short sMaxLongs); + +U14API(void) U14SetTimeout(short hand, int lTimeout); +U14API(int) U14GetTimeout(short hand); +U14API(short) U14OutBufSpace(short hand); +U14API(int) U14BaseAddr1401(short hand); +U14API(int) U14DriverVersion(short hand); +U14API(int) U14DriverType(short hand); +U14API(short) U14DriverName(short hand, char* pBuf, WORD wMax); +U14API(short) U14GetUserMemorySize(short hand, DWORD *pMemorySize); +U14API(short) U14KillIO1401(short hand); + +U14API(short) U14BlkTransState(short hand); +U14API(short) U14StateOf1401(short hand); + +U14API(short) U14Grab1401(short hand); +U14API(short) U14Free1401(short hand); +U14API(short) U14Peek1401(short hand, DWORD dwAddr, int nSize, int nRepeats); +U14API(short) U14Poke1401(short hand, DWORD dwAddr, DWORD dwValue, int nSize, int nRepeats); +U14API(short) U14Ramp1401(short hand, DWORD dwAddr, DWORD dwDef, DWORD dwEnable, int nSize, int nRepeats); +U14API(short) U14RampAddr(short hand, DWORD dwDef, DWORD dwEnable, int nSize, int nRepeats); +U14API(short) U14StopDebugLoop(short hand); +U14API(short) U14GetDebugData(short hand, U14LONG *plValue); + +U14API(short) U14StartSelfTest(short hand); +U14API(short) U14CheckSelfTest(short hand, U14LONG *pData); +U14API(short) U14TransferFlags(short hand); +U14API(void) U14GetErrorString(short nErr, char* pStr, WORD wMax); +U14API(int) U14MonitorRev(short hand); +U14API(void) U14CloseAll(void); + +U14API(short) U14WorkingSet(DWORD dwMinKb, DWORD dwMaxKb); +U14API(int) U14InitLib(void); + +#ifdef __cplusplus +} +#endif + +#endif /* End of ifndef __USE1401_H__ */ diff --git a/drivers/staging/ced1401/use14_ioc.h b/drivers/staging/ced1401/use14_ioc.h new file mode 100644 index 0000000..15ca638 --- /dev/null +++ b/drivers/staging/ced1401/use14_ioc.h @@ -0,0 +1,301 @@ +/* use14_ioc.h +** definitions of use1401 module stuff that is shared between use1401 and the driver. +** Copyright (C) Cambridge Electronic Design Limited 2010 +** Author Greg P Smith +************************************************************************************/ +#ifndef __USE14_IOC_H__ +#define __USE14_IOC_H__ + +#define MAX_TRANSAREAS 8 /* The number of transfer areas supported by driver */ + +#define i386 +#include "winioctl.h" /* needed so we can access driver */ + +/* +** Defines for IOCTL functions to ask driver to perform. These must be matched +** in both use1401 and in the driver. The IOCTL code contains a command +** identifier, plus other information about the device, the type of access +** with which the file must have been opened, and the type of buffering. +** The IOCTL function codes from 0x80 to 0xFF are for developer use. +*/ +#define FILE_DEVICE_CED1401 0x8001 +#define FNNUMBASE 0x800 + +#define U14_OPEN1401 CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_CLOSE1401 CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+1, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_SENDSTRING CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+2, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_RESET1401 CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+3, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_GETCHAR CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+4, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_SENDCHAR CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+5, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_STAT1401 CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+6, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_LINECOUNT CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+7, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_GETSTRING CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+8, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_REGCALLBACK CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+9, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_GETMONITORBUF CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+10, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_SETTRANSFER CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+11, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_UNSETTRANSFER CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+12, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_SETTRANSEVENT CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+13, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_GETOUTBUFSPACE CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+14, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_GETBASEADDRESS CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+15, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_GETDRIVERREVISION CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+16, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_GETTRANSFER CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+17, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_KILLIO1401 CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+18, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_BLKTRANSSTATE CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+19, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_BYTECOUNT CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+20, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_ZEROBLOCKCOUNT CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+21, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_STOPCIRCULAR CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+22, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_STATEOF1401 CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+23, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_REGISTERS1401 CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+24, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_GRAB1401 CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+25, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_FREE1401 CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+26, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_STEP1401 CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+27, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_SET1401REGISTERS CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+28, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_STEPTILL1401 CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+29, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_SETORIN CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+30, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_STARTSELFTEST CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+31, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_CHECKSELFTEST CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+32, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_TYPEOF1401 CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+33, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_TRANSFERFLAGS CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+34, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_DBGPEEK CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+35, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_DBGPOKE CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+36, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_DBGRAMPDATA CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+37, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_DBGRAMPADDR CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+38, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_DBGGETDATA CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+39, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_DBGSTOPLOOP CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+40, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_FULLRESET CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+41, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_SETCIRCULAR CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+42, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_GETCIRCBLK CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+43, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define U14_FREECIRCBLK CTL_CODE( FILE_DEVICE_CED1401, \ + FNNUMBASE+44, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +//--------------- Structures that are shared with the driver ------------- +#pragma pack(1) + +typedef struct /* used for get/set standard 1401 registers */ +{ + short sPC; + char A; + char X; + char Y; + char stat; + char rubbish; +} T1401REGISTERS; + +typedef union /* to communicate with 1401 driver status & control funcs */ +{ + char chrs[22]; + short ints[11]; + long longs[5]; + T1401REGISTERS registers; +} TCSBLOCK; + +typedef TCSBLOCK* LPTCSBLOCK; + +typedef struct paramBlk +{ + short sState; + TCSBLOCK csBlock; +} PARAMBLK; + +typedef PARAMBLK* PPARAMBLK; + +typedef struct TransferDesc /* Structure and type for SetTransArea */ +{ + WORD wArea; /* number of transfer area to set up */ + void FAR * lpvBuff; /* address of transfer area */ + DWORD dwLength; /* length of area to set up */ + short eSize; /* size to move (for swapping on MAC) */ +} TRANSFERDESC; + +typedef TRANSFERDESC FAR * LPTRANSFERDESC; + +/* This is the structure used to set up a transfer area */ +typedef struct VXTransferDesc /* use1401.c and use1432x.x use only */ +{ + WORD wArea; /* number of transfer area to set up */ + WORD wAddrSel; /* 16 bit selector for area */ + DWORD dwAddrOfs; /* 32 bit offset for area start */ + DWORD dwLength; /* length of area to set up */ +} VXTRANSFERDESC; + +#pragma pack() + +#endif \ No newline at end of file diff --git a/drivers/staging/ced1401/userspace/use1401.c b/drivers/staging/ced1401/userspace/use1401.c new file mode 100644 index 0000000..d4c6316 --- /dev/null +++ b/drivers/staging/ced1401/userspace/use1401.c @@ -0,0 +1,3035 @@ +/**************************************************************************** +** use1401.c +** Copyright (C) Cambridge Electronic Design Ltd, 1992-2010 +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +** +** Contact CED: Cambridge Electronic Design Limited, Science Park, Milton Road +** Cambridge, CB6 0FE. +** www.ced.co.uk +** greg@ced.co.uk +** +** Title: USE1401.C +** Version: 4.00 +** Author: Paul Cox, Tim Bergel, Greg Smith +** +** The code was vigorously pruned in DEC 2010 to remove the macintosh options +** and to get rid of the 16-bit support. It has also been aligned with the +** Linux version. See CVS for revisions. This will work for Win 9x onwards. +**************************************************************************** +** +** Notes on Windows interface to driver +** ************************************ +** +** Under Windows 9x and NT, Use1401 uses DeviceIoControl to get access to +** the 1401 driver. This has parameters for the device handle, the function +** code, an input pointer and byte count, an output pointer and byte count +** and a pointer to a DWORD to hold the output byte count. Note that input +** and output are from the point-of-view of the driver, so the output stuff +** is used to read values from the 1401, not send to the 1401. The use of +** these parameters varies with the function in use and the operating +** system; there are five separate DIOC calls SendString, GetString and +** SetTransferArea all have their own specialised calls, the rest use the +** Status1401 or Control1401 functions. +** +** There are two basic styles of DIOC call used, one for Win9x VxD drivers +** and one for NT Kernel-mode and WDM drivers (see below for tables showing +** the different parameters used. The array bUseNTDIOC[] selects between +** these two calling styles. +** +** Function codes +** In Win3.x, simple function codes from 0 to 40 were used, shifted left 8 +** bits with a sub-function code in the lower 8 bits. These were also used +** in the Windows 95 driver, though we had to add 1 to the code value to +** avoid problems (Open from CreateFile is zero), and the sub-function code +** is now unused. We found that this gave some problems with Windows 98 +** as the function code values are reserved by microsoft, so we switched to +** using the NT function codes instead. The NT codes are generated using the +** CTL_CODE macro, essentially this gives 0x80012000 | (func << 2), where +** func is the original 0 to 34 value. The driver will handle both types of +** code and Use1432 only uses the NT codes if it knows the driver is new +** enough. The array bUseNTCodes[] holds flags on the type of codes required. +** GPS/TDB Dec 2010: we removed the bUseNTCodes array as this is always true +** as we no longer support ancient versions. +** +** The CreateFile and CloseFile function calls are also handled +** by DIOC, using the special function codes 0 and -1 respectively. +** +** Input pointer and buffer size +** These are intended for data sent to the device driver. In nearly all cases +** they are unused in calls to the Win95 driver, the NT driver uses them +** for all information sent to the driver. The table below shows the pointer +** and byte count used for the various calls: +** +** Win 95 Win NT +** SendString NULL, 0 pStr, nStr +** GetString NULL, 0 NULL, 0 +** SetTransferArea pBuf, nBuf (unused?) pDesc, nDesc +** GetTransfer NULL, 0 NULL, 0 +** Status1401 NULL, 0 NULL, 0 +** Control1401 NULL, 0 pBlk, nBlk +** +** pStr and nStr are pointers to a char buffer and the buffer length for +** string I/O, note that these are temporary buffers owned by the DLL, not +** application memory, pBuf and nBuf are the transfer area buffer (I think +** these are unused), pDesc and nDesc are the TRANSFERDESC structure, pBlk +** and nBlk are the TCSBLOCK structure. +** +** +** Output pointer and buffer size +** These are intended for data read from the device driver. These are used +** for almost all information sent to the Win95 driver, the NT driver uses +** them for information read from the driver, chiefly the error code. The +** table below shows the pointer and byte count used for the various calls: +** +** Win 95 Win NT +** SendString pStr, nStr pPar, nPar +** GetString pStr, nStr+2 pStr, nStr+2 +** SetTransferArea pDesc, nDesc pPar, nPar +** GetTransfer pGet, nGet pGet, nGet +** Status1401 pBlk, nBlk pPar, nPar +** Control1401 pBlk, nBlk pPar, nPar +** +** pStr and nStr are pointers to a char buffer and the buffer length for +** string I/O, the +2 for GetString refers to two spare bytes at the start +** used to hold the string length and returning an error code for NT. Note +** again that these are (and must be) DLL-owned temporary buffers. pPar +** and nPar are a PARAM structure used in NT (it holds an error code and a +** TCSBLOCK structure). pDesc and nDesc are the VXTRANSFERDESC structure, +** pBlk and nBlk are the TCSBLOCK structure. pGet and nGet indicate the +** TGET_TX_BLOCK structure used for GetTransfer. +** +** +** The output byte count +** Both drivers return the output buffer size here, regardless of the actual +** bytes output. This is used to check that we did get through to the driver. +** +** Multiple 1401s +** ************** +** +** We have code that tries to support the use of multiple 1401s, but there +** are problems: The lDriverVersion and lDriverType variables are global, not +** per-1401 (a particular problem as the U14 functions that use them don't +** have a hand parameter). In addition, the mechansim for finding a free +** 1401 depends upon the 1401 device driver open operation failing if it's +** already in use, which doesn't always happen, particularly with the VxDs. +** The code in TryToOpen tries to fix this by relying on TYPEOF1401 to detect +** the 1401-in-use state - the VxDs contain special code to help this. This is +** working OK but multiple 1401 support works better with the Win2000 drivers. +** +** USB driver +** ********** +** +** The USB driver, which runs on both Win98 and NT2000, uses the NT-style +** calling convention, both for the DIOC codes and the DIOC parameters. The +** TryToOpen function has been altered to look for an NT driver first in +** the appropriate circumstances, and to set the driver DIOC flags up in +** the correct state. +** +** Adding a new 1401 type - now almost nothing to do +** ************************************************* +** +** The 1401 types are defined by a set of U14TYPExxxx codes in USE1401.H. +** You should add a new one of these to keep things tidy for applications. +** +** DRIVERET_MAX (below) specifies the maximum allowed type code from the +** 1401 driver; I have set this high to accomodate as yet undesigned 1401 +** types. Similarly, as long as the command file names follow the ARM, +** ARN, ARO sequence, these are calculated by the ExtForType function, so +** you don't need to do anything here either. +** +** Version number +** ************** +** The new U14InitLib() function returns 0 if the OS is incapable of use, +** otherwise is returns the version of the USE1401 library. This is done +** in three parts: Major(31-24).Minor(23-16).Revision.(15-0) (brackets are +** the bits used). The Major number starts at 2 for the first revision with +** the U14InitLib() function. Changes to the Major version means that we +** have broken backwards compatibility. Minor number changes mean that we +** have added new functionality that does not break backwards compatibility. +** we starts at 0. Revision changes mean we have fixed something. Each index +** returns to 0 when a higer one changes. +*/ +#define U14LIB_MAJOR 4 +#define U14LIB_MINOR 0 +#define U14LIB_REVISION 0 +#define U14LIB_VERSION ((U14LIB_MAJOR<<24) | (U14LIB_MINOR<<16) | U14LIB_REVISION) + +#include +#include +#include + +#include "USE1401.H" + +#ifdef _IS_WINDOWS_ +#include +#include +#pragma warning(disable: 4100) /* Disable "Unused formal parameter" warning */ +#include +#include "process.h" + + +#define sprintf wsprintf +#define PATHSEP '\\' +#define PATHSEPSTR "\\" +#define DEFCMDPATH "\\1401\\" // default command path if all else fails +#define MINDRIVERMAJREV 1 // minimum driver revision level we need +#define __packed // does nothing in Windows + +#include "use14_ioc.h" // links to device driver stuff +#endif + +#ifdef LINUX +#include +#include +#include +#include +#include +#include +#include +#define PATHSEP '/' +#define PATHSEPSTR "/" +#define DEFCMDPATH "/var/1401/" // default command path if all else fails +#define MINDRIVERMAJREV 2 // minimum driver revision level we need + +#include "ced_ioctl.h" // links to device driver stuff +#endif + +#define MAX1401 8 // The number of 1401s that can be supported + +/* +** These are the 1401 type codes returned by the driver, they are a slightly +** odd sequence & start for reasons of compatability with the DOS driver. +** The maximum code value is the upper limit of 1401 device types. +*/ +#define DRIVRET_STD 4 // Codes for 1401 types matching driver values +#define DRIVRET_U1401 5 // This table does not need extending, as +#define DRIVRET_PLUS 6 // we can calculate values now. +#define DRIVRET_POWER 7 // but we need all of these values still +#define DRIVRET_MAX 26 // Maximum tolerated code - future designs + +/* +** These variables store data that will be used to generate the last +** error string. For now, a string will hold the 1401 command file name. +*/ +static char szLastName[20]; // additional text information + +/* +** Information stored per handle. NBNB, driverType and DriverVersion used to be +** only stored once for all handles... i.e. nonsensical. This change means that +** three U14...() calls now include handles that were previously void. We have +** set a constructor and a destructor call for the library (see the end) to +** initialise important structures, or call use1401_load(). +*/ +static short asDriverType[MAX1401] = {0}; +static int lLastDriverVersion = U14ERR_NO1401DRIV; +static int lLastDriverType = U14TYPEUNKNOWN; +static int alDriverVersion[MAX1401]; // version/type of each driver +static int alTimeOutPeriod[MAX1401]; // timeout time in milliseconds +static short asLastRetCode[MAX1401]; // last code from a fn call +static short asType1401[MAX1401] = {0}; // The type of the 1401 +static BOOL abGrabbed[MAX1401] = {0}; // Flag for grabbed, set true by grab1401 +static int iAttached = 0; // counts process attaches so can let go + +#ifdef _IS_WINDOWS_ +/**************************************************************************** +** Windows NT Specific Variables and internal types +****************************************************************************/ +static HANDLE aHand1401[MAX1401] = {0}; // handles for 1401s +static HANDLE aXferEvent[MAX1401] = {0}; // transfer events for the 1401s +static LPVOID apAreas[MAX1401][MAX_TRANSAREAS]; // Locked areas +static DWORD auAreas[MAX1401][MAX_TRANSAREAS]; // Size of locked areas +static BOOL bWindows9x = FALSE; // if we are Windows 95 or better +#ifdef _WIN64 +#define USE_NT_DIOC(ind) TRUE +#else +static BOOL abUseNTDIOC[MAX1401]; // Use NT-style DIOC parameters */ +#define USE_NT_DIOC(ind) abUseNTDIOC[ind] +#endif + +#endif + +#ifdef LINUX +static int aHand1401[MAX1401] = {0}; // handles for 1401s +#define INVALID_HANDLE_VALUE 0 // to avoid code differences +#endif + + +/* +** The CmdHead relates to backwards compatibility with ancient Microsoft (and Sperry!) +** versions of BASIC, where this header was needed so we could load a command into +** memory. +*/ +#pragma pack(1) // pack our structure +typedef struct CmdHead // defines header block on command +{ // for PC commands + char acBasic[5]; // BASIC information - needed to align things + WORD wBasicSz; // size as seen by BASIC + WORD wCmdSize; // size of the following info +} __packed CMDHEAD; +#pragma pack() // back to normal + +/* +** The rest of the header looks like this... +** int iRelPnt; relocation pointer... actual start +** char acName[8]; string holding the command name +** BYTE bMonRev; monitor revision level +** BYTE bCmdRev; command revision level +*/ + +typedef CMDHEAD *LPCMDHEAD; // pointer to a command header + +#define MAXSTRLEN 255 // maximum string length we use +#define TOHOST FALSE +#define TO1401 TRUE + +static short CheckHandle(short h) +{ + if ((h < 0) || (h >= MAX1401)) // must be legal range... + return U14ERR_BADHAND; + if (aHand1401[h] <= 0) // must be open + return U14ERR_BADHAND; + return U14ERR_NOERROR; +} + +#ifdef _IS_WINDOWS_ +/**************************************************************************** +** U14Status1401 Used for functions which do not pass any data in but +** get data back +****************************************************************************/ +static short U14Status1401(short sHand, LONG lCode, TCSBLOCK* pBlk) +{ + DWORD dwBytes = 0; + + if ((sHand < 0) || (sHand >= MAX1401)) /* Check parameters */ + return U14ERR_BADHAND; +#ifndef _WIN64 + if (!USE_NT_DIOC(sHand)) + { /* Windows 9x DIOC methods? */ + if (DeviceIoControl(aHand1401[sHand], lCode, NULL, 0, pBlk,sizeof(TCSBLOCK),&dwBytes,NULL)) + return (short)((dwBytes>=sizeof(TCSBLOCK)) ? U14ERR_NOERROR : U14ERR_DRIVCOMMS); + else + return (short)GetLastError(); + } + else +#endif + { /* Windows NT or USB driver */ + PARAMBLK rWork; + rWork.sState = U14ERR_DRIVCOMMS; + if (DeviceIoControl(aHand1401[sHand], lCode, NULL, 0, &rWork,sizeof(PARAMBLK),&dwBytes,NULL) && + (dwBytes >= sizeof(PARAMBLK))) + { + *pBlk = rWork.csBlock; + return rWork.sState; + } + } + + return U14ERR_DRIVCOMMS; +} + +/**************************************************************************** +** U14Control1401 Used for functions which pass data in and only expect +** an error code back +****************************************************************************/ +static short U14Control1401(short sHand, LONG lCode, TCSBLOCK* pBlk) +{ + DWORD dwBytes = 0; + + if ((sHand < 0) || (sHand >= MAX1401)) /* Check parameters */ + return U14ERR_BADHAND; + +#ifndef _WIN64 + if (!USE_NT_DIOC(sHand)) + { /* Windows 9x DIOC methods */ + if (DeviceIoControl(aHand1401[sHand], lCode, NULL, 0, pBlk, sizeof(TCSBLOCK), &dwBytes, NULL)) + return (short)(dwBytes >= sizeof(TCSBLOCK) ? U14ERR_NOERROR : U14ERR_DRIVCOMMS); + else + return (short)GetLastError(); + } + else +#endif + { /* Windows NT or later */ + PARAMBLK rWork; + rWork.sState = U14ERR_DRIVCOMMS; + if (DeviceIoControl(aHand1401[sHand], lCode, pBlk, sizeof(TCSBLOCK), &rWork, sizeof(PARAMBLK), &dwBytes, NULL) && + (dwBytes >= sizeof(PARAMBLK))) + return rWork.sState; + } + + return U14ERR_DRIVCOMMS; +} +#endif + +/**************************************************************************** +** SafeTickCount +** Gets time in approximately units of a millisecond. +*****************************************************************************/ +static long SafeTickCount() +{ +#ifdef _IS_WINDOWS_ + return GetTickCount(); +#endif +#ifdef LINUX + struct timeval tv; + gettimeofday(&tv, NULL); + return (tv.tv_sec*1000 + tv.tv_usec/1000); +#endif +} + +/**************************************************************************** +** A utility routine to get the command file extension for a given type +** of 1401. We assume the type code is vaguely legal. +****************************************************************************/ +static int ExtForType(short sType, char* szExt) +{ + szExt[0] = 0; /* Default return is a blank string */ + switch (sType) + { + case U14TYPE1401: strcpy(szExt, ".CMD"); break; // Standard 1401 + case U14TYPEPLUS: strcpy(szExt, ".GXC"); break; // 1401 plus + default: // All others are in a predictable sequence + strcpy(szExt, ".ARM"); + szExt[3] = (char)('M' + sType - U14TYPEU1401); + if (szExt[3] > 'Z') // Wrap round to ARA after ARZ + szExt[3] = (char)(szExt[3] - 26); + } + return 0; +} + +/**************************************************************************** +** U14WhenToTimeOut +** Returns the time to time out in time units suitable for the machine +** we are running on ie millsecs for pc/linux, or Mac/ +****************************************************************************/ +U14API(int) U14WhenToTimeOut(short hand) +{ + int iNow = SafeTickCount(); + if ((hand >= 0) && (hand < MAX1401)) + iNow += alTimeOutPeriod[hand]; + return iNow; +} + +/**************************************************************************** +** U14PassedTime +** Returns non zero if the timed passed in has been passed 0 if not +****************************************************************************/ +U14API(short) U14PassedTime(int lCheckTime) +{ + return (short)((SafeTickCount()-lCheckTime) > 0); +} + +/**************************************************************************** +** TranslateString +** Tidies up string that U14GetString returns. Converts all the commas in a +** string to spaces. Removes terminating CR character. May do more in future. +****************************************************************************/ +static void TranslateString(char* pStr) +{ + int i = 0; + while (pStr[i]) + { + if (pStr[i] == ',') + pStr[i] = ' '; /* convert comma to space */ + ++i; + } + + if ((i > 0) && (pStr[i-1] == '\n')) /* kill terminating LF */ + pStr[i-1] = (char)0; +} + +/**************************************************************************** +** U14StrToLongs +** Converts a string to an array of longs and returns the number of values +****************************************************************************/ +U14API(short) U14StrToLongs(const char* pszBuff, U14LONG *palNums, short sMaxLongs) +{ + WORD wChInd = 0; // index into source + short sLgInd = 0; // index into result longs + + while (pszBuff[wChInd] && // until we get to end of string... + (sLgInd < sMaxLongs)) // ...or filled the buffer + { + // Why not use a C Library converter? + switch (pszBuff[wChInd]) + { + case '-': + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + { + BOOL bDone = FALSE; // true at end of number + int iSign = 1; // sign of number + long lValue = 0; + + while ((!bDone) && pszBuff[wChInd]) + { + switch (pszBuff[wChInd]) + { + case '-': + iSign = -1; // swap sign + break; + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + lValue *= 10; // move to next digit base 10 + lValue += ((int)pszBuff[wChInd]-(int)'0'); + break; + + default: // end of number + bDone = TRUE; + break; + } + wChInd++; // move onto next character + } + palNums[sLgInd] = lValue * iSign; + sLgInd++; + } + break; + + default: + wChInd++; // look at next char + break; + } + } + return (sLgInd); +} + + +/**************************************************************************** +** U14LongsFrom1401 +** Gets the next waiting line from the 1401 and converts it longs +** Returns the number of numbers read or an error. +****************************************************************************/ +U14API(short) U14LongsFrom1401(short hand, U14LONG *palBuff, short sMaxLongs) +{ + char szWork[MAXSTRLEN]; + short sResult = U14GetString(hand, szWork, MAXSTRLEN);/* get reply from 1401 */ + if (sResult == U14ERR_NOERROR) /* if no error convert */ + sResult = U14StrToLongs(szWork, palBuff, sMaxLongs); + return sResult; +} + +/**************************************************************************** +** U14CheckErr +** Sends the ERR command to the 1401 and gets the result. Returns 0, a +** negative error code, or the first error value. +****************************************************************************/ +U14API(short) U14CheckErr(short hand) +{ + short sResult = U14SendString(hand, ";ERR;"); + if (sResult == U14ERR_NOERROR) + { + U14LONG er[3]; + sResult = U14LongsFrom1401(hand, er, 3); + if (sResult > 0) + { + sResult = (short)er[0]; /* Either zero or an error value */ +#ifdef _DEBUG + if (er[0] != 0) + { + char szMsg[50]; + sprintf(szMsg, "U14CheckErr returned %d,%d\n", er[0], er[1]); + OutputDebugString(szMsg); + } +#endif + } + else + { + if (sResult == 0) + sResult = U14ERR_TIMEOUT; /* No numbers equals timeout */ + } + } + + return sResult; +} + +/**************************************************************************** +** U14LastErrCode +** Returns the last code from the driver. This is for Windows where all calls +** go through the Control and Status routines, so we can save any error. +****************************************************************************/ +U14API(short) U14LastErrCode(short hand) +{ + if ((hand < 0) || (hand >= MAX1401)) + return U14ERR_BADHAND; + return asLastRetCode[hand]; +} + +/**************************************************************************** +** U14SetTimeout +** Set the timeout period for 1401 comms in milliseconds +****************************************************************************/ +U14API(void) U14SetTimeout(short hand, int lTimeOut) +{ + if ((hand < 0) || (hand >= MAX1401)) + return; + alTimeOutPeriod[hand] = lTimeOut; +} + +/**************************************************************************** +** U14GetTimeout +** Get the timeout period for 1401 comms in milliseconds +****************************************************************************/ +U14API(int) U14GetTimeout(short hand) +{ + if ((hand < 0) || (hand >= MAX1401)) + return U14ERR_BADHAND; + return alTimeOutPeriod[hand]; +} + +/**************************************************************************** +** U14OutBufSpace +** Return the space in the output buffer, or an error. +****************************************************************************/ +U14API(short) U14OutBufSpace(short hand) +{ +#ifdef _IS_WINDOWS_ + TCSBLOCK csBlock; + short sErr = U14Status1401(hand, U14_GETOUTBUFSPACE,&csBlock); + if (sErr == U14ERR_NOERROR) + sErr = csBlock.ints[0]; + return sErr; +#endif +#ifdef LINUX + short sErr = CheckHandle(hand); + return (sErr == U14ERR_NOERROR) ? CED_GetOutBufSpace(aHand1401[hand]) : sErr; +#endif +} + + +/**************************************************************************** +** U14BaseAddr1401 +** Returns the 1401 base address or an error code. Meaningless nowadays +****************************************************************************/ +U14API(int) U14BaseAddr1401(short hand) +{ +#ifdef _IS_WINDOWS_ + TCSBLOCK csBlock; + int iError = U14Status1401(hand, U14_GETBASEADDRESS,&csBlock); + if (iError == U14ERR_NOERROR) + iError = csBlock.longs[0]; + return iError; +#endif +#ifdef LINUX + short sErr = CheckHandle(hand); + return (sErr == U14ERR_NOERROR) ? CED_GetBaseAddress(aHand1401[hand]) : sErr; +#endif +} + +/**************************************************************************** +** U14StateOf1401 +** Return error state, either NOERROR or a negative code. +****************************************************************************/ +U14API(short) U14StateOf1401(short hand) +{ +#ifdef _IS_WINDOWS_ + TCSBLOCK csBlock; + short sErr = U14Status1401(hand, U14_STATEOF1401, &csBlock); + if (sErr == U14ERR_NOERROR) + { + sErr = csBlock.ints[0]; // returned 1401 state + if ((sErr >= DRIVRET_STD) && (sErr <= DRIVRET_MAX)) + sErr = U14ERR_NOERROR; + } +#endif +#ifdef LINUX + short sErr = CheckHandle(hand); + if (sErr == U14ERR_NOERROR) + { + sErr = (short)CED_StateOf1401(aHand1401[hand]); + if ((sErr >= DRIVRET_STD) && (sErr <= DRIVRET_MAX)) + sErr = U14ERR_NOERROR; + } +#endif + return sErr; +} + +/**************************************************************************** +** U14DriverVersion +** Returns the driver version. Hi word is major revision, low word is minor. +** If you pass in a silly handle (like -1), we return the version of the last +** driver we know of (to cope with PCI and no 1401 attached). +****************************************************************************/ +U14API(int) U14DriverVersion(short hand) +{ + return CheckHandle(hand) != U14ERR_NOERROR ? lLastDriverVersion : alDriverVersion[hand]; +} + +/**************************************************************************** +** U14DriverType +** Returns the driver type. The type, 0=ISA/NU-Bus, 1=PCI, 2=USB, 3=HSS +** If you pass in a silly handle (like -1), we return the type of the last +** driver we know of (to cope with PCI and no 1401 attached). +****************************************************************************/ +U14API(int) U14DriverType(short hand) +{ + return CheckHandle(hand) != U14ERR_NOERROR ? lLastDriverType : asDriverType[hand]; +} + +/**************************************************************************** +** U14DriverName +** Returns the driver type as 3 character (ISA, PCI, USB or HSS)) +****************************************************************************/ +U14API(short) U14DriverName(short hand, char* pBuf, WORD wMax) +{ + char* pName; + *pBuf = 0; // Start off with a blank string + switch (U14DriverType(hand)) // Results according to type + { + case 0: pName = "ISA"; break; + case 1: pName = "PCI"; break; + case 2: pName = "USB"; break; + case 3: pName = "HSS"; break; + default: pName = "???"; break; + } + strncpy(pBuf, pName, wMax); // Copy the correct name to return + + return U14ERR_NOERROR; +} + +/**************************************************************************** +** U14BlkTransState +** Returns 0 no transfer in progress, 1 transfer in progress or an error code +****************************************************************************/ +U14API(short) U14BlkTransState(short hand) +{ +#ifdef _IS_WINDOWS_ + TCSBLOCK csBlock; + short sErr = U14Status1401(hand, U14_BLKTRANSSTATE, &csBlock); + if (sErr == U14ERR_NOERROR) + sErr = csBlock.ints[0]; + return sErr; +#endif +#ifdef LINUX + short sErr = CheckHandle(hand); + return (sErr == U14ERR_NOERROR) ? CED_BlkTransState(aHand1401[hand]) : sErr; +#endif +} + +/**************************************************************************** +** U14Grab1401 +** Take control of the 1401 for diagnostics purposes. USB does nothing. +****************************************************************************/ +U14API(short) U14Grab1401(short hand) +{ + short sErr = CheckHandle(hand); + if (sErr == U14ERR_NOERROR) + { +#ifdef _IS_WINDOWS_ + if (abGrabbed[hand]) // 1401 should not have been grabbed + sErr = U14ERR_ALREADYSET; // Error code defined for this + else + { + TCSBLOCK csBlock; + sErr = U14Control1401(hand, U14_GRAB1401, &csBlock); + } +#endif +#ifdef LINUX + // 1401 should not have been grabbed + sErr = abGrabbed[hand] ? U14ERR_ALREADYSET : CED_Grab1401(aHand1401[hand]); +#endif + if (sErr == U14ERR_NOERROR) + abGrabbed[hand] = TRUE; + } + return sErr; +} + +/**************************************************************************** +** U14Free1401 +****************************************************************************/ +U14API(short) U14Free1401(short hand) +{ + short sErr = CheckHandle(hand); + if (sErr == U14ERR_NOERROR) + { +#ifdef _IS_WINDOWS_ + if (abGrabbed[hand]) // 1401 should have been grabbed + { + TCSBLOCK csBlock; + sErr = U14Control1401(hand, U14_FREE1401, &csBlock); + } + else + sErr = U14ERR_NOTSET; +#endif +#ifdef LINUX + // 1401 should not have been grabbed + sErr = abGrabbed[hand] ? CED_Free1401(aHand1401[hand]) : U14ERR_NOTSET; +#endif + if (sErr == U14ERR_NOERROR) + abGrabbed[hand] = FALSE; + } + return sErr; +} + +/**************************************************************************** +** U14Peek1401 +** DESCRIPTION Cause the 1401 to do one or more peek operations. +** If lRepeats is zero, the loop will continue until U14StopDebugLoop +** is called. After the peek is done, use U14GetDebugData to retrieve +** the results of the peek. +****************************************************************************/ +U14API(short) U14Peek1401(short hand, DWORD dwAddr, int nSize, int nRepeats) +{ + short sErr = CheckHandle(hand); + if (sErr == U14ERR_NOERROR) + { + if (abGrabbed[hand]) // 1401 should have been grabbed + { +#ifdef _IS_WINDOWS_ + TCSBLOCK csBlock; + csBlock.longs[0] = (long)dwAddr; + csBlock.longs[1] = nSize; + csBlock.longs[2] = nRepeats; + sErr = U14Control1401(hand, U14_DBGPEEK, &csBlock); +#endif +#ifdef LINUX + TDBGBLOCK dbb; + dbb.iAddr = (int)dwAddr; + dbb.iWidth = nSize; + dbb.iRepeats = nRepeats; + sErr = CED_DbgPeek(aHand1401[hand], &dbb); +#endif + } + else + sErr = U14ERR_NOTSET; + } + return sErr; +} + +/**************************************************************************** +** U14Poke1401 +** DESCRIPTION Cause the 1401 to do one or more poke operations. +** If lRepeats is zero, the loop will continue until U14StopDebugLoop +** is called. +****************************************************************************/ +U14API(short) U14Poke1401(short hand, DWORD dwAddr, DWORD dwValue, + int nSize, int nRepeats) +{ + short sErr = CheckHandle(hand); + if (sErr == U14ERR_NOERROR) + { + if (abGrabbed[hand]) // 1401 should have been grabbed + { +#ifdef _IS_WINDOWS_ + TCSBLOCK csBlock; + csBlock.longs[0] = (long)dwAddr; + csBlock.longs[1] = nSize; + csBlock.longs[2] = nRepeats; + csBlock.longs[3] = (long)dwValue; + sErr = U14Control1401(hand, U14_DBGPOKE, &csBlock); +#endif +#ifdef LINUX + TDBGBLOCK dbb; + dbb.iAddr = (int)dwAddr; + dbb.iWidth = nSize; + dbb.iRepeats= nRepeats; + dbb.iData = (int)dwValue; + sErr = CED_DbgPoke(aHand1401[hand], &dbb); +#endif + } + else + sErr = U14ERR_NOTSET; + } + return sErr; +} + +/**************************************************************************** +** U14Ramp1401 +** DESCRIPTION Cause the 1401 to loop, writing a ramp to a location. +** If lRepeats is zero, the loop will continue until U14StopDebugLoop. +****************************************************************************/ +U14API(short) U14Ramp1401(short hand, DWORD dwAddr, DWORD dwDef, DWORD dwEnable, + int nSize, int nRepeats) +{ + short sErr = CheckHandle(hand); + if (sErr == U14ERR_NOERROR) + { + if (abGrabbed[hand]) // 1401 should have been grabbed + { +#ifdef _IS_WINDOWS_ + TCSBLOCK csBlock; + csBlock.longs[0] = (long)dwAddr; + csBlock.longs[1] = (long)dwDef; + csBlock.longs[2] = (long)dwEnable; + csBlock.longs[3] = nSize; + csBlock.longs[4] = nRepeats; + sErr = U14Control1401(hand, U14_DBGRAMPDATA, &csBlock); +#endif +#ifdef LINUX + TDBGBLOCK dbb; + dbb.iAddr = (int)dwAddr; + dbb.iDefault = (int)dwDef; + dbb.iMask = (int)dwEnable; + dbb.iWidth = nSize; + dbb.iRepeats = nRepeats; + sErr = CED_DbgRampAddr(aHand1401[hand], &dbb); +#endif + } + else + sErr = U14ERR_NOTSET; + } + return sErr; +} + +/**************************************************************************** +** U14RampAddr +** DESCRIPTION Cause the 1401 to loop, reading from a ramping location. +** If lRepeats is zero, the loop will continue until U14StopDebugLoop +****************************************************************************/ +U14API(short) U14RampAddr(short hand, DWORD dwDef, DWORD dwEnable, + int nSize, int nRepeats) +{ + short sErr = CheckHandle(hand); + if (sErr == U14ERR_NOERROR) + { + if (abGrabbed[hand]) // 1401 should have been grabbed + { +#ifdef _IS_WINDOWS_ + TCSBLOCK csBlock; + csBlock.longs[0] = (long)dwDef; + csBlock.longs[1] = (long)dwEnable; + csBlock.longs[2] = nSize; + csBlock.longs[3] = nRepeats; + sErr = U14Control1401(hand, U14_DBGRAMPADDR, &csBlock); +#endif +#ifdef LINUX + TDBGBLOCK dbb; + dbb.iDefault = (int)dwDef; + dbb.iMask = (int)dwEnable; + dbb.iWidth = nSize; + dbb.iRepeats = nRepeats; + sErr = CED_DbgRampAddr(aHand1401[hand], &dbb); +#endif + } + else + sErr = U14ERR_NOTSET; + } + return sErr; +} + +/**************************************************************************** +** U14StopDebugLoop +** DESCRIPTION Stops a peek\poke\ramp that, with repeats set to zero, +** will otherwise continue forever. +****************************************************************************/ +U14API(short) U14StopDebugLoop(short hand) +{ + short sErr = CheckHandle(hand); + if (sErr == U14ERR_NOERROR) +#ifdef _IS_WINDOWS_ + { + if (abGrabbed[hand]) // 1401 should have been grabbed + { + TCSBLOCK csBlock; + sErr = U14Control1401(hand, U14_DBGSTOPLOOP, &csBlock); + } + else + sErr = U14ERR_NOTSET; + } +#endif +#ifdef LINUX + sErr = abGrabbed[hand] ? CED_DbgStopLoop(aHand1401[hand]) : U14ERR_NOTSET; +#endif + return sErr; +} + +/**************************************************************************** +** U14GetDebugData +** DESCRIPTION Returns the result from a previous peek operation. +****************************************************************************/ +U14API(short) U14GetDebugData(short hand, U14LONG* plValue) +{ + short sErr = CheckHandle(hand); + if (sErr == U14ERR_NOERROR) + { + if (abGrabbed[hand]) // 1401 should have been grabbed + { +#ifdef _IS_WINDOWS_ + TCSBLOCK csBlock; + sErr = U14Status1401(hand, U14_DBGGETDATA, &csBlock); + if (sErr == U14ERR_NOERROR) + *plValue = csBlock.longs[0]; // Return the data +#endif +#ifdef LINUX + TDBGBLOCK dbb; + sErr = CED_DbgGetData(aHand1401[hand], &dbb); + if (sErr == U14ERR_NOERROR) + *plValue = dbb.iData; /* Return the data */ +#endif + } + else + sErr = U14ERR_NOTSET; + } + return sErr; +} + +/**************************************************************************** +** U14StartSelfTest +****************************************************************************/ +U14API(short) U14StartSelfTest(short hand) +{ +#ifdef _IS_WINDOWS_ + TCSBLOCK csBlock; + return U14Control1401(hand, U14_STARTSELFTEST, &csBlock); +#endif +#ifdef LINUX + short sErr = CheckHandle(hand); + return (sErr == U14ERR_NOERROR) ? CED_StartSelfTest(aHand1401[hand]) : sErr; +#endif +} + +/**************************************************************************** +** U14CheckSelfTest +****************************************************************************/ +U14API(short) U14CheckSelfTest(short hand, U14LONG *pData) +{ +#ifdef _IS_WINDOWS_ + TCSBLOCK csBlock; + short sErr = U14Status1401(hand, U14_CHECKSELFTEST, &csBlock); + if (sErr == U14ERR_NOERROR) + { + pData[0] = csBlock.longs[0]; /* Return the results to user */ + pData[1] = csBlock.longs[1]; + pData[2] = csBlock.longs[2]; + } +#endif +#ifdef LINUX + short sErr = CheckHandle(hand); + if (sErr == U14ERR_NOERROR) /* Check parameters */ + { + TGET_SELFTEST gst; + sErr = CED_CheckSelfTest(aHand1401[hand], &gst); + if (sErr == U14ERR_NOERROR) + { + pData[0] = gst.code; /* Return the results to user */ + pData[1] = gst.x; + pData[2] = gst.y; + } + } +#endif + return sErr; +} + +/**************************************************************************** +** U14GetUserMemorySize +****************************************************************************/ +U14API(short) U14GetUserMemorySize(short hand, DWORD *pMemorySize) +{ + // The original 1401 used a different command for getting the size + short sErr = U14SendString(hand, (asType1401[hand] == U14TYPE1401) ? "MEMTOP;" : "MEMTOP,?;"); + *pMemorySize = 0; /* if we get error then leave size set at 0 */ + if (sErr == U14ERR_NOERROR) + { + U14LONG alLimits[4]; + sErr = U14LongsFrom1401(hand, alLimits, 4); + if (sErr > 0) /* +ve sErr is the number of values read */ + { + sErr = U14ERR_NOERROR; /* All OK, flag success */ + if (asType1401[hand] == U14TYPE1401) /* result for standard */ + *pMemorySize = alLimits[0] - alLimits[1]; /* memtop-membot */ + else + *pMemorySize = alLimits[0]; /* result for plus or u1401 */ + } + } + return sErr; +} + +/**************************************************************************** +** U14TypeOf1401 +** Returns the type of the 1401, maybe unknown +****************************************************************************/ +U14API(short) U14TypeOf1401(short hand) +{ + if ((hand < 0) || (hand >= MAX1401)) /* Check parameters */ + return U14ERR_BADHAND; + else + return asType1401[hand]; +} + +/**************************************************************************** +** U14NameOf1401 +** Returns the type of the 1401 as a string, blank if unknown +****************************************************************************/ +U14API(short) U14NameOf1401(short hand, char* pBuf, WORD wMax) +{ + short sErr = CheckHandle(hand); + if (sErr == U14ERR_NOERROR) + { + char* pName; + switch (asType1401[hand]) // Results according to type + { + case U14TYPE1401: pName = "Std 1401"; break; + case U14TYPEPLUS: pName = "1401plus"; break; + case U14TYPEU1401: pName = "micro1401"; break; + case U14TYPEPOWER: pName = "Power1401"; break; + case U14TYPEU14012:pName = "Micro1401 mk II"; break; + case U14TYPEPOWER2:pName = "Power1401 mk II"; break; + case U14TYPEU14013:pName = "Micro1401-3"; break; + case U14TYPEPOWER3:pName = "Power1401-3"; break; + default: pName = "Unknown"; + } + strncpy(pBuf, pName, wMax); + } + return sErr; +} + +/**************************************************************************** +** U14TransferFlags +** Returns the driver block transfer flags. +** Bits can be set - see U14TF_ constants in use1401.h +*****************************************************************************/ +U14API(short) U14TransferFlags(short hand) +{ +#ifdef _IS_WINDOWS_ + TCSBLOCK csBlock; + short sErr = U14Status1401(hand, U14_TRANSFERFLAGS, &csBlock); + return (sErr == U14ERR_NOERROR) ? (short)csBlock.ints[0] : sErr; +#endif +#ifdef LINUX + short sErr = CheckHandle(hand); + return (sErr == U14ERR_NOERROR) ? CED_TransferFlags(aHand1401[hand]) : sErr; +#endif +} + +/**************************************************************************** +** GetDriverVersion +** Actually reads driver version from the device driver. +** Hi word is major revision, low word is minor revision. +** Assumes that hand has been checked. Also codes driver type in bits 24 up. +*****************************************************************************/ +static int GetDriverVersion(short hand) +{ +#ifdef _IS_WINDOWS_ + TCSBLOCK csBlock; + int iErr = U14Status1401(hand, U14_GETDRIVERREVISION, &csBlock); + if (iErr == U14ERR_NOERROR) + iErr = csBlock.longs[0]; + return iErr; +#endif +#ifdef LINUX + return CED_GetDriverRevision(aHand1401[hand]); +#endif +} + +/**************************************************************************** +** U14MonitorRev +** Returns the 1401 monitor revision number. +** The number returned is the minor revision - the part after the +** decimal point - plus the major revision times 1000. +*****************************************************************************/ +U14API(int) U14MonitorRev(short hand) +{ + int iRev = 0; + int iErr = CheckHandle(hand); + if (iErr != U14ERR_NOERROR) // Check open and in use + return iErr; + + if (asType1401[hand] >= U14TYPEPOWER2) // The Power2 onwards can give us the monitor + { // revision directly for all versions + iErr = U14SendString(hand, "INFO,S,28;"); + if (iErr == U14ERR_NOERROR) + { + U14LONG lVals[2]; // Read a single number being the revision + iErr = U14LongsFrom1401(hand, lVals, 1); + if (iErr > 0) + { + iErr = U14ERR_NOERROR; + iRev = lVals[0]; // This is the minor part of the revision + iRev += asType1401[hand] * 10000; + } + } + } + else + { /* Do it the hard way for older hardware */ + iErr = U14SendString(hand, ";CLIST;"); /* ask for command levels */ + if (iErr == U14ERR_NOERROR) + { + while (iErr == U14ERR_NOERROR) + { + char wstr[50]; + iErr = U14GetString(hand, wstr, 45); + if (iErr == U14ERR_NOERROR) + { + char *pstr = strstr(wstr,"RESET"); /* Is this the RESET command? */ + if ((pstr == wstr) && (wstr[5] == ' ')) + { + char *pstr2; + size_t l; + pstr += 6; /* Move past RESET and followinmg char */ + l = strlen(pstr); /* The length of text remaining */ + while (((pstr[l-1] == ' ') || (pstr[l-1] == 13)) && (l > 0)) + { + pstr[l-1] = 0; /* Tidy up string at the end */ + l--; /* by removing spaces and CRs */ + } + pstr2 = strchr(pstr, '.'); /* Find the decimal point */ + if (pstr2 != NULL) /* If we found the DP */ + { + *pstr2 = 0; /* End pstr string at DP */ + pstr2++; /* Now past the decimal point */ + iRev = atoi(pstr2); /* Get the number after point */ + } + iRev += (atoi(pstr) * 1000); /* Add first bit * 1000 */ + } + if ((strlen(wstr) < 3) && (wstr[0] == ' ')) + break; /* Spot the last line of results */ + } + } + } + } + if (iErr == U14ERR_NOERROR) /* Return revision if no error */ + iErr = iRev; + + return iErr; +} + +/**************************************************************************** +** U14TryToOpen Tries to open the 1401 number passed +** Note : This will succeed with NT driver even if no I/F card or +** 1401 switched off, so we check state and close the driver +** if the state is unsatisfactory in U14Open1401. +****************************************************************************/ +#ifdef _IS_WINDOWS_ +#define U14NAMEOLD "\\\\.\\CED_140%d" +#define U14NAMENEW "\\\\.\\CED%d" +static short U14TryToOpen(int n1401, long* plRetVal, short* psHandle) +{ + short sErr = U14ERR_NOERROR; + HANDLE hDevice = INVALID_HANDLE_VALUE; + DWORD dwErr = 0; + int nFirst, nLast, nDev = 0; /* Used for the search for a 1401 */ + BOOL bOldName = FALSE; /* start by looking for a modern driver */ + + if (n1401 == 0) /* If we need to look for a 1401 */ + { + nFirst = 1; /* Set the search range */ + nLast = MAX1401; /* through all the possible 1401s */ + } + else + nFirst = nLast = n1401; /* Otherwise just one 1401 */ + + while (hDevice == INVALID_HANDLE_VALUE) /* Loop to try for a 1401 */ + { + for (nDev = nFirst; nDev <= nLast; nDev++) + { + char szDevName[40]; /* name of the device to open */ + sprintf(szDevName, bOldName ? U14NAMEOLD : U14NAMENEW, nDev); + hDevice = CreateFile(szDevName, GENERIC_WRITE | GENERIC_READ, + 0, 0, /* Unshared mode does nothing as this is a device */ + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + + if (hDevice != INVALID_HANDLE_VALUE)/* Check 1401 if opened */ + { + TCSBLOCK csBlock; + assert(aHand1401[nDev-1] == INVALID_HANDLE_VALUE); // assert if already open + aHand1401[nDev-1] = hDevice; /* Save handle for now */ + +#ifndef _WIN64 + // Use DIOC method if not windows 9x or if using new device name + abUseNTDIOC[nDev-1] = (BOOL)(!bWindows9x || !bOldName); +#endif + sErr = U14Status1401((short)(nDev-1), U14_TYPEOF1401, &csBlock); + if (sErr == U14ERR_NOERROR) + { + *plRetVal = csBlock.ints[0]; + if (csBlock.ints[0] == U14ERR_INUSE)/* Prevent multi opens */ + { + CloseHandle(hDevice); /* treat as open failure */ + hDevice = INVALID_HANDLE_VALUE; + aHand1401[nDev-1] = INVALID_HANDLE_VALUE; + sErr = U14ERR_INUSE; + } + else + break; /* Exit from for loop on success */ + } + else + { + CloseHandle(hDevice); /* Give up if func fails */ + hDevice = INVALID_HANDLE_VALUE; + aHand1401[nDev-1] = INVALID_HANDLE_VALUE; + } + } + else + { + DWORD dwe = GetLastError(); /* Get error code otherwise */ + if ((dwe != ERROR_FILE_NOT_FOUND) || (dwErr == 0)) + dwErr = dwe; /* Ignore repeats of 'not found' */ + } + } + + if ((hDevice == INVALID_HANDLE_VALUE) &&/* No device found, and... */ + (bWindows9x) && /* ...old names are allowed, and... */ + (bOldName == FALSE)) /* ...not tried old names yet */ + bOldName = TRUE; /* Set flag and go round again */ + else + break; /* otherwise that's all folks */ + } + + if (hDevice != INVALID_HANDLE_VALUE) /* If we got our device open */ + *psHandle = (short)(nDev-1); /* return 1401 number opened */ + else + { + if (dwErr == ERROR_FILE_NOT_FOUND) /* Sort out the error codes */ + sErr = U14ERR_NO1401DRIV; /* if file not found */ + else if (dwErr == ERROR_NOT_SUPPORTED) + sErr = U14ERR_DRIVTOOOLD; /* if DIOC not supported */ + else if (dwErr == ERROR_ACCESS_DENIED) + sErr = U14ERR_INUSE; + else + sErr = U14ERR_DRIVCOMMS; /* otherwise assume comms problem */ + } + return sErr; +} +#endif +#ifdef LINUX +static short U14TryToOpen(int n1401, long* plRetVal, short* psHandle) +{ + short sErr = U14ERR_NOERROR; + int fh = 0; // will be 1401 handle + int iErr = 0; + int nFirst, nLast, nDev = 0; // Used for the search for a 1401 + + if (n1401 == 0) // If we need to look for a 1401 + { + nFirst = 1; /* Set the search range */ + nLast = MAX1401; /* through all the possible 1401s */ + } + else + nFirst = nLast = n1401; /* Otherwise just one 1401 */ + + for (nDev = nFirst; nDev <= nLast; nDev++) + { + char szDevName[40]; // name of the device to open + sprintf(szDevName,"/dev/cedusb/%d", nDev-1); + fh = open(szDevName, O_RDWR); // can only be opened once at a time + if (fh > 0) // Check 1401 if opened + { + int iType1401 = CED_TypeOf1401(fh); // get 1401 type + aHand1401[nDev-1] = fh; // Save handle for now + if (iType1401 >= 0) + { + *plRetVal = iType1401; + break; // Exit from for loop on success + } + else + { + close(fh); // Give up if func fails + fh = 0; + aHand1401[nDev-1] = 0; + } + } + else + { + if (((errno != ENODEV) && (errno != ENOENT)) || (iErr == 0)) + iErr = errno; // Ignore repeats of 'not found' + } + } + + + if (fh) // If we got our device open + *psHandle = (short)(nDev-1); // return 1401 number opened + else + { + if ((iErr == ENODEV) || (iErr == ENOENT)) // Sort out the error codes + sErr = U14ERR_NO1401DRIV; // if file not found + else if (iErr == EBUSY) + sErr = U14ERR_INUSE; + else + sErr = U14ERR_DRIVCOMMS; // otherwise assume comms problem + } + + return sErr; +} +#endif +/**************************************************************************** +** U14Open1401 +** Tries to get the 1401 for use by this application +*****************************************************************************/ +U14API(short) U14Open1401(short n1401) +{ + long lRetVal = -1; + short sErr; + short hand = 0; + + if ((n1401 < 0) || (n1401 > MAX1401)) // must check the 1401 number + return U14ERR_BAD1401NUM; + + szLastName[0] = 0; /* initialise the error info string */ + + sErr = U14TryToOpen(n1401, &lRetVal, &hand); + if (sErr == U14ERR_NOERROR) + { + long lDriverVersion = GetDriverVersion(hand); /* get driver revision */ + long lDriverRev = -1; + if (lDriverVersion >= 0) /* can use it if all OK */ + { + lLastDriverType = (lDriverVersion >> 24) & 0x000000FF; + asDriverType[hand] = (short)lLastDriverType; /* Drv type */ + lLastDriverVersion = lDriverVersion & 0x00FFFFFF; + alDriverVersion[hand] = lLastDriverVersion; /* Actual version */ + lDriverRev = ((lDriverVersion>>16) & 0x00FF); /* use hi word */ + } + else + { + U14Close1401(hand); /* If there is a problem we should close */ + return (short)lDriverVersion; /* and return the error code */ + } + + if (lDriverRev < MINDRIVERMAJREV) /* late enough version? */ + { + U14Close1401(hand); /* If there is a problem we should close */ + return U14ERR_DRIVTOOOLD; /* too old */ + } + + asLastRetCode[hand] = U14ERR_NOERROR; /* Initialise this 1401s info */ + abGrabbed[hand] = FALSE; /* we are not in single step mode */ + U14SetTimeout(hand, 3000); /* set 3 seconds as default timeout */ + + switch (lRetVal) + { + case DRIVRET_STD: asType1401[hand] = U14TYPE1401; break; /* Some we do by hand */ + case DRIVRET_U1401:asType1401[hand] = U14TYPEU1401; break; + case DRIVRET_PLUS: asType1401[hand] = U14TYPEPLUS; break; + default: // For the power upwards, we can calculate the codes + if ((lRetVal >= DRIVRET_POWER) && (lRetVal <= DRIVRET_MAX)) + asType1401[hand] = (short)(lRetVal - (DRIVRET_POWER - U14TYPEPOWER)); + else + asType1401[hand] = U14TYPEUNKNOWN; + break; + } + U14KillIO1401(hand); /* resets the 1401 buffers */ + + if (asType1401[hand] != U14TYPEUNKNOWN) /* If all seems OK so far */ + { + sErr = U14CheckErr(hand); /* we can check 1401 comms now */ + if (sErr != 0) /* If this failed to go OK */ + U14Reset1401(hand); /* Reset the 1401 to try to sort it out */ + } + + sErr = U14StateOf1401(hand);/* Get the state of the 1401 for return */ + if (sErr == U14ERR_NOERROR) + sErr = hand; /* return the handle if no problem */ + else + U14Close1401(hand); /* If there is a problem we should close */ + } + + return sErr; +} + + +/**************************************************************************** +** U14Close1401 +** Closes the 1401 so someone else can use it. +****************************************************************************/ +U14API(short) U14Close1401(short hand) +{ + int j; + int iAreaMask = 0; // Mask for active areas + short sErr = CheckHandle(hand); + if (sErr != U14ERR_NOERROR) // Check open and in use + return sErr; + + for (j = 0; j MAXSTRLEN) + return U14ERR_STRLEN; // String too long + +#ifdef _IS_WINDOWS_ + // To get here we must wait for the buffer to have some space + lTimeOutTicks = U14WhenToTimeOut(hand); + do + { + bSpaceToSend = (BOOL)((long)U14OutBufSpace(hand) >= nChars); + } + while (!bSpaceToSend && !U14PassedTime(lTimeOutTicks)); + + if (!bSpaceToSend) /* Last-ditch attempt to avoid timeout */ + { /* This can happen with anti-virus or network activity! */ + int i; + for (i = 0; (i < 4) && (!bSpaceToSend); ++i) + { + Sleep(25); /* Give other threads a chance for a while */ + bSpaceToSend = (BOOL)((long)U14OutBufSpace(hand) >= nChars); + } + } + + if (asLastRetCode[hand] == U14ERR_NOERROR) /* no errors? */ + { + if (bSpaceToSend) + { + PARAMBLK rData; + DWORD dwBytes; + char tstr[MAXSTRLEN+5]; /* Buffer for chars */ + + if ((hand < 0) || (hand >= MAX1401)) + sErr = U14ERR_BADHAND; + else + { + strcpy(tstr, pString); /* Into local buf */ +#ifndef _WIN64 + if (!USE_NT_DIOC(hand)) /* Using WIN 95 driver access? */ + { + int iOK = DeviceIoControl(aHand1401[hand], (DWORD)U14_SENDSTRING, + NULL, 0, tstr, nChars, + &dwBytes, NULL); + if (iOK) + sErr = (dwBytes >= (DWORD)nChars) ? U14ERR_NOERROR : U14ERR_DRIVCOMMS; + else + sErr = (short)GetLastError(); + } + else +#endif + { + int iOK = DeviceIoControl(aHand1401[hand],(DWORD)U14_SENDSTRING, + tstr, nChars, + &rData,sizeof(PARAMBLK),&dwBytes,NULL); + if (iOK && (dwBytes >= sizeof(PARAMBLK))) + sErr = rData.sState; + else + sErr = U14ERR_DRIVCOMMS; + } + + if (sErr != U14ERR_NOERROR) // If we have had a comms error + U14ForceReset(hand); // make sure we get real reset + } + + return sErr; + + } + else + { + U14ForceReset(hand); // make sure we get real reset + return U14ERR_TIMEOUT; + } + } + else + return asLastRetCode[hand]; +#endif +#ifdef LINUX + // Just try to send it and see what happens! + sErr = CED_SendString(aHand1401[hand], pString, nChars); + if (sErr != U14ERR_NOOUT) // if any result except "no room in output"... + { + if (sErr != U14ERR_NOERROR) // if a problem... + U14ForceReset(hand); // ...make sure we get real reset next time + return sErr; // ... we are done as nothing we can do + } + + // To get here we must wait for the buffer to have some space + lTimeOutTicks = U14WhenToTimeOut(hand); + do + { + bSpaceToSend = (BOOL)((long)U14OutBufSpace(hand) >= nChars); + if (!bSpaceToSend) + sched_yield(); // let others have fun while we wait + } + while (!bSpaceToSend && !U14PassedTime(lTimeOutTicks)); + + if (asLastRetCode[hand] == U14ERR_NOERROR) /* no errors? */ + { + if (bSpaceToSend) + { + sErr = CED_SendString(aHand1401[hand], pString, nChars); + if (sErr != U14ERR_NOERROR) // If we have had a comms error + U14ForceReset(hand); // make sure we get real reset + return sErr; + } + else + { + U14ForceReset(hand); // make sure we get real reset + return U14ERR_TIMEOUT; + } + } + else + return asLastRetCode[hand]; +#endif +} + +/**************************************************************************** +** U14SendChar +** Send character to the 1401 +*****************************************************************************/ +U14API(short) U14SendChar(short hand, char cChar) +{ +#ifdef _IS_WINDOWS_ + char sz[2]=" "; // convert to a string and send + sz[0] = cChar; + sz[1] = 0; + return(U14SendString(hand, sz)); // String routines are better +#endif +#ifdef LINUX + short sErr = CheckHandle(hand); + return (sErr == U14ERR_NOERROR) ? CED_SendChar(aHand1401[hand], cChar) : sErr; +#endif +} + +/**************************************************************************** +** U14GetString +** Get a string from the 1401. Returns a null terminated string. +** The string is all the characters up to the next CR in the buffer +** or the end of the buffer if that comes first. This only returns text +** if there is a CR in the buffer. The terminating CR character is removed. +** wMaxLen Is the size of the buffer and must be at least 2 or an error. +** Returns U14ERR_NOERR if OK with the result in the string or a negative +** error code. Any error from the device causes us to set up for +** a full reset. +****************************************************************************/ +U14API(short) U14GetString(short hand, char* pBuffer, WORD wMaxLen) +{ + short sErr = CheckHandle(hand); + if (sErr != U14ERR_NOERROR) // If an error... + return sErr; // ...bail out! + +#ifdef _IS_WINDOWS_ + if (wMaxLen>1) // we need space for terminating 0 + { + BOOL bLineToGet; // true when a line to get + long lTimeOutTicks = U14WhenToTimeOut(hand); + do + bLineToGet = (BOOL)(U14LineCount(hand) != 0); + while (!bLineToGet && !U14PassedTime(lTimeOutTicks)); + + if (!bLineToGet) /* Last-ditch attempt to avoid timeout */ + { /* This can happen with anti-virus or network activity! */ + int i; + for (i = 0; (i < 4) && (!bLineToGet); ++i) + { + Sleep(25); /* Give other threads a chance for a while */ + bLineToGet = (BOOL)(U14LineCount(hand) != 0); + } + } + + if (bLineToGet) + { + if (asLastRetCode[hand] == U14ERR_NOERROR) /* all ok so far */ + { + DWORD dwBytes = 0; + *((WORD *)pBuffer) = wMaxLen; /* set up length */ +#ifndef _WIN64 + if (!USE_NT_DIOC(hand)) /* Win 95 DIOC here ? */ + { + char tstr[MAXSTRLEN+5]; /* Buffer for Win95 chars */ + int iOK; + + if (wMaxLen > MAXSTRLEN) /* Truncate length */ + wMaxLen = MAXSTRLEN; + + *((WORD *)tstr) = wMaxLen; /* set len */ + + iOK = DeviceIoControl(aHand1401[hand],(DWORD)U14_GETSTRING, + NULL, 0, tstr, wMaxLen+sizeof(short), + &dwBytes, NULL); + if (iOK) /* Device IO control OK ? */ + { + if (dwBytes >= 0) /* If driver OK */ + { + strcpy(pBuffer, tstr); + sErr = U14ERR_NOERROR; + } + else + sErr = U14ERR_DRIVCOMMS; + } + else + { + sErr = (short)GetLastError(); + if (sErr > 0) /* Errors are -ve */ + sErr = (short)-sErr; + } + } + else +#endif + { /* Here for NT, the DLL must own the buffer */ + HANDLE hMem = GlobalAlloc(GMEM_MOVEABLE,wMaxLen+sizeof(short)); + if (hMem) + { + char* pMem = (char*)GlobalLock(hMem); + if (pMem) + { + int iOK = DeviceIoControl(aHand1401[hand],(DWORD)U14_GETSTRING, + NULL, 0, pMem, wMaxLen+sizeof(short), + &dwBytes, NULL); + if (iOK) /* Device IO control OK ? */ + { + if (dwBytes >= wMaxLen) + { + strcpy(pBuffer, pMem+sizeof(short)); + sErr = *((SHORT*)pMem); + } + else + sErr = U14ERR_DRIVCOMMS; + } + else + sErr = U14ERR_DRIVCOMMS; + + GlobalUnlock(hMem); + } + else + sErr = U14ERR_OUTOFMEMORY; + + GlobalFree(hMem); + } + else + sErr = U14ERR_OUTOFMEMORY; + } + + if (sErr == U14ERR_NOERROR) // If all OK... + TranslateString(pBuffer); // ...convert any commas to spaces + else // If we have had a comms error... + U14ForceReset(hand); // ...make sure we get real reset + + } + else + sErr = asLastRetCode[hand]; + } + else + { + sErr = U14ERR_TIMEOUT; + U14ForceReset(hand); // make sure we get real reset + } + } + else + sErr = U14ERR_BUFF_SMALL; + return sErr; +#endif +#ifdef LINUX + if (wMaxLen>1) // we need space for terminating 0 + { + BOOL bLineToGet; // true when a line to get + long lTimeOutTicks = U14WhenToTimeOut(hand); + do + { + bLineToGet = (BOOL)(U14LineCount(hand) != 0); + if (!bLineToGet) + sched_yield(); + + } + while (!bLineToGet && !U14PassedTime(lTimeOutTicks)); + + if (bLineToGet) + { + sErr = CED_GetString(aHand1401[hand], pBuffer, wMaxLen-1); // space for terminator + if (sErr >=0) // if we were OK... + { + if (sErr >= wMaxLen) // this should NOT happen unless + sErr = U14ERR_DRIVCOMMS; // ...driver Comms are very bad + else + { + pBuffer[sErr] = 0; // OK, so terminate the string... + TranslateString(pBuffer); // ...and convert commas to spaces. + } + } + + if (sErr < U14ERR_NOERROR) // If we have had a comms error + U14ForceReset(hand); // make sure we get real reset + } + else + { + sErr = U14ERR_TIMEOUT; + U14ForceReset(hand); // make sure we get real reset + } + } + else + sErr = U14ERR_BUFF_SMALL; + + return sErr >= U14ERR_NOERROR ? U14ERR_NOERROR : sErr; +#endif +} + +/**************************************************************************** +** U14GetChar +** Get a character from the 1401. CR returned as CR. +*****************************************************************************/ +U14API(short) U14GetChar(short hand, char* pcChar) +{ +#ifdef _IS_WINDOWS_ + char sz[2]; // read a very short string + short sErr = U14GetString(hand, sz, 2); // read one char and nul terminate it + *pcChar = sz[0]; // copy to result, NB char translate done by GetString + if (sErr == U14ERR_NOERROR) + { // undo translate of CR to zero + if (*pcChar == '\0') // by converting back + *pcChar = '\n'; // What a nasty thing to have to do + } + return sErr; +#endif +#ifdef LINUX + short sErr = CheckHandle(hand); + if (sErr != U14ERR_NOERROR) // Check parameters + return sErr; + sErr = CED_GetChar(aHand1401[hand]); // get one char, if available + if (sErr >= 0) + { + *pcChar = (char)sErr; // return if it we have one + return U14ERR_NOERROR; // say all OK + } + else + return sErr; +#endif +} + +/**************************************************************************** +** U14Stat1401 +** Returns 0 for no lines or error or non zero for something waiting +****************************************************************************/ +U14API(short) U14Stat1401(short hand) +{ + return ((short)(U14LineCount(hand) > 0)); +} + +/**************************************************************************** +** U14CharCount +** Returns the number of characters in the input buffer +*****************************************************************************/ +U14API(short) U14CharCount(short hand) +{ +#ifdef _IS_WINDOWS_ + TCSBLOCK csBlock; + short sErr = U14Status1401(hand, U14_STAT1401, &csBlock); + if (sErr == U14ERR_NOERROR) + sErr = csBlock.ints[0]; + return sErr; +#endif +#ifdef LINUX + short sErr = CheckHandle(hand); + return (sErr == U14ERR_NOERROR) ? CED_Stat1401(aHand1401[hand]) : sErr; +#endif +} + +/**************************************************************************** +** U14LineCount +** Returns the number of CR characters in the input buffer +*****************************************************************************/ +U14API(short) U14LineCount(short hand) +{ +#ifdef _IS_WINDOWS_ + TCSBLOCK csBlock; + short sErr = U14Status1401(hand, U14_LINECOUNT, &csBlock); + if (sErr == U14ERR_NOERROR) + sErr = csBlock.ints[0]; + return sErr; +#endif +#ifdef LINUX + short sErr = CheckHandle(hand); + return (sErr == U14ERR_NOERROR) ? CED_LineCount(aHand1401[hand]) : sErr; +#endif +} + +/**************************************************************************** +** U14GetErrorString +** Converts error code supplied to a decent descriptive string. +** NOTE: This function may use some extra information stored +** internally in the DLL. This information is stored on a +** per-process basis, but it might be altered if you call +** other functions after getting an error and before using +** this function. +****************************************************************************/ +U14API(void) U14GetErrorString(short nErr, char* pStr, WORD wMax) +{ + char wstr[150]; + + switch (nErr) /* Basically, we do this with a switch block */ + { + case U14ERR_OFF: + sprintf(wstr, "The 1401 is apparently switched off (code %d)", nErr); + break; + + case U14ERR_NC: + sprintf(wstr, "The 1401 is not connected to the interface card (code %d)", nErr); + break; + + case U14ERR_ILL: + sprintf(wstr, "The 1401 is not working correctly (code %d)", nErr); + break; + + case U14ERR_NOIF: + sprintf(wstr, "The 1401 interface card was not detected (code %d)", nErr); + break; + + case U14ERR_TIME: + sprintf(wstr, "The 1401 fails to become ready for use (code %d)", nErr); + break; + + case U14ERR_BADSW: + sprintf(wstr, "The 1401 interface card jumpers are incorrect (code %d)", nErr); + break; + + case U14ERR_NOINT: + sprintf(wstr, "The 1401 interrupt is not available for use (code %d)", nErr); + break; + + case U14ERR_INUSE: + sprintf(wstr, "The 1401 is already in use by another program (code %d)", nErr); + break; + + case U14ERR_NODMA: + sprintf(wstr, "The 1401 DMA channel is not available for use (code %d)", nErr); + break; + + case U14ERR_BADHAND: + sprintf(wstr, "The application supplied an incorrect 1401 handle (code %d)", nErr); + break; + + case U14ERR_BAD1401NUM: + sprintf(wstr, "The application used an incorrect 1401 number (code %d)", nErr); + break; + + case U14ERR_NO_SUCH_FN: + sprintf(wstr, "The code passed to the 1401 driver is invalid (code %d)", nErr); + break; + + case U14ERR_NO_SUCH_SUBFN: + sprintf(wstr, "The sub-code passed to the 1401 driver is invalid (code %d)", nErr); + break; + + case U14ERR_NOOUT: + sprintf(wstr, "No room in buffer for characters for the 1401 (code %d)", nErr); + break; + + case U14ERR_NOIN: + sprintf(wstr, "No characters from the 1401 are available (code %d)", nErr); + break; + + case U14ERR_STRLEN: + sprintf(wstr, "A string sent to or read from the 1401 was too long (code %d)", nErr); + break; + + case U14ERR_LOCKFAIL: + sprintf(wstr, "Failed to lock host memory for data transfer (code %d)", nErr); + break; + + case U14ERR_UNLOCKFAIL: + sprintf(wstr, "Failed to unlock host memory after data transfer (code %d)", nErr); + break; + + case U14ERR_ALREADYSET: + sprintf(wstr, "The transfer area used is already set up (code %d)", nErr); + break; + + case U14ERR_NOTSET: + sprintf(wstr, "The transfer area used has not been set up (code %d)", nErr); + break; + + case U14ERR_BADAREA: + sprintf(wstr, "The transfer area number is incorrect (code %d)", nErr); + break; + + case U14ERR_NOFILE: + sprintf(wstr, "The command file %s could not be opened (code %d)", szLastName, nErr); + break; + + case U14ERR_READERR: + sprintf(wstr, "The command file %s could not be read (code %d)", szLastName, nErr); + break; + + case U14ERR_UNKNOWN: + sprintf(wstr, "The %s command resource could not be found (code %d)", szLastName, nErr); + break; + + case U14ERR_HOSTSPACE: + sprintf(wstr, "Unable to allocate memory for loading command %s (code %d)", szLastName, nErr); + break; + + case U14ERR_LOCKERR: + sprintf(wstr, "Unable to lock memory for loading command %s (code %d)", szLastName, nErr); + break; + + case U14ERR_CLOADERR: + sprintf(wstr, "Error in loading command %s, bad command format (code %d)", szLastName, nErr); + break; + + case U14ERR_TOXXXERR: + sprintf(wstr, "Error detected after data transfer to or from the 1401 (code %d)", nErr); + break; + + case U14ERR_NO386ENH: + sprintf(wstr, "Windows 3.1 is not running in 386 enhanced mode (code %d)", nErr); + break; + + case U14ERR_NO1401DRIV: + sprintf(wstr, "The 1401 device driver cannot be found (code %d)\nUSB: check plugged in and powered\nOther: not installed?", nErr); + break; + + case U14ERR_DRIVTOOOLD: + sprintf(wstr, "The 1401 device driver is too old for use (code %d)", nErr); + break; + + case U14ERR_TIMEOUT: + sprintf(wstr, "Character transmissions to the 1401 timed-out (code %d)", nErr); + break; + + case U14ERR_BUFF_SMALL: + sprintf(wstr, "Buffer for text from the 1401 was too small (code %d)", nErr); + break; + + case U14ERR_CBALREADY: + sprintf(wstr, "1401 monitor callback already set up (code %d)", nErr); + break; + + case U14ERR_BADDEREG: + sprintf(wstr, "1401 monitor callback deregister invalid (code %d)", nErr); + break; + + case U14ERR_DRIVCOMMS: + sprintf(wstr, "1401 device driver communications failed (code %d)", nErr); + break; + + case U14ERR_OUTOFMEMORY: + sprintf(wstr, "Failed to allocate or lock memory for text from the 1401 (code %d)", nErr); + break; + + default: + sprintf(wstr, "1401 error code %d returned; this code is unknown", nErr); + break; + + } + if ((WORD)strlen(wstr) >= wMax-1) /* Check for string being too long */ + wstr[wMax-1] = 0; /* and truncate it if so */ + strcpy(pStr, wstr); /* Return the error string */ +} + +/*************************************************************************** +** U14GetTransfer +** Get a TGET_TX_BLOCK describing a transfer area (held in the block) +***************************************************************************/ +U14API(short) U14GetTransfer(short hand, TGET_TX_BLOCK *pTransBlock) +{ + short sErr = CheckHandle(hand); +#ifdef _IS_WINDOWS_ + if (sErr == U14ERR_NOERROR) + { + DWORD dwBytes = 0; + BOOL bOK = DeviceIoControl(aHand1401[hand], (DWORD)U14_GETTRANSFER, NULL, 0, pTransBlock, + sizeof(TGET_TX_BLOCK), &dwBytes, NULL); + + if (bOK && (dwBytes >= sizeof(TGET_TX_BLOCK))) + sErr = U14ERR_NOERROR; + else + sErr = U14ERR_DRIVCOMMS; + } + return sErr; +#endif +#ifdef LINUX + return (sErr == U14ERR_NOERROR) ? CED_GetTransfer(aHand1401[hand], pTransBlock) : sErr; +#endif +} +///////////////////////////////////////////////////////////////////////////// +// U14WorkingSet +// For Win32 only, adjusts process working set so that minimum is at least +// dwMinKb and maximum is at least dwMaxKb. +// Return value is zero if all went OK, or a code from 1 to 3 indicating the +// cause of the failure: +// +// 1 unable to access process (insufficient rights?) +// 2 unable to read process working set +// 3 unable to set process working set - bad parameters? +U14API(short) U14WorkingSet(DWORD dwMinKb, DWORD dwMaxKb) +{ +#ifdef _IS_WINDOWS_ + short sRetVal = 0; // 0 means all is OK + HANDLE hProcess; + DWORD dwVer = GetVersion(); + if (dwVer & 0x80000000) // is this not NT? + return 0; // then give up right now + + // Now attempt to get information on working set size + hProcess = OpenProcess(STANDARD_RIGHTS_REQUIRED | + PROCESS_QUERY_INFORMATION | + PROCESS_SET_QUOTA, + FALSE, _getpid()); + if (hProcess) + { + SIZE_T dwMinSize,dwMaxSize; + if (GetProcessWorkingSetSize(hProcess, &dwMinSize, &dwMaxSize)) + { + DWORD dwMin = dwMinKb << 10; // convert from kb to bytes + DWORD dwMax = dwMaxKb << 10; + + // if we get here, we have managed to read the current size + if (dwMin > dwMinSize) // need to change sizes? + dwMinSize = dwMin; + + if (dwMax > dwMaxSize) + dwMaxSize = dwMax; + + if (!SetProcessWorkingSetSize(hProcess, dwMinSize, dwMaxSize)) + sRetVal = 3; // failed to change size + } + else + sRetVal = 2; // failed to read original size + + CloseHandle(hProcess); + } + else + sRetVal = 1; // failed to get handle + + return sRetVal; +#endif +#ifdef LINUX + if (dwMinKb | dwMaxKb) + { + // to stop compiler moaning + } + return U14ERR_NOERROR; +#endif +} + +/**************************************************************************** +** U14UnSetTransfer Cancels a transfer area +** wArea The index of a block previously used in by SetTransfer +*****************************************************************************/ +U14API(short) U14UnSetTransfer(short hand, WORD wArea) +{ + short sErr = CheckHandle(hand); +#ifdef _IS_WINDOWS_ + if (sErr == U14ERR_NOERROR) + { + TCSBLOCK csBlock; + csBlock.ints[0] = (short)wArea; /* Area number into control block */ + sErr = U14Control1401(hand, U14_UNSETTRANSFER, &csBlock); /* Free area */ + + VirtualUnlock(apAreas[hand][wArea], auAreas[hand][wArea]);/* Unlock */ + apAreas[hand][wArea] = NULL; /* Clear locations */ + auAreas[hand][wArea] = 0; + } + return sErr; +#endif +#ifdef LINUX + return (sErr == U14ERR_NOERROR) ? CED_UnsetTransfer(aHand1401[hand], wArea) : sErr; +#endif +} + +/**************************************************************************** +** U14SetTransArea Sets an area up to be used for transfers +** WORD wArea The area number to set up +** void *pvBuff The address of the buffer for the data. +** DWORD dwLength The length of the buffer for the data +** short eSz The element size (used for byte swapping on the Mac) +****************************************************************************/ +U14API(short) U14SetTransArea(short hand, WORD wArea, void *pvBuff, + DWORD dwLength, short eSz) +{ + TRANSFERDESC td; + short sErr = CheckHandle(hand); + if (sErr != U14ERR_NOERROR) + return sErr; + if (wArea >= MAX_TRANSAREAS) // Is this a valid area number + return U14ERR_BADAREA; + +#ifdef _IS_WINDOWS_ + assert(apAreas[hand][wArea] == NULL); + assert(auAreas[hand][wArea] == 0); + + apAreas[hand][wArea] = pvBuff; /* Save data for later */ + auAreas[hand][wArea] = dwLength; + + if (!VirtualLock(pvBuff, dwLength)) /* Lock using WIN32 calls */ + { + apAreas[hand][wArea] = NULL; /* Clear locations */ + auAreas[hand][wArea] = 0; + return U14ERR_LOCKERR; /* VirtualLock failed */ + } +#ifndef _WIN64 + if (!USE_NT_DIOC(hand)) /* Use Win 9x DIOC? */ + { + DWORD dwBytes; + VXTRANSFERDESC vxDesc; /* Structure to pass to VXD */ + vxDesc.wArea = wArea; /* Copy across simple params */ + vxDesc.dwLength = dwLength; + + // Check we are not asking an old driver for more than area 0 + if ((wArea != 0) && (U14DriverVersion(hand) < 0x00010002L)) + sErr = U14ERR_DRIVTOOOLD; + else + { + vxDesc.dwAddrOfs = (DWORD)pvBuff; /* 32 bit offset */ + vxDesc.wAddrSel = 0; + + if (DeviceIoControl(aHand1401[hand], (DWORD)U14_SETTRANSFER, + pvBuff,dwLength, /* Will translate pointer */ + &vxDesc,sizeof(VXTRANSFERDESC), + &dwBytes,NULL)) + { + if (dwBytes >= sizeof(VXTRANSFERDESC)) /* Driver OK ? */ + sErr = U14ERR_NOERROR; + else + sErr = U14ERR_DRIVCOMMS; /* Else never got there */ + } + else + sErr = (short)GetLastError(); + } + } + else +#endif + { + PARAMBLK rWork; + DWORD dwBytes; + td.wArea = wArea; /* Pure NT - put data into struct */ + td.lpvBuff = pvBuff; + td.dwLength = dwLength; + td.eSize = 0; // Dummy element size + + if (DeviceIoControl(aHand1401[hand],(DWORD)U14_SETTRANSFER, + &td,sizeof(TRANSFERDESC), + &rWork,sizeof(PARAMBLK),&dwBytes,NULL)) + { + if (dwBytes >= sizeof(PARAMBLK)) // maybe error from driver? + sErr = rWork.sState; // will report any error + else + sErr = U14ERR_DRIVCOMMS; // Else never got there + } + else + sErr = U14ERR_DRIVCOMMS; + } + + if (sErr != U14ERR_NOERROR) + { + if (sErr != U14ERR_LOCKERR) // unless lock failed... + VirtualUnlock(pvBuff, dwLength); // ...release the lock + apAreas[hand][wArea] = NULL; // Clear locations + auAreas[hand][wArea] = 0; + } + + return sErr; +#endif +#ifdef LINUX + // The strange cast is so that it works in 64 and 32-bit linux as long is 64-bits + // in the 64 bit version. + td.lpvBuff = (long long)((unsigned long)pvBuff); + td.wAreaNum = wArea; + td.dwLength = dwLength; + td.eSize = eSz; // Dummy element size + return CED_SetTransfer(aHand1401[hand], &td); +#endif +} + +/**************************************************************************** +** U14SetTransferEvent Sets an event for notification of application +** wArea The tranfer area index, from 0 to MAXAREAS-1 +** bEvent True to create an event, false to remove it +** bToHost Set 0 for notification on to1401 tranfers, 1 for +** notification of transfers to the host PC +** dwStart The offset of the sub-area of interest +** dwLength The size of the sub-area of interest +** +** The device driver will set the event supplied to the signalled state +** whenever a DMA transfer to/from the specified area is completed. The +** transfer has to be in the direction specified by bToHost, and overlap +** that part of the whole transfer area specified by dwStart and dwLength. +** It is important that this function is called with bEvent false to release +** the event once 1401 activity is finished. +** +** Returns 1 if an event handle exists, 0 if all OK and no event handle or +** a negative code for an error. +****************************************************************************/ +U14API(short) U14SetTransferEvent(short hand, WORD wArea, BOOL bEvent, + BOOL bToHost, DWORD dwStart, DWORD dwLength) +{ +#ifdef _IS_WINDOWS_ + TCSBLOCK csBlock; + short sErr = U14TransferFlags(hand); // see if we can handle events + if (sErr >= U14ERR_NOERROR) // check handle is OK + { + bEvent = bEvent && ((sErr & U14TF_NOTIFY) != 0); // remove request if we cannot do events + if (wArea >= MAX_TRANSAREAS) // Check a valid area... + return U14ERR_BADAREA; // ...and bail of not + + // We can hold an event for each area, so see if we need to change the + // state of the event. + if ((bEvent != 0) != (aXferEvent[hand] != 0)) // change of event state? + { + if (bEvent) // want one and none present + aXferEvent[hand] = CreateEvent(NULL, FALSE, FALSE, NULL); + else + { + CloseHandle(aXferEvent[hand]); // clear the existing event + aXferEvent[hand] = NULL; // and clear handle + } + } + + // We have to store the parameters differently for 64-bit operations + // because a handle is 64 bits long. The drivers know of this and + // handle the information appropriately. +#ifdef _WIN64 + csBlock.longs[0] = wArea; // Pass paramaters into the driver... + if (bToHost != 0) // The direction flag is held in the + csBlock.longs[0] |= 0x10000; // upper word of the transfer area value + *((HANDLE*)&csBlock.longs[1]) = aXferEvent[hand]; // The event handle is 64-bits + csBlock.longs[3] = dwStart; // Thankfully these two remain + csBlock.longs[4] = dwLength; // as unsigned 32-bit values +#else + csBlock.longs[0] = wArea; // pass paramaters into the driver... + csBlock.longs[1] = (long)aXferEvent[hand]; // ...especially the event handle + csBlock.longs[2] = bToHost; + csBlock.longs[3] = dwStart; + csBlock.longs[4] = dwLength; +#endif + sErr = U14Control1401(hand, U14_SETTRANSEVENT, &csBlock); + if (sErr == U14ERR_NOERROR) + sErr = (short)(aXferEvent[hand] != NULL); // report if we have a flag + } + + return sErr; +#endif +#ifdef LINUX + TRANSFEREVENT te; + short sErr = CheckHandle(hand); + if (sErr != U14ERR_NOERROR) + return sErr; + + if (wArea >= MAX_TRANSAREAS) // Is this a valid area number + return U14ERR_BADAREA; + + te.wAreaNum = wArea; // copy parameters to the control block + te.wFlags = bToHost ? 1 : 0; // bit 0 sets the direction + te.dwStart = dwStart; // start offset of the event area + te.dwLength = dwLength; // size of the event area + te.iSetEvent = bEvent; // in Windows, this creates/destroys the event + return CED_SetEvent(aHand1401[hand], &te); +#endif +} + +/**************************************************************************** +** U14TestTransferEvent +** Would a U14WaitTransferEvent() call return immediately? return 1 if so, +** 0 if not or a negative code if a problem. +****************************************************************************/ +U14API(int) U14TestTransferEvent(short hand, WORD wArea) +{ +#ifdef _IS_WINDOWS_ + int iErr = CheckHandle(hand); + if (iErr == U14ERR_NOERROR) + { + if (aXferEvent[hand]) // if a handle is set... + iErr = WaitForSingleObject(aXferEvent[hand], 0) == WAIT_OBJECT_0; + } + return iErr; +#endif +#ifdef LINUX + short sErr = CheckHandle(hand); + return (sErr == U14ERR_NOERROR) ? CED_TestEvent(aHand1401[hand], wArea) : sErr; +#endif +} + +/**************************************************************************** +** U14WaitTransferEvent +** Wait for a transfer event with a timeout. +** msTimeOut is 0 for an infinite wait, else it is the maximum time to wait +** in milliseconds in range 0-0x00ffffff. +** Returns If no event handle then return immediately. Else return 1 if +** timed out or 0=event, and a negative code if a problem. +****************************************************************************/ +U14API(int) U14WaitTransferEvent(short hand, WORD wArea, int msTimeOut) +{ +#ifdef _IS_WINDOWS_ + int iErr = CheckHandle(hand); + if (iErr == U14ERR_NOERROR) + { + if (aXferEvent[hand]) + { + if (msTimeOut == 0) + msTimeOut = INFINITE; + iErr = WaitForSingleObject(aXferEvent[hand], msTimeOut) != WAIT_OBJECT_0; + } + else + iErr = TRUE; // say we timed out if no event + } + return iErr; +#endif +#ifdef LINUX + short sErr = CheckHandle(hand); + return (sErr == U14ERR_NOERROR) ? CED_WaitEvent(aHand1401[hand], wArea, msTimeOut) : sErr; +#endif +} + +/**************************************************************************** +** U14SetCircular Sets an area up for circular DMA transfers +** WORD wArea The area number to set up +** BOOL bToHost Sets the direction of data transfer +** void *pvBuff The address of the buffer for the data +** DWORD dwLength The length of the buffer for the data +****************************************************************************/ +U14API(short) U14SetCircular(short hand, WORD wArea, BOOL bToHost, + void *pvBuff, DWORD dwLength) +{ + short sErr = CheckHandle(hand); + if (sErr != U14ERR_NOERROR) + return sErr; + + if (wArea >= MAX_TRANSAREAS) /* Is this a valid area number */ + return U14ERR_BADAREA; + + if (!bToHost) /* For now, support tohost transfers only */ + return U14ERR_BADAREA; /* best error code I can find */ +#ifdef _IS_WINDOWS_ + assert(apAreas[hand][wArea] == NULL); + assert(auAreas[hand][wArea] == 0); + + apAreas[hand][wArea] = pvBuff; /* Save data for later */ + auAreas[hand][wArea] = dwLength; + + if (!VirtualLock(pvBuff, dwLength)) /* Lock using WIN32 calls */ + sErr = U14ERR_LOCKERR; /* VirtualLock failed */ + else + { + PARAMBLK rWork; + DWORD dwBytes; + TRANSFERDESC txDesc; + txDesc.wArea = wArea; /* Pure NT - put data into struct */ + txDesc.lpvBuff = pvBuff; + txDesc.dwLength = dwLength; + txDesc.eSize = (short)bToHost; /* Use this for direction flag */ + + if (DeviceIoControl(aHand1401[hand],(DWORD)U14_SETCIRCULAR, + &txDesc, sizeof(TRANSFERDESC), + &rWork, sizeof(PARAMBLK),&dwBytes,NULL)) + { + if (dwBytes >= sizeof(PARAMBLK)) /* error from driver? */ + sErr = rWork.sState; /* No, just return driver data */ + else + sErr = U14ERR_DRIVCOMMS; /* Else never got there */ + } + else + sErr = U14ERR_DRIVCOMMS; + } + + if (sErr != U14ERR_NOERROR) + { + if (sErr != U14ERR_LOCKERR) + VirtualUnlock(pvBuff, dwLength); /* Release NT lock */ + apAreas[hand][wArea] = NULL; /* Clear locations */ + auAreas[hand][wArea] = 0; + } + + return sErr; +#endif +#ifdef LINUX + else + { + TRANSFERDESC td; + td.lpvBuff = (long long)((unsigned long)pvBuff); + td.wAreaNum = wArea; + td.dwLength = dwLength; + td.eSize = (short)bToHost; /* Use this for direction flag */ + return CED_SetCircular(aHand1401[hand], &td); + } +#endif +} + +/**************************************************************************** +** Function GetCircBlk returns the size (& start offset) of the next +** available block of circular data. +****************************************************************************/ +U14API(int) U14GetCircBlk(short hand, WORD wArea, DWORD *pdwOffs) +{ + int lErr = CheckHandle(hand); + if (lErr != U14ERR_NOERROR) + return lErr; + + if (wArea >= MAX_TRANSAREAS) // Is this a valid area number? + return U14ERR_BADAREA; + else + { +#ifdef _IS_WINDOWS_ + PARAMBLK rWork; + TCSBLOCK csBlock; + DWORD dwBytes; + csBlock.longs[0] = wArea; // Area number into control block + rWork.sState = U14ERR_DRIVCOMMS; + if (DeviceIoControl(aHand1401[hand], (DWORD)U14_GETCIRCBLK, &csBlock, sizeof(TCSBLOCK), &rWork, sizeof(PARAMBLK), &dwBytes, NULL) && + (dwBytes >= sizeof(PARAMBLK))) + lErr = rWork.sState; + else + lErr = U14ERR_DRIVCOMMS; + + if (lErr == U14ERR_NOERROR) // Did everything go OK? + { // Yes, we can pass the results back + lErr = rWork.csBlock.longs[1]; // Return the block information + *pdwOffs = rWork.csBlock.longs[0]; // Offset is first in array + } +#endif +#ifdef LINUX + TCIRCBLOCK cb; + cb.nArea = wArea; // Area number into control block + cb.dwOffset = 0; + cb.dwSize = 0; + lErr = CED_GetCircBlock(aHand1401[hand], &cb); + if (lErr == U14ERR_NOERROR) // Did everything go OK? + { // Yes, we can pass the results back + lErr = cb.dwSize; // return the size + *pdwOffs = cb.dwOffset; // and the offset + } +#endif + } + return lErr; +} + +/**************************************************************************** +** Function FreeCircBlk marks the specified area of memory as free for +** resuse for circular transfers and returns the size (& start +** offset) of the next available block of circular data. +****************************************************************************/ +U14API(int) U14FreeCircBlk(short hand, WORD wArea, DWORD dwOffs, DWORD dwSize, + DWORD *pdwOffs) +{ + int lErr = CheckHandle(hand); + if (lErr != U14ERR_NOERROR) + return lErr; + + if (wArea < MAX_TRANSAREAS) // Is this a valid area number + { +#ifdef _IS_WINDOWS_ + PARAMBLK rWork; + TCSBLOCK csBlock; + DWORD dwBytes; + csBlock.longs[0] = wArea; // Area number into control block + csBlock.longs[1] = dwOffs; + csBlock.longs[2] = dwSize; + rWork.sState = U14ERR_DRIVCOMMS; + if (DeviceIoControl(aHand1401[hand], (DWORD)U14_FREECIRCBLK, &csBlock, sizeof(TCSBLOCK), + &rWork, sizeof(PARAMBLK), &dwBytes, NULL) && + (dwBytes >= sizeof(PARAMBLK))) + lErr = rWork.sState; + else + lErr = U14ERR_DRIVCOMMS; + if (lErr == U14ERR_NOERROR) // Did everything work OK? + { // Yes, we can pass the results back + lErr = rWork.csBlock.longs[1]; // Return the block information + *pdwOffs = rWork.csBlock.longs[0]; // Offset is first in array + } +#endif +#ifdef LINUX + TCIRCBLOCK cb; + cb.nArea = wArea; // Area number into control block + cb.dwOffset = dwOffs; + cb.dwSize = dwSize; + + lErr = CED_FreeCircBlock(aHand1401[hand], &cb); + if (lErr == U14ERR_NOERROR) // Did everything work OK? + { // Yes, we can pass the results back + lErr = cb.dwSize; // Return the block information + *pdwOffs = cb.dwOffset; // Offset is first in array + } +#endif + } + else + lErr = U14ERR_BADAREA; + + return lErr; +} + +/**************************************************************************** +** Transfer +** Transfer moves data to 1401 or to host +** Assumes memory is allocated and locked, +** which it should be to get a pointer +*****************************************************************************/ +static short Transfer(short hand, BOOL bTo1401, char* pData, + DWORD dwSize, DWORD dw1401, short eSz) +{ + char strcopy[MAXSTRLEN+1]; // to hold copy of work string + short sResult = U14SetTransArea(hand, 0, (void *)pData, dwSize, eSz); + if (sResult == U14ERR_NOERROR) // no error + { + sprintf(strcopy, // data offset is always 0 + "TO%s,$%X,$%X,0;", bTo1401 ? "1401" : "HOST", dw1401, dwSize); + + U14SendString(hand, strcopy); // send transfer string + + sResult = U14CheckErr(hand); // Use ERR command to check for done + if (sResult > 0) + sResult = U14ERR_TOXXXERR; // If a 1401 error, use this code + + U14UnSetTransfer(hand, 0); + } + return sResult; +} + +/**************************************************************************** +** Function ToHost transfers data into the host from the 1401 +****************************************************************************/ +U14API(short) U14ToHost(short hand, char* pAddrHost, DWORD dwSize, + DWORD dw1401, short eSz) +{ + short sErr = CheckHandle(hand); + if ((sErr == U14ERR_NOERROR) && dwSize) // TOHOST is a constant + sErr = Transfer(hand, TOHOST, pAddrHost, dwSize, dw1401, eSz); + return sErr; +} + +/**************************************************************************** +** Function To1401 transfers data into the 1401 from the host +****************************************************************************/ +U14API(short) U14To1401(short hand, const char* pAddrHost,DWORD dwSize, + DWORD dw1401, short eSz) +{ + short sErr = CheckHandle(hand); + if ((sErr == U14ERR_NOERROR) && dwSize) // TO1401 is a constant + sErr = Transfer(hand, TO1401, (char*)pAddrHost, dwSize, dw1401, eSz); + return sErr; +} + +/**************************************************************************** +** Function LdCmd Loads a command from a full path or just a file +*****************************************************************************/ +#ifdef _IS_WINDOWS_ +#define file_exist(name) (_access(name, 0) != -1) +#define file_open(name) _lopen(name, OF_READ) +#define file_close(h) _lclose(h) +#define file_seek(h, pos) _llseek(h, pos, FILE_BEGIN) +#define file_read(h, buffer, size) (_lread(h, buffer, size) == size) +#endif +#ifdef LINUX +#define file_exist(name) (access(name, F_OK) != -1) +#define file_open(name) open(name, O_RDONLY) +#define file_close(h) close(h) +#define file_seek(h, pos) lseek(h, pos, SEEK_SET) +#define file_read(h, buffer, size) (read(h, buffer, size) == (ssize_t)size) +static DWORD GetModuleFileName(void* dummy, char* buffer, int max) +{ + // The following works for Linux systems with a /proc file system. + char szProcPath[32]; + sprintf(szProcPath, "/proc/%d/exe", getpid()); // attempt to read link + if (readlink(szProcPath, buffer, max) != -1) + { + dirname (buffer); + strcat (buffer, "/"); + return strlen(buffer); + } + return 0; +} +#endif + +U14API(short) U14LdCmd(short hand, const char* command) +{ + char strcopy[MAXSTRLEN+1]; // to hold copy of work string + BOOL bGotIt = FALSE; // have we found the command file? + int iFHandle; // file handle of command +#define FNSZ 260 + char filnam[FNSZ]; // space to build name in + char szCmd[25]; // just the command name with extension + + short sErr = CheckHandle(hand); + if (sErr != U14ERR_NOERROR) + return sErr; + + if (strchr(command, '.') != NULL) // see if we have full name + { + if (file_exist(command)) // If the file exists + { + strcpy(filnam, command); // use name as is + bGotIt = TRUE; // Flag no more searching + } + else // not found, get file name for search + { + char* pStr = strrchr(command, PATHSEP); // Point to last separator + if (pStr != NULL) // Check we got it + { + pStr++; // move past the backslash + strcpy(szCmd, pStr); // copy file name as is + } + else + strcpy(szCmd, command); // use as is + } + } + else // File extension not supplied, so build the command file name + { + char szExt[8]; + strcpy(szCmd, command); // Build command file name + ExtForType(asType1401[hand], szExt);// File extension string + strcat(szCmd, szExt); // add it to the end + } + + // Next place to look is in the 1401 folder in the same place as the + // application was run from. + if (!bGotIt) // Still not got it? + { + DWORD dwLen = GetModuleFileName(NULL, filnam, FNSZ); // Get app path + if (dwLen > 0) // and use it as path if found + { + char* pStr = strrchr(filnam, PATHSEP); // Point to last separator + if (pStr != NULL) + { + *(++pStr) = 0; // Terminate string there + if (strlen(filnam) < FNSZ-6) // make sure we have space + { + strcat(filnam, "1401" PATHSEPSTR); // add in 1401 subdir + strcat(filnam,szCmd); + bGotIt = (BOOL)file_exist(filnam); // See if file exists + } + } + } + } + + // Next place to look is in whatever path is set by the 1401DIR environment + // variable, if it exists. + if (!bGotIt) // Need to do more searches?/ + { + char* pStr = getenv("1401DIR"); // Try to find environment var + if (pStr != NULL) // and use it as path if found + { + strcpy(filnam, pStr); // Use path in environment + if (filnam[strlen(filnam)-1] != PATHSEP)// We need separator + strcat(filnam, PATHSEPSTR); + strcat(filnam, szCmd); + bGotIt = (BOOL)file_exist(filnam); // Got this one? + } + } + + // Last place to look is the default location. + if (!bGotIt) // Need to do more searches? + { + strcpy(filnam, DEFCMDPATH); // Use default path + strcat(filnam, szCmd); + bGotIt = file_exist(filnam); // Got this one? + } + + iFHandle = file_open(filnam); + if (iFHandle == -1) + sErr = U14ERR_NOFILE; + else + { // first read in the header block + CMDHEAD rCmdHead; // to hold the command header + if (file_read(iFHandle, &rCmdHead, sizeof(CMDHEAD))) + { + size_t nComSize = rCmdHead.wCmdSize; + char* pMem = malloc(nComSize); + if (pMem != NULL) + { + file_seek(iFHandle, sizeof(CMDHEAD)); + if (file_read(iFHandle, pMem, (UINT)nComSize)) + { + sErr = U14SetTransArea(hand, 0, (void *)pMem, (DWORD)nComSize, ESZBYTES); + if (sErr == U14ERR_NOERROR) + { + sprintf(strcopy, "CLOAD,0,$%X;", (int)nComSize); + sErr = U14SendString(hand, strcopy); + if (sErr == U14ERR_NOERROR) + { + sErr = U14CheckErr(hand); // Use ERR to check for done + if (sErr > 0) + sErr = U14ERR_CLOADERR; // If an error, this code + } + U14UnSetTransfer(hand, 0); // release transfer area + } + } + else + sErr = U14ERR_READERR; + free(pMem); + } + else + sErr = U14ERR_HOSTSPACE; // memory allocate failed + } + else + sErr = U14ERR_READERR; + + file_close(iFHandle); // close the file + } + + return sErr; +} + + +/**************************************************************************** +** Ld +** Loads a command into the 1401 +** Returns NOERROR code or a long with error in lo word and index of +** command that failed in high word +****************************************************************************/ +U14API(DWORD) U14Ld(short hand, const char* vl, const char* str) +{ + DWORD dwIndex = 0; // index to current command + long lErr = U14ERR_NOERROR; // what the error was that went wrong + char strcopy[MAXSTRLEN+1]; // stores unmodified str parameter + char szFExt[8]; // The command file extension + short sErr = CheckHandle(hand); + if (sErr != U14ERR_NOERROR) + return sErr; + + ExtForType(asType1401[hand], szFExt); // File extension string + strcpy(strcopy, str); // to avoid changing original + + // now break out one command at a time and see if loaded + if (*str) // if anything there + { + BOOL bDone = FALSE; // true when finished all commands + int iLoop1 = 0; // Point at start of string for command name + int iLoop2 = 0; // and at start of str parameter + do // repeat until end of str + { + char filnam[MAXSTRLEN+1]; // filename to use + char szFName[MAXSTRLEN+1]; // filename work string + + if (!strcopy[iLoop1]) // at the end of the string? + bDone = TRUE; // set the finish flag + + if (bDone || (strcopy[iLoop1] == ',')) // end of cmd? + { + U14LONG er[5]; // Used to read back error results + ++dwIndex; // Keep count of command number, first is 1 + szFName[iLoop2]=(char)0; // null terminate name of command + + strncpy(szLastName, szFName, sizeof(szLastName)); // Save for error info + szLastName[sizeof(szLastName)-1] = 0; + strncat(szLastName, szFExt, sizeof(szLastName)); // with extension included + szLastName[sizeof(szLastName)-1] = 0; + + U14SendString(hand, szFName); // ask if loaded + U14SendString(hand, ";ERR;"); // add err return + + lErr = U14LongsFrom1401(hand, er, 5); + if (lErr > 0) + { + lErr = U14ERR_NOERROR; + if (er[0] == 255) // if command not loaded at all + { + if (vl && *vl) // if we have a path name + { + strcpy(filnam, vl); + if (strchr("\\/:", filnam[strlen(filnam)-1]) == NULL) + strcat(filnam, PATHSEPSTR); // add separator if none found + strcat(filnam, szFName); // add the file name + strcat(filnam, szFExt); // and extension + } + else + strcpy(filnam, szFName); // simple name + + lErr = U14LdCmd(hand, filnam); // load cmd + if (lErr != U14ERR_NOERROR) // spot any errors + bDone = TRUE; // give up if an error + } + } + else + bDone = TRUE; // give up if an error + + iLoop2 = 0; // Reset pointer to command name string + ++iLoop1; // and move on through str parameter + } + else + szFName[iLoop2++] = strcopy[iLoop1++]; // no command end, so copy 1 char + } + while (!bDone); + } + + if (lErr == U14ERR_NOERROR) + { + szLastName[0] = 0; // No error, so clean out command name here + return lErr; + } + else + return ((dwIndex<<16) | ((DWORD)lErr & 0x0000FFFF)); +} + +// Initialise the library (if not initialised) and return the library version +U14API(int) U14InitLib(void) +{ + int iRetVal = U14LIB_VERSION; + if (iAttached == 0) // only do this the first time please + { + int i; +#ifdef _IS_WINDOWS_ + int j; + DWORD dwVersion = GetVersion(); + bWindows9x = FALSE; // Assume not Win9x + + if (dwVersion & 0x80000000) // if not windows NT + { + if ((LOBYTE(LOWORD(dwVersion)) < 4) && // if Win32s or... + (HIBYTE(LOWORD(dwVersion)) < 95)) // ...below Windows 95 + iRetVal = 0; // We do not support this + else + bWindows9x = TRUE; // Flag we have Win9x + } +#endif + + for (i = 0; i < MAX1401; i++) // initialise the device area + { + aHand1401[i] = INVALID_HANDLE_VALUE; // Clear handle values + asType1401[i] = U14TYPEUNKNOWN; // and 1401 type codes + alTimeOutPeriod[i] = 3000; // 3 second timeouts +#ifdef _IS_WINDOWS_ +#ifndef _WIN64 + abUseNTDIOC[i] = (BOOL)!bWindows9x; +#endif + aXferEvent[i] = NULL; // there are no Xfer events + for (j = 0; j < MAX_TRANSAREAS; j++) // Clear out locked area info + { + apAreas[i][j] = NULL; + auAreas[i][j] = 0; + } +#endif + } + } + return iRetVal; +} + +///-------------------------------------------------------------------------------- +/// Functions called when the library is loaded and unloaded to give us a chance to +/// setup the library. + + +#ifdef _IS_WINDOWS_ +#ifndef U14_NOT_DLL +/**************************************************************************** +** FUNCTION: DllMain(HANDLE, DWORD, LPVOID) +** LibMain is called by Windows when the DLL is initialized, Thread Attached, +** and other times. Refer to SDK documentation, as to the different ways this +** may be called. +****************************************************************************/ +INT APIENTRY DllMain(HANDLE hInst, DWORD ul_reason_being_called, LPVOID lpReserved) +{ + int iRetVal = 1; + + switch (ul_reason_being_called) + { + case DLL_PROCESS_ATTACH: + iRetVal = U14InitLib() > 0; // does nothing if iAttached != 0 + ++iAttached; // count times attached + break; + + case DLL_PROCESS_DETACH: + if (--iAttached == 0) // last man out? + U14CloseAll(); // release all open handles + break; + } + return iRetVal; + + UNREFERENCED_PARAMETER(lpReserved); +} +#endif +#endif +#ifdef LINUX +void __attribute__((constructor)) use1401_load(void) +{ + U14InitLib(); + ++iAttached; +} + +void __attribute__((destructor)) use1401_unload(void) +{ + if (--iAttached == 0) // last man out? + U14CloseAll(); // release all open handles +} +#endif -- cgit v0.10.2 From 6ede1edea3e7632e50a4b86165112d6364cdadb6 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 17 Sep 2012 19:36:03 -0700 Subject: Staging: ced1401: usb1401: fix build errors. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes up the usb1401.c file to remove the usage of err() (which is gone), and the two-argument kmap_atomic() call, and the compat_ioctl pointer warning. The code now builds properly, there are lots of warnings still, but it's a start. Cc: Alois Schlögl Cc: Greg P. Smith Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ced1401/usb1401.c b/drivers/staging/ced1401/usb1401.c index 54595b8..bf08baa 100644 --- a/drivers/staging/ced1401/usb1401.c +++ b/drivers/staging/ced1401/usb1401.c @@ -171,7 +171,7 @@ static int ced_open(struct inode *inode, struct file *file) struct usb_interface* interface = usb_find_interface(&ced_driver, subminor); if (!interface) { - err("%s - error, can't find device for minor %d", __func__, subminor); + pr_err("%s - error, can't find device for minor %d", __func__, subminor); retval = -ENODEV; goto exit; } @@ -491,7 +491,7 @@ static void CopyUserSpace(DEVICE_EXTENSION *pdx, int n) int nPage = dwOffset >> PAGE_SHIFT; // page number in table if (nPage < pArea->nPages) { - char *pvAddress = (char*)kmap_atomic(pArea->pPages[nPage], KM_IRQ0); + char *pvAddress = (char*)kmap_atomic(pArea->pPages[nPage]); if (pvAddress) { unsigned int uiPageOff = dwOffset & (PAGE_SIZE-1); // offset into the page @@ -502,7 +502,7 @@ static void CopyUserSpace(DEVICE_EXTENSION *pdx, int n) memcpy(pvAddress+uiPageOff, pCoherBuf, uiXfer); else memcpy(pCoherBuf, pvAddress+uiPageOff, uiXfer); - kunmap_atomic(pvAddress, KM_IRQ0); + kunmap_atomic(pvAddress); dwOffset += uiXfer; pCoherBuf += uiXfer; n -= uiXfer; @@ -1198,7 +1198,7 @@ int Allowi(DEVICE_EXTENSION* pdx, bool bInCallback) ** enough for a 64-bit pointer. *****************************************************************************/ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36) -static int ced_ioctl(struct file * file, unsigned int cmd, unsigned long ulArg) +static long ced_ioctl(struct file * file, unsigned int cmd, unsigned long ulArg) #else static int ced_ioctl(struct inode * node, struct file * file, unsigned int cmd, unsigned long ulArg) #endif @@ -1367,7 +1367,7 @@ static int ced_probe(struct usb_interface *interface, const struct usb_device_id pdx = kzalloc(sizeof(*pdx), GFP_KERNEL); if (!pdx) { - err("Out of memory"); + dev_err(&interface->dev, "Out of memory\n"); goto error; } @@ -1458,7 +1458,7 @@ static int ced_probe(struct usb_interface *interface, const struct usb_device_id if (retval) { /* something prevented us from registering this driver */ - err("Not able to get a minor for this device."); + dev_err(&interface->dev, "Not able to get a minor for this device.\n"); usb_set_intfdata(interface, NULL); goto error; } @@ -1578,11 +1578,7 @@ static struct usb_driver ced_driver = static int __init usb_skel_init(void) { /* register this driver with the USB subsystem */ - int result = usb_register(&ced_driver); - if (result) - err("usb_register failed. Error number %d", result); - - return result; + return usb_register(&ced_driver); } static void __exit usb_skel_exit(void) -- cgit v0.10.2 From c7fbfc825fdf183829fac42f55e1e5727f746bb0 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 17 Sep 2012 19:42:05 -0700 Subject: Staging: ced1401: add TODO file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds a first cut of a TODO file to get this driver out of the staging directory. Cc: Alois Schlögl Cc: Greg P. Smith Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ced1401/TODO b/drivers/staging/ced1401/TODO new file mode 100644 index 0000000..9fd5630 --- /dev/null +++ b/drivers/staging/ced1401/TODO @@ -0,0 +1,10 @@ +TODO: + - coding syle fixes + - build warning fixups + - ioctl auditing + - usb api auditing + - proper USB minor number (it's stomping on an existing one right now.) + +Please send patches to Greg Kroah-Hartman and Cc: +Alois Schlögl + -- cgit v0.10.2 From 2d96650139bf6f163970f72ef8aa1abaa6c8b3d1 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 17 Sep 2012 19:43:33 -0700 Subject: Staging: ced1401: add driver to the build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds the ced1401 driver to the build system. Yes, there are a lot of warning messages, but it does compile, so it should be good to get going. Cc: Alois Schlögl Cc: Greg P. Smith Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 08d279f..025d8c9 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -138,4 +138,6 @@ source "drivers/staging/ramster/Kconfig" source "drivers/staging/silicom/Kconfig" +source "drivers/staging/ced1401/Kconfig" + endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 0f04a28..08e9667 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -61,3 +61,4 @@ obj-$(CONFIG_CSR_WIFI) += csr/ obj-$(CONFIG_OMAP_BANDGAP) += omap-thermal/ obj-$(CONFIG_ZCACHE2) += ramster/ obj-$(CONFIG_NET_VENDOR_SILICOM) += silicom/ +obj-$(CONFIG_CED1401) += ced1401/ diff --git a/drivers/staging/ced1401/Kconfig b/drivers/staging/ced1401/Kconfig new file mode 100644 index 0000000..ae36d1b --- /dev/null +++ b/drivers/staging/ced1401/Kconfig @@ -0,0 +1,6 @@ +config CED1401 + tristate "Cambridge Electronic Design 1401 USB support" + depends on USB + help + This driver supports the Cambridge Electronic Design 1401 USB device + (whatever that is.) diff --git a/drivers/staging/ced1401/Makefile b/drivers/staging/ced1401/Makefile index 6acb031..f0c114b 100644 --- a/drivers/staging/ced1401/Makefile +++ b/drivers/staging/ced1401/Makefile @@ -1,12 +1,3 @@ -obj-m := cedusb.o -cedusb-objs := usb1401.o ced_ioc.o -KDIR := /lib/modules/$(shell uname -r)/build -PWD := $(shell pwd) -KBUILD_EXTRA_SYMBOLS := $(PWD) -EXTRA_CFLAGS = -I$(HOME)/src/ced1401 -all: - $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules - -clean: - $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean +obj-$(CONFIG_CED1401) := cedusb.o +cedusb-objs := usb1401.o ced_ioc.o -- cgit v0.10.2 From cd915200af6e01a8e923cc5440f72fb288bf2d6b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 17 Sep 2012 21:12:59 -0700 Subject: Staging ced1401: cleanup coding style issues. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A basic Lindent run on the .c files, clean up the .h file by hand. Cc: Alois Schlögl Cc: Greg P. Smith Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ced1401/ced_ioc.c b/drivers/staging/ced1401/ced_ioc.c index 4a13c10..bb29c7f 100644 --- a/drivers/staging/ced1401/ced_ioc.c +++ b/drivers/staging/ced1401/ced_ioc.c @@ -37,17 +37,18 @@ ** ** Empties the Output buffer and sets int lines. Used from user level only ****************************************************************************/ -void FlushOutBuff(DEVICE_EXTENSION *pdx) +void FlushOutBuff(DEVICE_EXTENSION * pdx) { - dev_dbg(&pdx->interface->dev, "%s currentState=%d", __func__, pdx->sCurrentState); - if (pdx->sCurrentState == U14ERR_TIME) /* Do nothing if hardware in trouble */ - return; + dev_dbg(&pdx->interface->dev, "%s currentState=%d", __func__, + pdx->sCurrentState); + if (pdx->sCurrentState == U14ERR_TIME) /* Do nothing if hardware in trouble */ + return; // CharSend_Cancel(pdx); /* Kill off any pending I/O */ - spin_lock_irq(&pdx->charOutLock); - pdx->dwNumOutput = 0; - pdx->dwOutBuffGet = 0; - pdx->dwOutBuffPut = 0; - spin_unlock_irq(&pdx->charOutLock); + spin_lock_irq(&pdx->charOutLock); + pdx->dwNumOutput = 0; + pdx->dwOutBuffGet = 0; + pdx->dwOutBuffPut = 0; + spin_unlock_irq(&pdx->charOutLock); } /**************************************************************************** @@ -56,17 +57,18 @@ void FlushOutBuff(DEVICE_EXTENSION *pdx) ** ** Empties the input buffer and sets int lines ****************************************************************************/ -void FlushInBuff(DEVICE_EXTENSION *pdx) +void FlushInBuff(DEVICE_EXTENSION * pdx) { - dev_dbg(&pdx->interface->dev, "%s currentState=%d", __func__, pdx->sCurrentState); - if (pdx->sCurrentState == U14ERR_TIME) /* Do nothing if hardware in trouble */ - return; + dev_dbg(&pdx->interface->dev, "%s currentState=%d", __func__, + pdx->sCurrentState); + if (pdx->sCurrentState == U14ERR_TIME) /* Do nothing if hardware in trouble */ + return; // CharRead_Cancel(pDevObject); /* Kill off any pending I/O */ - spin_lock_irq(&pdx->charInLock); - pdx->dwNumInput = 0; - pdx->dwInBuffGet = 0; - pdx->dwInBuffPut = 0; - spin_unlock_irq(&pdx->charInLock); + spin_lock_irq(&pdx->charInLock); + pdx->dwNumInput = 0; + pdx->dwInBuffGet = 0; + pdx->dwInBuffPut = 0; + spin_unlock_irq(&pdx->charInLock); } /**************************************************************************** @@ -75,29 +77,26 @@ void FlushInBuff(DEVICE_EXTENSION *pdx) ** Utility routine to copy chars into the output buffer and fire them off. ** called from user mode, holds charOutLock. ****************************************************************************/ -static int PutChars(DEVICE_EXTENSION* pdx, const char* pCh, unsigned int uCount) +static int PutChars(DEVICE_EXTENSION * pdx, const char *pCh, + unsigned int uCount) { - int iReturn; - spin_lock_irq(&pdx->charOutLock); // get the output spin lock - if ((OUTBUF_SZ - pdx->dwNumOutput) >= uCount) - { - unsigned int u; - for (u=0; uoutputBuffer[pdx->dwOutBuffPut++] = pCh[u]; - if (pdx->dwOutBuffPut >= OUTBUF_SZ) - pdx->dwOutBuffPut = 0; - } - pdx->dwNumOutput += uCount; - spin_unlock_irq(&pdx->charOutLock); - iReturn = SendChars(pdx); // ...give a chance to transmit data - } - else - { - iReturn = U14ERR_NOOUT; // no room at the out (ha-ha) - spin_unlock_irq(&pdx->charOutLock); - } - return iReturn; + int iReturn; + spin_lock_irq(&pdx->charOutLock); // get the output spin lock + if ((OUTBUF_SZ - pdx->dwNumOutput) >= uCount) { + unsigned int u; + for (u = 0; u < uCount; u++) { + pdx->outputBuffer[pdx->dwOutBuffPut++] = pCh[u]; + if (pdx->dwOutBuffPut >= OUTBUF_SZ) + pdx->dwOutBuffPut = 0; + } + pdx->dwNumOutput += uCount; + spin_unlock_irq(&pdx->charOutLock); + iReturn = SendChars(pdx); // ...give a chance to transmit data + } else { + iReturn = U14ERR_NOOUT; // no room at the out (ha-ha) + spin_unlock_irq(&pdx->charOutLock); + } + return iReturn; } /***************************************************************************** @@ -105,27 +104,29 @@ static int PutChars(DEVICE_EXTENSION* pdx, const char* pCh, unsigned int uCount) ** trigger an output transfer if this is appropriate. User mode. ** Holds the io_mutex *****************************************************************************/ -int SendString(DEVICE_EXTENSION* pdx, const char __user* pData, unsigned int n) +int SendString(DEVICE_EXTENSION * pdx, const char __user * pData, + unsigned int n) { - int iReturn = U14ERR_NOERROR; // assume all will be well - char buffer[OUTBUF_SZ+1]; // space in our address space for characters - if (n > OUTBUF_SZ) // check space in local buffer... - return U14ERR_NOOUT; // ...too many characters - if (copy_from_user(buffer, pData, n)) - return -ENOMEM; // could not copy - buffer[n] = 0; // terminate for debug purposes - - mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o - if (n > 0) // do nothing if nowt to do! - { - dev_dbg(&pdx->interface->dev, "%s n=%d>%s<", __func__, n, buffer); - iReturn = PutChars(pdx, buffer, n); - } - - Allowi(pdx, false); // make sure we have input int - mutex_unlock(&pdx->io_mutex); - - return iReturn; + int iReturn = U14ERR_NOERROR; // assume all will be well + char buffer[OUTBUF_SZ + 1]; // space in our address space for characters + if (n > OUTBUF_SZ) // check space in local buffer... + return U14ERR_NOOUT; // ...too many characters + if (copy_from_user(buffer, pData, n)) + return -ENOMEM; // could not copy + buffer[n] = 0; // terminate for debug purposes + + mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o + if (n > 0) // do nothing if nowt to do! + { + dev_dbg(&pdx->interface->dev, "%s n=%d>%s<", __func__, n, + buffer); + iReturn = PutChars(pdx, buffer, n); + } + + Allowi(pdx, false); // make sure we have input int + mutex_unlock(&pdx->io_mutex); + + return iReturn; } /**************************************************************************** @@ -133,15 +134,15 @@ int SendString(DEVICE_EXTENSION* pdx, const char __user* pData, unsigned int n) ** ** Sends a single character to the 1401. User mode, holds io_mutex. ****************************************************************************/ -int SendChar(DEVICE_EXTENSION *pdx, char c) +int SendChar(DEVICE_EXTENSION * pdx, char c) { - int iReturn; - mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o - iReturn = PutChars(pdx, &c, 1); - dev_dbg(&pdx->interface->dev,"SendChar >%c< (0x%02x)", c, c); - Allowi(pdx, false); // Make sure char reads are running - mutex_unlock(&pdx->io_mutex); - return iReturn; + int iReturn; + mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o + iReturn = PutChars(pdx, &c, 1); + dev_dbg(&pdx->interface->dev, "SendChar >%c< (0x%02x)", c, c); + Allowi(pdx, false); // Make sure char reads are running + mutex_unlock(&pdx->io_mutex); + return iReturn; } /*************************************************************************** @@ -170,48 +171,47 @@ int SendChar(DEVICE_EXTENSION *pdx, char c) ** ** return error code (U14ERR_NOERROR for OK) */ -int Get1401State(DEVICE_EXTENSION* pdx, __u32* state, __u32* error) +int Get1401State(DEVICE_EXTENSION * pdx, __u32 * state, __u32 * error) { - int nGot; - dev_dbg(&pdx->interface->dev, "Get1401State() entry"); - - *state = 0xFFFFFFFF; // Start off with invalid state - nGot = usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0), - GET_STATUS, (D_TO_H|VENDOR|DEVREQ), 0,0, - pdx->statBuf, sizeof(pdx->statBuf), HZ); - if (nGot != sizeof(pdx->statBuf)) - { - dev_err(&pdx->interface->dev, "Get1401State() FAILED, return code %d", nGot); - pdx->sCurrentState = U14ERR_TIME; // Indicate that things are very wrong indeed - *state = 0; // Force status values to a known state - *error = 0; - } - else - { - int nDevice; - dev_dbg(&pdx->interface->dev, "Get1401State() Success, state: 0x%x, 0x%x", - pdx->statBuf[0], pdx->statBuf[1]); - - *state = pdx->statBuf[0]; // Return the state values to the calling code - *error = pdx->statBuf[1]; - - nDevice = pdx->udev->descriptor.bcdDevice >> 8; // 1401 type code value - switch (nDevice) // so we can clean up current state - { - case 0: - pdx->sCurrentState = U14ERR_U1401; - break; - - default: // allow lots of device codes for future 1401s - if ((nDevice >= 1) && (nDevice <= 23)) - pdx->sCurrentState = (short)(nDevice + 6); - else - pdx->sCurrentState = U14ERR_ILL; - break; - } - } - - return pdx->sCurrentState >= 0 ? U14ERR_NOERROR : pdx->sCurrentState; + int nGot; + dev_dbg(&pdx->interface->dev, "Get1401State() entry"); + + *state = 0xFFFFFFFF; // Start off with invalid state + nGot = usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0), + GET_STATUS, (D_TO_H | VENDOR | DEVREQ), 0, 0, + pdx->statBuf, sizeof(pdx->statBuf), HZ); + if (nGot != sizeof(pdx->statBuf)) { + dev_err(&pdx->interface->dev, + "Get1401State() FAILED, return code %d", nGot); + pdx->sCurrentState = U14ERR_TIME; // Indicate that things are very wrong indeed + *state = 0; // Force status values to a known state + *error = 0; + } else { + int nDevice; + dev_dbg(&pdx->interface->dev, + "Get1401State() Success, state: 0x%x, 0x%x", + pdx->statBuf[0], pdx->statBuf[1]); + + *state = pdx->statBuf[0]; // Return the state values to the calling code + *error = pdx->statBuf[1]; + + nDevice = pdx->udev->descriptor.bcdDevice >> 8; // 1401 type code value + switch (nDevice) // so we can clean up current state + { + case 0: + pdx->sCurrentState = U14ERR_U1401; + break; + + default: // allow lots of device codes for future 1401s + if ((nDevice >= 1) && (nDevice <= 23)) + pdx->sCurrentState = (short)(nDevice + 6); + else + pdx->sCurrentState = U14ERR_ILL; + break; + } + } + + return pdx->sCurrentState >= 0 ? U14ERR_NOERROR : pdx->sCurrentState; } /**************************************************************************** @@ -219,49 +219,53 @@ int Get1401State(DEVICE_EXTENSION* pdx, __u32* state, __u32* error) ** ** Kills off staged read\write request from the USB if one is pending. ****************************************************************************/ -int ReadWrite_Cancel(DEVICE_EXTENSION *pdx) +int ReadWrite_Cancel(DEVICE_EXTENSION * pdx) { - dev_dbg(&pdx->interface->dev, "ReadWrite_Cancel entry %d", pdx->bStagedUrbPending); + dev_dbg(&pdx->interface->dev, "ReadWrite_Cancel entry %d", + pdx->bStagedUrbPending); #ifdef NOT_WRITTEN_YET - int ntStatus = STATUS_SUCCESS; - bool bResult = false; - unsigned int i; - // We can fill this in when we know how we will implement the staged transfer stuff - spin_lock_irq(&pdx->stagedLock); - - if (pdx->bStagedUrbPending) // anything to be cancelled? May need more... - { - dev_info(&pdx->interface-dev, "ReadWrite_Cancel about to cancel Urb"); - - // KeClearEvent(&pdx->StagingDoneEvent); // Clear the staging done flag - USB_ASSERT(pdx->pStagedIrp != NULL); - - // Release the spinlock first otherwise the completion routine may hang - // on the spinlock while this function hands waiting for the event. - spin_unlock_irq(&pdx->stagedLock); - bResult = IoCancelIrp(pdx->pStagedIrp); // Actually do the cancel - if (bResult) - { - LARGE_INTEGER timeout; - timeout.QuadPart = -10000000; // Use a timeout of 1 second - dev_info(&pdx->interface-dev, "ReadWrite_Cancel about to wait till done"); - ntStatus = KeWaitForSingleObject(&pdx->StagingDoneEvent, Executive, - KernelMode, FALSE, &timeout); - } - else - { - dev_info(&pdx->interface-dev, "ReadWrite_Cancel, cancellation failed"); - ntStatus = U14ERR_FAIL; - } - USB_KdPrint(DBGLVL_DEFAULT, ("ReadWrite_Cancel ntStatus = 0x%x decimal %d\n", ntStatus, ntStatus)); - } - else - spin_unlock_irq(&pdx->stagedLock); - - dev_info(&pdx->interface-dev, "ReadWrite_Cancel done"); - return ntStatus; + int ntStatus = STATUS_SUCCESS; + bool bResult = false; + unsigned int i; + // We can fill this in when we know how we will implement the staged transfer stuff + spin_lock_irq(&pdx->stagedLock); + + if (pdx->bStagedUrbPending) // anything to be cancelled? May need more... + { + dev_info(&pdx->interface - dev, + "ReadWrite_Cancel about to cancel Urb"); + + // KeClearEvent(&pdx->StagingDoneEvent); // Clear the staging done flag + USB_ASSERT(pdx->pStagedIrp != NULL); + + // Release the spinlock first otherwise the completion routine may hang + // on the spinlock while this function hands waiting for the event. + spin_unlock_irq(&pdx->stagedLock); + bResult = IoCancelIrp(pdx->pStagedIrp); // Actually do the cancel + if (bResult) { + LARGE_INTEGER timeout; + timeout.QuadPart = -10000000; // Use a timeout of 1 second + dev_info(&pdx->interface - dev, + "ReadWrite_Cancel about to wait till done"); + ntStatus = + KeWaitForSingleObject(&pdx->StagingDoneEvent, + Executive, KernelMode, FALSE, + &timeout); + } else { + dev_info(&pdx->interface - dev, + "ReadWrite_Cancel, cancellation failed"); + ntStatus = U14ERR_FAIL; + } + USB_KdPrint(DBGLVL_DEFAULT, + ("ReadWrite_Cancel ntStatus = 0x%x decimal %d\n", + ntStatus, ntStatus)); + } else + spin_unlock_irq(&pdx->stagedLock); + + dev_info(&pdx->interface - dev, "ReadWrite_Cancel done"); + return ntStatus; #else - return U14ERR_NOERROR; + return U14ERR_NOERROR; #endif } @@ -270,15 +274,15 @@ int ReadWrite_Cancel(DEVICE_EXTENSION *pdx) ** InSelfTest - utility to check in self test. Return 1 for ST, 0 for not or ** a -ve error code if we failed for some reason. ***************************************************************************/ -static int InSelfTest(DEVICE_EXTENSION* pdx, unsigned int* pState) +static int InSelfTest(DEVICE_EXTENSION * pdx, unsigned int *pState) { - unsigned int state, error; - int iReturn = Get1401State(pdx, &state, &error); // see if in self-test - if (iReturn == U14ERR_NOERROR) // if all still OK - iReturn = (state == (unsigned int)-1) || // TX problem or... - ((state & 0xff) == 0x80); // ...self test - *pState = state; // return actual state - return iReturn; + unsigned int state, error; + int iReturn = Get1401State(pdx, &state, &error); // see if in self-test + if (iReturn == U14ERR_NOERROR) // if all still OK + iReturn = (state == (unsigned int)-1) || // TX problem or... + ((state & 0xff) == 0x80); // ...self test + *pState = state; // return actual state + return iReturn; } /*************************************************************************** @@ -299,52 +303,50 @@ static int InSelfTest(DEVICE_EXTENSION* pdx, unsigned int* pState) ** ** Returns TRUE if a 1401 detected and OK, else FALSE ****************************************************************************/ -bool Is1401(DEVICE_EXTENSION* pdx) +bool Is1401(DEVICE_EXTENSION * pdx) { - int iReturn; - dev_dbg(&pdx->interface->dev, "%s", __func__); - - ced_draw_down(pdx); // wait for, then kill outstanding Urbs - FlushInBuff(pdx); // Clear out input buffer & pipe - FlushOutBuff(pdx); // Clear output buffer & pipe - - // The next call returns 0 if OK, but has returned 1 in the past, meaning that - // usb_unlock_device() is needed... now it always is - iReturn = usb_lock_device_for_reset(pdx->udev, pdx->interface); - - // release the io_mutex because if we don't, we will deadlock due to system - // calls back into the driver. - mutex_unlock(&pdx->io_mutex); // locked, so we will not get system calls - if (iReturn >= 0) // if we failed - { - iReturn = usb_reset_device(pdx->udev); // try to do the reset - usb_unlock_device(pdx->udev); // undo the lock - } - - mutex_lock(&pdx->io_mutex); // hold stuff off while we wait - pdx->dwDMAFlag = MODE_CHAR; // Clear DMA mode flag regardless! - if (iReturn == 0) // if all is OK still - { - unsigned int state; - iReturn = InSelfTest(pdx, &state); // see if likely in self test - if (iReturn > 0) // do we need to wait for self-test? - { - unsigned long ulTimeOut = jiffies + 30*HZ; // when to give up - while((iReturn > 0) && time_before(jiffies, ulTimeOut)) - { - schedule(); // let other stuff run - iReturn = InSelfTest(pdx, &state); // see if done yet - } - } - - if (iReturn == 0) // if all is OK... - iReturn = state == 0; // then sucess is that the state is 0 - } - else - iReturn = 0; // we failed - pdx->bForceReset = false; // Clear forced reset flag now - - return iReturn > 0; + int iReturn; + dev_dbg(&pdx->interface->dev, "%s", __func__); + + ced_draw_down(pdx); // wait for, then kill outstanding Urbs + FlushInBuff(pdx); // Clear out input buffer & pipe + FlushOutBuff(pdx); // Clear output buffer & pipe + + // The next call returns 0 if OK, but has returned 1 in the past, meaning that + // usb_unlock_device() is needed... now it always is + iReturn = usb_lock_device_for_reset(pdx->udev, pdx->interface); + + // release the io_mutex because if we don't, we will deadlock due to system + // calls back into the driver. + mutex_unlock(&pdx->io_mutex); // locked, so we will not get system calls + if (iReturn >= 0) // if we failed + { + iReturn = usb_reset_device(pdx->udev); // try to do the reset + usb_unlock_device(pdx->udev); // undo the lock + } + + mutex_lock(&pdx->io_mutex); // hold stuff off while we wait + pdx->dwDMAFlag = MODE_CHAR; // Clear DMA mode flag regardless! + if (iReturn == 0) // if all is OK still + { + unsigned int state; + iReturn = InSelfTest(pdx, &state); // see if likely in self test + if (iReturn > 0) // do we need to wait for self-test? + { + unsigned long ulTimeOut = jiffies + 30 * HZ; // when to give up + while ((iReturn > 0) && time_before(jiffies, ulTimeOut)) { + schedule(); // let other stuff run + iReturn = InSelfTest(pdx, &state); // see if done yet + } + } + + if (iReturn == 0) // if all is OK... + iReturn = state == 0; // then sucess is that the state is 0 + } else + iReturn = 0; // we failed + pdx->bForceReset = false; // Clear forced reset flag now + + return iReturn > 0; } /**************************************************************************** @@ -361,44 +363,48 @@ bool Is1401(DEVICE_EXTENSION* pdx) ** ** The return value is TRUE if a useable 1401 is found, FALSE if not */ -bool QuickCheck(DEVICE_EXTENSION* pdx, bool bTestBuff, bool bCanReset) +bool QuickCheck(DEVICE_EXTENSION * pdx, bool bTestBuff, bool bCanReset) { - bool bRet = false; // assume it will fail and we will reset - bool bShortTest; - - bShortTest = ((pdx->dwDMAFlag == MODE_CHAR) && // no DMA running - (!pdx->bForceReset) && // Not had a real reset forced - (pdx->sCurrentState >= U14ERR_STD)); // No 1401 errors stored - - dev_dbg(&pdx->interface->dev, "%s DMAFlag:%d, state:%d, force:%d, testBuff:%d, short:%d", - __func__, pdx->dwDMAFlag, pdx->sCurrentState, pdx->bForceReset, bTestBuff, bShortTest); - - if ((bTestBuff) && // Buffer check requested, and... - (pdx->dwNumInput || pdx->dwNumOutput)) // ...characters were in the buffer? - { - bShortTest = false; // Then do the full test - dev_dbg(&pdx->interface->dev, "%s will reset as buffers not empty", __func__); - } - - if (bShortTest || !bCanReset) // Still OK to try the short test? - { // Always test if no reset - we want state update - unsigned int state, error; - dev_dbg(&pdx->interface->dev, "%s->Get1401State", __func__); - if (Get1401State(pdx, &state, &error) == U14ERR_NOERROR) // Check on the 1401 state - { - if ((state & 0xFF) == 0) // If call worked, check the status value - bRet = true; // If that was zero, all is OK, no reset needed - } - } - - if (!bRet && bCanReset) // If all not OK, then - { - dev_info(&pdx->interface->dev, "%s->Is1401 %d %d %d %d", - __func__, bShortTest, pdx->sCurrentState, bTestBuff, pdx->bForceReset); - bRet = Is1401(pdx); // do full test - } - - return bRet; + bool bRet = false; // assume it will fail and we will reset + bool bShortTest; + + bShortTest = ((pdx->dwDMAFlag == MODE_CHAR) && // no DMA running + (!pdx->bForceReset) && // Not had a real reset forced + (pdx->sCurrentState >= U14ERR_STD)); // No 1401 errors stored + + dev_dbg(&pdx->interface->dev, + "%s DMAFlag:%d, state:%d, force:%d, testBuff:%d, short:%d", + __func__, pdx->dwDMAFlag, pdx->sCurrentState, pdx->bForceReset, + bTestBuff, bShortTest); + + if ((bTestBuff) && // Buffer check requested, and... + (pdx->dwNumInput || pdx->dwNumOutput)) // ...characters were in the buffer? + { + bShortTest = false; // Then do the full test + dev_dbg(&pdx->interface->dev, + "%s will reset as buffers not empty", __func__); + } + + if (bShortTest || !bCanReset) // Still OK to try the short test? + { // Always test if no reset - we want state update + unsigned int state, error; + dev_dbg(&pdx->interface->dev, "%s->Get1401State", __func__); + if (Get1401State(pdx, &state, &error) == U14ERR_NOERROR) // Check on the 1401 state + { + if ((state & 0xFF) == 0) // If call worked, check the status value + bRet = true; // If that was zero, all is OK, no reset needed + } + } + + if (!bRet && bCanReset) // If all not OK, then + { + dev_info(&pdx->interface->dev, "%s->Is1401 %d %d %d %d", + __func__, bShortTest, pdx->sCurrentState, bTestBuff, + pdx->bForceReset); + bRet = Is1401(pdx); // do full test + } + + return bRet; } /**************************************************************************** @@ -406,13 +412,13 @@ bool QuickCheck(DEVICE_EXTENSION* pdx, bool bTestBuff, bool bCanReset) ** ** Resets the 1401 and empties the i/o buffers *****************************************************************************/ -int Reset1401(DEVICE_EXTENSION *pdx) +int Reset1401(DEVICE_EXTENSION * pdx) { - mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o - dev_dbg(&pdx->interface->dev,"ABout to call QuickCheck"); - QuickCheck(pdx, true, true); // Check 1401, reset if not OK - mutex_unlock(&pdx->io_mutex); - return U14ERR_NOERROR; + mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o + dev_dbg(&pdx->interface->dev, "ABout to call QuickCheck"); + QuickCheck(pdx, true, true); // Check 1401, reset if not OK + mutex_unlock(&pdx->io_mutex); + return U14ERR_NOERROR; } /**************************************************************************** @@ -420,32 +426,31 @@ int Reset1401(DEVICE_EXTENSION *pdx) ** ** Gets a single character from the 1401 ****************************************************************************/ -int GetChar(DEVICE_EXTENSION *pdx) +int GetChar(DEVICE_EXTENSION * pdx) { - int iReturn = U14ERR_NOIN; // assume we will get nothing - mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o - - dev_dbg(&pdx->interface->dev, "GetChar"); - - Allowi(pdx, false); // Make sure char reads are running - SendChars(pdx); // and send any buffered chars - - spin_lock_irq(&pdx->charInLock); - if (pdx->dwNumInput > 0) // worth looking - { - iReturn = pdx->inputBuffer[pdx->dwInBuffGet++]; - if (pdx->dwInBuffGet >= INBUF_SZ) - pdx->dwInBuffGet = 0; - pdx->dwNumInput--; - } - else - iReturn = U14ERR_NOIN; // no input data to read - spin_unlock_irq(&pdx->charInLock); - - Allowi(pdx, false); // Make sure char reads are running - - mutex_unlock(&pdx->io_mutex); // Protect disconnect from new i/o - return iReturn; + int iReturn = U14ERR_NOIN; // assume we will get nothing + mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o + + dev_dbg(&pdx->interface->dev, "GetChar"); + + Allowi(pdx, false); // Make sure char reads are running + SendChars(pdx); // and send any buffered chars + + spin_lock_irq(&pdx->charInLock); + if (pdx->dwNumInput > 0) // worth looking + { + iReturn = pdx->inputBuffer[pdx->dwInBuffGet++]; + if (pdx->dwInBuffGet >= INBUF_SZ) + pdx->dwInBuffGet = 0; + pdx->dwNumInput--; + } else + iReturn = U14ERR_NOIN; // no input data to read + spin_unlock_irq(&pdx->charInLock); + + Allowi(pdx, false); // Make sure char reads are running + + mutex_unlock(&pdx->io_mutex); // Protect disconnect from new i/o + return iReturn; } /**************************************************************************** @@ -459,78 +464,77 @@ int GetChar(DEVICE_EXTENSION *pdx) ** returns the count of characters (including the terminator, or 0 if none ** or a negative error code. ****************************************************************************/ -int GetString(DEVICE_EXTENSION *pdx, char __user* pUser, int n) +int GetString(DEVICE_EXTENSION * pdx, char __user * pUser, int n) { - int nAvailable; // character in the buffer - int iReturn = U14ERR_NOIN; - if (n <= 0) - return -ENOMEM; - - mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o - Allowi(pdx, false); // Make sure char reads are running - SendChars(pdx); // and send any buffered chars - - spin_lock_irq(&pdx->charInLock); - nAvailable = pdx->dwNumInput; // characters available now - if (nAvailable > n) // read max of space in pUser... - nAvailable = n; // ...or input characters - - if (nAvailable > 0) // worth looking? - { - char buffer[INBUF_SZ+1]; // space for a linear copy of data - int nGot = 0; - int nCopyToUser; // number to copy to user - char cData; - do - { - cData = pdx->inputBuffer[pdx->dwInBuffGet++]; - if (cData == CR_CHAR) // replace CR with zero - cData = (char)0; - - if (pdx->dwInBuffGet >= INBUF_SZ) - pdx->dwInBuffGet = 0; // wrap buffer pointer - - buffer[nGot++] = cData; // save the output - } - while((nGot < nAvailable) && cData); - - nCopyToUser = nGot; // what to copy... - if (cData) // do we need null - { - buffer[nGot] = (char)0; // make it tidy - if (nGot < n) // if space in user buffer... - ++nCopyToUser; // ...copy the 0 as well. - } - - pdx->dwNumInput -= nGot; - spin_unlock_irq(&pdx->charInLock); - - dev_dbg(&pdx->interface->dev,"GetString read %d characters >%s<", nGot, buffer); - copy_to_user(pUser, buffer, nCopyToUser); - - iReturn = nGot; // report characters read - } - else - spin_unlock_irq(&pdx->charInLock); - - Allowi(pdx, false); // Make sure char reads are running - mutex_unlock(&pdx->io_mutex); // Protect disconnect from new i/o - - return iReturn; + int nAvailable; // character in the buffer + int iReturn = U14ERR_NOIN; + if (n <= 0) + return -ENOMEM; + + mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o + Allowi(pdx, false); // Make sure char reads are running + SendChars(pdx); // and send any buffered chars + + spin_lock_irq(&pdx->charInLock); + nAvailable = pdx->dwNumInput; // characters available now + if (nAvailable > n) // read max of space in pUser... + nAvailable = n; // ...or input characters + + if (nAvailable > 0) // worth looking? + { + char buffer[INBUF_SZ + 1]; // space for a linear copy of data + int nGot = 0; + int nCopyToUser; // number to copy to user + char cData; + do { + cData = pdx->inputBuffer[pdx->dwInBuffGet++]; + if (cData == CR_CHAR) // replace CR with zero + cData = (char)0; + + if (pdx->dwInBuffGet >= INBUF_SZ) + pdx->dwInBuffGet = 0; // wrap buffer pointer + + buffer[nGot++] = cData; // save the output + } + while ((nGot < nAvailable) && cData); + + nCopyToUser = nGot; // what to copy... + if (cData) // do we need null + { + buffer[nGot] = (char)0; // make it tidy + if (nGot < n) // if space in user buffer... + ++nCopyToUser; // ...copy the 0 as well. + } + + pdx->dwNumInput -= nGot; + spin_unlock_irq(&pdx->charInLock); + + dev_dbg(&pdx->interface->dev, + "GetString read %d characters >%s<", nGot, buffer); + copy_to_user(pUser, buffer, nCopyToUser); + + iReturn = nGot; // report characters read + } else + spin_unlock_irq(&pdx->charInLock); + + Allowi(pdx, false); // Make sure char reads are running + mutex_unlock(&pdx->io_mutex); // Protect disconnect from new i/o + + return iReturn; } /******************************************************************************* ** Get count of characters in the inout buffer. *******************************************************************************/ -int Stat1401(DEVICE_EXTENSION *pdx) +int Stat1401(DEVICE_EXTENSION * pdx) { - int iReturn; - mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o - Allowi(pdx, false); // make sure we allow pending chars - SendChars(pdx); // in both directions - iReturn = pdx->dwNumInput; // no lock as single read - mutex_unlock(&pdx->io_mutex); // Protect disconnect from new i/o - return iReturn; + int iReturn; + mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o + Allowi(pdx, false); // make sure we allow pending chars + SendChars(pdx); // in both directions + iReturn = pdx->dwNumInput; // no lock as single read + mutex_unlock(&pdx->io_mutex); // Protect disconnect from new i/o + return iReturn; } /**************************************************************************** @@ -540,34 +544,33 @@ int Stat1401(DEVICE_EXTENSION *pdx) ** any fancy interlocks as we only read the interrupt routine data, and the ** system is arranged so nothing can be destroyed. ****************************************************************************/ -int LineCount(DEVICE_EXTENSION *pdx) +int LineCount(DEVICE_EXTENSION * pdx) { - int iReturn = 0; // will be count of line ends - - mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o - Allowi(pdx, false); // Make sure char reads are running - SendChars(pdx); // and send any buffered chars - spin_lock_irq(&pdx->charInLock); // Get protection - - if (pdx->dwNumInput > 0) // worth looking? - { - unsigned int dwIndex = pdx->dwInBuffGet;// start at first available - unsigned int dwEnd = pdx->dwInBuffPut; // Position for search end - do - { - if (pdx->inputBuffer[dwIndex++] == CR_CHAR) - ++iReturn; // inc count if CR - - if (dwIndex >= INBUF_SZ) // see if we fall off buff - dwIndex = 0; - } - while (dwIndex != dwEnd); // go to last avaliable - } - - spin_unlock_irq(&pdx->charInLock); - dev_dbg(&pdx->interface->dev,"LineCount returned %d", iReturn); - mutex_unlock(&pdx->io_mutex); // Protect disconnect from new i/o - return iReturn; + int iReturn = 0; // will be count of line ends + + mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o + Allowi(pdx, false); // Make sure char reads are running + SendChars(pdx); // and send any buffered chars + spin_lock_irq(&pdx->charInLock); // Get protection + + if (pdx->dwNumInput > 0) // worth looking? + { + unsigned int dwIndex = pdx->dwInBuffGet; // start at first available + unsigned int dwEnd = pdx->dwInBuffPut; // Position for search end + do { + if (pdx->inputBuffer[dwIndex++] == CR_CHAR) + ++iReturn; // inc count if CR + + if (dwIndex >= INBUF_SZ) // see if we fall off buff + dwIndex = 0; + } + while (dwIndex != dwEnd); // go to last avaliable + } + + spin_unlock_irq(&pdx->charInLock); + dev_dbg(&pdx->interface->dev, "LineCount returned %d", iReturn); + mutex_unlock(&pdx->io_mutex); // Protect disconnect from new i/o + return iReturn; } /**************************************************************************** @@ -575,15 +578,15 @@ int LineCount(DEVICE_EXTENSION *pdx) ** ** Gets the space in the output buffer. Called from user code. *****************************************************************************/ -int GetOutBufSpace(DEVICE_EXTENSION *pdx) +int GetOutBufSpace(DEVICE_EXTENSION * pdx) { - int iReturn; - mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o - SendChars(pdx); // send any buffered chars - iReturn = (int)(OUTBUF_SZ - pdx->dwNumOutput); // no lock needed for single read - dev_dbg(&pdx->interface->dev,"OutBufSpace %d", iReturn); - mutex_unlock(&pdx->io_mutex); // Protect disconnect from new i/o - return iReturn; + int iReturn; + mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o + SendChars(pdx); // send any buffered chars + iReturn = (int)(OUTBUF_SZ - pdx->dwNumOutput); // no lock needed for single read + dev_dbg(&pdx->interface->dev, "OutBufSpace %d", iReturn); + mutex_unlock(&pdx->io_mutex); // Protect disconnect from new i/o + return iReturn; } /**************************************************************************** @@ -593,74 +596,75 @@ int GetOutBufSpace(DEVICE_EXTENSION *pdx) ** Clears up a transfer area. This is always called in the context of a user ** request, never from a call-back. ****************************************************************************/ -int ClearArea(DEVICE_EXTENSION *pdx, int nArea) +int ClearArea(DEVICE_EXTENSION * pdx, int nArea) { - int iReturn = U14ERR_NOERROR; - - if ((nArea < 0) || (nArea >= MAX_TRANSAREAS)) - { - iReturn = U14ERR_BADAREA; - dev_err(&pdx->interface->dev, "%s Attempt to clear area %d", __func__, nArea); - } - else - { - TRANSAREA *pTA = &pdx->rTransDef[nArea]; // to save typing - if (!pTA->bUsed) // if not used... - iReturn = U14ERR_NOTSET; // ...nothing to be done - else - { - // We must save the memory we return as we shouldn't mess with memory while - // holding a spin lock. - struct page **pPages = 0; // save page address list - int nPages = 0; // and number of pages - int np; - - dev_dbg(&pdx->interface->dev, "%s area %d", __func__, nArea); - spin_lock_irq(&pdx->stagedLock); - if ((pdx->StagedId == nArea) && (pdx->dwDMAFlag > MODE_CHAR)) - { - iReturn = U14ERR_UNLOCKFAIL; // cannot delete as in use - dev_err(&pdx->interface->dev, "%s call on area %d while active", __func__, nArea); - } - else - { - pPages = pTA->pPages; // save page address list - nPages = pTA->nPages; // and page count - if (pTA->dwEventSz) // if events flagging in use - wake_up_interruptible(&pTA->wqEvent); // release anything that was waiting - - if (pdx->bXFerWaiting && (pdx->rDMAInfo.wIdent == nArea)) - pdx->bXFerWaiting = false; // Cannot have pending xfer if area cleared - - // Clean out the TRANSAREA except for the wait queue, which is at the end - // This sets bUsed to false and dwEventSz to 0 to say area not used and no events. - memset(pTA, 0, sizeof(TRANSAREA)-sizeof(wait_queue_head_t)); - } - spin_unlock_irq(&pdx->stagedLock); - - if (pPages) // if we decided to release the memory - { - // Now we must undo the pinning down of the pages. We will assume the worst and mark - // all the pages as dirty. Don't be tempted to move this up above as you must not be - // holding a spin lock to do this stuff as it is not atomic. - dev_dbg(&pdx->interface->dev, "%s nPages=%d", __func__, nPages); - - for (np = 0; np < nPages; ++np) - { - if (pPages[np]) - { - SetPageDirty(pPages[np]); - page_cache_release(pPages[np]); - } - } - - kfree(pPages); - dev_dbg(&pdx->interface->dev, "%s kfree(pPages) done", __func__); - } - } - } - - return iReturn; + int iReturn = U14ERR_NOERROR; + + if ((nArea < 0) || (nArea >= MAX_TRANSAREAS)) { + iReturn = U14ERR_BADAREA; + dev_err(&pdx->interface->dev, "%s Attempt to clear area %d", + __func__, nArea); + } else { + TRANSAREA *pTA = &pdx->rTransDef[nArea]; // to save typing + if (!pTA->bUsed) // if not used... + iReturn = U14ERR_NOTSET; // ...nothing to be done + else { + // We must save the memory we return as we shouldn't mess with memory while + // holding a spin lock. + struct page **pPages = 0; // save page address list + int nPages = 0; // and number of pages + int np; + + dev_dbg(&pdx->interface->dev, "%s area %d", __func__, + nArea); + spin_lock_irq(&pdx->stagedLock); + if ((pdx->StagedId == nArea) + && (pdx->dwDMAFlag > MODE_CHAR)) { + iReturn = U14ERR_UNLOCKFAIL; // cannot delete as in use + dev_err(&pdx->interface->dev, + "%s call on area %d while active", + __func__, nArea); + } else { + pPages = pTA->pPages; // save page address list + nPages = pTA->nPages; // and page count + if (pTA->dwEventSz) // if events flagging in use + wake_up_interruptible(&pTA->wqEvent); // release anything that was waiting + + if (pdx->bXFerWaiting + && (pdx->rDMAInfo.wIdent == nArea)) + pdx->bXFerWaiting = false; // Cannot have pending xfer if area cleared + + // Clean out the TRANSAREA except for the wait queue, which is at the end + // This sets bUsed to false and dwEventSz to 0 to say area not used and no events. + memset(pTA, 0, + sizeof(TRANSAREA) - + sizeof(wait_queue_head_t)); + } + spin_unlock_irq(&pdx->stagedLock); + + if (pPages) // if we decided to release the memory + { + // Now we must undo the pinning down of the pages. We will assume the worst and mark + // all the pages as dirty. Don't be tempted to move this up above as you must not be + // holding a spin lock to do this stuff as it is not atomic. + dev_dbg(&pdx->interface->dev, "%s nPages=%d", + __func__, nPages); + + for (np = 0; np < nPages; ++np) { + if (pPages[np]) { + SetPageDirty(pPages[np]); + page_cache_release(pPages[np]); + } + } + + kfree(pPages); + dev_dbg(&pdx->interface->dev, + "%s kfree(pPages) done", __func__); + } + } + } + + return iReturn; } /**************************************************************************** @@ -669,78 +673,78 @@ int ClearArea(DEVICE_EXTENSION *pdx, int nArea) ** Sets up a transfer area - the functional part. Called by both ** SetTransfer and SetCircular. ****************************************************************************/ -static int SetArea(DEVICE_EXTENSION *pdx, int nArea, char __user* puBuf, - unsigned int dwLength, bool bCircular, bool bCircToHost) +static int SetArea(DEVICE_EXTENSION * pdx, int nArea, char __user * puBuf, + unsigned int dwLength, bool bCircular, bool bCircToHost) { - // Start by working out the page aligned start of the area and the size - // of the area in pages, allowing for the start not being aligned and the - // end needing to be rounded up to a page boundary. - unsigned long ulStart = ((unsigned long)puBuf) & PAGE_MASK; - unsigned int ulOffset = ((unsigned long)puBuf) & (PAGE_SIZE-1); - int len = (dwLength + ulOffset+PAGE_SIZE - 1) >> PAGE_SHIFT; - - TRANSAREA *pTA = &pdx->rTransDef[nArea]; // to save typing - struct page **pPages = 0; // space for page tables - int nPages = 0; // and number of pages - - int iReturn = ClearArea(pdx, nArea); // see if OK to use this area - if ((iReturn != U14ERR_NOTSET) && // if not area unused and... - (iReturn != U14ERR_NOERROR)) // ...not all OK, then... - return iReturn; // ...we cannot use this area - - if (!access_ok(VERIFY_WRITE, puBuf, dwLength)) // if we cannot access the memory... - return -EFAULT; // ...then we are done - - // Now allocate space to hold the page pointer and virtual address pointer tables - pPages = (struct page **)kmalloc(len*sizeof(struct page *), GFP_KERNEL); - if (!pPages) - { - iReturn = U14ERR_NOMEMORY; - goto error; - } - dev_dbg(&pdx->interface->dev, "%s %p, length=%06x, circular %d", __func__, puBuf, dwLength, bCircular); - - // To pin down user pages we must first acquire the mapping semaphore. - down_read(¤t->mm->mmap_sem); // get memory map semaphore - nPages = get_user_pages(current, current->mm, ulStart, len, 1, 0, pPages, 0); - up_read(¤t->mm->mmap_sem); // release the semaphore - dev_dbg(&pdx->interface->dev, "%s nPages = %d", __func__, nPages); - - if (nPages > 0) // if we succeeded - { - // If you are tempted to use page_address (form LDD3), forget it. You MUST use - // kmap() or kmap_atomic() to get a virtual address. page_address will give you - // (null) or at least it does in this context with an x86 machine. - spin_lock_irq(&pdx->stagedLock); - pTA->lpvBuff = puBuf; // keep start of region (user address) - pTA->dwBaseOffset = ulOffset; // save offset in first page to start of xfer - pTA->dwLength = dwLength; // Size if the region in bytes - pTA->pPages = pPages; // list of pages that are used by buffer - pTA->nPages = nPages; // number of pages - - pTA->bCircular = bCircular; - pTA->bCircToHost = bCircToHost; - - pTA->aBlocks[0].dwOffset = 0; - pTA->aBlocks[0].dwSize = 0; - pTA->aBlocks[1].dwOffset = 0; - pTA->aBlocks[1].dwSize = 0; - pTA->bUsed = true; // This is now a used block - - spin_unlock_irq(&pdx->stagedLock); - iReturn = U14ERR_NOERROR; // say all was well - } - else - { - iReturn = U14ERR_LOCKFAIL; - goto error; - } - - return iReturn; + // Start by working out the page aligned start of the area and the size + // of the area in pages, allowing for the start not being aligned and the + // end needing to be rounded up to a page boundary. + unsigned long ulStart = ((unsigned long)puBuf) & PAGE_MASK; + unsigned int ulOffset = ((unsigned long)puBuf) & (PAGE_SIZE - 1); + int len = (dwLength + ulOffset + PAGE_SIZE - 1) >> PAGE_SHIFT; + + TRANSAREA *pTA = &pdx->rTransDef[nArea]; // to save typing + struct page **pPages = 0; // space for page tables + int nPages = 0; // and number of pages + + int iReturn = ClearArea(pdx, nArea); // see if OK to use this area + if ((iReturn != U14ERR_NOTSET) && // if not area unused and... + (iReturn != U14ERR_NOERROR)) // ...not all OK, then... + return iReturn; // ...we cannot use this area + + if (!access_ok(VERIFY_WRITE, puBuf, dwLength)) // if we cannot access the memory... + return -EFAULT; // ...then we are done + + // Now allocate space to hold the page pointer and virtual address pointer tables + pPages = + (struct page **)kmalloc(len * sizeof(struct page *), GFP_KERNEL); + if (!pPages) { + iReturn = U14ERR_NOMEMORY; + goto error; + } + dev_dbg(&pdx->interface->dev, "%s %p, length=%06x, circular %d", + __func__, puBuf, dwLength, bCircular); + + // To pin down user pages we must first acquire the mapping semaphore. + down_read(¤t->mm->mmap_sem); // get memory map semaphore + nPages = + get_user_pages(current, current->mm, ulStart, len, 1, 0, pPages, 0); + up_read(¤t->mm->mmap_sem); // release the semaphore + dev_dbg(&pdx->interface->dev, "%s nPages = %d", __func__, nPages); + + if (nPages > 0) // if we succeeded + { + // If you are tempted to use page_address (form LDD3), forget it. You MUST use + // kmap() or kmap_atomic() to get a virtual address. page_address will give you + // (null) or at least it does in this context with an x86 machine. + spin_lock_irq(&pdx->stagedLock); + pTA->lpvBuff = puBuf; // keep start of region (user address) + pTA->dwBaseOffset = ulOffset; // save offset in first page to start of xfer + pTA->dwLength = dwLength; // Size if the region in bytes + pTA->pPages = pPages; // list of pages that are used by buffer + pTA->nPages = nPages; // number of pages + + pTA->bCircular = bCircular; + pTA->bCircToHost = bCircToHost; + + pTA->aBlocks[0].dwOffset = 0; + pTA->aBlocks[0].dwSize = 0; + pTA->aBlocks[1].dwOffset = 0; + pTA->aBlocks[1].dwSize = 0; + pTA->bUsed = true; // This is now a used block + + spin_unlock_irq(&pdx->stagedLock); + iReturn = U14ERR_NOERROR; // say all was well + } else { + iReturn = U14ERR_LOCKFAIL; + goto error; + } + + return iReturn; error: - kfree(pPages); - return iReturn; + kfree(pPages); + return iReturn; } /**************************************************************************** @@ -750,32 +754,36 @@ error: ** unset it. Unsetting will fail if the area is booked, and a transfer to that ** area is in progress. Otherwise, we will release the area and re-assign it. ****************************************************************************/ -int SetTransfer(DEVICE_EXTENSION *pdx, TRANSFERDESC __user *pTD) +int SetTransfer(DEVICE_EXTENSION * pdx, TRANSFERDESC __user * pTD) { - int iReturn; - TRANSFERDESC td; - copy_from_user(&td, pTD, sizeof(td)); - mutex_lock(&pdx->io_mutex); - dev_dbg(&pdx->interface->dev,"%s area:%d, size:%08x", __func__, td.wAreaNum, td.dwLength); - // The strange cast is done so that we don't get warnings in 32-bit linux about the size of the - // pointer. The pointer is always passed as a 64-bit object so that we don't have problems using - // a 32-bit program on a 64-bit system. unsigned long is 64-bits on a 64-bit system. - iReturn = SetArea(pdx, td.wAreaNum, (char __user *)((unsigned long)td.lpvBuff), td.dwLength, false, false); - mutex_unlock(&pdx->io_mutex); - return iReturn; + int iReturn; + TRANSFERDESC td; + copy_from_user(&td, pTD, sizeof(td)); + mutex_lock(&pdx->io_mutex); + dev_dbg(&pdx->interface->dev, "%s area:%d, size:%08x", __func__, + td.wAreaNum, td.dwLength); + // The strange cast is done so that we don't get warnings in 32-bit linux about the size of the + // pointer. The pointer is always passed as a 64-bit object so that we don't have problems using + // a 32-bit program on a 64-bit system. unsigned long is 64-bits on a 64-bit system. + iReturn = + SetArea(pdx, td.wAreaNum, + (char __user *)((unsigned long)td.lpvBuff), td.dwLength, + false, false); + mutex_unlock(&pdx->io_mutex); + return iReturn; } /**************************************************************************** ** UnSetTransfer ** Erases a transfer area record ****************************************************************************/ -int UnsetTransfer(DEVICE_EXTENSION *pdx, int nArea) +int UnsetTransfer(DEVICE_EXTENSION * pdx, int nArea) { - int iReturn; - mutex_lock(&pdx->io_mutex); - iReturn = ClearArea(pdx, nArea); - mutex_unlock(&pdx->io_mutex); - return iReturn; + int iReturn; + mutex_lock(&pdx->io_mutex); + iReturn = ClearArea(pdx, nArea); + mutex_unlock(&pdx->io_mutex); + return iReturn; } /**************************************************************************** @@ -786,31 +794,30 @@ int UnsetTransfer(DEVICE_EXTENSION *pdx, int nArea) ** pretend that whatever the user asked for was achieved, so we return 1 if ** try to create one, and 0 if they ask to remove (assuming all else was OK). ****************************************************************************/ -int SetEvent(DEVICE_EXTENSION *pdx, TRANSFEREVENT __user*pTE) +int SetEvent(DEVICE_EXTENSION * pdx, TRANSFEREVENT __user * pTE) { - int iReturn = U14ERR_NOERROR; - TRANSFEREVENT te; - copy_from_user(&te, pTE, sizeof(te)); // get a local copy of the data - if (te.wAreaNum >= MAX_TRANSAREAS) // the area must exist - return U14ERR_BADAREA; - else - { - TRANSAREA *pTA = &pdx->rTransDef[te.wAreaNum]; - mutex_lock(&pdx->io_mutex); // make sure we have no competitor - spin_lock_irq(&pdx->stagedLock); - if (pTA->bUsed) // area must be in use - { - pTA->dwEventSt = te.dwStart; // set area regions - pTA->dwEventSz = te.dwLength; // set size (0 cancels it) - pTA->bEventToHost = te.wFlags & 1; // set the direction - pTA->iWakeUp = 0; // zero the wake up count - } - else - iReturn = U14ERR_NOTSET; - spin_unlock_irq(&pdx->stagedLock); - mutex_unlock(&pdx->io_mutex); - } - return iReturn == U14ERR_NOERROR ? (te.iSetEvent ? 1 : U14ERR_NOERROR) : iReturn; + int iReturn = U14ERR_NOERROR; + TRANSFEREVENT te; + copy_from_user(&te, pTE, sizeof(te)); // get a local copy of the data + if (te.wAreaNum >= MAX_TRANSAREAS) // the area must exist + return U14ERR_BADAREA; + else { + TRANSAREA *pTA = &pdx->rTransDef[te.wAreaNum]; + mutex_lock(&pdx->io_mutex); // make sure we have no competitor + spin_lock_irq(&pdx->stagedLock); + if (pTA->bUsed) // area must be in use + { + pTA->dwEventSt = te.dwStart; // set area regions + pTA->dwEventSz = te.dwLength; // set size (0 cancels it) + pTA->bEventToHost = te.wFlags & 1; // set the direction + pTA->iWakeUp = 0; // zero the wake up count + } else + iReturn = U14ERR_NOTSET; + spin_unlock_irq(&pdx->stagedLock); + mutex_unlock(&pdx->io_mutex); + } + return iReturn == + U14ERR_NOERROR ? (te.iSetEvent ? 1 : U14ERR_NOERROR) : iReturn; } /**************************************************************************** @@ -819,40 +826,45 @@ int SetEvent(DEVICE_EXTENSION *pdx, TRANSFEREVENT __user*pTE) ** of times that a block met the event condition since we last cleared it or ** 0 if timed out, or -ve error (bad area or not set, or signal). ****************************************************************************/ -int WaitEvent(DEVICE_EXTENSION *pdx, int nArea, int msTimeOut) +int WaitEvent(DEVICE_EXTENSION * pdx, int nArea, int msTimeOut) { - int iReturn; - if ((unsigned)nArea > MAX_TRANSAREAS) - return U14ERR_BADAREA; - else - { - int iWait; - TRANSAREA *pTA = &pdx->rTransDef[nArea]; - msTimeOut = (msTimeOut * HZ + 999)/1000; // convert timeout to jiffies - - // We cannot wait holding the mutex, but we check the flags while holding - // it. This may well be pointless as another thread could get in between - // releasing it and the wait call. However, this would have to clear the - // iWakeUp flag. However, the !pTA-bUsed may help us in this case. - mutex_lock(&pdx->io_mutex); // make sure we have no competitor - if (!pTA->bUsed || !pTA->dwEventSz) // check something to wait for... - return U14ERR_NOTSET; // ...else we do nothing - mutex_unlock(&pdx->io_mutex); - - if (msTimeOut) - iWait = wait_event_interruptible_timeout(pTA->wqEvent, pTA->iWakeUp || !pTA->bUsed, msTimeOut); - else - iWait = wait_event_interruptible(pTA->wqEvent, pTA->iWakeUp || !pTA->bUsed); - if (iWait) - iReturn = -ERESTARTSYS; // oops - we have had a SIGNAL - else - iReturn = pTA->iWakeUp; // else the wakeup count - - spin_lock_irq(&pdx->stagedLock); - pTA->iWakeUp = 0; // clear the flag - spin_unlock_irq(&pdx->stagedLock); - } - return iReturn; + int iReturn; + if ((unsigned)nArea > MAX_TRANSAREAS) + return U14ERR_BADAREA; + else { + int iWait; + TRANSAREA *pTA = &pdx->rTransDef[nArea]; + msTimeOut = (msTimeOut * HZ + 999) / 1000; // convert timeout to jiffies + + // We cannot wait holding the mutex, but we check the flags while holding + // it. This may well be pointless as another thread could get in between + // releasing it and the wait call. However, this would have to clear the + // iWakeUp flag. However, the !pTA-bUsed may help us in this case. + mutex_lock(&pdx->io_mutex); // make sure we have no competitor + if (!pTA->bUsed || !pTA->dwEventSz) // check something to wait for... + return U14ERR_NOTSET; // ...else we do nothing + mutex_unlock(&pdx->io_mutex); + + if (msTimeOut) + iWait = + wait_event_interruptible_timeout(pTA->wqEvent, + pTA->iWakeUp + || !pTA->bUsed, + msTimeOut); + else + iWait = + wait_event_interruptible(pTA->wqEvent, pTA->iWakeUp + || !pTA->bUsed); + if (iWait) + iReturn = -ERESTARTSYS; // oops - we have had a SIGNAL + else + iReturn = pTA->iWakeUp; // else the wakeup count + + spin_lock_irq(&pdx->stagedLock); + pTA->iWakeUp = 0; // clear the flag + spin_unlock_irq(&pdx->stagedLock); + } + return iReturn; } /**************************************************************************** @@ -861,52 +873,51 @@ int WaitEvent(DEVICE_EXTENSION *pdx, int nArea, int msTimeOut) ** number of times a block completed since the last call, or 0 if none or a ** negative error. ****************************************************************************/ -int TestEvent(DEVICE_EXTENSION *pdx, int nArea) +int TestEvent(DEVICE_EXTENSION * pdx, int nArea) { - int iReturn; - if ((unsigned)nArea > MAX_TRANSAREAS) - iReturn = U14ERR_BADAREA; - else - { - TRANSAREA *pTA = &pdx->rTransDef[nArea]; - mutex_lock(&pdx->io_mutex); // make sure we have no competitor - spin_lock_irq(&pdx->stagedLock); - iReturn = pTA->iWakeUp; // get wakeup count since last call - pTA->iWakeUp = 0; // clear the count - spin_unlock_irq(&pdx->stagedLock); - mutex_unlock(&pdx->io_mutex); - } - return iReturn; + int iReturn; + if ((unsigned)nArea > MAX_TRANSAREAS) + iReturn = U14ERR_BADAREA; + else { + TRANSAREA *pTA = &pdx->rTransDef[nArea]; + mutex_lock(&pdx->io_mutex); // make sure we have no competitor + spin_lock_irq(&pdx->stagedLock); + iReturn = pTA->iWakeUp; // get wakeup count since last call + pTA->iWakeUp = 0; // clear the count + spin_unlock_irq(&pdx->stagedLock); + mutex_unlock(&pdx->io_mutex); + } + return iReturn; } /**************************************************************************** ** GetTransferInfo ** Puts the current state of the 1401 in a TGET_TX_BLOCK. *****************************************************************************/ -int GetTransfer(DEVICE_EXTENSION *pdx, TGET_TX_BLOCK __user *pTX) +int GetTransfer(DEVICE_EXTENSION * pdx, TGET_TX_BLOCK __user * pTX) { - int iReturn = U14ERR_NOERROR; - unsigned int dwIdent; - - mutex_lock(&pdx->io_mutex); - dwIdent = pdx->StagedId; // area ident for last xfer - if (dwIdent >= MAX_TRANSAREAS) - iReturn = U14ERR_BADAREA; - else - { - // Return the best information we have - we don't have physical addresses - TGET_TX_BLOCK tx; - memset(&tx, 0, sizeof(tx)); // clean out local work structure - tx.size = pdx->rTransDef[dwIdent].dwLength; - tx.linear = (long long)((long)pdx->rTransDef[dwIdent].lpvBuff); - tx.avail = GET_TX_MAXENTRIES; // how many blocks we could return - tx.used = 1; // number we actually return - tx.entries[0].physical = (long long)(tx.linear+pdx->StagedOffset); - tx.entries[0].size = tx.size; - copy_to_user(pTX, &tx, sizeof(tx)); - } - mutex_unlock(&pdx->io_mutex); - return iReturn; + int iReturn = U14ERR_NOERROR; + unsigned int dwIdent; + + mutex_lock(&pdx->io_mutex); + dwIdent = pdx->StagedId; // area ident for last xfer + if (dwIdent >= MAX_TRANSAREAS) + iReturn = U14ERR_BADAREA; + else { + // Return the best information we have - we don't have physical addresses + TGET_TX_BLOCK tx; + memset(&tx, 0, sizeof(tx)); // clean out local work structure + tx.size = pdx->rTransDef[dwIdent].dwLength; + tx.linear = (long long)((long)pdx->rTransDef[dwIdent].lpvBuff); + tx.avail = GET_TX_MAXENTRIES; // how many blocks we could return + tx.used = 1; // number we actually return + tx.entries[0].physical = + (long long)(tx.linear + pdx->StagedOffset); + tx.entries[0].size = tx.size; + copy_to_user(pTX, &tx, sizeof(tx)); + } + mutex_unlock(&pdx->io_mutex); + return iReturn; } /**************************************************************************** @@ -914,14 +925,14 @@ int GetTransfer(DEVICE_EXTENSION *pdx, TGET_TX_BLOCK __user *pTX) ** ** Empties the host i/o buffers ****************************************************************************/ -int KillIO1401(DEVICE_EXTENSION *pdx) +int KillIO1401(DEVICE_EXTENSION * pdx) { - dev_dbg(&pdx->interface->dev, "%s", __func__); - mutex_lock(&pdx->io_mutex); - FlushOutBuff(pdx); - FlushInBuff(pdx); - mutex_unlock(&pdx->io_mutex); - return U14ERR_NOERROR; + dev_dbg(&pdx->interface->dev, "%s", __func__); + mutex_lock(&pdx->io_mutex); + FlushOutBuff(pdx); + FlushInBuff(pdx); + mutex_unlock(&pdx->io_mutex); + return U14ERR_NOERROR; } /**************************************************************************** @@ -929,11 +940,11 @@ int KillIO1401(DEVICE_EXTENSION *pdx) ** Returns a 0 or a 1 for whether DMA is happening. No point holding a mutex ** for this as it only does one read. *****************************************************************************/ -int BlkTransState(DEVICE_EXTENSION *pdx) +int BlkTransState(DEVICE_EXTENSION * pdx) { - int iReturn = pdx->dwDMAFlag != MODE_CHAR; - dev_dbg(&pdx->interface->dev, "%s = %d", __func__, iReturn); - return iReturn; + int iReturn = pdx->dwDMAFlag != MODE_CHAR; + dev_dbg(&pdx->interface->dev, "%s = %d", __func__, iReturn); + return iReturn; } /**************************************************************************** @@ -941,121 +952,121 @@ int BlkTransState(DEVICE_EXTENSION *pdx) ** ** Puts the current state of the 1401 in the Irp return buffer. *****************************************************************************/ -int StateOf1401(DEVICE_EXTENSION *pdx) +int StateOf1401(DEVICE_EXTENSION * pdx) { - int iReturn; - mutex_lock(&pdx->io_mutex); + int iReturn; + mutex_lock(&pdx->io_mutex); - QuickCheck(pdx, false, false); // get state up to date, no reset - iReturn = pdx->sCurrentState; + QuickCheck(pdx, false, false); // get state up to date, no reset + iReturn = pdx->sCurrentState; - mutex_unlock(&pdx->io_mutex); - dev_dbg(&pdx->interface->dev, "%s = %d", __func__, iReturn); + mutex_unlock(&pdx->io_mutex); + dev_dbg(&pdx->interface->dev, "%s = %d", __func__, iReturn); - return iReturn; + return iReturn; } + /**************************************************************************** ** StartSelfTest ** ** Initiates a self-test cycle. The assumption is that we have no interrupts ** active, so we should make sure that this is the case. *****************************************************************************/ -int StartSelfTest(DEVICE_EXTENSION *pdx) +int StartSelfTest(DEVICE_EXTENSION * pdx) { - int nGot; - mutex_lock(&pdx->io_mutex); - dev_dbg(&pdx->interface->dev, "%s", __func__); + int nGot; + mutex_lock(&pdx->io_mutex); + dev_dbg(&pdx->interface->dev, "%s", __func__); - ced_draw_down(pdx); // wait for, then kill outstanding Urbs - FlushInBuff(pdx); // Clear out input buffer & pipe - FlushOutBuff(pdx); // Clear output buffer & pipe + ced_draw_down(pdx); // wait for, then kill outstanding Urbs + FlushInBuff(pdx); // Clear out input buffer & pipe + FlushOutBuff(pdx); // Clear output buffer & pipe // ReadWrite_Cancel(pDeviceObject); /* so things stay tidy */ - pdx->dwDMAFlag = MODE_CHAR; /* Clear DMA mode flags here */ + pdx->dwDMAFlag = MODE_CHAR; /* Clear DMA mode flags here */ - nGot = usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0), - DB_SELFTEST, (H_TO_D|VENDOR|DEVREQ), 0, 0, - 0, 0, HZ); // allow 1 second timeout - pdx->ulSelfTestTime = jiffies + HZ*30; // 30 seconds into the future + nGot = usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0), DB_SELFTEST, (H_TO_D | VENDOR | DEVREQ), 0, 0, 0, 0, HZ); // allow 1 second timeout + pdx->ulSelfTestTime = jiffies + HZ * 30; // 30 seconds into the future - mutex_unlock(&pdx->io_mutex); - if (nGot < 0) - dev_err(&pdx->interface->dev, "%s err=%d", __func__, nGot); - return nGot < 0 ? U14ERR_FAIL : U14ERR_NOERROR; + mutex_unlock(&pdx->io_mutex); + if (nGot < 0) + dev_err(&pdx->interface->dev, "%s err=%d", __func__, nGot); + return nGot < 0 ? U14ERR_FAIL : U14ERR_NOERROR; } - /**************************************************************************** ** CheckSelfTest ** ** Check progress of a self-test cycle ****************************************************************************/ -int CheckSelfTest(DEVICE_EXTENSION *pdx, TGET_SELFTEST __user *pGST) +int CheckSelfTest(DEVICE_EXTENSION * pdx, TGET_SELFTEST __user * pGST) { - unsigned int state, error; - int iReturn; - TGET_SELFTEST gst; // local work space - memset(&gst, 0, sizeof(gst)); // clear out the space (sets code 0) - - mutex_lock(&pdx->io_mutex); - - dev_dbg(&pdx->interface->dev, "%s", __func__); - iReturn = Get1401State(pdx, &state, &error); - if (iReturn == U14ERR_NOERROR) // Only accept zero if it happens twice - iReturn = Get1401State(pdx, &state, &error); - - if (iReturn != U14ERR_NOERROR) // Self-test can cause comms errors - { // so we assume still testing - dev_err(&pdx->interface->dev, "%s Get1401State=%d, assuming still testing", __func__, iReturn); - state = 0x80; // Force still-testing, no error - error = 0; - iReturn = U14ERR_NOERROR; - } - - if ((state == -1) && (error == -1)) // If Get1401State had problems - { - dev_err(&pdx->interface->dev, "%s Get1401State failed, assuming still testing", __func__); - state = 0x80; // Force still-testing, no error - error = 0; - } - - if ((state & 0xFF) == 0x80) // If we are still in self-test - { - if (state & 0x00FF0000) // Have we got an error? - { - gst.code = (state & 0x00FF0000) >> 16; // read the error code - gst.x = error & 0x0000FFFF; // Error data X - gst.y = (error & 0xFFFF0000) >> 16; // and data Y - dev_dbg(&pdx->interface->dev,"Self-test error code %d", gst.code); - } - else // No error, check for timeout - { - unsigned long ulNow = jiffies; // get current time - if (time_after(ulNow, pdx->ulSelfTestTime)) - { - gst.code = -2; // Flag the timeout - dev_dbg(&pdx->interface->dev, "Self-test timed-out"); - } - else - dev_dbg(&pdx->interface->dev, "Self-test on-going"); - } - } - else - { - gst.code = -1; // Flag the test is done - dev_dbg(&pdx->interface->dev, "Self-test done"); - } - - if (gst.code < 0) // If we have a problem or finished - { // If using the 2890 we should reset properly - if ((pdx->nPipes == 4) && (pdx->s1401Type <= TYPEPOWER)) - Is1401(pdx); // Get 1401 reset and OK - else - QuickCheck(pdx, true, true); // Otherwise check without reset unless problems - } - mutex_unlock(&pdx->io_mutex); - - copy_to_user(pGST, &gst, sizeof(gst)); // copy result to user space - return iReturn; + unsigned int state, error; + int iReturn; + TGET_SELFTEST gst; // local work space + memset(&gst, 0, sizeof(gst)); // clear out the space (sets code 0) + + mutex_lock(&pdx->io_mutex); + + dev_dbg(&pdx->interface->dev, "%s", __func__); + iReturn = Get1401State(pdx, &state, &error); + if (iReturn == U14ERR_NOERROR) // Only accept zero if it happens twice + iReturn = Get1401State(pdx, &state, &error); + + if (iReturn != U14ERR_NOERROR) // Self-test can cause comms errors + { // so we assume still testing + dev_err(&pdx->interface->dev, + "%s Get1401State=%d, assuming still testing", __func__, + iReturn); + state = 0x80; // Force still-testing, no error + error = 0; + iReturn = U14ERR_NOERROR; + } + + if ((state == -1) && (error == -1)) // If Get1401State had problems + { + dev_err(&pdx->interface->dev, + "%s Get1401State failed, assuming still testing", + __func__); + state = 0x80; // Force still-testing, no error + error = 0; + } + + if ((state & 0xFF) == 0x80) // If we are still in self-test + { + if (state & 0x00FF0000) // Have we got an error? + { + gst.code = (state & 0x00FF0000) >> 16; // read the error code + gst.x = error & 0x0000FFFF; // Error data X + gst.y = (error & 0xFFFF0000) >> 16; // and data Y + dev_dbg(&pdx->interface->dev, "Self-test error code %d", + gst.code); + } else // No error, check for timeout + { + unsigned long ulNow = jiffies; // get current time + if (time_after(ulNow, pdx->ulSelfTestTime)) { + gst.code = -2; // Flag the timeout + dev_dbg(&pdx->interface->dev, + "Self-test timed-out"); + } else + dev_dbg(&pdx->interface->dev, + "Self-test on-going"); + } + } else { + gst.code = -1; // Flag the test is done + dev_dbg(&pdx->interface->dev, "Self-test done"); + } + + if (gst.code < 0) // If we have a problem or finished + { // If using the 2890 we should reset properly + if ((pdx->nPipes == 4) && (pdx->s1401Type <= TYPEPOWER)) + Is1401(pdx); // Get 1401 reset and OK + else + QuickCheck(pdx, true, true); // Otherwise check without reset unless problems + } + mutex_unlock(&pdx->io_mutex); + + copy_to_user(pGST, &gst, sizeof(gst)); // copy result to user space + return iReturn; } /**************************************************************************** @@ -1063,28 +1074,32 @@ int CheckSelfTest(DEVICE_EXTENSION *pdx, TGET_SELFTEST __user *pGST) ** ** Returns code for standard, plus, micro1401, power1401 or none ****************************************************************************/ -int TypeOf1401(DEVICE_EXTENSION *pdx) +int TypeOf1401(DEVICE_EXTENSION * pdx) { - int iReturn = TYPEUNKNOWN; - mutex_lock(&pdx->io_mutex); - dev_dbg(&pdx->interface->dev, "%s", __func__); - - switch (pdx->s1401Type) - { - case TYPE1401: iReturn = U14ERR_STD; break; // Handle these types directly - case TYPEPLUS: iReturn = U14ERR_PLUS; break; - case TYPEU1401:iReturn = U14ERR_U1401;break; - default: - if ((pdx->s1401Type >= TYPEPOWER) && - (pdx->s1401Type <= 25)) - iReturn = pdx->s1401Type + 4; // We can calculate types - else // for up-coming 1401 designs - iReturn = TYPEUNKNOWN; // Don't know or not there - } - dev_dbg(&pdx->interface->dev, "%s %d", __func__, iReturn); - mutex_unlock(&pdx->io_mutex); - - return iReturn; + int iReturn = TYPEUNKNOWN; + mutex_lock(&pdx->io_mutex); + dev_dbg(&pdx->interface->dev, "%s", __func__); + + switch (pdx->s1401Type) { + case TYPE1401: + iReturn = U14ERR_STD; + break; // Handle these types directly + case TYPEPLUS: + iReturn = U14ERR_PLUS; + break; + case TYPEU1401: + iReturn = U14ERR_U1401; + break; + default: + if ((pdx->s1401Type >= TYPEPOWER) && (pdx->s1401Type <= 25)) + iReturn = pdx->s1401Type + 4; // We can calculate types + else // for up-coming 1401 designs + iReturn = TYPEUNKNOWN; // Don't know or not there + } + dev_dbg(&pdx->interface->dev, "%s %d", __func__, iReturn); + mutex_unlock(&pdx->io_mutex); + + return iReturn; } /**************************************************************************** @@ -1092,17 +1107,17 @@ int TypeOf1401(DEVICE_EXTENSION *pdx) ** ** Returns flags on block transfer abilities ****************************************************************************/ -int TransferFlags(DEVICE_EXTENSION *pdx) +int TransferFlags(DEVICE_EXTENSION * pdx) { - int iReturn = U14TF_MULTIA | U14TF_DIAG | // we always have multiple DMA area - U14TF_NOTIFY | U14TF_CIRCTH; // diagnostics, notify and circular - dev_dbg(&pdx->interface->dev, "%s", __func__); - mutex_lock(&pdx->io_mutex); - if (pdx->bIsUSB2) // Set flag for USB2 if appropriate - iReturn |= U14TF_USB2; - mutex_unlock(&pdx->io_mutex); - - return iReturn; + int iReturn = U14TF_MULTIA | U14TF_DIAG | // we always have multiple DMA area + U14TF_NOTIFY | U14TF_CIRCTH; // diagnostics, notify and circular + dev_dbg(&pdx->interface->dev, "%s", __func__); + mutex_lock(&pdx->io_mutex); + if (pdx->bIsUSB2) // Set flag for USB2 if appropriate + iReturn |= U14TF_USB2; + mutex_unlock(&pdx->io_mutex); + + return iReturn; } /*************************************************************************** @@ -1110,18 +1125,17 @@ int TransferFlags(DEVICE_EXTENSION *pdx) ** Issues a debug\diagnostic command to the 1401 along with a 32-bit datum ** This is a utility command used for dbg operations. */ -static int DbgCmd1401(DEVICE_EXTENSION *pdx, unsigned char cmd, unsigned int data) +static int DbgCmd1401(DEVICE_EXTENSION * pdx, unsigned char cmd, + unsigned int data) { - int iReturn; - dev_dbg(&pdx->interface->dev, "%s entry", __func__); - iReturn = usb_control_msg(pdx->udev, usb_sndctrlpipe(pdx->udev, 0), - cmd, (H_TO_D|VENDOR|DEVREQ), - (unsigned short)data, (unsigned short)(data >> 16), - 0, 0, HZ); // allow 1 second timeout - if (iReturn < 0) - dev_err(&pdx->interface->dev, "%s fail code=%d", __func__, iReturn); - - return iReturn; + int iReturn; + dev_dbg(&pdx->interface->dev, "%s entry", __func__); + iReturn = usb_control_msg(pdx->udev, usb_sndctrlpipe(pdx->udev, 0), cmd, (H_TO_D | VENDOR | DEVREQ), (unsigned short)data, (unsigned short)(data >> 16), 0, 0, HZ); // allow 1 second timeout + if (iReturn < 0) + dev_err(&pdx->interface->dev, "%s fail code=%d", __func__, + iReturn); + + return iReturn; } /**************************************************************************** @@ -1129,146 +1143,141 @@ static int DbgCmd1401(DEVICE_EXTENSION *pdx, unsigned char cmd, unsigned int dat ** ** Execute the diagnostic peek operation. Uses address, width and repeats. ****************************************************************************/ -int DbgPeek(DEVICE_EXTENSION *pdx, TDBGBLOCK __user* pDB) +int DbgPeek(DEVICE_EXTENSION * pdx, TDBGBLOCK __user * pDB) { - int iReturn; - TDBGBLOCK db; - copy_from_user(&db, pDB, sizeof(db)); // get the data - - mutex_lock(&pdx->io_mutex); - dev_dbg(&pdx->interface->dev, "%s @ %08x", __func__, db.iAddr); - - iReturn = DbgCmd1401(pdx, DB_SETADD, db.iAddr); - if (iReturn == U14ERR_NOERROR) - iReturn = DbgCmd1401(pdx, DB_WIDTH, db.iWidth); - if (iReturn == U14ERR_NOERROR) - iReturn = DbgCmd1401(pdx, DB_REPEATS, db.iRepeats); - if (iReturn == U14ERR_NOERROR) - iReturn = DbgCmd1401(pdx, DB_PEEK, 0); - mutex_unlock(&pdx->io_mutex); - - return iReturn; + int iReturn; + TDBGBLOCK db; + copy_from_user(&db, pDB, sizeof(db)); // get the data + + mutex_lock(&pdx->io_mutex); + dev_dbg(&pdx->interface->dev, "%s @ %08x", __func__, db.iAddr); + + iReturn = DbgCmd1401(pdx, DB_SETADD, db.iAddr); + if (iReturn == U14ERR_NOERROR) + iReturn = DbgCmd1401(pdx, DB_WIDTH, db.iWidth); + if (iReturn == U14ERR_NOERROR) + iReturn = DbgCmd1401(pdx, DB_REPEATS, db.iRepeats); + if (iReturn == U14ERR_NOERROR) + iReturn = DbgCmd1401(pdx, DB_PEEK, 0); + mutex_unlock(&pdx->io_mutex); + + return iReturn; } - /**************************************************************************** ** DbgPoke ** ** Execute the diagnostic poke operation. Parameters are in the CSBLOCK struct ** in order address, size, repeats and value to poke. ****************************************************************************/ -int DbgPoke(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB) +int DbgPoke(DEVICE_EXTENSION * pdx, TDBGBLOCK __user * pDB) { - int iReturn; - TDBGBLOCK db; - copy_from_user(&db, pDB, sizeof(db)); // get the data - - mutex_lock(&pdx->io_mutex); - dev_dbg(&pdx->interface->dev, "%s @ %08x", __func__, db.iAddr); - - iReturn = DbgCmd1401(pdx, DB_SETADD, db.iAddr); - if (iReturn == U14ERR_NOERROR) - iReturn = DbgCmd1401(pdx, DB_WIDTH, db.iWidth); - if (iReturn == U14ERR_NOERROR) - iReturn = DbgCmd1401(pdx, DB_REPEATS, db.iRepeats); - if (iReturn == U14ERR_NOERROR) - iReturn = DbgCmd1401(pdx, DB_POKE, db.iData); - mutex_unlock(&pdx->io_mutex); - - return iReturn; + int iReturn; + TDBGBLOCK db; + copy_from_user(&db, pDB, sizeof(db)); // get the data + + mutex_lock(&pdx->io_mutex); + dev_dbg(&pdx->interface->dev, "%s @ %08x", __func__, db.iAddr); + + iReturn = DbgCmd1401(pdx, DB_SETADD, db.iAddr); + if (iReturn == U14ERR_NOERROR) + iReturn = DbgCmd1401(pdx, DB_WIDTH, db.iWidth); + if (iReturn == U14ERR_NOERROR) + iReturn = DbgCmd1401(pdx, DB_REPEATS, db.iRepeats); + if (iReturn == U14ERR_NOERROR) + iReturn = DbgCmd1401(pdx, DB_POKE, db.iData); + mutex_unlock(&pdx->io_mutex); + + return iReturn; } - /**************************************************************************** ** DbgRampData ** ** Execute the diagnostic ramp data operation. Parameters are in the CSBLOCK struct ** in order address, default, enable mask, size and repeats. ****************************************************************************/ -int DbgRampData(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB) +int DbgRampData(DEVICE_EXTENSION * pdx, TDBGBLOCK __user * pDB) { - int iReturn; - TDBGBLOCK db; - copy_from_user(&db, pDB, sizeof(db)); // get the data - - mutex_lock(&pdx->io_mutex); - dev_dbg(&pdx->interface->dev, "%s @ %08x", __func__, db.iAddr); - - iReturn = DbgCmd1401(pdx, DB_SETADD, db.iAddr); - if (iReturn == U14ERR_NOERROR) - iReturn = DbgCmd1401(pdx, DB_SETDEF, db.iDefault); - if (iReturn == U14ERR_NOERROR) - iReturn = DbgCmd1401(pdx, DB_SETMASK, db.iMask); - if (iReturn == U14ERR_NOERROR) - iReturn = DbgCmd1401(pdx, DB_WIDTH, db.iWidth); - if (iReturn == U14ERR_NOERROR) - iReturn = DbgCmd1401(pdx, DB_REPEATS, db.iRepeats); - if (iReturn == U14ERR_NOERROR) - iReturn = DbgCmd1401(pdx, DB_RAMPD, 0); - mutex_unlock(&pdx->io_mutex); - - return iReturn; + int iReturn; + TDBGBLOCK db; + copy_from_user(&db, pDB, sizeof(db)); // get the data + + mutex_lock(&pdx->io_mutex); + dev_dbg(&pdx->interface->dev, "%s @ %08x", __func__, db.iAddr); + + iReturn = DbgCmd1401(pdx, DB_SETADD, db.iAddr); + if (iReturn == U14ERR_NOERROR) + iReturn = DbgCmd1401(pdx, DB_SETDEF, db.iDefault); + if (iReturn == U14ERR_NOERROR) + iReturn = DbgCmd1401(pdx, DB_SETMASK, db.iMask); + if (iReturn == U14ERR_NOERROR) + iReturn = DbgCmd1401(pdx, DB_WIDTH, db.iWidth); + if (iReturn == U14ERR_NOERROR) + iReturn = DbgCmd1401(pdx, DB_REPEATS, db.iRepeats); + if (iReturn == U14ERR_NOERROR) + iReturn = DbgCmd1401(pdx, DB_RAMPD, 0); + mutex_unlock(&pdx->io_mutex); + + return iReturn; } - /**************************************************************************** ** DbgRampAddr ** ** Execute the diagnostic ramp address operation ****************************************************************************/ -int DbgRampAddr(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB) +int DbgRampAddr(DEVICE_EXTENSION * pdx, TDBGBLOCK __user * pDB) { - int iReturn; - TDBGBLOCK db; - copy_from_user(&db, pDB, sizeof(db)); // get the data - - mutex_lock(&pdx->io_mutex); - dev_dbg(&pdx->interface->dev, "%s", __func__); - - iReturn = DbgCmd1401(pdx, DB_SETDEF, db.iDefault); - if (iReturn == U14ERR_NOERROR) - iReturn = DbgCmd1401(pdx, DB_SETMASK, db.iMask); - if (iReturn == U14ERR_NOERROR) - iReturn = DbgCmd1401(pdx, DB_WIDTH, db.iWidth); - if (iReturn == U14ERR_NOERROR) - iReturn = DbgCmd1401(pdx, DB_REPEATS, db.iRepeats); - if (iReturn == U14ERR_NOERROR) - iReturn = DbgCmd1401(pdx, DB_RAMPA, 0); - mutex_unlock(&pdx->io_mutex); - - return iReturn; + int iReturn; + TDBGBLOCK db; + copy_from_user(&db, pDB, sizeof(db)); // get the data + + mutex_lock(&pdx->io_mutex); + dev_dbg(&pdx->interface->dev, "%s", __func__); + + iReturn = DbgCmd1401(pdx, DB_SETDEF, db.iDefault); + if (iReturn == U14ERR_NOERROR) + iReturn = DbgCmd1401(pdx, DB_SETMASK, db.iMask); + if (iReturn == U14ERR_NOERROR) + iReturn = DbgCmd1401(pdx, DB_WIDTH, db.iWidth); + if (iReturn == U14ERR_NOERROR) + iReturn = DbgCmd1401(pdx, DB_REPEATS, db.iRepeats); + if (iReturn == U14ERR_NOERROR) + iReturn = DbgCmd1401(pdx, DB_RAMPA, 0); + mutex_unlock(&pdx->io_mutex); + + return iReturn; } - /**************************************************************************** ** DbgGetData ** ** Retrieve the data resulting from the last debug Peek operation ****************************************************************************/ -int DbgGetData(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB) +int DbgGetData(DEVICE_EXTENSION * pdx, TDBGBLOCK __user * pDB) { - int iReturn; - TDBGBLOCK db; - memset(&db, 0, sizeof(db)); // fill returned block with 0s - - mutex_lock(&pdx->io_mutex); - dev_dbg(&pdx->interface->dev, "%s", __func__); - - // Read back the last peeked value from the 1401. - iReturn = usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0), - DB_DATA, (D_TO_H|VENDOR|DEVREQ), 0,0, - &db.iData, sizeof(db.iData), HZ); - if (iReturn == sizeof(db.iData)) - { - copy_to_user(pDB, &db, sizeof(db)); - iReturn = U14ERR_NOERROR; - } - else - dev_err(&pdx->interface->dev, "%s failed, code %d", __func__, iReturn); - - mutex_unlock(&pdx->io_mutex); - - return iReturn; + int iReturn; + TDBGBLOCK db; + memset(&db, 0, sizeof(db)); // fill returned block with 0s + + mutex_lock(&pdx->io_mutex); + dev_dbg(&pdx->interface->dev, "%s", __func__); + + // Read back the last peeked value from the 1401. + iReturn = usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0), + DB_DATA, (D_TO_H | VENDOR | DEVREQ), 0, 0, + &db.iData, sizeof(db.iData), HZ); + if (iReturn == sizeof(db.iData)) { + copy_to_user(pDB, &db, sizeof(db)); + iReturn = U14ERR_NOERROR; + } else + dev_err(&pdx->interface->dev, "%s failed, code %d", __func__, + iReturn); + + mutex_unlock(&pdx->io_mutex); + + return iReturn; } /**************************************************************************** @@ -1277,20 +1286,19 @@ int DbgGetData(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB) ** Stop any never-ending debug loop, we just call Get1401State for USB ** ****************************************************************************/ -int DbgStopLoop(DEVICE_EXTENSION *pdx) +int DbgStopLoop(DEVICE_EXTENSION * pdx) { - int iReturn; - unsigned int uState, uErr; + int iReturn; + unsigned int uState, uErr; - mutex_lock(&pdx->io_mutex); - dev_dbg(&pdx->interface->dev, "%s", __func__); - iReturn = Get1401State(pdx, &uState, &uErr); - mutex_unlock(&pdx->io_mutex); + mutex_lock(&pdx->io_mutex); + dev_dbg(&pdx->interface->dev, "%s", __func__); + iReturn = Get1401State(pdx, &uState, &uErr); + mutex_unlock(&pdx->io_mutex); - return iReturn; + return iReturn; } - /**************************************************************************** ** SetCircular ** @@ -1299,22 +1307,26 @@ int DbgStopLoop(DEVICE_EXTENSION *pdx) ** booked and a transfer to that area is in progress. Otherwise, we will ** release the area and re-assign it. ****************************************************************************/ -int SetCircular(DEVICE_EXTENSION *pdx, TRANSFERDESC __user *pTD) +int SetCircular(DEVICE_EXTENSION * pdx, TRANSFERDESC __user * pTD) { - int iReturn; - bool bToHost; - TRANSFERDESC td; - copy_from_user(&td, pTD, sizeof(td)); - mutex_lock(&pdx->io_mutex); - dev_dbg(&pdx->interface->dev,"%s area:%d, size:%08x", __func__, td.wAreaNum, td.dwLength); - bToHost = td.eSize != 0; // this is used as the tohost flag - - // The strange cast is done so that we don't get warnings in 32-bit linux about the size of the - // pointer. The pointer is always passed as a 64-bit object so that we don't have problems using - // a 32-bit program on a 64-bit system. unsigned long is 64-bits on a 64-bit system. - iReturn = SetArea(pdx, td.wAreaNum, (char __user *)((unsigned long)td.lpvBuff), td.dwLength, true, bToHost); - mutex_unlock(&pdx->io_mutex); - return iReturn; + int iReturn; + bool bToHost; + TRANSFERDESC td; + copy_from_user(&td, pTD, sizeof(td)); + mutex_lock(&pdx->io_mutex); + dev_dbg(&pdx->interface->dev, "%s area:%d, size:%08x", __func__, + td.wAreaNum, td.dwLength); + bToHost = td.eSize != 0; // this is used as the tohost flag + + // The strange cast is done so that we don't get warnings in 32-bit linux about the size of the + // pointer. The pointer is always passed as a 64-bit object so that we don't have problems using + // a 32-bit program on a 64-bit system. unsigned long is 64-bits on a 64-bit system. + iReturn = + SetArea(pdx, td.wAreaNum, + (char __user *)((unsigned long)td.lpvBuff), td.dwLength, + true, bToHost); + mutex_unlock(&pdx->io_mutex); + return iReturn; } /**************************************************************************** @@ -1322,140 +1334,145 @@ int SetCircular(DEVICE_EXTENSION *pdx, TRANSFERDESC __user *pTD) ** ** Return the next available block of circularly-transferred data. ****************************************************************************/ -int GetCircBlock(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user* pCB) +int GetCircBlock(DEVICE_EXTENSION * pdx, TCIRCBLOCK __user * pCB) { - int iReturn = U14ERR_NOERROR; - unsigned int nArea; - TCIRCBLOCK cb; - dev_dbg(&pdx->interface->dev, "%s", __func__); - copy_from_user(&cb, pCB, sizeof(cb)); - mutex_lock(&pdx->io_mutex); - - nArea = cb.nArea; // Retrieve parameters first - cb.dwOffset = 0; // set default result (nothing) - cb.dwSize = 0; - - if (nArea < MAX_TRANSAREAS) // The area number must be OK - { - TRANSAREA* pArea = &pdx->rTransDef[nArea]; // Pointer to relevant info - spin_lock_irq(&pdx->stagedLock); // Lock others out - - if ((pArea->bUsed) && (pArea->bCircular) && // Must be circular area - (pArea->bCircToHost)) // For now at least must be to host - { - if (pArea->aBlocks[0].dwSize > 0) // Got anything? - { - cb.dwOffset = pArea->aBlocks[0].dwOffset; - cb.dwSize = pArea->aBlocks[0].dwSize; - dev_dbg(&pdx->interface->dev, "%s return block 0: %d bytes at %d", __func__, cb.dwSize, cb.dwOffset); - } - } - else - iReturn = U14ERR_NOTSET; - - spin_unlock_irq(&pdx->stagedLock); - } - else - iReturn = U14ERR_BADAREA; - - copy_to_user(pCB, &cb, sizeof(cb)); - mutex_unlock(&pdx->io_mutex); - return iReturn; + int iReturn = U14ERR_NOERROR; + unsigned int nArea; + TCIRCBLOCK cb; + dev_dbg(&pdx->interface->dev, "%s", __func__); + copy_from_user(&cb, pCB, sizeof(cb)); + mutex_lock(&pdx->io_mutex); + + nArea = cb.nArea; // Retrieve parameters first + cb.dwOffset = 0; // set default result (nothing) + cb.dwSize = 0; + + if (nArea < MAX_TRANSAREAS) // The area number must be OK + { + TRANSAREA *pArea = &pdx->rTransDef[nArea]; // Pointer to relevant info + spin_lock_irq(&pdx->stagedLock); // Lock others out + + if ((pArea->bUsed) && (pArea->bCircular) && // Must be circular area + (pArea->bCircToHost)) // For now at least must be to host + { + if (pArea->aBlocks[0].dwSize > 0) // Got anything? + { + cb.dwOffset = pArea->aBlocks[0].dwOffset; + cb.dwSize = pArea->aBlocks[0].dwSize; + dev_dbg(&pdx->interface->dev, + "%s return block 0: %d bytes at %d", + __func__, cb.dwSize, cb.dwOffset); + } + } else + iReturn = U14ERR_NOTSET; + + spin_unlock_irq(&pdx->stagedLock); + } else + iReturn = U14ERR_BADAREA; + + copy_to_user(pCB, &cb, sizeof(cb)); + mutex_unlock(&pdx->io_mutex); + return iReturn; } - /**************************************************************************** ** FreeCircBlock ** ** Frees a block of circularly-transferred data and returns the next one. ****************************************************************************/ -int FreeCircBlock(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user* pCB) +int FreeCircBlock(DEVICE_EXTENSION * pdx, TCIRCBLOCK __user * pCB) { - int iReturn = U14ERR_NOERROR; - unsigned int nArea, uStart, uSize; - TCIRCBLOCK cb; - dev_dbg(&pdx->interface->dev, "%s", __func__); - copy_from_user(&cb, pCB, sizeof(cb)); - mutex_lock(&pdx->io_mutex); - - nArea = cb.nArea; // Retrieve parameters first - uStart = cb.dwOffset; - uSize = cb.dwSize; - cb.dwOffset = 0; // then set default result (nothing) - cb.dwSize = 0; - - if (nArea < MAX_TRANSAREAS) // The area number must be OK - { - TRANSAREA* pArea = &pdx->rTransDef[nArea]; // Pointer to relevant info - spin_lock_irq(&pdx->stagedLock); // Lock others out - - if ((pArea->bUsed) && (pArea->bCircular) && // Must be circular area - (pArea->bCircToHost)) // For now at least must be to host - { - bool bWaiting = false; - - if ((pArea->aBlocks[0].dwSize >= uSize) && // Got anything? - (pArea->aBlocks[0].dwOffset == uStart)) // Must be legal data - { - pArea->aBlocks[0].dwSize -= uSize; - pArea->aBlocks[0].dwOffset += uSize; - if (pArea->aBlocks[0].dwSize == 0) // Have we emptied this block? - { - if (pArea->aBlocks[1].dwSize) // Is there a second block? - { - pArea->aBlocks[0] = pArea->aBlocks[1]; // Copy down block 2 data - pArea->aBlocks[1].dwSize = 0; // and mark the second block as unused - pArea->aBlocks[1].dwOffset = 0; - } - else - pArea->aBlocks[0].dwOffset = 0; - } - - dev_dbg(&pdx->interface->dev, "%s free %d bytes at %d, return %d bytes at %d, wait=%d", - __func__, uSize, uStart, pArea->aBlocks[0].dwSize, pArea->aBlocks[0].dwOffset, pdx->bXFerWaiting); - - // Return the next available block of memory as well - if (pArea->aBlocks[0].dwSize > 0) // Got anything? - { - cb.dwOffset = pArea->aBlocks[0].dwOffset; - cb.dwSize = pArea->aBlocks[0].dwSize; - } - - bWaiting = pdx->bXFerWaiting; - if (bWaiting && pdx->bStagedUrbPending) - { - dev_err(&pdx->interface->dev, "%s ERROR: waiting xfer and staged Urb pending!", __func__); - bWaiting = false; - } - } - else - { - dev_err(&pdx->interface->dev, "%s ERROR: freeing %d bytes at %d, block 0 is %d bytes at %d", - __func__, uSize, uStart, pArea->aBlocks[0].dwSize, pArea->aBlocks[0].dwOffset); - iReturn = U14ERR_NOMEMORY; - } - - // If we have one, kick off pending transfer - if (bWaiting) // Got a block xfer waiting? - { - int RWMStat = ReadWriteMem(pdx, !pdx->rDMAInfo.bOutWard, - pdx->rDMAInfo.wIdent, pdx->rDMAInfo.dwOffset, pdx->rDMAInfo.dwSize); - if (RWMStat != U14ERR_NOERROR) - dev_err(&pdx->interface->dev, "%s rw setup failed %d", __func__, RWMStat); - } - } - else - iReturn = U14ERR_NOTSET; - - spin_unlock_irq(&pdx->stagedLock); - } - else - iReturn = U14ERR_BADAREA; - - copy_to_user(pCB, &cb, sizeof(cb)); - mutex_unlock(&pdx->io_mutex); - return iReturn; + int iReturn = U14ERR_NOERROR; + unsigned int nArea, uStart, uSize; + TCIRCBLOCK cb; + dev_dbg(&pdx->interface->dev, "%s", __func__); + copy_from_user(&cb, pCB, sizeof(cb)); + mutex_lock(&pdx->io_mutex); + + nArea = cb.nArea; // Retrieve parameters first + uStart = cb.dwOffset; + uSize = cb.dwSize; + cb.dwOffset = 0; // then set default result (nothing) + cb.dwSize = 0; + + if (nArea < MAX_TRANSAREAS) // The area number must be OK + { + TRANSAREA *pArea = &pdx->rTransDef[nArea]; // Pointer to relevant info + spin_lock_irq(&pdx->stagedLock); // Lock others out + + if ((pArea->bUsed) && (pArea->bCircular) && // Must be circular area + (pArea->bCircToHost)) // For now at least must be to host + { + bool bWaiting = false; + + if ((pArea->aBlocks[0].dwSize >= uSize) && // Got anything? + (pArea->aBlocks[0].dwOffset == uStart)) // Must be legal data + { + pArea->aBlocks[0].dwSize -= uSize; + pArea->aBlocks[0].dwOffset += uSize; + if (pArea->aBlocks[0].dwSize == 0) // Have we emptied this block? + { + if (pArea->aBlocks[1].dwSize) // Is there a second block? + { + pArea->aBlocks[0] = pArea->aBlocks[1]; // Copy down block 2 data + pArea->aBlocks[1].dwSize = 0; // and mark the second block as unused + pArea->aBlocks[1].dwOffset = 0; + } else + pArea->aBlocks[0].dwOffset = 0; + } + + dev_dbg(&pdx->interface->dev, + "%s free %d bytes at %d, return %d bytes at %d, wait=%d", + __func__, uSize, uStart, + pArea->aBlocks[0].dwSize, + pArea->aBlocks[0].dwOffset, + pdx->bXFerWaiting); + + // Return the next available block of memory as well + if (pArea->aBlocks[0].dwSize > 0) // Got anything? + { + cb.dwOffset = + pArea->aBlocks[0].dwOffset; + cb.dwSize = pArea->aBlocks[0].dwSize; + } + + bWaiting = pdx->bXFerWaiting; + if (bWaiting && pdx->bStagedUrbPending) { + dev_err(&pdx->interface->dev, + "%s ERROR: waiting xfer and staged Urb pending!", + __func__); + bWaiting = false; + } + } else { + dev_err(&pdx->interface->dev, + "%s ERROR: freeing %d bytes at %d, block 0 is %d bytes at %d", + __func__, uSize, uStart, + pArea->aBlocks[0].dwSize, + pArea->aBlocks[0].dwOffset); + iReturn = U14ERR_NOMEMORY; + } + + // If we have one, kick off pending transfer + if (bWaiting) // Got a block xfer waiting? + { + int RWMStat = + ReadWriteMem(pdx, !pdx->rDMAInfo.bOutWard, + pdx->rDMAInfo.wIdent, + pdx->rDMAInfo.dwOffset, + pdx->rDMAInfo.dwSize); + if (RWMStat != U14ERR_NOERROR) + dev_err(&pdx->interface->dev, + "%s rw setup failed %d", + __func__, RWMStat); + } + } else + iReturn = U14ERR_NOTSET; + + spin_unlock_irq(&pdx->stagedLock); + } else + iReturn = U14ERR_BADAREA; + + copy_to_user(pCB, &cb, sizeof(cb)); + mutex_unlock(&pdx->io_mutex); + return iReturn; } - - - diff --git a/drivers/staging/ced1401/ced_ioctl.h b/drivers/staging/ced1401/ced_ioctl.h index 075ecad..0895c94 100644 --- a/drivers/staging/ced1401/ced_ioctl.h +++ b/drivers/staging/ced1401/ced_ioctl.h @@ -1,232 +1,345 @@ -/* ced_ioctl.h - IOCTL calls for the CED1401 driver - Copyright (C) 2010 Cambridge Electronic Design Ltd - Author Greg P Smith (greg@ced.co.uk) - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ +/* + * IOCTL calls for the CED1401 driver + * Copyright (C) 2010 Cambridge Electronic Design Ltd + * Author Greg P Smith (greg@ced.co.uk) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ #ifndef __CED_IOCTL_H__ #define __CED_IOCTL_H__ -#include -/// dma modes, only MODE_CHAR and MODE_LINEAR are used in this driver -#define MODE_CHAR 0 -#define MODE_LINEAR 1 +#include + +/* dma modes, only MODE_CHAR and MODE_LINEAR are used in this driver */ +#define MODE_CHAR 0 +#define MODE_LINEAR 1 /**************************************************************************** ** TypeDefs *****************************************************************************/ -typedef unsigned short TBLOCKENTRY; // index the blk transfer table 0-7 +typedef unsigned short TBLOCKENTRY; /* index the blk transfer table 0-7 */ -typedef struct TransferDesc -{ - long long lpvBuff; // address of transfer area (for 64 or 32 bit) - unsigned int dwLength; // length of the area - TBLOCKENTRY wAreaNum; // number of transfer area to set up - short eSize; // element size - is tohost flag for circular +typedef struct TransferDesc { + long long lpvBuff; /* address of transfer area (for 64 or 32 bit) */ + unsigned int dwLength; /* length of the area */ + TBLOCKENTRY wAreaNum; /* number of transfer area to set up */ + short eSize; /* element size - is tohost flag for circular */ } TRANSFERDESC; -typedef TRANSFERDESC* LPTRANSFERDESC; +typedef TRANSFERDESC * LPTRANSFERDESC; -typedef struct TransferEvent -{ - unsigned int dwStart; // offset into the area - unsigned int dwLength; // length of the region - unsigned short wAreaNum; // the area number - unsigned short wFlags; // bit 0 set for toHost - int iSetEvent; // could be dummy in LINUX +typedef struct TransferEvent { + unsigned int dwStart; /* offset into the area */ + unsigned int dwLength; /* length of the region */ + unsigned short wAreaNum; /* the area number */ + unsigned short wFlags; /* bit 0 set for toHost */ + int iSetEvent; /* could be dummy in LINUX */ } TRANSFEREVENT; -#define MAX_TRANSFER_SIZE 0x4000 /* Maximum data bytes per IRP */ -#define MAX_AREA_LENGTH 0x100000 /* Maximum size of transfer area */ -#define MAX_TRANSAREAS 8 /* definitions for dma set up */ +#define MAX_TRANSFER_SIZE 0x4000 /* Maximum data bytes per IRP */ +#define MAX_AREA_LENGTH 0x100000 /* Maximum size of transfer area */ +#define MAX_TRANSAREAS 8 /* definitions for dma set up */ -typedef struct TGetSelfTest -{ - int code; // self-test error code - int x,y; // additional information +typedef struct TGetSelfTest { + int code; /* self-test error code */ + int x, y; /* additional information */ } TGET_SELFTEST; -/// Debug block used for several commands. Not all fields are used for all commands. -typedef struct TDbgBlock -{ - int iAddr; // the address in the 1401 - int iRepeats; // number of repeats - int iWidth; // width in bytes 1, 2, 4 - int iDefault; // default value - int iMask; // mask to apply - int iData; // data for poke, result for peek +/* Debug block used for several commands. Not all fields are used for all commands. */ +typedef struct TDbgBlock { + int iAddr; /* the address in the 1401 */ + int iRepeats; /* number of repeats */ + int iWidth; /* width in bytes 1, 2, 4 */ + int iDefault; /* default value */ + int iMask; /* mask to apply */ + int iData; /* data for poke, result for peek */ } TDBGBLOCK; -/// Used to collect information about a circular block from the device driver -typedef struct TCircBlock -{ - unsigned int nArea; // the area to collect information from - unsigned int dwOffset; // offset into the area to the available block - unsigned int dwSize; // size of the area +/* Used to collect information about a circular block from the device driver */ +typedef struct TCircBlock { + unsigned int nArea; /* the area to collect information from */ + unsigned int dwOffset; /* offset into the area to the available block */ + unsigned int dwSize; /* size of the area */ } TCIRCBLOCK; -/// Used to clollect the 1401 status -typedef struct TCSBlock -{ - unsigned int uiState; - unsigned int uiError; +/* Used to clollect the 1401 status */ +typedef struct TCSBlock { + unsigned int uiState; + unsigned int uiError; } TCSBLOCK; -// As seen by the user, an ioctl call looks like: -// int ioctl(int fd, unsigned long cmd, char* argp); -// We will then have all sorts of variants on this that can be used -// to pass stuff to our driver. We will generate macros for each type -// of call so as to provide some sort of type safety in the calling: +/* + * As seen by the user, an ioctl call looks like: int ioctl(int fd, unsigned + * long cmd, char* argp); We will then have all sorts of variants on this that + * can be used to pass stuff to our driver. We will generate macros for each + * type of call so as to provide some sort of type safety in the calling: + */ #define CED_MAGIC_IOC 0xce -// NBNB: READ and WRITE are from the point of view of the device, not user. -typedef struct ced_ioc_string -{ - int nChars; - char buffer[256]; +/* NBNB: READ and WRITE are from the point of view of the device, not user. */ +typedef struct ced_ioc_string { + int nChars; + char buffer[256]; } CED_IOC_STRING; -#define IOCTL_CED_SENDSTRING(n) _IOC(_IOC_WRITE, CED_MAGIC_IOC, 2, n) - -#define IOCTL_CED_RESET1401 _IO(CED_MAGIC_IOC, 3) -#define IOCTL_CED_GETCHAR _IO(CED_MAGIC_IOC, 4) -#define IOCTL_CED_SENDCHAR _IO(CED_MAGIC_IOC, 5) -#define IOCTL_CED_STAT1401 _IO(CED_MAGIC_IOC, 6) -#define IOCTL_CED_LINECOUNT _IO(CED_MAGIC_IOC, 7) -#define IOCTL_CED_GETSTRING(nMax) _IOC(_IOC_READ, CED_MAGIC_IOC, 8, nMax) - -#define IOCTL_CED_SETTRANSFER _IOW(CED_MAGIC_IOC, 11, TRANSFERDESC) -#define IOCTL_CED_UNSETTRANSFER _IO(CED_MAGIC_IOC, 12) -#define IOCTL_CED_SETEVENT _IOW(CED_MAGIC_IOC,13, TRANSFEREVENT) -#define IOCTL_CED_GETOUTBUFSPACE _IO(CED_MAGIC_IOC, 14) -#define IOCTL_CED_GETBASEADDRESS _IO(CED_MAGIC_IOC, 15) -#define IOCTL_CED_GETDRIVERREVISION _IO(CED_MAGIC_IOC, 16) - -#define IOCTL_CED_GETTRANSFER _IOR(CED_MAGIC_IOC,17, TGET_TX_BLOCK) -#define IOCTL_CED_KILLIO1401 _IO(CED_MAGIC_IOC,18) -#define IOCTL_CED_BLKTRANSSTATE _IO(CED_MAGIC_IOC,19) - -#define IOCTL_CED_STATEOF1401 _IO(CED_MAGIC_IOC,23) -#define IOCTL_CED_GRAB1401 _IO(CED_MAGIC_IOC,25) -#define IOCTL_CED_FREE1401 _IO(CED_MAGIC_IOC,26) -#define IOCTL_CED_STARTSELFTEST _IO(CED_MAGIC_IOC,31) -#define IOCTL_CED_CHECKSELFTEST _IOR(CED_MAGIC_IOC,32, TGET_SELFTEST) -#define IOCTL_CED_TYPEOF1401 _IO(CED_MAGIC_IOC,33) -#define IOCTL_CED_TRANSFERFLAGS _IO(CED_MAGIC_IOC,34) - -#define IOCTL_CED_DBGPEEK _IOW(CED_MAGIC_IOC,35, TDBGBLOCK) -#define IOCTL_CED_DBGPOKE _IOW(CED_MAGIC_IOC,36, TDBGBLOCK) -#define IOCTL_CED_DBGRAMPDATA _IOW(CED_MAGIC_IOC,37, TDBGBLOCK) -#define IOCTL_CED_DBGRAMPADDR _IOW(CED_MAGIC_IOC,38, TDBGBLOCK) -#define IOCTL_CED_DBGGETDATA _IOR(CED_MAGIC_IOC,39, TDBGBLOCK) -#define IOCTL_CED_DBGSTOPLOOP _IO(CED_MAGIC_IOC,40) -#define IOCTL_CED_FULLRESET _IO(CED_MAGIC_IOC,41) -#define IOCTL_CED_SETCIRCULAR _IOW(CED_MAGIC_IOC,42, TRANSFERDESC) -#define IOCTL_CED_GETCIRCBLOCK _IOWR(CED_MAGIC_IOC,43, TCIRCBLOCK) -#define IOCTL_CED_FREECIRCBLOCK _IOWR(CED_MAGIC_IOC,44, TCIRCBLOCK) -#define IOCTL_CED_WAITEVENT _IO(CED_MAGIC_IOC, 45) -#define IOCTL_CED_TESTEVENT _IO(CED_MAGIC_IOC, 46) +#define IOCTL_CED_SENDSTRING(n) _IOC(_IOC_WRITE, CED_MAGIC_IOC, 2, n) + +#define IOCTL_CED_RESET1401 _IO(CED_MAGIC_IOC, 3) +#define IOCTL_CED_GETCHAR _IO(CED_MAGIC_IOC, 4) +#define IOCTL_CED_SENDCHAR _IO(CED_MAGIC_IOC, 5) +#define IOCTL_CED_STAT1401 _IO(CED_MAGIC_IOC, 6) +#define IOCTL_CED_LINECOUNT _IO(CED_MAGIC_IOC, 7) +#define IOCTL_CED_GETSTRING(nMax) _IOC(_IOC_READ, CED_MAGIC_IOC, 8, nMax) + +#define IOCTL_CED_SETTRANSFER _IOW(CED_MAGIC_IOC, 11, TRANSFERDESC) +#define IOCTL_CED_UNSETTRANSFER _IO(CED_MAGIC_IOC, 12) +#define IOCTL_CED_SETEVENT _IOW(CED_MAGIC_IOC, 13, TRANSFEREVENT) +#define IOCTL_CED_GETOUTBUFSPACE _IO(CED_MAGIC_IOC, 14) +#define IOCTL_CED_GETBASEADDRESS _IO(CED_MAGIC_IOC, 15) +#define IOCTL_CED_GETDRIVERREVISION _IO(CED_MAGIC_IOC, 16) + +#define IOCTL_CED_GETTRANSFER _IOR(CED_MAGIC_IOC, 17, TGET_TX_BLOCK) +#define IOCTL_CED_KILLIO1401 _IO(CED_MAGIC_IOC, 18) +#define IOCTL_CED_BLKTRANSSTATE _IO(CED_MAGIC_IOC, 19) + +#define IOCTL_CED_STATEOF1401 _IO(CED_MAGIC_IOC, 23) +#define IOCTL_CED_GRAB1401 _IO(CED_MAGIC_IOC, 25) +#define IOCTL_CED_FREE1401 _IO(CED_MAGIC_IOC, 26) +#define IOCTL_CED_STARTSELFTEST _IO(CED_MAGIC_IOC, 31) +#define IOCTL_CED_CHECKSELFTEST _IOR(CED_MAGIC_IOC, 32, TGET_SELFTEST) +#define IOCTL_CED_TYPEOF1401 _IO(CED_MAGIC_IOC, 33) +#define IOCTL_CED_TRANSFERFLAGS _IO(CED_MAGIC_IOC, 34) + +#define IOCTL_CED_DBGPEEK _IOW(CED_MAGIC_IOC, 35, TDBGBLOCK) +#define IOCTL_CED_DBGPOKE _IOW(CED_MAGIC_IOC, 36, TDBGBLOCK) +#define IOCTL_CED_DBGRAMPDATA _IOW(CED_MAGIC_IOC, 37, TDBGBLOCK) +#define IOCTL_CED_DBGRAMPADDR _IOW(CED_MAGIC_IOC, 38, TDBGBLOCK) +#define IOCTL_CED_DBGGETDATA _IOR(CED_MAGIC_IOC, 39, TDBGBLOCK) +#define IOCTL_CED_DBGSTOPLOOP _IO(CED_MAGIC_IOC, 40) +#define IOCTL_CED_FULLRESET _IO(CED_MAGIC_IOC, 41) +#define IOCTL_CED_SETCIRCULAR _IOW(CED_MAGIC_IOC, 42, TRANSFERDESC) +#define IOCTL_CED_GETCIRCBLOCK _IOWR(CED_MAGIC_IOC, 43, TCIRCBLOCK) +#define IOCTL_CED_FREECIRCBLOCK _IOWR(CED_MAGIC_IOC, 44, TCIRCBLOCK) +#define IOCTL_CED_WAITEVENT _IO(CED_MAGIC_IOC, 45) +#define IOCTL_CED_TESTEVENT _IO(CED_MAGIC_IOC, 46) #ifndef __KERNEL__ -// If nothing said about return value, it is a U14ERR_... error code (U14ERR_NOERROR for none) -inline int CED_SendString(int fh, const char* szText, int n){return ioctl(fh, IOCTL_CED_SENDSTRING(n), szText);} +/* + * If nothing said about return value, it is a U14ERR_... error code + * (U14ERR_NOERROR for none) + */ +inline int CED_SendString(int fh, const char *szText, int n) +{ + return ioctl(fh, IOCTL_CED_SENDSTRING(n), szText); +} -inline int CED_Reset1401(int fh){return ioctl(fh, IOCTL_CED_RESET1401);} +inline int CED_Reset1401(int fh) +{ + return ioctl(fh, IOCTL_CED_RESET1401); +} -inline int CED_GetChar(int fh){return ioctl(fh, IOCTL_CED_GETCHAR);} -// Return the singe character or a -ve error code. +/* Return the singe character or a -ve error code. */ +inline int CED_GetChar(int fh) +{ + return ioctl(fh, IOCTL_CED_GETCHAR); +} -inline int CED_Stat1401(int fh){return ioctl(fh, IOCTL_CED_STAT1401);} -// Return character count in input buffer +/* Return character count in input buffer */ +inline int CED_Stat1401(int fh) +{ + return ioctl(fh, IOCTL_CED_STAT1401); +} -inline int CED_SendChar(int fh, char c){return ioctl(fh, IOCTL_CED_SENDCHAR, c);} +inline int CED_SendChar(int fh, char c) +{ + return ioctl(fh, IOCTL_CED_SENDCHAR, c); +} -inline int CED_LineCount(int fh){return ioctl(fh, IOCTL_CED_LINECOUNT);} +inline int CED_LineCount(int fh) +{ + return ioctl(fh, IOCTL_CED_LINECOUNT); +} + +/* + * return the count of characters returned. If the string was terminated by CR + * or 0, then the 0 is part of the count. Otherwise, we will add a zero if + * there is room, but it is not included in the count. The return value is 0 + * if there was nothing to read. + */ +inline int CED_GetString(int fh, char *szText, int nMax) +{ + return ioctl(fh, IOCTL_CED_GETSTRING(nMax), szText); +} -inline int CED_GetString(int fh, char* szText, int nMax){return ioctl(fh, IOCTL_CED_GETSTRING(nMax), szText);} -// return the count of characters returned. If the string was terminated by CR or 0, then the 0 is part -// of the count. Otherwise, we will add a zero if there is room, but it is not included in the count. -// The return value is 0 if there was nothing to read. +/* returns space in the output buffer. */ +inline int CED_GetOutBufSpace(int fh) +{ + return ioctl(fh, IOCTL_CED_GETOUTBUFSPACE); +} -inline int CED_GetOutBufSpace(int fh){return ioctl(fh, IOCTL_CED_GETOUTBUFSPACE);} -// returns space in the output buffer. +/* This always returns -1 as not implemented. */ +inline int CED_GetBaseAddress(int fh) +{ + return ioctl(fh, IOCTL_CED_GETBASEADDRESS); +} -inline int CED_GetBaseAddress(int fh){return ioctl(fh, IOCTL_CED_GETBASEADDRESS);} -// This always returns -1 as not implemented. +/* returns the major revision <<16 | minor revision. */ +inline int CED_GetDriverRevision(int fh) +{ + return ioctl(fh, IOCTL_CED_GETDRIVERREVISION); +} -inline int CED_GetDriverRevision(int fh){return ioctl(fh, IOCTL_CED_GETDRIVERREVISION);} -// returns the major revision <<16 | minor revision. +inline int CED_SetTransfer(int fh, TRANSFERDESC *pTD) +{ + return ioctl(fh, IOCTL_CED_SETTRANSFER, pTD); +} -inline int CED_SetTransfer(int fh, TRANSFERDESC* pTD){return ioctl(fh, IOCTL_CED_SETTRANSFER, pTD);} +inline int CED_UnsetTransfer(int fh, int nArea) +{ + return ioctl(fh, IOCTL_CED_UNSETTRANSFER, nArea); +} -inline int CED_UnsetTransfer(int fh, int nArea){return ioctl(fh, IOCTL_CED_UNSETTRANSFER, nArea);} +inline int CED_SetEvent(int fh, TRANSFEREVENT *pTE) +{ + return ioctl(fh, IOCTL_CED_SETEVENT, pTE); +} -inline int CED_SetEvent(int fh, TRANSFEREVENT* pTE){return ioctl(fh, IOCTL_CED_SETEVENT, pTE);} +inline int CED_GetTransfer(int fh, TGET_TX_BLOCK *pTX) +{ + return ioctl(fh, IOCTL_CED_GETTRANSFER, pTX); +} -inline int CED_GetTransfer(int fh, TGET_TX_BLOCK* pTX){return ioctl(fh, IOCTL_CED_GETTRANSFER, pTX);} +inline int CED_KillIO1401(int fh) +{ + return ioctl(fh, IOCTL_CED_KILLIO1401); +} -inline int CED_KillIO1401(int fh){return ioctl(fh, IOCTL_CED_KILLIO1401);} +/* returns 0 if no active DMA, 1 if active */ +inline int CED_BlkTransState(int fh) +{ + return ioctl(fh, IOCTL_CED_BLKTRANSSTATE); +} -inline int CED_BlkTransState(int fh){return ioctl(fh, IOCTL_CED_BLKTRANSSTATE);} -// returns 0 if no active DMA, 1 if active +inline int CED_StateOf1401(int fh) +{ + return ioctl(fh, IOCTL_CED_STATEOF1401); +} -inline int CED_StateOf1401(int fh){return ioctl(fh, IOCTL_CED_STATEOF1401);} +inline int CED_Grab1401(int fh) +{ + return ioctl(fh, IOCTL_CED_GRAB1401); +} -inline int CED_Grab1401(int fh){return ioctl(fh, IOCTL_CED_GRAB1401);} -inline int CED_Free1401(int fh){return ioctl(fh, IOCTL_CED_FREE1401);} +inline int CED_Free1401(int fh) +{ + return ioctl(fh, IOCTL_CED_FREE1401); +} -inline int CED_StartSelfTest(int fh){return ioctl(fh, IOCTL_CED_STARTSELFTEST);} -inline int CED_CheckSelfTest(int fh, TGET_SELFTEST* pGST){return ioctl(fh, IOCTL_CED_CHECKSELFTEST, pGST);} +inline int CED_StartSelfTest(int fh) +{ + return ioctl(fh, IOCTL_CED_STARTSELFTEST); +} + +inline int CED_CheckSelfTest(int fh, TGET_SELFTEST *pGST) +{ + return ioctl(fh, IOCTL_CED_CHECKSELFTEST, pGST); +} + +inline int CED_TypeOf1401(int fh) +{ + return ioctl(fh, IOCTL_CED_TYPEOF1401); +} + +inline int CED_TransferFlags(int fh) +{ + return ioctl(fh, IOCTL_CED_TRANSFERFLAGS); +} + +inline int CED_DbgPeek(int fh, TDBGBLOCK *pDB) +{ + return ioctl(fh, IOCTL_CED_DBGPEEK, pDB); +} + +inline int CED_DbgPoke(int fh, TDBGBLOCK *pDB) +{ + return ioctl(fh, IOCTL_CED_DBGPOKE, pDB); +} + +inline int CED_DbgRampData(int fh, TDBGBLOCK *pDB) +{ + return ioctl(fh, IOCTL_CED_DBGRAMPDATA, pDB); +} -inline int CED_TypeOf1401(int fh){return ioctl(fh, IOCTL_CED_TYPEOF1401);} -inline int CED_TransferFlags(int fh){return ioctl(fh, IOCTL_CED_TRANSFERFLAGS);} +inline int CED_DbgRampAddr(int fh, TDBGBLOCK *pDB) +{ + return ioctl(fh, IOCTL_CED_DBGRAMPADDR, pDB); +} -inline int CED_DbgPeek(int fh, TDBGBLOCK* pDB){return ioctl(fh, IOCTL_CED_DBGPEEK, pDB);} -inline int CED_DbgPoke(int fh, TDBGBLOCK* pDB){return ioctl(fh, IOCTL_CED_DBGPOKE, pDB);} -inline int CED_DbgRampData(int fh, TDBGBLOCK* pDB){return ioctl(fh, IOCTL_CED_DBGRAMPDATA, pDB);} -inline int CED_DbgRampAddr(int fh, TDBGBLOCK* pDB){return ioctl(fh, IOCTL_CED_DBGRAMPADDR, pDB);} -inline int CED_DbgGetData(int fh, TDBGBLOCK* pDB){return ioctl(fh, IOCTL_CED_DBGGETDATA, pDB);} -inline int CED_DbgStopLoop(int fh){return ioctl(fh, IOCTL_CED_DBGSTOPLOOP);} +inline int CED_DbgGetData(int fh, TDBGBLOCK *pDB) +{ + return ioctl(fh, IOCTL_CED_DBGGETDATA, pDB); +} -inline int CED_FullReset(int fh){return ioctl(fh, IOCTL_CED_FULLRESET);} +inline int CED_DbgStopLoop(int fh) +{ + return ioctl(fh, IOCTL_CED_DBGSTOPLOOP); +} -inline int CED_SetCircular(int fh, TRANSFERDESC* pTD){return ioctl(fh, IOCTL_CED_SETCIRCULAR, pTD);} -inline int CED_GetCircBlock(int fh, TCIRCBLOCK* pCB){return ioctl(fh, IOCTL_CED_GETCIRCBLOCK, pCB);} -inline int CED_FreeCircBlock(int fh, TCIRCBLOCK* pCB){return ioctl(fh, IOCTL_CED_FREECIRCBLOCK, pCB);} +inline int CED_FullReset(int fh) +{ + return ioctl(fh, IOCTL_CED_FULLRESET); +} -inline int CED_WaitEvent(int fh, int nArea, int msTimeOut){return ioctl(fh, IOCTL_CED_WAITEVENT, (nArea & 0xff)|(msTimeOut << 8));} -inline int CED_TestEvent(int fh, int nArea){return ioctl(fh, IOCTL_CED_TESTEVENT, nArea);} +inline int CED_SetCircular(int fh, TRANSFERDESC *pTD) +{ + return ioctl(fh, IOCTL_CED_SETCIRCULAR, pTD); +} + +inline int CED_GetCircBlock(int fh, TCIRCBLOCK *pCB) +{ + return ioctl(fh, IOCTL_CED_GETCIRCBLOCK, pCB); +} + +inline int CED_FreeCircBlock(int fh, TCIRCBLOCK *pCB) +{ + return ioctl(fh, IOCTL_CED_FREECIRCBLOCK, pCB); +} + +inline int CED_WaitEvent(int fh, int nArea, int msTimeOut) +{ + return ioctl(fh, IOCTL_CED_WAITEVENT, (nArea & 0xff)|(msTimeOut << 8)); +} + +inline int CED_TestEvent(int fh, int nArea) +{ + return ioctl(fh, IOCTL_CED_TESTEVENT, nArea); +} #endif #ifdef NOTWANTEDYET -#define IOCTL_CED_REGCALLBACK _IO(CED_MAGIC_IOC,9) // Not used -#define IOCTL_CED_GETMONITORBUF _IO(CED_MAGIC_IOC,10) // Not used +#define IOCTL_CED_REGCALLBACK _IO(CED_MAGIC_IOC, 9) /* Not used */ +#define IOCTL_CED_GETMONITORBUF _IO(CED_MAGIC_IOC, 10) /* Not used */ -#define IOCTL_CED_BYTECOUNT _IO(CED_MAGIC_IOC,20) // Not used -#define IOCTL_CED_ZEROBLOCKCOUNT _IO(CED_MAGIC_IOC,21) // Not used -#define IOCTL_CED_STOPCIRCULAR _IO(CED_MAGIC_IOC,22) // Not used +#define IOCTL_CED_BYTECOUNT _IO(CED_MAGIC_IOC, 20) /* Not used */ +#define IOCTL_CED_ZEROBLOCKCOUNT _IO(CED_MAGIC_IOC, 21) /* Not used */ +#define IOCTL_CED_STOPCIRCULAR _IO(CED_MAGIC_IOC, 22) /* Not used */ -#define IOCTL_CED_REGISTERS1401 _IO(CED_MAGIC_IOC,24) // Not used -#define IOCTL_CED_STEP1401 _IO(CED_MAGIC_IOC,27) // Not used -#define IOCTL_CED_SET1401REGISTERS _IO(CED_MAGIC_IOC,28) // Not used -#define IOCTL_CED_STEPTILL1401 _IO(CED_MAGIC_IOC,29) // Not used -#define IOCTL_CED_SETORIN _IO(CED_MAGIC_IOC,30) // Not used +#define IOCTL_CED_REGISTERS1401 _IO(CED_MAGIC_IOC, 24) /* Not used */ +#define IOCTL_CED_STEP1401 _IO(CED_MAGIC_IOC, 27) /* Not used */ +#define IOCTL_CED_SET1401REGISTERS _IO(CED_MAGIC_IOC, 28) /* Not used */ +#define IOCTL_CED_STEPTILL1401 _IO(CED_MAGIC_IOC, 29) /* Not used */ +#define IOCTL_CED_SETORIN _IO(CED_MAGIC_IOC, 30) /* Not used */ #endif -// __CED_IOCTL_H__ +/* __CED_IOCTL_H__ */ #endif diff --git a/drivers/staging/ced1401/usb1401.c b/drivers/staging/ced1401/usb1401.c index bf08baa..69b7f20 100644 --- a/drivers/staging/ced1401/usb1401.c +++ b/drivers/staging/ced1401/usb1401.c @@ -23,7 +23,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - Endpoints ********* There are 4 endpoints plus the control endpoint in the standard interface @@ -92,14 +91,13 @@ synchronous non-Urb based transfers. #include #include #if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) ) - #include - #include - #include - #include - #include +#include +#include +#include +#include +#include #endif - #include "usb1401.h" /* Define these values to match your devices */ @@ -107,13 +105,12 @@ synchronous non-Urb based transfers. #define USB_CED_PRODUCT_ID 0xa0f0 /* table of devices that work with this driver */ -static const struct usb_device_id ced_table[] = -{ - { USB_DEVICE(USB_CED_VENDOR_ID, USB_CED_PRODUCT_ID) }, - { } /* Terminating entry */ +static const struct usb_device_id ced_table[] = { + {USB_DEVICE(USB_CED_VENDOR_ID, USB_CED_PRODUCT_ID)}, + {} /* Terminating entry */ }; -MODULE_DEVICE_TABLE(usb, ced_table); +MODULE_DEVICE_TABLE(usb, ced_table); /* Get a minor range for your devices from the usb maintainer */ #define USB_CED_MINOR_BASE 192 @@ -134,151 +131,152 @@ The cause for these errors is that the driver makes use of the functions usb_buf This is needed on Debian 2.6.32-5-amd64 */ #if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) ) - #define usb_alloc_coherent usb_buffer_alloc - #define usb_free_coherent usb_buffer_free - #define noop_llseek NULL +#define usb_alloc_coherent usb_buffer_alloc +#define usb_free_coherent usb_buffer_free +#define noop_llseek NULL #endif static struct usb_driver ced_driver; static void ced_delete(struct kref *kref) { - DEVICE_EXTENSION *pdx = to_DEVICE_EXTENSION(kref); - - // Free up the output buffer, then free the output urb. Note that the interface member - // of pdx will probably be NULL, so cannot be used to get to dev. - usb_free_coherent(pdx->udev, OUTBUF_SZ, pdx->pCoherCharOut, pdx->pUrbCharOut->transfer_dma); - usb_free_urb(pdx->pUrbCharOut); - - // Do the same for chan input - usb_free_coherent(pdx->udev, INBUF_SZ, pdx->pCoherCharIn, pdx->pUrbCharIn->transfer_dma); - usb_free_urb(pdx->pUrbCharIn); - - // Do the same for the block transfers - usb_free_coherent(pdx->udev, STAGED_SZ, pdx->pCoherStagedIO, pdx->pStagedUrb->transfer_dma); - usb_free_urb(pdx->pStagedUrb); - - usb_put_dev(pdx->udev); - kfree(pdx); + DEVICE_EXTENSION *pdx = to_DEVICE_EXTENSION(kref); + + // Free up the output buffer, then free the output urb. Note that the interface member + // of pdx will probably be NULL, so cannot be used to get to dev. + usb_free_coherent(pdx->udev, OUTBUF_SZ, pdx->pCoherCharOut, + pdx->pUrbCharOut->transfer_dma); + usb_free_urb(pdx->pUrbCharOut); + + // Do the same for chan input + usb_free_coherent(pdx->udev, INBUF_SZ, pdx->pCoherCharIn, + pdx->pUrbCharIn->transfer_dma); + usb_free_urb(pdx->pUrbCharIn); + + // Do the same for the block transfers + usb_free_coherent(pdx->udev, STAGED_SZ, pdx->pCoherStagedIO, + pdx->pStagedUrb->transfer_dma); + usb_free_urb(pdx->pStagedUrb); + + usb_put_dev(pdx->udev); + kfree(pdx); } // This is the driver end of the open() call from user space. static int ced_open(struct inode *inode, struct file *file) { - DEVICE_EXTENSION *pdx; - int retval = 0; - int subminor = iminor(inode); - struct usb_interface* interface = usb_find_interface(&ced_driver, subminor); - if (!interface) - { - pr_err("%s - error, can't find device for minor %d", __func__, subminor); - retval = -ENODEV; - goto exit; - } - - pdx = usb_get_intfdata(interface); - if (!pdx) - { - retval = -ENODEV; - goto exit; - } - - dev_dbg(&interface->dev, "%s got pdx", __func__); - - /* increment our usage count for the device */ - kref_get(&pdx->kref); - - /* lock the device to allow correctly handling errors - * in resumption */ - mutex_lock(&pdx->io_mutex); - - if (!pdx->open_count++) - { - retval = usb_autopm_get_interface(interface); - if (retval) - { - pdx->open_count--; - mutex_unlock(&pdx->io_mutex); - kref_put(&pdx->kref, ced_delete); - goto exit; - } - } - else - { //uncomment this block if you want exclusive open - dev_err(&interface->dev, "%s fail: already open", __func__); + DEVICE_EXTENSION *pdx; + int retval = 0; + int subminor = iminor(inode); + struct usb_interface *interface = + usb_find_interface(&ced_driver, subminor); + if (!interface) { + pr_err("%s - error, can't find device for minor %d", __func__, + subminor); + retval = -ENODEV; + goto exit; + } + + pdx = usb_get_intfdata(interface); + if (!pdx) { + retval = -ENODEV; + goto exit; + } + + dev_dbg(&interface->dev, "%s got pdx", __func__); + + /* increment our usage count for the device */ + kref_get(&pdx->kref); + + /* lock the device to allow correctly handling errors + * in resumption */ + mutex_lock(&pdx->io_mutex); + + if (!pdx->open_count++) { + retval = usb_autopm_get_interface(interface); + if (retval) { + pdx->open_count--; + mutex_unlock(&pdx->io_mutex); + kref_put(&pdx->kref, ced_delete); + goto exit; + } + } else { //uncomment this block if you want exclusive open + dev_err(&interface->dev, "%s fail: already open", __func__); retval = -EBUSY; pdx->open_count--; mutex_unlock(&pdx->io_mutex); kref_put(&pdx->kref, ced_delete); goto exit; } - /* prevent the device from being autosuspended */ + /* prevent the device from being autosuspended */ - /* save our object in the file's private structure */ - file->private_data = pdx; - mutex_unlock(&pdx->io_mutex); + /* save our object in the file's private structure */ + file->private_data = pdx; + mutex_unlock(&pdx->io_mutex); exit: - return retval; + return retval; } static int ced_release(struct inode *inode, struct file *file) { - DEVICE_EXTENSION *pdx = file->private_data; - if (pdx == NULL) - return -ENODEV; - - dev_dbg(&pdx->interface->dev,"%s called", __func__); - mutex_lock(&pdx->io_mutex); - if (!--pdx->open_count && pdx->interface) // Allow autosuspend - usb_autopm_put_interface(pdx->interface); - mutex_unlock(&pdx->io_mutex); - - kref_put(&pdx->kref, ced_delete); // decrement the count on our device - return 0; + DEVICE_EXTENSION *pdx = file->private_data; + if (pdx == NULL) + return -ENODEV; + + dev_dbg(&pdx->interface->dev, "%s called", __func__); + mutex_lock(&pdx->io_mutex); + if (!--pdx->open_count && pdx->interface) // Allow autosuspend + usb_autopm_put_interface(pdx->interface); + mutex_unlock(&pdx->io_mutex); + + kref_put(&pdx->kref, ced_delete); // decrement the count on our device + return 0; } static int ced_flush(struct file *file, fl_owner_t id) { - int res; - DEVICE_EXTENSION *pdx = file->private_data; - if (pdx == NULL) - return -ENODEV; + int res; + DEVICE_EXTENSION *pdx = file->private_data; + if (pdx == NULL) + return -ENODEV; - dev_dbg(&pdx->interface->dev,"%s char in pend=%d", __func__, pdx->bReadCharsPending); + dev_dbg(&pdx->interface->dev, "%s char in pend=%d", __func__, + pdx->bReadCharsPending); - /* wait for io to stop */ - mutex_lock(&pdx->io_mutex); - dev_dbg(&pdx->interface->dev,"%s got io_mutex", __func__); - ced_draw_down(pdx); + /* wait for io to stop */ + mutex_lock(&pdx->io_mutex); + dev_dbg(&pdx->interface->dev, "%s got io_mutex", __func__); + ced_draw_down(pdx); - /* read out errors, leave subsequent opens a clean slate */ - spin_lock_irq(&pdx->err_lock); - res = pdx->errors ? (pdx->errors == -EPIPE ? -EPIPE : -EIO) : 0; - pdx->errors = 0; - spin_unlock_irq(&pdx->err_lock); + /* read out errors, leave subsequent opens a clean slate */ + spin_lock_irq(&pdx->err_lock); + res = pdx->errors ? (pdx->errors == -EPIPE ? -EPIPE : -EIO) : 0; + pdx->errors = 0; + spin_unlock_irq(&pdx->err_lock); - mutex_unlock(&pdx->io_mutex); - dev_dbg(&pdx->interface->dev,"%s exit reached", __func__); + mutex_unlock(&pdx->io_mutex); + dev_dbg(&pdx->interface->dev, "%s exit reached", __func__); - return res; + return res; } - static ssize_t ced_read(struct file *file, char *buffer, size_t count, - loff_t *ppos) + loff_t * ppos) { - DEVICE_EXTENSION *pdx = file->private_data; - dev_err(&pdx->interface->dev, "%s called: use ioctl for cedusb", __func__); - return 0; // as we do not do reads this way + DEVICE_EXTENSION *pdx = file->private_data; + dev_err(&pdx->interface->dev, "%s called: use ioctl for cedusb", + __func__); + return 0; // as we do not do reads this way } static ssize_t ced_write(struct file *file, const char *user_buffer, - size_t count, loff_t *ppos) + size_t count, loff_t * ppos) { - DEVICE_EXTENSION *pdx = file->private_data; - dev_err(&pdx->interface->dev, "%s called: use ioctl for cedusb", __func__); - return 0; + DEVICE_EXTENSION *pdx = file->private_data; + dev_err(&pdx->interface->dev, "%s called: use ioctl for cedusb", + __func__); + return 0; } /*************************************************************************** @@ -288,80 +286,86 @@ static ssize_t ced_write(struct file *file, const char *user_buffer, ** not help with a device extension held by a file. ** return true if can accept new io requests, else false */ -static bool CanAcceptIoRequests(DEVICE_EXTENSION* pdx) +static bool CanAcceptIoRequests(DEVICE_EXTENSION * pdx) { - return pdx && pdx->interface; // Can we accept IO requests + return pdx && pdx->interface; // Can we accept IO requests } /**************************************************************************** ** Callback routine to complete writes. This may need to fire off another ** urb to complete the transfer. ****************************************************************************/ -static void ced_writechar_callback(struct urb* pUrb) +static void ced_writechar_callback(struct urb *pUrb) { - DEVICE_EXTENSION *pdx = pUrb->context; - int nGot = pUrb->actual_length; // what we transferred - - if (pUrb->status) - { // sync/async unlink faults aren't errors - if (!(pUrb->status == -ENOENT || pUrb->status == -ECONNRESET || pUrb->status == -ESHUTDOWN)) - { - dev_err(&pdx->interface->dev, "%s - nonzero write bulk status received: %d", __func__, pUrb->status); - } - - spin_lock(&pdx->err_lock); - pdx->errors = pUrb->status; - spin_unlock(&pdx->err_lock); - nGot = 0; // and tidy up again if so - - spin_lock(&pdx->charOutLock); // already at irq level - pdx->dwOutBuffGet = 0; // Reset the output buffer - pdx->dwOutBuffPut = 0; - pdx->dwNumOutput = 0; // Clear the char count - pdx->bPipeError[0] = 1; // Flag an error for later - pdx->bSendCharsPending = false; // Allow other threads again - spin_unlock(&pdx->charOutLock); // already at irq level - dev_dbg(&pdx->interface->dev, "%s - char out done, 0 chars sent", __func__); - } - else - { - dev_dbg(&pdx->interface->dev, "%s - char out done, %d chars sent", __func__, nGot); - spin_lock(&pdx->charOutLock); // already at irq level - pdx->dwNumOutput -= nGot; // Now adjust the char send buffer - pdx->dwOutBuffGet += nGot; // to match what we did - if (pdx->dwOutBuffGet >= OUTBUF_SZ) // Can't do this any earlier as data could be overwritten - pdx->dwOutBuffGet = 0; - - if (pdx->dwNumOutput > 0) // if more to be done... - { - int nPipe = 0; // The pipe number to use - int iReturn; - char* pDat = &pdx->outputBuffer[pdx->dwOutBuffGet]; - unsigned int dwCount = pdx->dwNumOutput; // maximum to send - if ((pdx->dwOutBuffGet+dwCount) > OUTBUF_SZ) // does it cross buffer end? - dwCount = OUTBUF_SZ - pdx->dwOutBuffGet; - spin_unlock(&pdx->charOutLock); // we are done with stuff that changes - memcpy(pdx->pCoherCharOut, pDat, dwCount); // copy output data to the buffer - usb_fill_bulk_urb(pdx->pUrbCharOut, pdx->udev, - usb_sndbulkpipe(pdx->udev, pdx->epAddr[0]), - pdx->pCoherCharOut, dwCount, ced_writechar_callback, pdx); - pdx->pUrbCharOut->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - usb_anchor_urb(pdx->pUrbCharOut, &pdx->submitted); // in case we need to kill it - iReturn = usb_submit_urb(pdx->pUrbCharOut, GFP_ATOMIC); - dev_dbg(&pdx->interface->dev, "%s n=%d>%s<", __func__, dwCount, pDat); - spin_lock(&pdx->charOutLock); // grab lock for errors - if (iReturn) - { - pdx->bPipeError[nPipe] = 1; // Flag an error to be handled later - pdx->bSendCharsPending = false; // Allow other threads again - usb_unanchor_urb(pdx->pUrbCharOut); - dev_err(&pdx->interface->dev, "%s usb_submit_urb() returned %d", __func__, iReturn); - } - } - else - pdx->bSendCharsPending = false; // Allow other threads again - spin_unlock(&pdx->charOutLock); // already at irq level - } + DEVICE_EXTENSION *pdx = pUrb->context; + int nGot = pUrb->actual_length; // what we transferred + + if (pUrb->status) { // sync/async unlink faults aren't errors + if (! + (pUrb->status == -ENOENT || pUrb->status == -ECONNRESET + || pUrb->status == -ESHUTDOWN)) { + dev_err(&pdx->interface->dev, + "%s - nonzero write bulk status received: %d", + __func__, pUrb->status); + } + + spin_lock(&pdx->err_lock); + pdx->errors = pUrb->status; + spin_unlock(&pdx->err_lock); + nGot = 0; // and tidy up again if so + + spin_lock(&pdx->charOutLock); // already at irq level + pdx->dwOutBuffGet = 0; // Reset the output buffer + pdx->dwOutBuffPut = 0; + pdx->dwNumOutput = 0; // Clear the char count + pdx->bPipeError[0] = 1; // Flag an error for later + pdx->bSendCharsPending = false; // Allow other threads again + spin_unlock(&pdx->charOutLock); // already at irq level + dev_dbg(&pdx->interface->dev, + "%s - char out done, 0 chars sent", __func__); + } else { + dev_dbg(&pdx->interface->dev, + "%s - char out done, %d chars sent", __func__, nGot); + spin_lock(&pdx->charOutLock); // already at irq level + pdx->dwNumOutput -= nGot; // Now adjust the char send buffer + pdx->dwOutBuffGet += nGot; // to match what we did + if (pdx->dwOutBuffGet >= OUTBUF_SZ) // Can't do this any earlier as data could be overwritten + pdx->dwOutBuffGet = 0; + + if (pdx->dwNumOutput > 0) // if more to be done... + { + int nPipe = 0; // The pipe number to use + int iReturn; + char *pDat = &pdx->outputBuffer[pdx->dwOutBuffGet]; + unsigned int dwCount = pdx->dwNumOutput; // maximum to send + if ((pdx->dwOutBuffGet + dwCount) > OUTBUF_SZ) // does it cross buffer end? + dwCount = OUTBUF_SZ - pdx->dwOutBuffGet; + spin_unlock(&pdx->charOutLock); // we are done with stuff that changes + memcpy(pdx->pCoherCharOut, pDat, dwCount); // copy output data to the buffer + usb_fill_bulk_urb(pdx->pUrbCharOut, pdx->udev, + usb_sndbulkpipe(pdx->udev, + pdx->epAddr[0]), + pdx->pCoherCharOut, dwCount, + ced_writechar_callback, pdx); + pdx->pUrbCharOut->transfer_flags |= + URB_NO_TRANSFER_DMA_MAP; + usb_anchor_urb(pdx->pUrbCharOut, &pdx->submitted); // in case we need to kill it + iReturn = usb_submit_urb(pdx->pUrbCharOut, GFP_ATOMIC); + dev_dbg(&pdx->interface->dev, "%s n=%d>%s<", __func__, + dwCount, pDat); + spin_lock(&pdx->charOutLock); // grab lock for errors + if (iReturn) { + pdx->bPipeError[nPipe] = 1; // Flag an error to be handled later + pdx->bSendCharsPending = false; // Allow other threads again + usb_unanchor_urb(pdx->pUrbCharOut); + dev_err(&pdx->interface->dev, + "%s usb_submit_urb() returned %d", + __func__, iReturn); + } + } else + pdx->bSendCharsPending = false; // Allow other threads again + spin_unlock(&pdx->charOutLock); // already at irq level + } } /**************************************************************************** @@ -369,93 +373,91 @@ static void ced_writechar_callback(struct urb* pUrb) ** Transmit the characters in the output buffer to the 1401. This may need ** breaking down into multiple transfers. ****************************************************************************/ -int SendChars(DEVICE_EXTENSION* pdx) +int SendChars(DEVICE_EXTENSION * pdx) { - int iReturn = U14ERR_NOERROR; - - spin_lock_irq(&pdx->charOutLock); // Protect ourselves - - if ((!pdx->bSendCharsPending) && // Not currently sending - (pdx->dwNumOutput > 0) && // has characters to output - (CanAcceptIoRequests(pdx))) // and current activity is OK - { - unsigned int dwCount = pdx->dwNumOutput; // Get a copy of the character count - pdx->bSendCharsPending = true; // Set flag to lock out other threads - - dev_dbg(&pdx->interface->dev, "Send %d chars to 1401, EP0 flag %d\n", dwCount, pdx->nPipes == 3); - // If we have only 3 end points we must send the characters to the 1401 using EP0. - if (pdx->nPipes == 3) - { - // For EP0 character transmissions to the 1401, we have to hang about until they - // are gone, as otherwise without more character IO activity they will never go. - unsigned int count = dwCount; // Local char counter - unsigned int index = 0; // The index into the char buffer - - spin_unlock_irq(&pdx->charOutLock); // Free spinlock as we call USBD - - while ((count > 0) && (iReturn == U14ERR_NOERROR)) - { - // We have to break the transfer up into 64-byte chunks because of a 2270 problem - int n = count > 64 ? 64 : count; // Chars for this xfer, max of 64 - int nSent = usb_control_msg(pdx->udev, - usb_sndctrlpipe(pdx->udev,0), // use end point 0 - DB_CHARS, // bRequest - (H_TO_D|VENDOR|DEVREQ), // to the device, vendor request to the device - 0,0, // value and index are both 0 - &pdx->outputBuffer[index], // where to send from - n, // how much to send - 1000); // timeout in jiffies - if (nSent <= 0) - { - iReturn = nSent ? nSent : -ETIMEDOUT; // if 0 chars says we timed out - dev_err(&pdx->interface->dev, "Send %d chars by EP0 failed: %d", n, iReturn); - } - else - { - dev_dbg(&pdx->interface->dev, "Sent %d chars by EP0", n); - count -= nSent; - index += nSent; - } - } - - spin_lock_irq(&pdx->charOutLock); // Protect pdx changes, released by general code - pdx->dwOutBuffGet = 0; // so reset the output buffer - pdx->dwOutBuffPut = 0; - pdx->dwNumOutput = 0; // and clear the buffer count - pdx->bSendCharsPending = false; // Allow other threads again - } - else - { // Here for sending chars normally - we hold the spin lock - int nPipe = 0; // The pipe number to use - char* pDat = &pdx->outputBuffer[pdx->dwOutBuffGet]; - - if ((pdx->dwOutBuffGet+dwCount) > OUTBUF_SZ) // does it cross buffer end? - dwCount = OUTBUF_SZ - pdx->dwOutBuffGet; - spin_unlock_irq(&pdx->charOutLock); // we are done with stuff that changes - memcpy(pdx->pCoherCharOut, pDat, dwCount); // copy output data to the buffer - usb_fill_bulk_urb(pdx->pUrbCharOut, pdx->udev, - usb_sndbulkpipe(pdx->udev, pdx->epAddr[0]), - pdx->pCoherCharOut, dwCount, ced_writechar_callback, pdx); - pdx->pUrbCharOut->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - usb_anchor_urb(pdx->pUrbCharOut, &pdx->submitted); - iReturn = usb_submit_urb(pdx->pUrbCharOut, GFP_KERNEL); - spin_lock_irq(&pdx->charOutLock); // grab lock for errors - if (iReturn) - { - pdx->bPipeError[nPipe] = 1; // Flag an error to be handled later - pdx->bSendCharsPending = false; // Allow other threads again - usb_unanchor_urb(pdx->pUrbCharOut); // remove from list of active urbs - } - } - } - else - if (pdx->bSendCharsPending && (pdx->dwNumOutput > 0)) - dev_dbg(&pdx->interface->dev, "SendChars bSendCharsPending:true"); - - - dev_dbg(&pdx->interface->dev, "SendChars exit code: %d", iReturn); - spin_unlock_irq(&pdx->charOutLock); // Now let go of the spinlock - return iReturn; + int iReturn = U14ERR_NOERROR; + + spin_lock_irq(&pdx->charOutLock); // Protect ourselves + + if ((!pdx->bSendCharsPending) && // Not currently sending + (pdx->dwNumOutput > 0) && // has characters to output + (CanAcceptIoRequests(pdx))) // and current activity is OK + { + unsigned int dwCount = pdx->dwNumOutput; // Get a copy of the character count + pdx->bSendCharsPending = true; // Set flag to lock out other threads + + dev_dbg(&pdx->interface->dev, + "Send %d chars to 1401, EP0 flag %d\n", dwCount, + pdx->nPipes == 3); + // If we have only 3 end points we must send the characters to the 1401 using EP0. + if (pdx->nPipes == 3) { + // For EP0 character transmissions to the 1401, we have to hang about until they + // are gone, as otherwise without more character IO activity they will never go. + unsigned int count = dwCount; // Local char counter + unsigned int index = 0; // The index into the char buffer + + spin_unlock_irq(&pdx->charOutLock); // Free spinlock as we call USBD + + while ((count > 0) && (iReturn == U14ERR_NOERROR)) { + // We have to break the transfer up into 64-byte chunks because of a 2270 problem + int n = count > 64 ? 64 : count; // Chars for this xfer, max of 64 + int nSent = usb_control_msg(pdx->udev, + usb_sndctrlpipe(pdx->udev, 0), // use end point 0 + DB_CHARS, // bRequest + (H_TO_D | VENDOR | DEVREQ), // to the device, vendor request to the device + 0, 0, // value and index are both 0 + &pdx->outputBuffer[index], // where to send from + n, // how much to send + 1000); // timeout in jiffies + if (nSent <= 0) { + iReturn = nSent ? nSent : -ETIMEDOUT; // if 0 chars says we timed out + dev_err(&pdx->interface->dev, + "Send %d chars by EP0 failed: %d", + n, iReturn); + } else { + dev_dbg(&pdx->interface->dev, + "Sent %d chars by EP0", n); + count -= nSent; + index += nSent; + } + } + + spin_lock_irq(&pdx->charOutLock); // Protect pdx changes, released by general code + pdx->dwOutBuffGet = 0; // so reset the output buffer + pdx->dwOutBuffPut = 0; + pdx->dwNumOutput = 0; // and clear the buffer count + pdx->bSendCharsPending = false; // Allow other threads again + } else { // Here for sending chars normally - we hold the spin lock + int nPipe = 0; // The pipe number to use + char *pDat = &pdx->outputBuffer[pdx->dwOutBuffGet]; + + if ((pdx->dwOutBuffGet + dwCount) > OUTBUF_SZ) // does it cross buffer end? + dwCount = OUTBUF_SZ - pdx->dwOutBuffGet; + spin_unlock_irq(&pdx->charOutLock); // we are done with stuff that changes + memcpy(pdx->pCoherCharOut, pDat, dwCount); // copy output data to the buffer + usb_fill_bulk_urb(pdx->pUrbCharOut, pdx->udev, + usb_sndbulkpipe(pdx->udev, + pdx->epAddr[0]), + pdx->pCoherCharOut, dwCount, + ced_writechar_callback, pdx); + pdx->pUrbCharOut->transfer_flags |= + URB_NO_TRANSFER_DMA_MAP; + usb_anchor_urb(pdx->pUrbCharOut, &pdx->submitted); + iReturn = usb_submit_urb(pdx->pUrbCharOut, GFP_KERNEL); + spin_lock_irq(&pdx->charOutLock); // grab lock for errors + if (iReturn) { + pdx->bPipeError[nPipe] = 1; // Flag an error to be handled later + pdx->bSendCharsPending = false; // Allow other threads again + usb_unanchor_urb(pdx->pUrbCharOut); // remove from list of active urbs + } + } + } else if (pdx->bSendCharsPending && (pdx->dwNumOutput > 0)) + dev_dbg(&pdx->interface->dev, + "SendChars bSendCharsPending:true"); + + dev_dbg(&pdx->interface->dev, "SendChars exit code: %d", iReturn); + spin_unlock_irq(&pdx->charOutLock); // Now let go of the spinlock + return iReturn; } /*************************************************************************** @@ -472,228 +474,265 @@ int SendChars(DEVICE_EXTENSION* pdx) ** pdx Is our device extension which holds all we know about the transfer. ** n The number of bytes to move one way or the other. ***************************************************************************/ -static void CopyUserSpace(DEVICE_EXTENSION *pdx, int n) +static void CopyUserSpace(DEVICE_EXTENSION * pdx, int n) { - unsigned int nArea = pdx->StagedId; - if (nArea < MAX_TRANSAREAS) - { - TRANSAREA *pArea = &pdx->rTransDef[nArea]; // area to be used - unsigned int dwOffset = pdx->StagedDone + pdx->StagedOffset + pArea->dwBaseOffset; - char* pCoherBuf = pdx->pCoherStagedIO; // coherent buffer - if (!pArea->bUsed) - { - dev_err(&pdx->interface->dev, "%s area %d unused", __func__, nArea); - return; - } - - while (n) - { - int nPage = dwOffset >> PAGE_SHIFT; // page number in table - if (nPage < pArea->nPages) - { - char *pvAddress = (char*)kmap_atomic(pArea->pPages[nPage]); - if (pvAddress) - { - unsigned int uiPageOff = dwOffset & (PAGE_SIZE-1); // offset into the page - size_t uiXfer = PAGE_SIZE - uiPageOff; // max to transfer on this page - if (uiXfer > n) // limit byte count if too much - uiXfer = n; // for the page - if (pdx->StagedRead) - memcpy(pvAddress+uiPageOff, pCoherBuf, uiXfer); - else - memcpy(pCoherBuf, pvAddress+uiPageOff, uiXfer); - kunmap_atomic(pvAddress); - dwOffset += uiXfer; - pCoherBuf += uiXfer; - n -= uiXfer; - } - else - { - dev_err(&pdx->interface->dev, "%s did not map page %d", __func__, nPage); - return; - } - - } - else - { - dev_err(&pdx->interface->dev, "%s exceeded pages %d", __func__, nPage); - return; - } - } - } - else - dev_err(&pdx->interface->dev, "%s bad area %d", __func__, nArea); + unsigned int nArea = pdx->StagedId; + if (nArea < MAX_TRANSAREAS) { + TRANSAREA *pArea = &pdx->rTransDef[nArea]; // area to be used + unsigned int dwOffset = + pdx->StagedDone + pdx->StagedOffset + pArea->dwBaseOffset; + char *pCoherBuf = pdx->pCoherStagedIO; // coherent buffer + if (!pArea->bUsed) { + dev_err(&pdx->interface->dev, "%s area %d unused", + __func__, nArea); + return; + } + + while (n) { + int nPage = dwOffset >> PAGE_SHIFT; // page number in table + if (nPage < pArea->nPages) { + char *pvAddress = + (char *)kmap_atomic(pArea->pPages[nPage]); + if (pvAddress) { + unsigned int uiPageOff = dwOffset & (PAGE_SIZE - 1); // offset into the page + size_t uiXfer = PAGE_SIZE - uiPageOff; // max to transfer on this page + if (uiXfer > n) // limit byte count if too much + uiXfer = n; // for the page + if (pdx->StagedRead) + memcpy(pvAddress + uiPageOff, + pCoherBuf, uiXfer); + else + memcpy(pCoherBuf, + pvAddress + uiPageOff, + uiXfer); + kunmap_atomic(pvAddress); + dwOffset += uiXfer; + pCoherBuf += uiXfer; + n -= uiXfer; + } else { + dev_err(&pdx->interface->dev, + "%s did not map page %d", + __func__, nPage); + return; + } + + } else { + dev_err(&pdx->interface->dev, + "%s exceeded pages %d", __func__, + nPage); + return; + } + } + } else + dev_err(&pdx->interface->dev, "%s bad area %d", __func__, + nArea); } // Forward declarations for stuff used circularly -static int StageChunk(DEVICE_EXTENSION *pdx); +static int StageChunk(DEVICE_EXTENSION * pdx); /*************************************************************************** ** ReadWrite_Complete ** ** Completion routine for our staged read/write Irps */ -static void staged_callback(struct urb* pUrb) +static void staged_callback(struct urb *pUrb) { - DEVICE_EXTENSION *pdx = pUrb->context; - unsigned int nGot = pUrb->actual_length; // what we transferred - bool bCancel = false; - bool bRestartCharInput; // used at the end - - spin_lock(&pdx->stagedLock); // stop ReadWriteMem() action while this routine is running - pdx->bStagedUrbPending = false; // clear the flag for staged IRP pending - - if (pUrb->status) - { // sync/async unlink faults aren't errors - if (!(pUrb->status == -ENOENT || pUrb->status == -ECONNRESET || pUrb->status == -ESHUTDOWN)) - { - dev_err(&pdx->interface->dev, "%s - nonzero write bulk status received: %d", __func__, pUrb->status); - } - else - dev_info(&pdx->interface->dev, "%s - staged xfer cancelled", __func__); - - spin_lock(&pdx->err_lock); - pdx->errors = pUrb->status; - spin_unlock(&pdx->err_lock); - nGot = 0; // and tidy up again if so - bCancel = true; - } - else - { - dev_dbg(&pdx->interface->dev, "%s %d chars xferred", __func__, nGot); - if (pdx->StagedRead) // if reading, save to user space - CopyUserSpace(pdx, nGot); // copy from buffer to user - if (nGot == 0) - dev_dbg(&pdx->interface->dev, "%s ZLP", __func__); - } - - // Update the transfer length based on the TransferBufferLength value in the URB - pdx->StagedDone += nGot; - - dev_dbg(&pdx->interface->dev, "%s, done %d bytes of %d", __func__, pdx->StagedDone, pdx->StagedLength); - - if ((pdx->StagedDone == pdx->StagedLength) || // If no more to do - (bCancel)) // or this IRP was cancelled - { - TRANSAREA* pArea = &pdx->rTransDef[pdx->StagedId]; // Transfer area info - dev_dbg(&pdx->interface->dev, "%s transfer done, bytes %d, cancel %d", __func__, pdx->StagedDone, bCancel); - - // Here is where we sort out what to do with this transfer if using a circular buffer. We have - // a completed transfer that can be assumed to fit into the transfer area. We should be able to - // add this to the end of a growing block or to use it to start a new block unless the code - // that calculates the offset to use (in ReadWriteMem) is totally duff. - if ((pArea->bCircular) && (pArea->bCircToHost) && (!bCancel) && // Time to sort out circular buffer info? - (pdx->StagedRead)) // Only for tohost transfers for now - { - if (pArea->aBlocks[1].dwSize > 0) // If block 1 is in use we must append to it - { - if (pdx->StagedOffset == (pArea->aBlocks[1].dwOffset + pArea->aBlocks[1].dwSize)) - { - pArea->aBlocks[1].dwSize += pdx->StagedLength; - dev_dbg(&pdx->interface->dev, "RWM_Complete, circ block 1 now %d bytes at %d", - pArea->aBlocks[1].dwSize, pArea->aBlocks[1].dwOffset); - } - else - { - // Here things have gone very, very, wrong, but I cannot see how this can actually be achieved - pArea->aBlocks[1].dwOffset = pdx->StagedOffset; - pArea->aBlocks[1].dwSize = pdx->StagedLength; - dev_err(&pdx->interface->dev, "%s ERROR, circ block 1 re-started %d bytes at %d", - __func__, pArea->aBlocks[1].dwSize, pArea->aBlocks[1].dwOffset); - } - } - else // If block 1 is not used, we try to add to block 0 - { - if (pArea->aBlocks[0].dwSize > 0) // Got stored block 0 information? - { // Must append onto the existing block 0 - if (pdx->StagedOffset == (pArea->aBlocks[0].dwOffset + pArea->aBlocks[0].dwSize)) - { - pArea->aBlocks[0].dwSize += pdx->StagedLength; // Just add this transfer in - dev_dbg(&pdx->interface->dev, "RWM_Complete, circ block 0 now %d bytes at %d", - pArea->aBlocks[0].dwSize, pArea->aBlocks[0].dwOffset); - } - else // If it doesn't append, put into new block 1 - { - pArea->aBlocks[1].dwOffset = pdx->StagedOffset; - pArea->aBlocks[1].dwSize = pdx->StagedLength; - dev_dbg(&pdx->interface->dev, "RWM_Complete, circ block 1 started %d bytes at %d", - pArea->aBlocks[1].dwSize, pArea->aBlocks[1].dwOffset); - } - } - else // No info stored yet, just save in block 0 - { - pArea->aBlocks[0].dwOffset = pdx->StagedOffset; - pArea->aBlocks[0].dwSize = pdx->StagedLength; - dev_dbg(&pdx->interface->dev, "RWM_Complete, circ block 0 started %d bytes at %d", - pArea->aBlocks[0].dwSize, pArea->aBlocks[0].dwOffset); - } - } - } - - if (!bCancel) // Don't generate an event if cancelled - { - dev_dbg(&pdx->interface->dev, "RWM_Complete, bCircular %d, bToHost %d, eStart %d, eSize %d", - pArea->bCircular, pArea->bEventToHost, pArea->dwEventSt, pArea->dwEventSz); - if ((pArea->dwEventSz) && // Set a user-mode event... - (pdx->StagedRead == pArea->bEventToHost)) // ...on transfers in this direction? - { - int iWakeUp = 0; // assume - // If we have completed the right sort of DMA transfer then set the event to notify - // the user code to wake up anyone that is waiting. - if ((pArea->bCircular) && // Circular areas use a simpler test - (pArea->bCircToHost)) // only in supported direction - { // Is total data waiting up to size limit? - unsigned int dwTotal = pArea->aBlocks[0].dwSize + pArea->aBlocks[1].dwSize; - iWakeUp = (dwTotal >= pArea->dwEventSz); - } - else - { - unsigned int transEnd = pdx->StagedOffset + pdx->StagedLength; - unsigned int eventEnd = pArea->dwEventSt + pArea->dwEventSz; - iWakeUp = (pdx->StagedOffset < eventEnd) && (transEnd > pArea->dwEventSt); - } - - if (iWakeUp) - { - dev_dbg(&pdx->interface->dev, "About to set event to notify app"); - wake_up_interruptible(&pArea->wqEvent); // wake up waiting processes - ++pArea->iWakeUp; // increment wakeup count - } - } - } - - pdx->dwDMAFlag = MODE_CHAR; // Switch back to char mode before ReadWriteMem call - - if (!bCancel) // Don't look for waiting transfer if cancelled - { - // If we have a transfer waiting, kick it off - if (pdx->bXFerWaiting) // Got a block xfer waiting? - { - int iReturn; - dev_info(&pdx->interface->dev, "*** RWM_Complete *** pending transfer will now be set up!!!"); - iReturn = ReadWriteMem(pdx, !pdx->rDMAInfo.bOutWard, pdx->rDMAInfo.wIdent, pdx->rDMAInfo.dwOffset, pdx->rDMAInfo.dwSize); - - if (iReturn) - dev_err(&pdx->interface->dev, "RWM_Complete rw setup failed %d", iReturn); - } - } - - } - else // Here for more to do - StageChunk(pdx); // fire off the next bit - - // While we hold the stagedLock, see if we should reallow character input ints - // Don't allow if cancelled, or if a new block has started or if there is a waiting block. - // This feels wrong as we should ask which spin lock protects dwDMAFlag. - bRestartCharInput = !bCancel && (pdx->dwDMAFlag == MODE_CHAR) && !pdx->bXFerWaiting; - - spin_unlock(&pdx->stagedLock); // Finally release the lock again - - // This is not correct as dwDMAFlag is protected by the staged lock, but it is treated - // in Allowi as if it were protected by the char lock. In any case, most systems will - // not be upset by char input during DMA... sigh. Needs sorting out. - if (bRestartCharInput) // may be out of date, but... - Allowi(pdx, true); // ...Allowi tests a lock too. - dev_dbg(&pdx->interface->dev, "%s done", __func__); + DEVICE_EXTENSION *pdx = pUrb->context; + unsigned int nGot = pUrb->actual_length; // what we transferred + bool bCancel = false; + bool bRestartCharInput; // used at the end + + spin_lock(&pdx->stagedLock); // stop ReadWriteMem() action while this routine is running + pdx->bStagedUrbPending = false; // clear the flag for staged IRP pending + + if (pUrb->status) { // sync/async unlink faults aren't errors + if (! + (pUrb->status == -ENOENT || pUrb->status == -ECONNRESET + || pUrb->status == -ESHUTDOWN)) { + dev_err(&pdx->interface->dev, + "%s - nonzero write bulk status received: %d", + __func__, pUrb->status); + } else + dev_info(&pdx->interface->dev, + "%s - staged xfer cancelled", __func__); + + spin_lock(&pdx->err_lock); + pdx->errors = pUrb->status; + spin_unlock(&pdx->err_lock); + nGot = 0; // and tidy up again if so + bCancel = true; + } else { + dev_dbg(&pdx->interface->dev, "%s %d chars xferred", __func__, + nGot); + if (pdx->StagedRead) // if reading, save to user space + CopyUserSpace(pdx, nGot); // copy from buffer to user + if (nGot == 0) + dev_dbg(&pdx->interface->dev, "%s ZLP", __func__); + } + + // Update the transfer length based on the TransferBufferLength value in the URB + pdx->StagedDone += nGot; + + dev_dbg(&pdx->interface->dev, "%s, done %d bytes of %d", __func__, + pdx->StagedDone, pdx->StagedLength); + + if ((pdx->StagedDone == pdx->StagedLength) || // If no more to do + (bCancel)) // or this IRP was cancelled + { + TRANSAREA *pArea = &pdx->rTransDef[pdx->StagedId]; // Transfer area info + dev_dbg(&pdx->interface->dev, + "%s transfer done, bytes %d, cancel %d", __func__, + pdx->StagedDone, bCancel); + + // Here is where we sort out what to do with this transfer if using a circular buffer. We have + // a completed transfer that can be assumed to fit into the transfer area. We should be able to + // add this to the end of a growing block or to use it to start a new block unless the code + // that calculates the offset to use (in ReadWriteMem) is totally duff. + if ((pArea->bCircular) && (pArea->bCircToHost) && (!bCancel) && // Time to sort out circular buffer info? + (pdx->StagedRead)) // Only for tohost transfers for now + { + if (pArea->aBlocks[1].dwSize > 0) // If block 1 is in use we must append to it + { + if (pdx->StagedOffset == + (pArea->aBlocks[1].dwOffset + + pArea->aBlocks[1].dwSize)) { + pArea->aBlocks[1].dwSize += + pdx->StagedLength; + dev_dbg(&pdx->interface->dev, + "RWM_Complete, circ block 1 now %d bytes at %d", + pArea->aBlocks[1].dwSize, + pArea->aBlocks[1].dwOffset); + } else { + // Here things have gone very, very, wrong, but I cannot see how this can actually be achieved + pArea->aBlocks[1].dwOffset = + pdx->StagedOffset; + pArea->aBlocks[1].dwSize = + pdx->StagedLength; + dev_err(&pdx->interface->dev, + "%s ERROR, circ block 1 re-started %d bytes at %d", + __func__, + pArea->aBlocks[1].dwSize, + pArea->aBlocks[1].dwOffset); + } + } else // If block 1 is not used, we try to add to block 0 + { + if (pArea->aBlocks[0].dwSize > 0) // Got stored block 0 information? + { // Must append onto the existing block 0 + if (pdx->StagedOffset == + (pArea->aBlocks[0].dwOffset + + pArea->aBlocks[0].dwSize)) { + pArea->aBlocks[0].dwSize += pdx->StagedLength; // Just add this transfer in + dev_dbg(&pdx->interface->dev, + "RWM_Complete, circ block 0 now %d bytes at %d", + pArea->aBlocks[0]. + dwSize, + pArea->aBlocks[0]. + dwOffset); + } else // If it doesn't append, put into new block 1 + { + pArea->aBlocks[1].dwOffset = + pdx->StagedOffset; + pArea->aBlocks[1].dwSize = + pdx->StagedLength; + dev_dbg(&pdx->interface->dev, + "RWM_Complete, circ block 1 started %d bytes at %d", + pArea->aBlocks[1]. + dwSize, + pArea->aBlocks[1]. + dwOffset); + } + } else // No info stored yet, just save in block 0 + { + pArea->aBlocks[0].dwOffset = + pdx->StagedOffset; + pArea->aBlocks[0].dwSize = + pdx->StagedLength; + dev_dbg(&pdx->interface->dev, + "RWM_Complete, circ block 0 started %d bytes at %d", + pArea->aBlocks[0].dwSize, + pArea->aBlocks[0].dwOffset); + } + } + } + + if (!bCancel) // Don't generate an event if cancelled + { + dev_dbg(&pdx->interface->dev, + "RWM_Complete, bCircular %d, bToHost %d, eStart %d, eSize %d", + pArea->bCircular, pArea->bEventToHost, + pArea->dwEventSt, pArea->dwEventSz); + if ((pArea->dwEventSz) && // Set a user-mode event... + (pdx->StagedRead == pArea->bEventToHost)) // ...on transfers in this direction? + { + int iWakeUp = 0; // assume + // If we have completed the right sort of DMA transfer then set the event to notify + // the user code to wake up anyone that is waiting. + if ((pArea->bCircular) && // Circular areas use a simpler test + (pArea->bCircToHost)) // only in supported direction + { // Is total data waiting up to size limit? + unsigned int dwTotal = + pArea->aBlocks[0].dwSize + + pArea->aBlocks[1].dwSize; + iWakeUp = (dwTotal >= pArea->dwEventSz); + } else { + unsigned int transEnd = + pdx->StagedOffset + + pdx->StagedLength; + unsigned int eventEnd = + pArea->dwEventSt + pArea->dwEventSz; + iWakeUp = (pdx->StagedOffset < eventEnd) + && (transEnd > pArea->dwEventSt); + } + + if (iWakeUp) { + dev_dbg(&pdx->interface->dev, + "About to set event to notify app"); + wake_up_interruptible(&pArea->wqEvent); // wake up waiting processes + ++pArea->iWakeUp; // increment wakeup count + } + } + } + + pdx->dwDMAFlag = MODE_CHAR; // Switch back to char mode before ReadWriteMem call + + if (!bCancel) // Don't look for waiting transfer if cancelled + { + // If we have a transfer waiting, kick it off + if (pdx->bXFerWaiting) // Got a block xfer waiting? + { + int iReturn; + dev_info(&pdx->interface->dev, + "*** RWM_Complete *** pending transfer will now be set up!!!"); + iReturn = + ReadWriteMem(pdx, !pdx->rDMAInfo.bOutWard, + pdx->rDMAInfo.wIdent, + pdx->rDMAInfo.dwOffset, + pdx->rDMAInfo.dwSize); + + if (iReturn) + dev_err(&pdx->interface->dev, + "RWM_Complete rw setup failed %d", + iReturn); + } + } + + } else // Here for more to do + StageChunk(pdx); // fire off the next bit + + // While we hold the stagedLock, see if we should reallow character input ints + // Don't allow if cancelled, or if a new block has started or if there is a waiting block. + // This feels wrong as we should ask which spin lock protects dwDMAFlag. + bRestartCharInput = !bCancel && (pdx->dwDMAFlag == MODE_CHAR) + && !pdx->bXFerWaiting; + + spin_unlock(&pdx->stagedLock); // Finally release the lock again + + // This is not correct as dwDMAFlag is protected by the staged lock, but it is treated + // in Allowi as if it were protected by the char lock. In any case, most systems will + // not be upset by char input during DMA... sigh. Needs sorting out. + if (bRestartCharInput) // may be out of date, but... + Allowi(pdx, true); // ...Allowi tests a lock too. + dev_dbg(&pdx->interface->dev, "%s done", __func__); } /**************************************************************************** @@ -704,46 +743,50 @@ static void staged_callback(struct urb* pUrb) ** The calling code must have acquired the staging spinlock before calling ** this function, and is responsible for releasing it. We are at callback level. ****************************************************************************/ -static int StageChunk(DEVICE_EXTENSION *pdx) +static int StageChunk(DEVICE_EXTENSION * pdx) { - int iReturn = U14ERR_NOERROR; + int iReturn = U14ERR_NOERROR; unsigned int ChunkSize; - int nPipe = pdx->StagedRead ? 3 : 2; // The pipe number to use for reads or writes - if (pdx->nPipes == 3) nPipe--; // Adjust for the 3-pipe case - if (nPipe < 0) // and trap case that should never happen - return U14ERR_FAIL; - - if (!CanAcceptIoRequests(pdx)) // got sudden remove? - { - dev_info(&pdx->interface->dev, "%s sudden remove, giving up", __func__); - return U14ERR_FAIL; // could do with a better error - } - - ChunkSize = (pdx->StagedLength - pdx->StagedDone); // transfer length remaining - if (ChunkSize > STAGED_SZ) // make sure to keep legal - ChunkSize = STAGED_SZ; // limit to max allowed - - if (!pdx->StagedRead) // if writing... - CopyUserSpace(pdx, ChunkSize); // ...copy data into the buffer - - usb_fill_bulk_urb(pdx->pStagedUrb, pdx->udev, - pdx->StagedRead ? usb_rcvbulkpipe(pdx->udev, pdx->epAddr[nPipe]): - usb_sndbulkpipe(pdx->udev, pdx->epAddr[nPipe]), - pdx->pCoherStagedIO, ChunkSize, staged_callback, pdx); - pdx->pStagedUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - usb_anchor_urb(pdx->pStagedUrb, &pdx->submitted); // in case we need to kill it - iReturn = usb_submit_urb(pdx->pStagedUrb, GFP_ATOMIC); - if (iReturn) - { - usb_unanchor_urb(pdx->pStagedUrb); // kill it - pdx->bPipeError[nPipe] = 1; // Flag an error to be handled later - dev_err(&pdx->interface->dev, "%s submit urb failed, code %d", __func__, iReturn); - } - else - pdx->bStagedUrbPending = true; // Set the flag for staged URB pending - dev_dbg(&pdx->interface->dev, "%s done so far:%d, this size:%d", __func__, pdx->StagedDone, ChunkSize); - - return iReturn; + int nPipe = pdx->StagedRead ? 3 : 2; // The pipe number to use for reads or writes + if (pdx->nPipes == 3) + nPipe--; // Adjust for the 3-pipe case + if (nPipe < 0) // and trap case that should never happen + return U14ERR_FAIL; + + if (!CanAcceptIoRequests(pdx)) // got sudden remove? + { + dev_info(&pdx->interface->dev, "%s sudden remove, giving up", + __func__); + return U14ERR_FAIL; // could do with a better error + } + + ChunkSize = (pdx->StagedLength - pdx->StagedDone); // transfer length remaining + if (ChunkSize > STAGED_SZ) // make sure to keep legal + ChunkSize = STAGED_SZ; // limit to max allowed + + if (!pdx->StagedRead) // if writing... + CopyUserSpace(pdx, ChunkSize); // ...copy data into the buffer + + usb_fill_bulk_urb(pdx->pStagedUrb, pdx->udev, + pdx->StagedRead ? usb_rcvbulkpipe(pdx->udev, + pdx-> + epAddr[nPipe]) : + usb_sndbulkpipe(pdx->udev, pdx->epAddr[nPipe]), + pdx->pCoherStagedIO, ChunkSize, staged_callback, pdx); + pdx->pStagedUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + usb_anchor_urb(pdx->pStagedUrb, &pdx->submitted); // in case we need to kill it + iReturn = usb_submit_urb(pdx->pStagedUrb, GFP_ATOMIC); + if (iReturn) { + usb_unanchor_urb(pdx->pStagedUrb); // kill it + pdx->bPipeError[nPipe] = 1; // Flag an error to be handled later + dev_err(&pdx->interface->dev, "%s submit urb failed, code %d", + __func__, iReturn); + } else + pdx->bStagedUrbPending = true; // Set the flag for staged URB pending + dev_dbg(&pdx->interface->dev, "%s done so far:%d, this size:%d", + __func__, pdx->StagedDone, ChunkSize); + + return iReturn; } /*************************************************************************** @@ -763,85 +806,95 @@ static int StageChunk(DEVICE_EXTENSION *pdx) ** transfer. ** dwLen - the number of bytes to transfer. */ -int ReadWriteMem(DEVICE_EXTENSION *pdx, bool Read, unsigned short wIdent, - unsigned int dwOffs, unsigned int dwLen) +int ReadWriteMem(DEVICE_EXTENSION * pdx, bool Read, unsigned short wIdent, + unsigned int dwOffs, unsigned int dwLen) { - TRANSAREA* pArea = &pdx->rTransDef[wIdent]; // Transfer area info - - if (!CanAcceptIoRequests(pdx)) // Are we in a state to accept new requests? - { - dev_err(&pdx->interface->dev, "%s can't accept requests", __func__); - return U14ERR_FAIL; - } - - dev_dbg(&pdx->interface->dev, "%s xfer %d bytes to %s, offset %d, area %d", - __func__, dwLen, Read ? "host" : "1401", dwOffs, wIdent); - - // Amazingly, we can get an escape sequence back before the current staged Urb is done, so we - // have to check for this situation and, if so, wait until all is OK. - if (pdx->bStagedUrbPending) - { - pdx->bXFerWaiting = true; // Flag we are waiting - dev_info(&pdx->interface->dev, "%s xfer is waiting, as previous staged pending", __func__); - return U14ERR_NOERROR; - } - - if (dwLen == 0) // allow 0-len read or write; just return success - { - dev_dbg(&pdx->interface->dev, "%s OK; zero-len read/write request", __func__); - return U14ERR_NOERROR; - } - - if ((pArea->bCircular) && // Circular transfer? - (pArea->bCircToHost) && (Read)) // In a supported direction - { // If so, we sort out offset ourself - bool bWait = false; // Flag for transfer having to wait - - dev_dbg(&pdx->interface->dev, "Circular buffers are %d at %d and %d at %d", - pArea->aBlocks[0].dwSize, pArea->aBlocks[0].dwOffset, pArea->aBlocks[1].dwSize, pArea->aBlocks[1].dwOffset); - if (pArea->aBlocks[1].dwSize > 0) // Using the second block already? - { - dwOffs = pArea->aBlocks[1].dwOffset + pArea->aBlocks[1].dwSize; // take offset from that - bWait = (dwOffs + dwLen) > pArea->aBlocks[0].dwOffset; // Wait if will overwrite block 0? - bWait |= (dwOffs + dwLen) > pArea->dwLength; // or if it overflows the buffer - } - else // Area 1 not in use, try to use area 0 - { - if (pArea->aBlocks[0].dwSize == 0) // Reset block 0 if not in use - pArea->aBlocks[0].dwOffset = 0; - dwOffs = pArea->aBlocks[0].dwOffset + pArea->aBlocks[0].dwSize; - if ((dwOffs+dwLen) > pArea->dwLength) // Off the end of the buffer? - { - pArea->aBlocks[1].dwOffset = 0; // Set up to use second block - dwOffs = 0; - bWait = (dwOffs + dwLen) > pArea->aBlocks[0].dwOffset; // Wait if will overwrite block 0? - bWait |= (dwOffs + dwLen) > pArea->dwLength; // or if it overflows the buffer - } - } - - if (bWait) // This transfer will have to wait? - { - pdx->bXFerWaiting = true; // Flag we are waiting - dev_dbg(&pdx->interface->dev, "%s xfer waiting for circular buffer space", __func__); - return U14ERR_NOERROR; - } - - dev_dbg(&pdx->interface->dev, "%s circular xfer, %d bytes starting at %d", __func__, dwLen, dwOffs); - } - - // Save the parameters for the read\write transfer - pdx->StagedRead = Read; // Save the parameters for this read - pdx->StagedId = wIdent; // ID allows us to get transfer area info - pdx->StagedOffset = dwOffs; // The area within the transfer area - pdx->StagedLength = dwLen; - pdx->StagedDone = 0; // Initialise the byte count - pdx->dwDMAFlag = MODE_LINEAR; // Set DMA mode flag at this point - pdx->bXFerWaiting = false; // Clearly not a transfer waiting now + TRANSAREA *pArea = &pdx->rTransDef[wIdent]; // Transfer area info + + if (!CanAcceptIoRequests(pdx)) // Are we in a state to accept new requests? + { + dev_err(&pdx->interface->dev, "%s can't accept requests", + __func__); + return U14ERR_FAIL; + } + + dev_dbg(&pdx->interface->dev, + "%s xfer %d bytes to %s, offset %d, area %d", __func__, dwLen, + Read ? "host" : "1401", dwOffs, wIdent); + + // Amazingly, we can get an escape sequence back before the current staged Urb is done, so we + // have to check for this situation and, if so, wait until all is OK. + if (pdx->bStagedUrbPending) { + pdx->bXFerWaiting = true; // Flag we are waiting + dev_info(&pdx->interface->dev, + "%s xfer is waiting, as previous staged pending", + __func__); + return U14ERR_NOERROR; + } + + if (dwLen == 0) // allow 0-len read or write; just return success + { + dev_dbg(&pdx->interface->dev, + "%s OK; zero-len read/write request", __func__); + return U14ERR_NOERROR; + } + + if ((pArea->bCircular) && // Circular transfer? + (pArea->bCircToHost) && (Read)) // In a supported direction + { // If so, we sort out offset ourself + bool bWait = false; // Flag for transfer having to wait + + dev_dbg(&pdx->interface->dev, + "Circular buffers are %d at %d and %d at %d", + pArea->aBlocks[0].dwSize, pArea->aBlocks[0].dwOffset, + pArea->aBlocks[1].dwSize, pArea->aBlocks[1].dwOffset); + if (pArea->aBlocks[1].dwSize > 0) // Using the second block already? + { + dwOffs = pArea->aBlocks[1].dwOffset + pArea->aBlocks[1].dwSize; // take offset from that + bWait = (dwOffs + dwLen) > pArea->aBlocks[0].dwOffset; // Wait if will overwrite block 0? + bWait |= (dwOffs + dwLen) > pArea->dwLength; // or if it overflows the buffer + } else // Area 1 not in use, try to use area 0 + { + if (pArea->aBlocks[0].dwSize == 0) // Reset block 0 if not in use + pArea->aBlocks[0].dwOffset = 0; + dwOffs = + pArea->aBlocks[0].dwOffset + + pArea->aBlocks[0].dwSize; + if ((dwOffs + dwLen) > pArea->dwLength) // Off the end of the buffer? + { + pArea->aBlocks[1].dwOffset = 0; // Set up to use second block + dwOffs = 0; + bWait = (dwOffs + dwLen) > pArea->aBlocks[0].dwOffset; // Wait if will overwrite block 0? + bWait |= (dwOffs + dwLen) > pArea->dwLength; // or if it overflows the buffer + } + } + + if (bWait) // This transfer will have to wait? + { + pdx->bXFerWaiting = true; // Flag we are waiting + dev_dbg(&pdx->interface->dev, + "%s xfer waiting for circular buffer space", + __func__); + return U14ERR_NOERROR; + } + + dev_dbg(&pdx->interface->dev, + "%s circular xfer, %d bytes starting at %d", __func__, + dwLen, dwOffs); + } + // Save the parameters for the read\write transfer + pdx->StagedRead = Read; // Save the parameters for this read + pdx->StagedId = wIdent; // ID allows us to get transfer area info + pdx->StagedOffset = dwOffs; // The area within the transfer area + pdx->StagedLength = dwLen; + pdx->StagedDone = 0; // Initialise the byte count + pdx->dwDMAFlag = MODE_LINEAR; // Set DMA mode flag at this point + pdx->bXFerWaiting = false; // Clearly not a transfer waiting now // KeClearEvent(&pdx->StagingDoneEvent); // Clear the transfer done event - StageChunk(pdx); // fire off the first chunk + StageChunk(pdx); // fire off the first chunk - return U14ERR_NOERROR; + return U14ERR_NOERROR; } /**************************************************************************** @@ -852,20 +905,21 @@ int ReadWriteMem(DEVICE_EXTENSION *pdx, bool Read, unsigned short wIdent, ** data we return FALSE. Used as part of decoding a DMA request. ** ****************************************************************************/ -static bool ReadChar(unsigned char* pChar, char* pBuf, unsigned int* pdDone, unsigned int dGot) +static bool ReadChar(unsigned char *pChar, char *pBuf, unsigned int *pdDone, + unsigned int dGot) { - bool bRead = false; - unsigned int dDone = *pdDone; - - if (dDone < dGot) // If there is more data - { - *pChar = (unsigned char)pBuf[dDone];// Extract the next char - dDone++; // Increment the done count - *pdDone = dDone; - bRead = true; // and flag success - } - - return bRead; + bool bRead = false; + unsigned int dDone = *pdDone; + + if (dDone < dGot) // If there is more data + { + *pChar = (unsigned char)pBuf[dDone]; // Extract the next char + dDone++; // Increment the done count + *pdDone = dDone; + bRead = true; // and flag success + } + + return bRead; } #ifdef NOTUSED @@ -876,12 +930,14 @@ static bool ReadChar(unsigned char* pChar, char* pBuf, unsigned int* pdDone, uns ** Reads a word from the 1401, just uses ReadChar twice; passes on any error ** *****************************************************************************/ -static bool ReadWord(unsigned short* pWord, char* pBuf, unsigned int* pdDone, unsigned int dGot) +static bool ReadWord(unsigned short *pWord, char *pBuf, unsigned int *pdDone, + unsigned int dGot) { - if (ReadChar((unsigned char*)pWord, pBuf, pdDone, dGot)) - return ReadChar(((unsigned char*)pWord)+1, pBuf, pdDone, dGot); - else - return false; + if (ReadChar((unsigned char *)pWord, pBuf, pdDone, dGot)) + return ReadChar(((unsigned char *)pWord) + 1, pBuf, pdDone, + dGot); + else + return false; } #endif @@ -895,39 +951,35 @@ static bool ReadWord(unsigned short* pWord, char* pBuf, unsigned int* pdDone, un ** to indicate three byte total. ** *****************************************************************************/ -static bool ReadHuff(volatile unsigned int* pDWord, char* pBuf, unsigned int* pdDone, unsigned int dGot) +static bool ReadHuff(volatile unsigned int *pDWord, char *pBuf, + unsigned int *pdDone, unsigned int dGot) { - unsigned char ucData; /* for each read to ReadChar */ - bool bReturn = true; /* assume we will succeed */ - unsigned int dwData = 0; /* Accumulator for the data */ - - if (ReadChar(&ucData, pBuf, pdDone, dGot)) - { - dwData = ucData; /* copy the data */ - if ((dwData & 0x00000080) != 0) /* Bit set for more data ? */ - { - dwData &= 0x0000007F; /* Clear the relevant bit */ - if (ReadChar(&ucData, pBuf, pdDone, dGot)) - { - dwData = (dwData << 8) | ucData; - if ((dwData & 0x00004000) != 0) /* three byte sequence ? */ - { - dwData &= 0x00003FFF; /* Clear the relevant bit */ - if (ReadChar(&ucData, pBuf, pdDone, dGot)) - dwData = (dwData << 8) | ucData; - else - bReturn = false; - } - } - else - bReturn = false; /* couldn't read data */ - } - } - else - bReturn = false; - - *pDWord = dwData; /* return the data */ - return bReturn; + unsigned char ucData; /* for each read to ReadChar */ + bool bReturn = true; /* assume we will succeed */ + unsigned int dwData = 0; /* Accumulator for the data */ + + if (ReadChar(&ucData, pBuf, pdDone, dGot)) { + dwData = ucData; /* copy the data */ + if ((dwData & 0x00000080) != 0) { /* Bit set for more data ? */ + dwData &= 0x0000007F; /* Clear the relevant bit */ + if (ReadChar(&ucData, pBuf, pdDone, dGot)) { + dwData = (dwData << 8) | ucData; + if ((dwData & 0x00004000) != 0) { /* three byte sequence ? */ + dwData &= 0x00003FFF; /* Clear the relevant bit */ + if (ReadChar + (&ucData, pBuf, pdDone, dGot)) + dwData = (dwData << 8) | ucData; + else + bReturn = false; + } + } else + bReturn = false; /* couldn't read data */ + } + } else + bReturn = false; + + *pDWord = dwData; /* return the data */ + return bReturn; } /*************************************************************************** @@ -944,66 +996,77 @@ static bool ReadHuff(volatile unsigned int* pDWord, char* pBuf, unsigned int* pd ** we start handling the data at offset zero. ** *****************************************************************************/ -static bool ReadDMAInfo(volatile DMADESC* pDmaDesc, DEVICE_EXTENSION *pdx, - char* pBuf, unsigned int dwCount) +static bool ReadDMAInfo(volatile DMADESC * pDmaDesc, DEVICE_EXTENSION * pdx, + char *pBuf, unsigned int dwCount) { - bool bResult = false; // assume we won't succeed - unsigned char ucData; - unsigned int dDone = 0; // We haven't parsed anything so far - - dev_dbg(&pdx->interface->dev, "%s", __func__); - - if (ReadChar(&ucData, pBuf, &dDone, dwCount)) - { - unsigned char ucTransCode = (ucData & 0x0F); // get code for transfer type - unsigned short wIdent = ((ucData >> 4) & 0x07); // and area identifier - - // fill in the structure we were given - pDmaDesc->wTransType = ucTransCode; // type of transfer - pDmaDesc->wIdent = wIdent; // area to use - pDmaDesc->dwSize = 0; // initialise other bits - pDmaDesc->dwOffset = 0; - - dev_dbg(&pdx->interface->dev, "%s type: %d ident: %d", __func__, pDmaDesc->wTransType, pDmaDesc->wIdent); - - pDmaDesc->bOutWard = (ucTransCode != TM_EXTTOHOST); // set transfer direction - - switch (ucTransCode) - { - case TM_EXTTOHOST: // Extended linear transfer modes (the only ones!) - case TM_EXTTO1401: - { - bResult = ReadHuff(&(pDmaDesc->dwOffset), pBuf, &dDone, dwCount) && - ReadHuff(&(pDmaDesc->dwSize), pBuf, &dDone, dwCount); - if (bResult) - { - dev_dbg(&pdx->interface->dev, "%s xfer offset & size %d %d", - __func__, pDmaDesc->dwOffset, pDmaDesc->dwSize); - - if ((wIdent >= MAX_TRANSAREAS) || // Illegal area number, or... - (!pdx->rTransDef[wIdent].bUsed) || // area not set up, or... - (pDmaDesc->dwOffset > pdx->rTransDef[wIdent].dwLength) || // range/size - ((pDmaDesc->dwOffset + pDmaDesc->dwSize) > (pdx->rTransDef[wIdent].dwLength))) - { - bResult = false; // bad parameter(s) - dev_dbg(&pdx->interface->dev, "%s bad param - id %d, bUsed %d, offset %d, size %d, area length %d", - __func__, wIdent, pdx->rTransDef[wIdent].bUsed, pDmaDesc->dwOffset, pDmaDesc->dwSize, - pdx->rTransDef[wIdent].dwLength); - } - } - break; - } - default: - break; - } - } - else - bResult = false; - - if (!bResult) // now check parameters for validity - dev_err(&pdx->interface->dev, "%s error reading Esc sequence", __func__); - - return bResult; + bool bResult = false; // assume we won't succeed + unsigned char ucData; + unsigned int dDone = 0; // We haven't parsed anything so far + + dev_dbg(&pdx->interface->dev, "%s", __func__); + + if (ReadChar(&ucData, pBuf, &dDone, dwCount)) { + unsigned char ucTransCode = (ucData & 0x0F); // get code for transfer type + unsigned short wIdent = ((ucData >> 4) & 0x07); // and area identifier + + // fill in the structure we were given + pDmaDesc->wTransType = ucTransCode; // type of transfer + pDmaDesc->wIdent = wIdent; // area to use + pDmaDesc->dwSize = 0; // initialise other bits + pDmaDesc->dwOffset = 0; + + dev_dbg(&pdx->interface->dev, "%s type: %d ident: %d", __func__, + pDmaDesc->wTransType, pDmaDesc->wIdent); + + pDmaDesc->bOutWard = (ucTransCode != TM_EXTTOHOST); // set transfer direction + + switch (ucTransCode) { + case TM_EXTTOHOST: // Extended linear transfer modes (the only ones!) + case TM_EXTTO1401: + { + bResult = + ReadHuff(&(pDmaDesc->dwOffset), pBuf, + &dDone, dwCount) + && ReadHuff(&(pDmaDesc->dwSize), pBuf, + &dDone, dwCount); + if (bResult) { + dev_dbg(&pdx->interface->dev, + "%s xfer offset & size %d %d", + __func__, pDmaDesc->dwOffset, + pDmaDesc->dwSize); + + if ((wIdent >= MAX_TRANSAREAS) || // Illegal area number, or... + (!pdx->rTransDef[wIdent].bUsed) || // area not set up, or... + (pDmaDesc->dwOffset > pdx->rTransDef[wIdent].dwLength) || // range/size + ((pDmaDesc->dwOffset + + pDmaDesc->dwSize) > + (pdx->rTransDef[wIdent]. + dwLength))) { + bResult = false; // bad parameter(s) + dev_dbg(&pdx->interface->dev, + "%s bad param - id %d, bUsed %d, offset %d, size %d, area length %d", + __func__, wIdent, + pdx->rTransDef[wIdent]. + bUsed, + pDmaDesc->dwOffset, + pDmaDesc->dwSize, + pdx->rTransDef[wIdent]. + dwLength); + } + } + break; + } + default: + break; + } + } else + bResult = false; + + if (!bResult) // now check parameters for validity + dev_err(&pdx->interface->dev, "%s error reading Esc sequence", + __func__); + + return bResult; } /**************************************************************************** @@ -1020,122 +1083,130 @@ static bool ReadDMAInfo(volatile DMADESC* pDmaDesc, DEVICE_EXTENSION *pdx, ** this is known to be at least 2 or we will not be called. ** ****************************************************************************/ -static int Handle1401Esc(DEVICE_EXTENSION* pdx, char* pCh, unsigned int dwCount) +static int Handle1401Esc(DEVICE_EXTENSION * pdx, char *pCh, + unsigned int dwCount) { - int iReturn = U14ERR_FAIL; - - // I have no idea what this next test is about. '?' is 0x3f, which is area 3, code - // 15. At the moment, this is not used, so it does no harm, but unless someone can - // tell me what this is for, it should be removed from this and the Windows driver. - if (pCh[0] == '?') // Is this an information response - { // Parse and save the information - } - else - { - spin_lock(&pdx->stagedLock); // Lock others out - - if (ReadDMAInfo(&pdx->rDMAInfo, pdx, pCh, dwCount)) // Get DMA parameters - { - unsigned short wTransType = pdx->rDMAInfo.wTransType; // check transfer type - - dev_dbg(&pdx->interface->dev, "%s xfer to %s, offset %d, length %d", __func__, - pdx->rDMAInfo.bOutWard ? "1401" : "host", - pdx->rDMAInfo.dwOffset, pdx->rDMAInfo.dwSize); - - if (pdx->bXFerWaiting) // Check here for badly out of kilter... - { // This can never happen, really - dev_err(&pdx->interface->dev, "ERROR: DMA setup while transfer still waiting"); - spin_unlock(&pdx->stagedLock); - } - else - { - if ((wTransType == TM_EXTTOHOST) || (wTransType == TM_EXTTO1401)) - { - iReturn = ReadWriteMem(pdx, !pdx->rDMAInfo.bOutWard, pdx->rDMAInfo.wIdent, pdx->rDMAInfo.dwOffset, pdx->rDMAInfo.dwSize); - if (iReturn != U14ERR_NOERROR) - dev_err(&pdx->interface->dev, "%s ReadWriteMem() failed %d", __func__, iReturn); - } - else // This covers non-linear transfer setup - dev_err(&pdx->interface->dev, "%s Unknown block xfer type %d", __func__, wTransType); - } - } - else // Failed to read parameters - dev_err(&pdx->interface->dev, "%s ReadDMAInfo() fail", __func__); - - spin_unlock(&pdx->stagedLock); // OK here - } - - dev_dbg(&pdx->interface->dev, "%s returns %d", __func__, iReturn); - - return iReturn; + int iReturn = U14ERR_FAIL; + + // I have no idea what this next test is about. '?' is 0x3f, which is area 3, code + // 15. At the moment, this is not used, so it does no harm, but unless someone can + // tell me what this is for, it should be removed from this and the Windows driver. + if (pCh[0] == '?') // Is this an information response + { // Parse and save the information + } else { + spin_lock(&pdx->stagedLock); // Lock others out + + if (ReadDMAInfo(&pdx->rDMAInfo, pdx, pCh, dwCount)) // Get DMA parameters + { + unsigned short wTransType = pdx->rDMAInfo.wTransType; // check transfer type + + dev_dbg(&pdx->interface->dev, + "%s xfer to %s, offset %d, length %d", __func__, + pdx->rDMAInfo.bOutWard ? "1401" : "host", + pdx->rDMAInfo.dwOffset, pdx->rDMAInfo.dwSize); + + if (pdx->bXFerWaiting) // Check here for badly out of kilter... + { // This can never happen, really + dev_err(&pdx->interface->dev, + "ERROR: DMA setup while transfer still waiting"); + spin_unlock(&pdx->stagedLock); + } else { + if ((wTransType == TM_EXTTOHOST) + || (wTransType == TM_EXTTO1401)) { + iReturn = + ReadWriteMem(pdx, + !pdx->rDMAInfo. + bOutWard, + pdx->rDMAInfo.wIdent, + pdx->rDMAInfo.dwOffset, + pdx->rDMAInfo.dwSize); + if (iReturn != U14ERR_NOERROR) + dev_err(&pdx->interface->dev, + "%s ReadWriteMem() failed %d", + __func__, iReturn); + } else // This covers non-linear transfer setup + dev_err(&pdx->interface->dev, + "%s Unknown block xfer type %d", + __func__, wTransType); + } + } else // Failed to read parameters + dev_err(&pdx->interface->dev, "%s ReadDMAInfo() fail", + __func__); + + spin_unlock(&pdx->stagedLock); // OK here + } + + dev_dbg(&pdx->interface->dev, "%s returns %d", __func__, iReturn); + + return iReturn; } /**************************************************************************** ** Callback for the character read complete or error ****************************************************************************/ -static void ced_readchar_callback(struct urb* pUrb) +static void ced_readchar_callback(struct urb *pUrb) { - DEVICE_EXTENSION *pdx = pUrb->context; - int nGot = pUrb->actual_length; // what we transferred - - if (pUrb->status) // Do we have a problem to handle? - { - int nPipe = pdx->nPipes == 4 ? 1 : 0; // The pipe number to use for error - // sync/async unlink faults aren't errors... just saying device removed or stopped - if (!(pUrb->status == -ENOENT || pUrb->status == -ECONNRESET || pUrb->status == -ESHUTDOWN)) - { - dev_err(&pdx->interface->dev, "%s - nonzero write bulk status received: %d", __func__, pUrb->status); - } - else - dev_dbg(&pdx->interface->dev, "%s - 0 chars pUrb->status=%d (shutdown?)", __func__, pUrb->status); - - spin_lock(&pdx->err_lock); - pdx->errors = pUrb->status; - spin_unlock(&pdx->err_lock); - nGot = 0; // and tidy up again if so - - spin_lock(&pdx->charInLock); // already at irq level - pdx->bPipeError[nPipe] = 1; // Flag an error for later - } - else - { - if ((nGot > 1) && ((pdx->pCoherCharIn[0] & 0x7f) == 0x1b)) // Esc sequence? - { - Handle1401Esc(pdx, &pdx->pCoherCharIn[1], nGot-1); // handle it - spin_lock(&pdx->charInLock); // already at irq level - } - else - { - spin_lock(&pdx->charInLock); // already at irq level - if (nGot > 0) - { - unsigned int i; - if (nGot < INBUF_SZ) - { - pdx->pCoherCharIn[nGot] = 0; // tidy the string - dev_dbg(&pdx->interface->dev, "%s got %d chars >%s<", __func__, nGot, pdx->pCoherCharIn); - } - - // We know that whatever we read must fit in the input buffer - for (i = 0; i < nGot; i++) - { - pdx->inputBuffer[pdx->dwInBuffPut++] = pdx->pCoherCharIn[i] & 0x7F; - if (pdx->dwInBuffPut >= INBUF_SZ) - pdx->dwInBuffPut = 0; - } - - if ((pdx->dwNumInput + nGot) <= INBUF_SZ) - pdx->dwNumInput += nGot; // Adjust the buffer count accordingly - } - else - dev_dbg(&pdx->interface->dev, "%s read ZLP", __func__); - } - } - - pdx->bReadCharsPending = false; // No longer have a pending read - spin_unlock(&pdx->charInLock); // already at irq level - - Allowi(pdx, true); // see if we can do the next one + DEVICE_EXTENSION *pdx = pUrb->context; + int nGot = pUrb->actual_length; // what we transferred + + if (pUrb->status) // Do we have a problem to handle? + { + int nPipe = pdx->nPipes == 4 ? 1 : 0; // The pipe number to use for error + // sync/async unlink faults aren't errors... just saying device removed or stopped + if (! + (pUrb->status == -ENOENT || pUrb->status == -ECONNRESET + || pUrb->status == -ESHUTDOWN)) { + dev_err(&pdx->interface->dev, + "%s - nonzero write bulk status received: %d", + __func__, pUrb->status); + } else + dev_dbg(&pdx->interface->dev, + "%s - 0 chars pUrb->status=%d (shutdown?)", + __func__, pUrb->status); + + spin_lock(&pdx->err_lock); + pdx->errors = pUrb->status; + spin_unlock(&pdx->err_lock); + nGot = 0; // and tidy up again if so + + spin_lock(&pdx->charInLock); // already at irq level + pdx->bPipeError[nPipe] = 1; // Flag an error for later + } else { + if ((nGot > 1) && ((pdx->pCoherCharIn[0] & 0x7f) == 0x1b)) // Esc sequence? + { + Handle1401Esc(pdx, &pdx->pCoherCharIn[1], nGot - 1); // handle it + spin_lock(&pdx->charInLock); // already at irq level + } else { + spin_lock(&pdx->charInLock); // already at irq level + if (nGot > 0) { + unsigned int i; + if (nGot < INBUF_SZ) { + pdx->pCoherCharIn[nGot] = 0; // tidy the string + dev_dbg(&pdx->interface->dev, + "%s got %d chars >%s<", + __func__, nGot, + pdx->pCoherCharIn); + } + // We know that whatever we read must fit in the input buffer + for (i = 0; i < nGot; i++) { + pdx->inputBuffer[pdx->dwInBuffPut++] = + pdx->pCoherCharIn[i] & 0x7F; + if (pdx->dwInBuffPut >= INBUF_SZ) + pdx->dwInBuffPut = 0; + } + + if ((pdx->dwNumInput + nGot) <= INBUF_SZ) + pdx->dwNumInput += nGot; // Adjust the buffer count accordingly + } else + dev_dbg(&pdx->interface->dev, "%s read ZLP", + __func__); + } + } + + pdx->bReadCharsPending = false; // No longer have a pending read + spin_unlock(&pdx->charInLock); // already at irq level + + Allowi(pdx, true); // see if we can do the next one } /**************************************************************************** @@ -1145,48 +1216,50 @@ static void ced_readchar_callback(struct urb* pUrb) ** we can pick up any inward transfers. This can be called in multiple contexts ** so we use the irqsave version of the spinlock. ****************************************************************************/ -int Allowi(DEVICE_EXTENSION* pdx, bool bInCallback) +int Allowi(DEVICE_EXTENSION * pdx, bool bInCallback) { - int iReturn = U14ERR_NOERROR; - unsigned long flags; - spin_lock_irqsave(&pdx->charInLock, flags); // can be called in multiple contexts - - // We don't want char input running while DMA is in progress as we know that this - // can cause sequencing problems for the 2270. So don't. It will also allow the - // ERR response to get back to the host code too early on some PCs, even if there - // is no actual driver failure, so we don't allow this at all. - if (!pdx->bInDrawDown && // stop input if - !pdx->bReadCharsPending && // If no read request outstanding - (pdx->dwNumInput < (INBUF_SZ/2)) && // and there is some space - (pdx->dwDMAFlag == MODE_CHAR) && // not doing any DMA - (!pdx->bXFerWaiting) && // no xfer waiting to start - (CanAcceptIoRequests(pdx))) // and activity is generally OK - { // then off we go - unsigned int nMax = INBUF_SZ-pdx->dwNumInput; // max we could read - int nPipe = pdx->nPipes == 4 ? 1 : 0; // The pipe number to use - - dev_dbg(&pdx->interface->dev, "%s %d chars in input buffer", __func__, pdx->dwNumInput); - - usb_fill_int_urb(pdx->pUrbCharIn, pdx->udev, - usb_rcvintpipe(pdx->udev, pdx->epAddr[nPipe]), - pdx->pCoherCharIn, nMax, ced_readchar_callback, - pdx, pdx->bInterval); - pdx->pUrbCharIn->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; // short xfers are OK by default - usb_anchor_urb(pdx->pUrbCharIn, &pdx->submitted); // in case we need to kill it - iReturn = usb_submit_urb(pdx->pUrbCharIn, bInCallback ? GFP_ATOMIC : GFP_KERNEL); - if (iReturn) - { - usb_unanchor_urb(pdx->pUrbCharIn); // remove from list of active Urbs - pdx->bPipeError[nPipe] = 1; // Flag an error to be handled later - dev_err(&pdx->interface->dev,"%s submit urb failed: %d", __func__, iReturn); - } - else - pdx->bReadCharsPending = true; // Flag that we are active here - } - - spin_unlock_irqrestore(&pdx->charInLock, flags); - - return iReturn; + int iReturn = U14ERR_NOERROR; + unsigned long flags; + spin_lock_irqsave(&pdx->charInLock, flags); // can be called in multiple contexts + + // We don't want char input running while DMA is in progress as we know that this + // can cause sequencing problems for the 2270. So don't. It will also allow the + // ERR response to get back to the host code too early on some PCs, even if there + // is no actual driver failure, so we don't allow this at all. + if (!pdx->bInDrawDown && // stop input if + !pdx->bReadCharsPending && // If no read request outstanding + (pdx->dwNumInput < (INBUF_SZ / 2)) && // and there is some space + (pdx->dwDMAFlag == MODE_CHAR) && // not doing any DMA + (!pdx->bXFerWaiting) && // no xfer waiting to start + (CanAcceptIoRequests(pdx))) // and activity is generally OK + { // then off we go + unsigned int nMax = INBUF_SZ - pdx->dwNumInput; // max we could read + int nPipe = pdx->nPipes == 4 ? 1 : 0; // The pipe number to use + + dev_dbg(&pdx->interface->dev, "%s %d chars in input buffer", + __func__, pdx->dwNumInput); + + usb_fill_int_urb(pdx->pUrbCharIn, pdx->udev, + usb_rcvintpipe(pdx->udev, pdx->epAddr[nPipe]), + pdx->pCoherCharIn, nMax, ced_readchar_callback, + pdx, pdx->bInterval); + pdx->pUrbCharIn->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; // short xfers are OK by default + usb_anchor_urb(pdx->pUrbCharIn, &pdx->submitted); // in case we need to kill it + iReturn = + usb_submit_urb(pdx->pUrbCharIn, + bInCallback ? GFP_ATOMIC : GFP_KERNEL); + if (iReturn) { + usb_unanchor_urb(pdx->pUrbCharIn); // remove from list of active Urbs + pdx->bPipeError[nPipe] = 1; // Flag an error to be handled later + dev_err(&pdx->interface->dev, + "%s submit urb failed: %d", __func__, iReturn); + } else + pdx->bReadCharsPending = true; // Flag that we are active here + } + + spin_unlock_irqrestore(&pdx->charInLock, flags); + + return iReturn; } @@ -1198,147 +1271,147 @@ int Allowi(DEVICE_EXTENSION* pdx, bool bInCallback) ** enough for a 64-bit pointer. *****************************************************************************/ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36) -static long ced_ioctl(struct file * file, unsigned int cmd, unsigned long ulArg) +static long ced_ioctl(struct file *file, unsigned int cmd, unsigned long ulArg) #else -static int ced_ioctl(struct inode * node, struct file * file, unsigned int cmd, unsigned long ulArg) +static int ced_ioctl(struct inode *node, struct file *file, unsigned int cmd, + unsigned long ulArg) #endif { - int err = 0; - DEVICE_EXTENSION *pdx = file->private_data; - if (!CanAcceptIoRequests(pdx)) // check we still exist - return -ENODEV; + int err = 0; + DEVICE_EXTENSION *pdx = file->private_data; + if (!CanAcceptIoRequests(pdx)) // check we still exist + return -ENODEV; - // Check that access is allowed, where is is needed. Anything that would have an indeterminate - // size will be checked by the specific command. - if (_IOC_DIR(cmd) & _IOC_READ) // read from point of view of user... - err = !access_ok(VERIFY_WRITE, (void __user *)ulArg, _IOC_SIZE(cmd)); // is kernel write - else if (_IOC_DIR(cmd) & _IOC_WRITE) // and write from point of view of user... - err = !access_ok(VERIFY_READ, (void __user *)ulArg, _IOC_SIZE(cmd)); // is kernel read - if (err) - return -EFAULT; + // Check that access is allowed, where is is needed. Anything that would have an indeterminate + // size will be checked by the specific command. + if (_IOC_DIR(cmd) & _IOC_READ) // read from point of view of user... + err = !access_ok(VERIFY_WRITE, (void __user *)ulArg, _IOC_SIZE(cmd)); // is kernel write + else if (_IOC_DIR(cmd) & _IOC_WRITE) // and write from point of view of user... + err = !access_ok(VERIFY_READ, (void __user *)ulArg, _IOC_SIZE(cmd)); // is kernel read + if (err) + return -EFAULT; - switch (_IOC_NR(cmd)) - { - case _IOC_NR(IOCTL_CED_SENDSTRING(0)): - return SendString(pdx, (const char __user*)ulArg, _IOC_SIZE(cmd)); + switch (_IOC_NR(cmd)) { + case _IOC_NR(IOCTL_CED_SENDSTRING(0)): + return SendString(pdx, (const char __user *)ulArg, + _IOC_SIZE(cmd)); - case _IOC_NR(IOCTL_CED_RESET1401): - return Reset1401(pdx); + case _IOC_NR(IOCTL_CED_RESET1401): + return Reset1401(pdx); - case _IOC_NR(IOCTL_CED_GETCHAR): - return GetChar(pdx); + case _IOC_NR(IOCTL_CED_GETCHAR): + return GetChar(pdx); - case _IOC_NR(IOCTL_CED_SENDCHAR): - return SendChar(pdx, (char)ulArg); + case _IOC_NR(IOCTL_CED_SENDCHAR): + return SendChar(pdx, (char)ulArg); - case _IOC_NR(IOCTL_CED_STAT1401): - return Stat1401(pdx); + case _IOC_NR(IOCTL_CED_STAT1401): + return Stat1401(pdx); - case _IOC_NR(IOCTL_CED_LINECOUNT): - return LineCount(pdx); + case _IOC_NR(IOCTL_CED_LINECOUNT): + return LineCount(pdx); - case _IOC_NR(IOCTL_CED_GETSTRING(0)): - return GetString(pdx, (char __user*)ulArg, _IOC_SIZE(cmd)); + case _IOC_NR(IOCTL_CED_GETSTRING(0)): + return GetString(pdx, (char __user *)ulArg, _IOC_SIZE(cmd)); - case _IOC_NR(IOCTL_CED_SETTRANSFER): - return SetTransfer(pdx, (TRANSFERDESC __user*)ulArg); + case _IOC_NR(IOCTL_CED_SETTRANSFER): + return SetTransfer(pdx, (TRANSFERDESC __user *) ulArg); - case _IOC_NR(IOCTL_CED_UNSETTRANSFER): - return UnsetTransfer(pdx, (int)ulArg); + case _IOC_NR(IOCTL_CED_UNSETTRANSFER): + return UnsetTransfer(pdx, (int)ulArg); - case _IOC_NR(IOCTL_CED_SETEVENT): - return SetEvent(pdx, (TRANSFEREVENT __user*)ulArg); + case _IOC_NR(IOCTL_CED_SETEVENT): + return SetEvent(pdx, (TRANSFEREVENT __user *) ulArg); - case _IOC_NR(IOCTL_CED_GETOUTBUFSPACE): - return GetOutBufSpace(pdx); + case _IOC_NR(IOCTL_CED_GETOUTBUFSPACE): + return GetOutBufSpace(pdx); - case _IOC_NR(IOCTL_CED_GETBASEADDRESS): - return -1; + case _IOC_NR(IOCTL_CED_GETBASEADDRESS): + return -1; - case _IOC_NR(IOCTL_CED_GETDRIVERREVISION): - return (2<<24)|(DRIVERMAJREV<<16) | DRIVERMINREV; // USB | MAJOR | MINOR + case _IOC_NR(IOCTL_CED_GETDRIVERREVISION): + return (2 << 24) | (DRIVERMAJREV << 16) | DRIVERMINREV; // USB | MAJOR | MINOR - case _IOC_NR(IOCTL_CED_GETTRANSFER): - return GetTransfer(pdx, (TGET_TX_BLOCK __user*)ulArg); + case _IOC_NR(IOCTL_CED_GETTRANSFER): + return GetTransfer(pdx, (TGET_TX_BLOCK __user *) ulArg); - case _IOC_NR(IOCTL_CED_KILLIO1401): - return KillIO1401(pdx); + case _IOC_NR(IOCTL_CED_KILLIO1401): + return KillIO1401(pdx); - case _IOC_NR(IOCTL_CED_STATEOF1401): - return StateOf1401(pdx); + case _IOC_NR(IOCTL_CED_STATEOF1401): + return StateOf1401(pdx); - case _IOC_NR(IOCTL_CED_GRAB1401): - case _IOC_NR(IOCTL_CED_FREE1401): - return U14ERR_NOERROR; + case _IOC_NR(IOCTL_CED_GRAB1401): + case _IOC_NR(IOCTL_CED_FREE1401): + return U14ERR_NOERROR; - case _IOC_NR(IOCTL_CED_STARTSELFTEST): - return StartSelfTest(pdx); + case _IOC_NR(IOCTL_CED_STARTSELFTEST): + return StartSelfTest(pdx); - case _IOC_NR(IOCTL_CED_CHECKSELFTEST): - return CheckSelfTest(pdx, (TGET_SELFTEST __user*)ulArg); + case _IOC_NR(IOCTL_CED_CHECKSELFTEST): + return CheckSelfTest(pdx, (TGET_SELFTEST __user *) ulArg); - case _IOC_NR(IOCTL_CED_TYPEOF1401): - return TypeOf1401(pdx); + case _IOC_NR(IOCTL_CED_TYPEOF1401): + return TypeOf1401(pdx); - case _IOC_NR(IOCTL_CED_TRANSFERFLAGS): - return TransferFlags(pdx); + case _IOC_NR(IOCTL_CED_TRANSFERFLAGS): + return TransferFlags(pdx); - case _IOC_NR(IOCTL_CED_DBGPEEK): - return DbgPeek(pdx, (TDBGBLOCK __user*)ulArg); + case _IOC_NR(IOCTL_CED_DBGPEEK): + return DbgPeek(pdx, (TDBGBLOCK __user *) ulArg); - case _IOC_NR(IOCTL_CED_DBGPOKE): - return DbgPoke(pdx, (TDBGBLOCK __user*)ulArg); + case _IOC_NR(IOCTL_CED_DBGPOKE): + return DbgPoke(pdx, (TDBGBLOCK __user *) ulArg); - case _IOC_NR(IOCTL_CED_DBGRAMPDATA): - return DbgRampData(pdx, (TDBGBLOCK __user*)ulArg); + case _IOC_NR(IOCTL_CED_DBGRAMPDATA): + return DbgRampData(pdx, (TDBGBLOCK __user *) ulArg); - case _IOC_NR(IOCTL_CED_DBGRAMPADDR): - return DbgRampAddr(pdx, (TDBGBLOCK __user*)ulArg); + case _IOC_NR(IOCTL_CED_DBGRAMPADDR): + return DbgRampAddr(pdx, (TDBGBLOCK __user *) ulArg); - case _IOC_NR(IOCTL_CED_DBGGETDATA): - return DbgGetData(pdx, (TDBGBLOCK __user*)ulArg); + case _IOC_NR(IOCTL_CED_DBGGETDATA): + return DbgGetData(pdx, (TDBGBLOCK __user *) ulArg); - case _IOC_NR(IOCTL_CED_DBGSTOPLOOP): - return DbgStopLoop(pdx); + case _IOC_NR(IOCTL_CED_DBGSTOPLOOP): + return DbgStopLoop(pdx); - case _IOC_NR(IOCTL_CED_FULLRESET): - pdx->bForceReset = true; // Set a flag for a full reset - break; + case _IOC_NR(IOCTL_CED_FULLRESET): + pdx->bForceReset = true; // Set a flag for a full reset + break; - case _IOC_NR(IOCTL_CED_SETCIRCULAR): - return SetCircular(pdx, (TRANSFERDESC __user*)ulArg); + case _IOC_NR(IOCTL_CED_SETCIRCULAR): + return SetCircular(pdx, (TRANSFERDESC __user *) ulArg); - case _IOC_NR(IOCTL_CED_GETCIRCBLOCK): - return GetCircBlock(pdx, (TCIRCBLOCK __user*)ulArg); + case _IOC_NR(IOCTL_CED_GETCIRCBLOCK): + return GetCircBlock(pdx, (TCIRCBLOCK __user *) ulArg); - case _IOC_NR(IOCTL_CED_FREECIRCBLOCK): - return FreeCircBlock(pdx, (TCIRCBLOCK __user*)ulArg); + case _IOC_NR(IOCTL_CED_FREECIRCBLOCK): + return FreeCircBlock(pdx, (TCIRCBLOCK __user *) ulArg); - case _IOC_NR(IOCTL_CED_WAITEVENT): - return WaitEvent(pdx, (int)(ulArg & 0xff), (int)(ulArg >> 8)); + case _IOC_NR(IOCTL_CED_WAITEVENT): + return WaitEvent(pdx, (int)(ulArg & 0xff), (int)(ulArg >> 8)); - case _IOC_NR(IOCTL_CED_TESTEVENT): - return TestEvent(pdx, (int)ulArg); + case _IOC_NR(IOCTL_CED_TESTEVENT): + return TestEvent(pdx, (int)ulArg); - default: - return U14ERR_NO_SUCH_FN; - } - return U14ERR_NOERROR; + default: + return U14ERR_NO_SUCH_FN; + } + return U14ERR_NOERROR; } -static const struct file_operations ced_fops = -{ - .owner = THIS_MODULE, - .read = ced_read, - .write = ced_write, - .open = ced_open, - .release = ced_release, - .flush = ced_flush, - .llseek = noop_llseek, +static const struct file_operations ced_fops = { + .owner = THIS_MODULE, + .read = ced_read, + .write = ced_write, + .open = ced_open, + .release = ced_release, + .flush = ced_flush, + .llseek = noop_llseek, #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36) - .unlocked_ioctl = ced_ioctl, + .unlocked_ioctl = ced_ioctl, #else - .ioctl = ced_ioctl, + .ioctl = ced_ioctl, #endif }; @@ -1346,245 +1419,250 @@ static const struct file_operations ced_fops = * usb class driver info in order to get a minor number from the usb core, * and to have the device registered with the driver core */ -static struct usb_class_driver ced_class = -{ - .name = "cedusb%d", - .fops = &ced_fops, - .minor_base = USB_CED_MINOR_BASE, +static struct usb_class_driver ced_class = { + .name = "cedusb%d", + .fops = &ced_fops, + .minor_base = USB_CED_MINOR_BASE, }; // Check that the device that matches a 1401 vendor and product ID is OK to use and // initialise our DEVICE_EXTENSION. -static int ced_probe(struct usb_interface *interface, const struct usb_device_id *id) +static int ced_probe(struct usb_interface *interface, + const struct usb_device_id *id) { - DEVICE_EXTENSION *pdx; - struct usb_host_interface *iface_desc; - struct usb_endpoint_descriptor *endpoint; - int i, bcdDevice; - int retval = -ENOMEM; - - // allocate memory for our device extension and initialize it - pdx = kzalloc(sizeof(*pdx), GFP_KERNEL); - if (!pdx) - { - dev_err(&interface->dev, "Out of memory\n"); - goto error; - } - - for (i=0; irTransDef[i].wqEvent); - } - - // Put initialises for our stuff here. Note that all of *pdx is zero, so - // no need to explicitly zero it. - spin_lock_init(&pdx->charOutLock); - spin_lock_init(&pdx->charInLock); - spin_lock_init(&pdx->stagedLock); - - // Initialises from the skeleton stuff - kref_init(&pdx->kref); - mutex_init(&pdx->io_mutex); - spin_lock_init(&pdx->err_lock); - init_usb_anchor(&pdx->submitted); - - pdx->udev = usb_get_dev(interface_to_usbdev(interface)); - pdx->interface = interface; - - // Attempt to identify the device - bcdDevice = pdx->udev->descriptor.bcdDevice; - i = (bcdDevice >> 8); - if (i == 0) - pdx->s1401Type = TYPEU1401; - else if ((i>=1) && (i<=23)) - pdx->s1401Type = i+2; - else - { - dev_err(&interface->dev, "%s Unknown device. bcdDevice = %d", __func__, bcdDevice); - goto error; - } - // set up the endpoint information. We only care about the number of EP as - // we know that we are dealing with a 1401 device. - iface_desc = interface->cur_altsetting; - pdx->nPipes = iface_desc->desc.bNumEndpoints; - dev_info(&interface->dev, "1401Type=%d with %d End Points", pdx->s1401Type, pdx->nPipes); - if ((pdx->nPipes < 3) || (pdx->nPipes > 4)) - goto error; - - // Allocate the URBs we hold for performing transfers - pdx->pUrbCharOut = usb_alloc_urb(0, GFP_KERNEL); // character output URB - pdx->pUrbCharIn = usb_alloc_urb(0, GFP_KERNEL); // character input URB - pdx->pStagedUrb = usb_alloc_urb(0, GFP_KERNEL); // block transfer URB - if (!pdx->pUrbCharOut || !pdx->pUrbCharIn || !pdx->pStagedUrb) - { - dev_err(&interface->dev, "%s URB alloc failed", __func__); - goto error; - } - - pdx->pCoherStagedIO = usb_alloc_coherent(pdx->udev, STAGED_SZ, GFP_KERNEL, &pdx->pStagedUrb->transfer_dma); - pdx->pCoherCharOut = usb_alloc_coherent(pdx->udev, OUTBUF_SZ, GFP_KERNEL, &pdx->pUrbCharOut->transfer_dma); - pdx->pCoherCharIn = usb_alloc_coherent(pdx->udev, INBUF_SZ, GFP_KERNEL, &pdx->pUrbCharIn->transfer_dma); - if (!pdx->pCoherCharOut || !pdx->pCoherCharIn || !pdx->pCoherStagedIO) - { - dev_err(&interface->dev, "%s Coherent buffer alloc failed", __func__); - goto error; - } - - for (i = 0; i < pdx->nPipes; ++i) - { - endpoint = &iface_desc->endpoint[i].desc; - pdx->epAddr[i] = endpoint->bEndpointAddress; - dev_info(&interface->dev, "Pipe %d, ep address %02x", i, pdx->epAddr[i]); - if (((pdx->nPipes==3) && (i==0)) || // if char input end point - ((pdx->nPipes==4) && (i==1))) - { - pdx->bInterval = endpoint->bInterval; // save the endpoint interrupt interval - dev_info(&interface->dev, "Pipe %d, bInterval = %d", i, pdx->bInterval); - } - - // Detect USB2 by checking last ep size (64 if USB1) - if (i == pdx->nPipes-1) // if this is the last ep (bulk) - { - pdx->bIsUSB2 = le16_to_cpu(endpoint->wMaxPacketSize) > 64; - dev_info(&pdx->interface->dev, "USB%d", pdx->bIsUSB2 + 1); - } - } - - /* save our data pointer in this interface device */ - usb_set_intfdata(interface, pdx); - - /* we can register the device now, as it is ready */ - retval = usb_register_dev(interface, &ced_class); - if (retval) - { - /* something prevented us from registering this driver */ - dev_err(&interface->dev, "Not able to get a minor for this device.\n"); - usb_set_intfdata(interface, NULL); - goto error; - } - - /* let the user know what node this device is now attached to */ - dev_info(&interface->dev, - "USB CEDUSB device now attached to cedusb #%d", - interface->minor); - return 0; + DEVICE_EXTENSION *pdx; + struct usb_host_interface *iface_desc; + struct usb_endpoint_descriptor *endpoint; + int i, bcdDevice; + int retval = -ENOMEM; + + // allocate memory for our device extension and initialize it + pdx = kzalloc(sizeof(*pdx), GFP_KERNEL); + if (!pdx) { + dev_err(&interface->dev, "Out of memory\n"); + goto error; + } + + for (i = 0; i < MAX_TRANSAREAS; ++i) // Initialise the wait queues + { + init_waitqueue_head(&pdx->rTransDef[i].wqEvent); + } + + // Put initialises for our stuff here. Note that all of *pdx is zero, so + // no need to explicitly zero it. + spin_lock_init(&pdx->charOutLock); + spin_lock_init(&pdx->charInLock); + spin_lock_init(&pdx->stagedLock); + + // Initialises from the skeleton stuff + kref_init(&pdx->kref); + mutex_init(&pdx->io_mutex); + spin_lock_init(&pdx->err_lock); + init_usb_anchor(&pdx->submitted); + + pdx->udev = usb_get_dev(interface_to_usbdev(interface)); + pdx->interface = interface; + + // Attempt to identify the device + bcdDevice = pdx->udev->descriptor.bcdDevice; + i = (bcdDevice >> 8); + if (i == 0) + pdx->s1401Type = TYPEU1401; + else if ((i >= 1) && (i <= 23)) + pdx->s1401Type = i + 2; + else { + dev_err(&interface->dev, "%s Unknown device. bcdDevice = %d", + __func__, bcdDevice); + goto error; + } + // set up the endpoint information. We only care about the number of EP as + // we know that we are dealing with a 1401 device. + iface_desc = interface->cur_altsetting; + pdx->nPipes = iface_desc->desc.bNumEndpoints; + dev_info(&interface->dev, "1401Type=%d with %d End Points", + pdx->s1401Type, pdx->nPipes); + if ((pdx->nPipes < 3) || (pdx->nPipes > 4)) + goto error; + + // Allocate the URBs we hold for performing transfers + pdx->pUrbCharOut = usb_alloc_urb(0, GFP_KERNEL); // character output URB + pdx->pUrbCharIn = usb_alloc_urb(0, GFP_KERNEL); // character input URB + pdx->pStagedUrb = usb_alloc_urb(0, GFP_KERNEL); // block transfer URB + if (!pdx->pUrbCharOut || !pdx->pUrbCharIn || !pdx->pStagedUrb) { + dev_err(&interface->dev, "%s URB alloc failed", __func__); + goto error; + } + + pdx->pCoherStagedIO = + usb_alloc_coherent(pdx->udev, STAGED_SZ, GFP_KERNEL, + &pdx->pStagedUrb->transfer_dma); + pdx->pCoherCharOut = + usb_alloc_coherent(pdx->udev, OUTBUF_SZ, GFP_KERNEL, + &pdx->pUrbCharOut->transfer_dma); + pdx->pCoherCharIn = + usb_alloc_coherent(pdx->udev, INBUF_SZ, GFP_KERNEL, + &pdx->pUrbCharIn->transfer_dma); + if (!pdx->pCoherCharOut || !pdx->pCoherCharIn || !pdx->pCoherStagedIO) { + dev_err(&interface->dev, "%s Coherent buffer alloc failed", + __func__); + goto error; + } + + for (i = 0; i < pdx->nPipes; ++i) { + endpoint = &iface_desc->endpoint[i].desc; + pdx->epAddr[i] = endpoint->bEndpointAddress; + dev_info(&interface->dev, "Pipe %d, ep address %02x", i, + pdx->epAddr[i]); + if (((pdx->nPipes == 3) && (i == 0)) || // if char input end point + ((pdx->nPipes == 4) && (i == 1))) { + pdx->bInterval = endpoint->bInterval; // save the endpoint interrupt interval + dev_info(&interface->dev, "Pipe %d, bInterval = %d", i, + pdx->bInterval); + } + // Detect USB2 by checking last ep size (64 if USB1) + if (i == pdx->nPipes - 1) // if this is the last ep (bulk) + { + pdx->bIsUSB2 = + le16_to_cpu(endpoint->wMaxPacketSize) > 64; + dev_info(&pdx->interface->dev, "USB%d", + pdx->bIsUSB2 + 1); + } + } + + /* save our data pointer in this interface device */ + usb_set_intfdata(interface, pdx); + + /* we can register the device now, as it is ready */ + retval = usb_register_dev(interface, &ced_class); + if (retval) { + /* something prevented us from registering this driver */ + dev_err(&interface->dev, + "Not able to get a minor for this device.\n"); + usb_set_intfdata(interface, NULL); + goto error; + } + + /* let the user know what node this device is now attached to */ + dev_info(&interface->dev, + "USB CEDUSB device now attached to cedusb #%d", + interface->minor); + return 0; error: - if (pdx) - kref_put(&pdx->kref, ced_delete); // frees allocated memory - return retval; + if (pdx) + kref_put(&pdx->kref, ced_delete); // frees allocated memory + return retval; } static void ced_disconnect(struct usb_interface *interface) { - DEVICE_EXTENSION *pdx = usb_get_intfdata(interface); - int minor = interface->minor; // save for message at the end - int i; - - usb_set_intfdata(interface, NULL); // remove the pdx from the interface - usb_deregister_dev(interface, &ced_class); // give back our minor device number - - mutex_lock(&pdx->io_mutex); // stop more I/O starting while... - ced_draw_down(pdx); // ...wait for then kill any io - for (i=0; iinterface->dev, "%s Area %d was in used", __func__, i); - } - pdx->interface = NULL; // ...we kill off link to interface - mutex_unlock(&pdx->io_mutex); + DEVICE_EXTENSION *pdx = usb_get_intfdata(interface); + int minor = interface->minor; // save for message at the end + int i; + + usb_set_intfdata(interface, NULL); // remove the pdx from the interface + usb_deregister_dev(interface, &ced_class); // give back our minor device number + + mutex_lock(&pdx->io_mutex); // stop more I/O starting while... + ced_draw_down(pdx); // ...wait for then kill any io + for (i = 0; i < MAX_TRANSAREAS; ++i) { + int iErr = ClearArea(pdx, i); // ...release any used memory + if (iErr == U14ERR_UNLOCKFAIL) + dev_err(&pdx->interface->dev, "%s Area %d was in used", + __func__, i); + } + pdx->interface = NULL; // ...we kill off link to interface + mutex_unlock(&pdx->io_mutex); - usb_kill_anchored_urbs(&pdx->submitted); + usb_kill_anchored_urbs(&pdx->submitted); - kref_put(&pdx->kref, ced_delete); // decrement our usage count + kref_put(&pdx->kref, ced_delete); // decrement our usage count - dev_info(&interface->dev, "USB cedusb #%d now disconnected", minor); + dev_info(&interface->dev, "USB cedusb #%d now disconnected", minor); } // Wait for all the urbs we know of to be done with, then kill off any that // are left. NBNB we will need to have a mechanism to stop circular xfers // from trying to fire off more urbs. We will wait up to 3 seconds for Urbs // to be done. -void ced_draw_down(DEVICE_EXTENSION *pdx) +void ced_draw_down(DEVICE_EXTENSION * pdx) { - int time; - dev_dbg(&pdx->interface->dev,"%s called", __func__); - - pdx->bInDrawDown = true; - time = usb_wait_anchor_empty_timeout(&pdx->submitted, 3000); - if (!time) // if we timed out we kill the urbs - { - usb_kill_anchored_urbs(&pdx->submitted); - dev_err(&pdx->interface->dev,"%s timed out", __func__); - } - pdx->bInDrawDown = false; - } + int time; + dev_dbg(&pdx->interface->dev, "%s called", __func__); + + pdx->bInDrawDown = true; + time = usb_wait_anchor_empty_timeout(&pdx->submitted, 3000); + if (!time) // if we timed out we kill the urbs + { + usb_kill_anchored_urbs(&pdx->submitted); + dev_err(&pdx->interface->dev, "%s timed out", __func__); + } + pdx->bInDrawDown = false; +} static int ced_suspend(struct usb_interface *intf, pm_message_t message) { - DEVICE_EXTENSION *pdx = usb_get_intfdata(intf); - if (!pdx) - return 0; - ced_draw_down(pdx); + DEVICE_EXTENSION *pdx = usb_get_intfdata(intf); + if (!pdx) + return 0; + ced_draw_down(pdx); - dev_dbg(&pdx->interface->dev,"%s called", __func__); - return 0; + dev_dbg(&pdx->interface->dev, "%s called", __func__); + return 0; } static int ced_resume(struct usb_interface *intf) { - DEVICE_EXTENSION *pdx = usb_get_intfdata(intf); - if (!pdx) - return 0; - dev_dbg(&pdx->interface->dev,"%s called", __func__); - return 0; + DEVICE_EXTENSION *pdx = usb_get_intfdata(intf); + if (!pdx) + return 0; + dev_dbg(&pdx->interface->dev, "%s called", __func__); + return 0; } static int ced_pre_reset(struct usb_interface *intf) { - DEVICE_EXTENSION *pdx = usb_get_intfdata(intf); - dev_dbg(&pdx->interface->dev, "%s", __func__); - mutex_lock(&pdx->io_mutex); - ced_draw_down(pdx); - return 0; + DEVICE_EXTENSION *pdx = usb_get_intfdata(intf); + dev_dbg(&pdx->interface->dev, "%s", __func__); + mutex_lock(&pdx->io_mutex); + ced_draw_down(pdx); + return 0; } static int ced_post_reset(struct usb_interface *intf) { - DEVICE_EXTENSION *pdx = usb_get_intfdata(intf); - dev_dbg(&pdx->interface->dev, "%s", __func__); + DEVICE_EXTENSION *pdx = usb_get_intfdata(intf); + dev_dbg(&pdx->interface->dev, "%s", __func__); - /* we are sure no URBs are active - no locking needed */ - pdx->errors = -EPIPE; - mutex_unlock(&pdx->io_mutex); + /* we are sure no URBs are active - no locking needed */ + pdx->errors = -EPIPE; + mutex_unlock(&pdx->io_mutex); - return 0; + return 0; } -static struct usb_driver ced_driver = -{ - .name = "cedusb", - .probe = ced_probe, - .disconnect = ced_disconnect, - .suspend = ced_suspend, - .resume = ced_resume, - .pre_reset = ced_pre_reset, - .post_reset = ced_post_reset, - .id_table = ced_table, - .supports_autosuspend = 1, +static struct usb_driver ced_driver = { + .name = "cedusb", + .probe = ced_probe, + .disconnect = ced_disconnect, + .suspend = ced_suspend, + .resume = ced_resume, + .pre_reset = ced_pre_reset, + .post_reset = ced_post_reset, + .id_table = ced_table, + .supports_autosuspend = 1, }; static int __init usb_skel_init(void) { - /* register this driver with the USB subsystem */ - return usb_register(&ced_driver); + /* register this driver with the USB subsystem */ + return usb_register(&ced_driver); } static void __exit usb_skel_exit(void) { - /* deregister this driver with the USB subsystem */ - usb_deregister(&ced_driver); + /* deregister this driver with the USB subsystem */ + usb_deregister(&ced_driver); } module_init(usb_skel_init); -- cgit v0.10.2 From 74f5671442c6e9b2b54137d20fd7789078265897 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 17 Sep 2012 21:25:28 -0700 Subject: Staging: ced1401: fix copy_from/to_user warning messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Properly check the return value of copy_from/to_user() and handle any errors that might happen. This removes a bunch of compiler warnings. Cc: Alois Schlögl Cc: Greg P. Smith Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ced1401/ced_ioc.c b/drivers/staging/ced1401/ced_ioc.c index bb29c7f..693c454 100644 --- a/drivers/staging/ced1401/ced_ioc.c +++ b/drivers/staging/ced1401/ced_ioc.c @@ -112,7 +112,7 @@ int SendString(DEVICE_EXTENSION * pdx, const char __user * pData, if (n > OUTBUF_SZ) // check space in local buffer... return U14ERR_NOOUT; // ...too many characters if (copy_from_user(buffer, pData, n)) - return -ENOMEM; // could not copy + return -EFAULT; buffer[n] = 0; // terminate for debug purposes mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o @@ -511,9 +511,10 @@ int GetString(DEVICE_EXTENSION * pdx, char __user * pUser, int n) dev_dbg(&pdx->interface->dev, "GetString read %d characters >%s<", nGot, buffer); - copy_to_user(pUser, buffer, nCopyToUser); - - iReturn = nGot; // report characters read + if (copy_to_user(pUser, buffer, nCopyToUser)) + iReturn = -EFAULT; + else + iReturn = nGot; // report characters read } else spin_unlock_irq(&pdx->charInLock); @@ -758,7 +759,10 @@ int SetTransfer(DEVICE_EXTENSION * pdx, TRANSFERDESC __user * pTD) { int iReturn; TRANSFERDESC td; - copy_from_user(&td, pTD, sizeof(td)); + + if (copy_from_user(&td, pTD, sizeof(td))) + return -EFAULT; + mutex_lock(&pdx->io_mutex); dev_dbg(&pdx->interface->dev, "%s area:%d, size:%08x", __func__, td.wAreaNum, td.dwLength); @@ -798,7 +802,11 @@ int SetEvent(DEVICE_EXTENSION * pdx, TRANSFEREVENT __user * pTE) { int iReturn = U14ERR_NOERROR; TRANSFEREVENT te; - copy_from_user(&te, pTE, sizeof(te)); // get a local copy of the data + + // get a local copy of the data + if (copy_from_user(&te, pTE, sizeof(te))) + return -EFAULT; + if (te.wAreaNum >= MAX_TRANSAREAS) // the area must exist return U14ERR_BADAREA; else { @@ -914,7 +922,9 @@ int GetTransfer(DEVICE_EXTENSION * pdx, TGET_TX_BLOCK __user * pTX) tx.entries[0].physical = (long long)(tx.linear + pdx->StagedOffset); tx.entries[0].size = tx.size; - copy_to_user(pTX, &tx, sizeof(tx)); + + if (copy_to_user(pTX, &tx, sizeof(tx))) + iReturn = -EFAULT; } mutex_unlock(&pdx->io_mutex); return iReturn; @@ -1065,7 +1075,9 @@ int CheckSelfTest(DEVICE_EXTENSION * pdx, TGET_SELFTEST __user * pGST) } mutex_unlock(&pdx->io_mutex); - copy_to_user(pGST, &gst, sizeof(gst)); // copy result to user space + if (copy_to_user(pGST, &gst, sizeof(gst))) + return -EFAULT; + return iReturn; } @@ -1147,7 +1159,9 @@ int DbgPeek(DEVICE_EXTENSION * pdx, TDBGBLOCK __user * pDB) { int iReturn; TDBGBLOCK db; - copy_from_user(&db, pDB, sizeof(db)); // get the data + + if (copy_from_user(&db, pDB, sizeof(db))) + return -EFAULT; mutex_lock(&pdx->io_mutex); dev_dbg(&pdx->interface->dev, "%s @ %08x", __func__, db.iAddr); @@ -1174,7 +1188,9 @@ int DbgPoke(DEVICE_EXTENSION * pdx, TDBGBLOCK __user * pDB) { int iReturn; TDBGBLOCK db; - copy_from_user(&db, pDB, sizeof(db)); // get the data + + if (copy_from_user(&db, pDB, sizeof(db))) + return -EFAULT; mutex_lock(&pdx->io_mutex); dev_dbg(&pdx->interface->dev, "%s @ %08x", __func__, db.iAddr); @@ -1201,7 +1217,9 @@ int DbgRampData(DEVICE_EXTENSION * pdx, TDBGBLOCK __user * pDB) { int iReturn; TDBGBLOCK db; - copy_from_user(&db, pDB, sizeof(db)); // get the data + + if (copy_from_user(&db, pDB, sizeof(db))) + return -EFAULT; mutex_lock(&pdx->io_mutex); dev_dbg(&pdx->interface->dev, "%s @ %08x", __func__, db.iAddr); @@ -1231,7 +1249,9 @@ int DbgRampAddr(DEVICE_EXTENSION * pdx, TDBGBLOCK __user * pDB) { int iReturn; TDBGBLOCK db; - copy_from_user(&db, pDB, sizeof(db)); // get the data + + if (copy_from_user(&db, pDB, sizeof(db))) + return -EFAULT; mutex_lock(&pdx->io_mutex); dev_dbg(&pdx->interface->dev, "%s", __func__); @@ -1269,8 +1289,10 @@ int DbgGetData(DEVICE_EXTENSION * pdx, TDBGBLOCK __user * pDB) DB_DATA, (D_TO_H | VENDOR | DEVREQ), 0, 0, &db.iData, sizeof(db.iData), HZ); if (iReturn == sizeof(db.iData)) { - copy_to_user(pDB, &db, sizeof(db)); - iReturn = U14ERR_NOERROR; + if (copy_to_user(pDB, &db, sizeof(db))) + iReturn = -EFAULT; + else + iReturn = U14ERR_NOERROR; } else dev_err(&pdx->interface->dev, "%s failed, code %d", __func__, iReturn); @@ -1312,7 +1334,10 @@ int SetCircular(DEVICE_EXTENSION * pdx, TRANSFERDESC __user * pTD) int iReturn; bool bToHost; TRANSFERDESC td; - copy_from_user(&td, pTD, sizeof(td)); + + if (copy_from_user(&td, pTD, sizeof(td))) + return -EFAULT; + mutex_lock(&pdx->io_mutex); dev_dbg(&pdx->interface->dev, "%s area:%d, size:%08x", __func__, td.wAreaNum, td.dwLength); @@ -1339,8 +1364,12 @@ int GetCircBlock(DEVICE_EXTENSION * pdx, TCIRCBLOCK __user * pCB) int iReturn = U14ERR_NOERROR; unsigned int nArea; TCIRCBLOCK cb; + dev_dbg(&pdx->interface->dev, "%s", __func__); - copy_from_user(&cb, pCB, sizeof(cb)); + + if (copy_from_user(&cb, pCB, sizeof(cb))) + return -EFAULT; + mutex_lock(&pdx->io_mutex); nArea = cb.nArea; // Retrieve parameters first @@ -1370,7 +1399,9 @@ int GetCircBlock(DEVICE_EXTENSION * pdx, TCIRCBLOCK __user * pCB) } else iReturn = U14ERR_BADAREA; - copy_to_user(pCB, &cb, sizeof(cb)); + if (copy_to_user(pCB, &cb, sizeof(cb))) + iReturn = -EFAULT; + mutex_unlock(&pdx->io_mutex); return iReturn; } @@ -1385,8 +1416,12 @@ int FreeCircBlock(DEVICE_EXTENSION * pdx, TCIRCBLOCK __user * pCB) int iReturn = U14ERR_NOERROR; unsigned int nArea, uStart, uSize; TCIRCBLOCK cb; + dev_dbg(&pdx->interface->dev, "%s", __func__); - copy_from_user(&cb, pCB, sizeof(cb)); + + if (copy_from_user(&cb, pCB, sizeof(cb))) + return -EFAULT; + mutex_lock(&pdx->io_mutex); nArea = cb.nArea; // Retrieve parameters first @@ -1472,7 +1507,9 @@ int FreeCircBlock(DEVICE_EXTENSION * pdx, TCIRCBLOCK __user * pCB) } else iReturn = U14ERR_BADAREA; - copy_to_user(pCB, &cb, sizeof(cb)); + if (copy_to_user(pCB, &cb, sizeof(cb))) + return -EFAULT; + mutex_unlock(&pdx->io_mutex); return iReturn; } -- cgit v0.10.2 From ba753e41803681d164eb17274b53085c7987d07c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 17 Sep 2012 23:02:36 -0700 Subject: Staging: remove CONFIG_EXPERIMENTAL dependancies As discussed at the kernel summit this year, CONFIG_EXPERIMENTAL means nothing, so let's get rid of it. Cc: Kees Cook Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/Kconfig b/drivers/staging/bcm/Kconfig index 96adb10..83c9752 100644 --- a/drivers/staging/bcm/Kconfig +++ b/drivers/staging/bcm/Kconfig @@ -1,6 +1,6 @@ config BCM_WIMAX tristate "Beceem BCS200/BCS220-3 and BCSM250 wimax support" - depends on USB && NET && EXPERIMENTAL + depends on USB && NET default N help This is an experimental driver for the Beceem WIMAX chipset used diff --git a/drivers/staging/usbip/Kconfig b/drivers/staging/usbip/Kconfig index dd13c02..199b1d4 100644 --- a/drivers/staging/usbip/Kconfig +++ b/drivers/staging/usbip/Kconfig @@ -1,6 +1,6 @@ config USBIP_CORE - tristate "USB/IP support (EXPERIMENTAL)" - depends on USB && NET && EXPERIMENTAL + tristate "USB/IP support" + depends on USB && NET default N ---help--- This enables pushing USB packets over IP to allow remote diff --git a/drivers/staging/winbond/Kconfig b/drivers/staging/winbond/Kconfig index 132671d..a29f608 100644 --- a/drivers/staging/winbond/Kconfig +++ b/drivers/staging/winbond/Kconfig @@ -1,6 +1,6 @@ config W35UND tristate "IS89C35 WLAN USB driver" - depends on MAC80211 && WLAN && USB && EXPERIMENTAL + depends on MAC80211 && WLAN && USB default n ---help--- This is highly experimental driver for Winbond WIFI card. -- cgit v0.10.2 From f45c69b1136078bb35ee0f1cb89ae92fd9bc5cd0 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 12 Sep 2012 07:07:00 +0100 Subject: HID: sensors: fix up for mfd_add_devices() API change Signed-off-by: Stephen Rothwell Signed-off-by: Jonathan Cameron diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index 34a35ba..4ac759c 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c @@ -596,7 +596,7 @@ static int sensor_hub_probe(struct hid_device *hdev, } } ret = mfd_add_devices(&hdev->dev, 0, sd->hid_sensor_hub_client_devs, - sd->hid_sensor_client_cnt, NULL, 0); + sd->hid_sensor_client_cnt, NULL, 0, NULL); if (ret < 0) goto err_free_names; -- cgit v0.10.2 From 2b7c4b8e3edfd109a8423ff593a12a5fe09615b2 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 14 Sep 2012 06:53:23 +0000 Subject: HID: sensors: use GFP_ATOMIC under spinlock We're holding a spinlock here so we can't call kmalloc() with GFP_KERNEL. Signed-off-by: Dan Carpenter Signed-off-by: Jiri Kosina Signed-off-by: Jonathan Cameron diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index 4ac759c..0c93b10 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c @@ -173,7 +173,7 @@ int sensor_hub_register_callback(struct hid_sensor_hub_device *hsdev, spin_unlock(&pdata->dyn_callback_lock); return -EINVAL; } - callback = kzalloc(sizeof(*callback), GFP_KERNEL); + callback = kzalloc(sizeof(*callback), GFP_ATOMIC); if (!callback) { spin_unlock(&pdata->dyn_callback_lock); return -ENOMEM; @@ -462,7 +462,7 @@ static int sensor_hub_raw_event(struct hid_device *hdev, if (pdata->pending.status && pdata->pending.attr_usage_id == report->field[i]->usage->hid) { hid_dbg(hdev, "data was pending ...\n"); - pdata->pending.raw_data = kmalloc(sz, GFP_KERNEL); + pdata->pending.raw_data = kmalloc(sz, GFP_ATOMIC); if (pdata->pending.raw_data) { memcpy(pdata->pending.raw_data, ptr, sz); pdata->pending.raw_size = sz; -- cgit v0.10.2 From 24db0d75d3666b2aa5950a8bec0c1898929f2945 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 14 Sep 2012 06:53:46 +0000 Subject: HID: sensors: remove some unneeded checks "report_id" is unsigned so it's never less than zero. These checks can be removed without any problem. Signed-off-by: Dan Carpenter Signed-off-by: Jiri Kosina Signed-off-by: Jonathan Cameron diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index 0c93b10..22ec3c6 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c @@ -214,9 +214,6 @@ int sensor_hub_set_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev); int ret = 0; - if (report_id < 0) - return -EINVAL; - mutex_lock(&data->mutex); report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT); if (!report || (field_index >= report->maxfield)) { @@ -241,9 +238,6 @@ int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev); int ret = 0; - if (report_id < 0) - return -EINVAL; - mutex_lock(&data->mutex); report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT); if (!report || (field_index >= report->maxfield)) { @@ -271,9 +265,6 @@ int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev, struct hid_report *report; int ret_val = 0; - if (report_id < 0) - return -EINVAL; - mutex_lock(&data->mutex); memset(&data->pending, 0, sizeof(data->pending)); init_completion(&data->pending.ready); -- cgit v0.10.2 From 7935c80c139cc2821fb4be32dd3f139ffcb3182e Mon Sep 17 00:00:00 2001 From: Daniel Cotey Date: Tue, 18 Sep 2012 04:47:58 -0700 Subject: Staging: silicom: bp_mod.c: checkpatch cleanup: fix returns Fix up all the returns to cannonical form, and an ifdef removal Signed-off-by: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/bp_mod.c b/drivers/staging/silicom/bp_mod.c index d1cf246..8ad761f 100644 --- a/drivers/staging/silicom/bp_mod.c +++ b/drivers/staging/silicom/bp_mod.c @@ -1791,14 +1791,14 @@ static bpctl_dev_t *get_status_port_fn(bpctl_dev_t *pbpctl_dev) && ((bpctl_dev_arr[idx_dev].func == 1) && (pbpctl_dev->func == 0))) { - return (&(bpctl_dev_arr[idx_dev])); + return &(bpctl_dev_arr[idx_dev]); } if ((bpctl_dev_arr[idx_dev].bus == pbpctl_dev->bus) && (bpctl_dev_arr[idx_dev].slot == pbpctl_dev->slot) && ((bpctl_dev_arr[idx_dev].func == 3) && (pbpctl_dev->func == 2))) { - return (&(bpctl_dev_arr[idx_dev])); + return &(bpctl_dev_arr[idx_dev]); } } } @@ -1821,14 +1821,14 @@ static bpctl_dev_t *get_master_port_fn(bpctl_dev_t *pbpctl_dev) && ((bpctl_dev_arr[idx_dev].func == 0) && (pbpctl_dev->func == 1))) { - return (&(bpctl_dev_arr[idx_dev])); + return &(bpctl_dev_arr[idx_dev]); } if ((bpctl_dev_arr[idx_dev].bus == pbpctl_dev->bus) && (bpctl_dev_arr[idx_dev].slot == pbpctl_dev->slot) && ((bpctl_dev_arr[idx_dev].func == 2) && (pbpctl_dev->func == 3))) { - return (&(bpctl_dev_arr[idx_dev])); + return &(bpctl_dev_arr[idx_dev]); } } } @@ -3245,7 +3245,7 @@ int wdt_exp_mode(bpctl_dev_t *pbpctl_dev, int mode) int bypass_fw_ver(bpctl_dev_t *pbpctl_dev) { if (is_bypass_fn(pbpctl_dev)) - return ((read_reg(pbpctl_dev, VER_REG_ADDR))); + return read_reg(pbpctl_dev, VER_REG_ADDR); else return BP_NOT_CAP; } @@ -3529,7 +3529,7 @@ static int bypass_status(bpctl_dev_t *pbpctl_dev) BPCTLI_CTRL_SWDPIN1) != 0 ? 1 : 0); } else { if ((bypass_status_clear(pbpctl_dev)) >= 0) - return (bypass_from_last_read(pbpctl_dev)); + return bypass_from_last_read(pbpctl_dev); } } @@ -3684,7 +3684,7 @@ int get_bp_prod_caps(bpctl_dev_t *pbpctl_dev) { if ((pbpctl_dev->bp_caps & SW_CTL_CAP) && (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER)) - return (read_reg(pbpctl_dev, PRODUCT_CAP_REG_ADDR)); + return read_reg(pbpctl_dev, PRODUCT_CAP_REG_ADDR); return BP_NOT_CAP; } @@ -3774,7 +3774,7 @@ int tap_status(bpctl_dev_t *pbpctl_dev) BPCTLI_CTRL_SWDPIN0) != 0 ? 1 : 0); else { if ((bypass_status_clear(pbpctl_dev)) >= 0) - return (bypass_from_last_read(pbpctl_dev)); + return bypass_from_last_read(pbpctl_dev); } } @@ -4366,7 +4366,7 @@ int bypass_off_init(bpctl_dev_t *pbpctl_dev) if ((ret = cmnd_on(pbpctl_dev)) < 0) return ret; if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) - return (dis_bypass_cap(pbpctl_dev)); + return dis_bypass_cap(pbpctl_dev); wdt_off(pbpctl_dev); if (pbpctl_dev->bp_caps & BP_CAP) bypass_off(pbpctl_dev); @@ -4460,7 +4460,7 @@ int bp_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) dev_kfree_skb_irq(skb); return 0; } - return (pbpctl_dev->hard_start_xmit_save(skb, dev)); + return pbpctl_dev->hard_start_xmit_save(skb, dev); } #endif @@ -4591,7 +4591,7 @@ int set_bypass_fn(bpctl_dev_t *pbpctl_dev, int bypass_mode) int get_bypass_fn(bpctl_dev_t *pbpctl_dev) { - return (bypass_status(pbpctl_dev)); + return bypass_status(pbpctl_dev); } int get_bypass_change_fn(bpctl_dev_t *pbpctl_dev) @@ -4599,7 +4599,7 @@ int get_bypass_change_fn(bpctl_dev_t *pbpctl_dev) if (!pbpctl_dev) return -1; - return (bypass_change_status(pbpctl_dev)); + return bypass_change_status(pbpctl_dev); } int set_dis_bypass_fn(bpctl_dev_t *pbpctl_dev, int dis_param) @@ -4625,7 +4625,7 @@ int get_dis_bypass_fn(bpctl_dev_t *pbpctl_dev) if (!pbpctl_dev) return -1; - return (dis_bypass_cap_status(pbpctl_dev)); + return dis_bypass_cap_status(pbpctl_dev); } int set_bypass_pwoff_fn(bpctl_dev_t *pbpctl_dev, int bypass_mode) @@ -4651,7 +4651,7 @@ int get_bypass_pwoff_fn(bpctl_dev_t *pbpctl_dev) if (!pbpctl_dev) return -1; - return (default_pwroff_status(pbpctl_dev)); + return default_pwroff_status(pbpctl_dev); } int set_bypass_pwup_fn(bpctl_dev_t *pbpctl_dev, int bypass_mode) @@ -4677,7 +4677,7 @@ int get_bypass_pwup_fn(bpctl_dev_t *pbpctl_dev) if (!pbpctl_dev) return -1; - return (default_pwron_status(pbpctl_dev)); + return default_pwron_status(pbpctl_dev); } int set_bypass_wd_fn(bpctl_dev_t *pbpctl_dev, int timeout) @@ -4714,7 +4714,7 @@ int get_wd_expire_time_fn(bpctl_dev_t *pbpctl_dev, int *time_left) if (!pbpctl_dev) return -1; - return (wdt_timer(pbpctl_dev, time_left)); + return wdt_timer(pbpctl_dev, time_left); } int reset_bypass_wd_timer_fn(bpctl_dev_t *pbpctl_dev) @@ -4722,7 +4722,7 @@ int reset_bypass_wd_timer_fn(bpctl_dev_t *pbpctl_dev) if (!pbpctl_dev) return -1; - return (wdt_timer_reload(pbpctl_dev)); + return wdt_timer_reload(pbpctl_dev); } int get_wd_set_caps_fn(bpctl_dev_t *pbpctl_dev) @@ -4773,7 +4773,7 @@ int get_std_nic_fn(bpctl_dev_t *pbpctl_dev) if (!pbpctl_dev) return -1; - return (std_nic_status(pbpctl_dev)); + return std_nic_status(pbpctl_dev); } int set_tap_fn(bpctl_dev_t *pbpctl_dev, int tap_mode) @@ -4797,7 +4797,7 @@ int get_tap_fn(bpctl_dev_t *pbpctl_dev) if (!pbpctl_dev) return -1; - return (tap_status(pbpctl_dev)); + return tap_status(pbpctl_dev); } int set_tap_pwup_fn(bpctl_dev_t *pbpctl_dev, int tap_mode) @@ -4834,7 +4834,7 @@ int get_tap_change_fn(bpctl_dev_t *pbpctl_dev) if (!pbpctl_dev) return -1; - return (tap_change_status(pbpctl_dev)); + return tap_change_status(pbpctl_dev); } int set_dis_tap_fn(bpctl_dev_t *pbpctl_dev, int dis_param) @@ -4859,7 +4859,7 @@ int get_dis_tap_fn(bpctl_dev_t *pbpctl_dev) if (!pbpctl_dev) return -1; - return (dis_tap_cap_status(pbpctl_dev)); + return dis_tap_cap_status(pbpctl_dev); } int set_disc_fn(bpctl_dev_t *pbpctl_dev, int disc_mode) @@ -4976,7 +4976,7 @@ int get_disc_port_fn(bpctl_dev_t *pbpctl_dev) if (!pbpctl_dev) return -1; - return (disc_port_status(pbpctl_dev)); + return disc_port_status(pbpctl_dev); } int set_disc_port_pwup_fn(bpctl_dev_t *pbpctl_dev, int disc_mode) @@ -5009,7 +5009,7 @@ int get_wd_exp_mode_fn(bpctl_dev_t *pbpctl_dev) if (!pbpctl_dev) return -1; - return (wdt_exp_mode_status(pbpctl_dev)); + return wdt_exp_mode_status(pbpctl_dev); } int set_wd_exp_mode_fn(bpctl_dev_t *pbpctl_dev, int param) @@ -5017,7 +5017,7 @@ int set_wd_exp_mode_fn(bpctl_dev_t *pbpctl_dev, int param) if (!pbpctl_dev) return -1; - return (wdt_exp_mode(pbpctl_dev, param)); + return wdt_exp_mode(pbpctl_dev, param); } int reset_cont_fn(bpctl_dev_t *pbpctl_dev) @@ -5028,7 +5028,7 @@ int reset_cont_fn(bpctl_dev_t *pbpctl_dev) if ((ret = cmnd_on(pbpctl_dev)) < 0) return ret; - return (reset_cont(pbpctl_dev)); + return reset_cont(pbpctl_dev); } int set_tx_fn(bpctl_dev_t *pbpctl_dev, int tx_state) @@ -5047,7 +5047,7 @@ int set_tx_fn(bpctl_dev_t *pbpctl_dev, int tx_state) (pbpctl_dev_b->bp_tpl_flag)) return BP_NOT_CAP; } - return (set_tx(pbpctl_dev, tx_state)); + return set_tx(pbpctl_dev, tx_state); } int set_bp_force_link_fn(int dev_num, int tx_state) @@ -5059,7 +5059,7 @@ int set_bp_force_link_fn(int dev_num, int tx_state) return -1; bpctl_dev_curr = &bpctl_dev_arr[dev_num]; - return (set_bp_force_link(bpctl_dev_curr, tx_state)); + return set_bp_force_link(bpctl_dev_curr, tx_state); } int set_wd_autoreset_fn(bpctl_dev_t *pbpctl_dev, int param) @@ -5067,7 +5067,7 @@ int set_wd_autoreset_fn(bpctl_dev_t *pbpctl_dev, int param) if (!pbpctl_dev) return -1; - return (set_bypass_wd_auto(pbpctl_dev, param)); + return set_bypass_wd_auto(pbpctl_dev, param); } int get_wd_autoreset_fn(bpctl_dev_t *pbpctl_dev) @@ -5075,7 +5075,7 @@ int get_wd_autoreset_fn(bpctl_dev_t *pbpctl_dev) if (!pbpctl_dev) return -1; - return (get_bypass_wd_auto(pbpctl_dev)); + return get_bypass_wd_auto(pbpctl_dev); } #ifdef BP_SELF_TEST @@ -5084,7 +5084,7 @@ int set_bp_self_test_fn(bpctl_dev_t *pbpctl_dev, int param) if (!pbpctl_dev) return -1; - return (set_bp_self_test(pbpctl_dev, param)); + return set_bp_self_test(pbpctl_dev, param); } int get_bp_self_test_fn(bpctl_dev_t *pbpctl_dev) @@ -5092,7 +5092,7 @@ int get_bp_self_test_fn(bpctl_dev_t *pbpctl_dev) if (!pbpctl_dev) return -1; - return (get_bp_self_test(pbpctl_dev)); + return get_bp_self_test(pbpctl_dev); } #endif @@ -5102,7 +5102,7 @@ int get_bypass_caps_fn(bpctl_dev_t *pbpctl_dev) if (!pbpctl_dev) return -1; - return (pbpctl_dev->bp_caps); + return pbpctl_dev->bp_caps; } @@ -5164,7 +5164,7 @@ int get_tx_fn(bpctl_dev_t *pbpctl_dev) (pbpctl_dev_b->bp_tpl_flag)) return BP_NOT_CAP; } - return (tx_status(pbpctl_dev)); + return tx_status(pbpctl_dev); } int get_bp_force_link_fn(int dev_num) @@ -5176,7 +5176,7 @@ int get_bp_force_link_fn(int dev_num) return -1; bpctl_dev_curr = &bpctl_dev_arr[dev_num]; - return (bp_force_link_status(bpctl_dev_curr)); + return bp_force_link_status(bpctl_dev_curr); } static int get_bypass_link_status(bpctl_dev_t *pbpctl_dev) @@ -5329,13 +5329,12 @@ int get_tpl_fn(bpctl_dev_t *pbpctl_dev) if (pbpctl_dev->bp_caps & TPL_CAP) { if (pbpctl_dev->bp_caps_ex & TPL2_CAP_EX) - return (tpl2_flag_status(pbpctl_dev)); + return tpl2_flag_status(pbpctl_dev); ret = pbpctl_dev->bp_tpl_flag; } return ret; } -//#ifdef PMC_FIX_FLAG int set_bp_wait_at_pwup_fn(bpctl_dev_t *pbpctl_dev, int tap_mode) { if (!pbpctl_dev) @@ -5403,7 +5402,6 @@ int get_bp_hw_reset_fn(bpctl_dev_t *pbpctl_dev) return ret; } -//#endif /*PMC_FIX_FLAG*/ int get_bypass_info_fn(bpctl_dev_t *pbpctl_dev, char *dev_name, char *add_param) @@ -7302,59 +7300,59 @@ module_exit(bypass_cleanup_module); int is_bypass_sd(int ifindex) { - return (is_bypass(get_dev_idx_p(ifindex))); + return is_bypass(get_dev_idx_p(ifindex)); } int set_bypass_sd(int ifindex, int bypass_mode) { - return (set_bypass_fn(get_dev_idx_p(ifindex), bypass_mode)); + return set_bypass_fn(get_dev_idx_p(ifindex), bypass_mode); } int get_bypass_sd(int ifindex) { - return (get_bypass_fn(get_dev_idx_p(ifindex))); + return get_bypass_fn(get_dev_idx_p(ifindex)); } int get_bypass_change_sd(int ifindex) { - return (get_bypass_change_fn(get_dev_idx_p(ifindex))); + return get_bypass_change_fn(get_dev_idx_p(ifindex)); } int set_dis_bypass_sd(int ifindex, int dis_param) { - return (set_dis_bypass_fn(get_dev_idx_p(ifindex), dis_param)); + return set_dis_bypass_fn(get_dev_idx_p(ifindex), dis_param); } int get_dis_bypass_sd(int ifindex) { - return (get_dis_bypass_fn(get_dev_idx_p(ifindex))); + return get_dis_bypass_fn(get_dev_idx_p(ifindex)); } int set_bypass_pwoff_sd(int ifindex, int bypass_mode) { - return (set_bypass_pwoff_fn(get_dev_idx_p(ifindex), bypass_mode)); + return set_bypass_pwoff_fn(get_dev_idx_p(ifindex), bypass_mode); } int get_bypass_pwoff_sd(int ifindex) { - return (get_bypass_pwoff_fn(get_dev_idx_p(ifindex))); + return get_bypass_pwoff_fn(get_dev_idx_p(ifindex)); } int set_bypass_pwup_sd(int ifindex, int bypass_mode) { - return (set_bypass_pwup_fn(get_dev_idx_p(ifindex), bypass_mode)); + return set_bypass_pwup_fn(get_dev_idx_p(ifindex), bypass_mode); } int get_bypass_pwup_sd(int ifindex) { - return (get_bypass_pwup_fn(get_dev_idx_p(ifindex))); + return get_bypass_pwup_fn(get_dev_idx_p(ifindex)); } @@ -7368,173 +7366,173 @@ int set_bypass_wd_sd(int if_index, int ms_timeout, int *ms_timeout_set) int get_bypass_wd_sd(int ifindex, int *timeout) { - return (get_bypass_wd_fn(get_dev_idx_p(ifindex), timeout)); + return get_bypass_wd_fn(get_dev_idx_p(ifindex), timeout); } int get_wd_expire_time_sd(int ifindex, int *time_left) { - return (get_wd_expire_time_fn(get_dev_idx_p(ifindex), time_left)); + return get_wd_expire_time_fn(get_dev_idx_p(ifindex), time_left); } int reset_bypass_wd_timer_sd(int ifindex) { - return (reset_bypass_wd_timer_fn(get_dev_idx_p(ifindex))); + return reset_bypass_wd_timer_fn(get_dev_idx_p(ifindex)); } int get_wd_set_caps_sd(int ifindex) { - return (get_wd_set_caps_fn(get_dev_idx_p(ifindex))); + return get_wd_set_caps_fn(get_dev_idx_p(ifindex)); } int set_std_nic_sd(int ifindex, int nic_mode) { - return (set_std_nic_fn(get_dev_idx_p(ifindex), nic_mode)); + return set_std_nic_fn(get_dev_idx_p(ifindex), nic_mode); } int get_std_nic_sd(int ifindex) { - return (get_std_nic_fn(get_dev_idx_p(ifindex))); + return get_std_nic_fn(get_dev_idx_p(ifindex)); } int set_tap_sd(int ifindex, int tap_mode) { - return (set_tap_fn(get_dev_idx_p(ifindex), tap_mode)); + return set_tap_fn(get_dev_idx_p(ifindex), tap_mode); } int get_tap_sd(int ifindex) { - return (get_tap_fn(get_dev_idx_p(ifindex))); + return get_tap_fn(get_dev_idx_p(ifindex)); } int set_tap_pwup_sd(int ifindex, int tap_mode) { - return (set_tap_pwup_fn(get_dev_idx_p(ifindex), tap_mode)); + return set_tap_pwup_fn(get_dev_idx_p(ifindex), tap_mode); } int get_tap_pwup_sd(int ifindex) { - return (get_tap_pwup_fn(get_dev_idx_p(ifindex))); + return get_tap_pwup_fn(get_dev_idx_p(ifindex)); } int get_tap_change_sd(int ifindex) { - return (get_tap_change_fn(get_dev_idx_p(ifindex))); + return get_tap_change_fn(get_dev_idx_p(ifindex)); } int set_dis_tap_sd(int ifindex, int dis_param) { - return (set_dis_tap_fn(get_dev_idx_p(ifindex), dis_param)); + return set_dis_tap_fn(get_dev_idx_p(ifindex), dis_param); } int get_dis_tap_sd(int ifindex) { - return (get_dis_tap_fn(get_dev_idx_p(ifindex))); + return get_dis_tap_fn(get_dev_idx_p(ifindex)); } int set_bp_disc_sd(int ifindex, int disc_mode) { - return (set_disc_fn(get_dev_idx_p(ifindex), disc_mode)); + return set_disc_fn(get_dev_idx_p(ifindex), disc_mode); } int get_bp_disc_sd(int ifindex) { - return (get_disc_fn(get_dev_idx_p(ifindex))); + return get_disc_fn(get_dev_idx_p(ifindex)); } int set_bp_disc_pwup_sd(int ifindex, int disc_mode) { - return (set_disc_pwup_fn(get_dev_idx_p(ifindex), disc_mode)); + return set_disc_pwup_fn(get_dev_idx_p(ifindex), disc_mode); } int get_bp_disc_pwup_sd(int ifindex) { - return (get_disc_pwup_fn(get_dev_idx_p(ifindex))); + return get_disc_pwup_fn(get_dev_idx_p(ifindex)); } int get_bp_disc_change_sd(int ifindex) { - return (get_disc_change_fn(get_dev_idx_p(ifindex))); + return get_disc_change_fn(get_dev_idx_p(ifindex)); } int set_bp_dis_disc_sd(int ifindex, int dis_param) { - return (set_dis_disc_fn(get_dev_idx_p(ifindex), dis_param)); + return set_dis_disc_fn(get_dev_idx_p(ifindex), dis_param); } int get_bp_dis_disc_sd(int ifindex) { - return (get_dis_disc_fn(get_dev_idx_p(ifindex))); + return get_dis_disc_fn(get_dev_idx_p(ifindex)); } int get_wd_exp_mode_sd(int ifindex) { - return (get_wd_exp_mode_fn(get_dev_idx_p(ifindex))); + return get_wd_exp_mode_fn(get_dev_idx_p(ifindex)); } int set_wd_exp_mode_sd(int ifindex, int param) { - return (set_wd_exp_mode_fn(get_dev_idx_p(ifindex), param)); + return set_wd_exp_mode_fn(get_dev_idx_p(ifindex), param); } int reset_cont_sd(int ifindex) { - return (reset_cont_fn(get_dev_idx_p(ifindex))); + return reset_cont_fn(get_dev_idx_p(ifindex)); } int set_tx_sd(int ifindex, int tx_state) { - return (set_tx_fn(get_dev_idx_p(ifindex), tx_state)); + return set_tx_fn(get_dev_idx_p(ifindex), tx_state); } int set_tpl_sd(int ifindex, int tpl_state) { - return (set_tpl_fn(get_dev_idx_p(ifindex), tpl_state)); + return set_tpl_fn(get_dev_idx_p(ifindex), tpl_state); } int set_bp_hw_reset_sd(int ifindex, int status) { - return (set_bp_hw_reset_fn(get_dev_idx_p(ifindex), status)); + return set_bp_hw_reset_fn(get_dev_idx_p(ifindex), status); } int set_wd_autoreset_sd(int ifindex, int param) { - return (set_wd_autoreset_fn(get_dev_idx_p(ifindex), param)); + return set_wd_autoreset_fn(get_dev_idx_p(ifindex), param); } int get_wd_autoreset_sd(int ifindex) { - return (get_wd_autoreset_fn(get_dev_idx_p(ifindex))); + return get_wd_autoreset_fn(get_dev_idx_p(ifindex)); } int get_bypass_caps_sd(int ifindex) { - return (get_bypass_caps_fn(get_dev_idx_p(ifindex))); + return get_bypass_caps_fn(get_dev_idx_p(ifindex)); } int get_bypass_slave_sd(int ifindex) @@ -7542,33 +7540,32 @@ int get_bypass_slave_sd(int ifindex) bpctl_dev_t *pbpctl_dev_out; int ret = get_bypass_slave_fn(get_dev_idx_p(ifindex), &pbpctl_dev_out); if (ret == 1) - return (pbpctl_dev_out->ifindex); + return pbpctl_dev_out->ifindex; return -1; } int get_tx_sd(int ifindex) { - return (get_tx_fn(get_dev_idx_p(ifindex))); + return get_tx_fn(get_dev_idx_p(ifindex)); } int get_tpl_sd(int ifindex) { - return (get_tpl_fn(get_dev_idx_p(ifindex))); + return get_tpl_fn(get_dev_idx_p(ifindex)); } int get_bp_hw_reset_sd(int ifindex) { - return (get_bp_hw_reset_fn(get_dev_idx_p(ifindex))); + return get_bp_hw_reset_fn(get_dev_idx_p(ifindex)); } int get_bypass_info_sd(int ifindex, struct bp_info *bp_info) { - return (get_bypass_info_fn - (get_dev_idx_p(ifindex), bp_info->prod_name, &bp_info->fw_ver)); + return get_bypass_info_fn(get_dev_idx_p(ifindex), bp_info->prod_name, &bp_info->fw_ver); } int bp_if_scan_sd(void) @@ -7691,11 +7688,11 @@ static struct proc_dir_entry *proc_getdir(char *name, #endif if (pde == (struct proc_dir_entry *)0) { - return (pde); + return pde; } } - return (pde); + return pde; } int bp_proc_create(void) -- cgit v0.10.2 From 687bcca02ceea90ef7f90615fe8aafd799036cde Mon Sep 17 00:00:00 2001 From: Daniel Cotey Date: Tue, 18 Sep 2012 04:47:59 -0700 Subject: Staging: silicom: bp_mod.c: checkpatch cleanups: C99 comments remove code or change to traditional comments Signed-off-by: Daniel Cotey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/bp_mod.c b/drivers/staging/silicom/bp_mod.c index 8ad761f..3cfd051 100644 --- a/drivers/staging/silicom/bp_mod.c +++ b/drivers/staging/silicom/bp_mod.c @@ -127,16 +127,12 @@ typedef struct _bpctl_dev { int bp_10g9; int bp_i80; int bp_540; - -// selftest stanza int (*hard_start_xmit_save) (struct sk_buff *skb, struct net_device *dev); const struct net_device_ops *old_ops; struct net_device_ops new_ops; int bp_self_test_flag; char *bp_tx_data; -// end selftest stanza -// struct bypass_pfs_sd bypass_pfs_set; } bpctl_dev_t; @@ -168,14 +164,13 @@ static int bp_device_event(struct notifier_block *unused, struct net_device *dev = ptr; static bpctl_dev_t *pbpctl_dev = NULL, *pbpctl_dev_m = NULL; int dev_num = 0, ret = 0, ret_d = 0, time_left = 0; - //printk("BP_PROC_SUPPORT event =%d %s %d\n", event,dev->name, dev->ifindex ); - //return NOTIFY_DONE; + /* printk("BP_PROC_SUPPORT event =%d %s %d\n", event,dev->name, dev->ifindex ); */ + /* return NOTIFY_DONE; */ if (!dev) return NOTIFY_DONE; if (event == NETDEV_REGISTER) { { struct ethtool_drvinfo drvinfo; - // char *str=NULL; char cbuf[32]; char *buf = NULL; char res[10]; @@ -198,13 +193,6 @@ static int bp_device_event(struct notifier_block *unused, memcpy(&cbuf, drvinfo.bus_info, 32); buf = &cbuf[0]; - // while(*buf++){ - - /*if(*buf==':'){ - buf++; - break; - } */ - //} while (*buf++ != ':') ; for (i = 0; i < 10; i++, buf++) { if (*buf == ':') @@ -245,7 +233,6 @@ static int bp_device_event(struct notifier_block *unused, } if (event == NETDEV_UNREGISTER) { int idx_dev = 0; - //if_scan(); for (idx_dev = 0; ((bpctl_dev_arr[idx_dev].pdev != NULL) && (idx_dev < device_num)); idx_dev++) { @@ -263,7 +250,6 @@ static int bp_device_event(struct notifier_block *unused, } if (event == NETDEV_CHANGENAME) { int idx_dev = 0; - //if_scan(); for (idx_dev = 0; ((bpctl_dev_arr[idx_dev].pdev != NULL) && (idx_dev < device_num)); idx_dev++) { @@ -281,7 +267,6 @@ static int bp_device_event(struct notifier_block *unused, return NOTIFY_DONE; } - //return NOTIFY_DONE; switch (event) { @@ -289,7 +274,6 @@ static int bp_device_event(struct notifier_block *unused, if (netif_carrier_ok(dev)) return NOTIFY_DONE; - //if_scan(); if (((dev_num = get_dev_idx(dev->ifindex)) == -1) || (!(pbpctl_dev = &bpctl_dev_arr[dev_num]))) return NOTIFY_DONE; @@ -441,12 +425,10 @@ static void write_pulse(bpctl_dev_t *pbpctl_dev, BPCTLI_CTRL_EXT_MCLK_DATA)); else { -/* To start management : MCLK 1, MDIO 1, output*/ - //writel((0x2|0x8), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ; + /* To start management : MCLK 1, MDIO 1, output*/ BP10G_WRITE_REG(pbpctl_dev, EODSDP, (ctrl_ext | BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT)); - //BP10G_WRITE_REG(pbpctl_dev, ESDP, (ctrl | BP10G_MDIO_DATA | BP10G_MDIO_DIR)); } @@ -513,12 +495,10 @@ static void write_pulse(bpctl_dev_t *pbpctl_dev, (BPCTLI_CTRL_EXT_MCLK_DATA))); else { - //writel((0x2), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ; BP10G_WRITE_REG(pbpctl_dev, EODSDP, ((ctrl_ext | BP10G_MDIO_DATA_OUT) & ~(BP10G_MCLK_DATA_OUT))); - // BP10G_WRITE_REG(pbpctl_dev, ESDP, (ctrl |BP10G_MDIO_DIR|BP10G_MDIO_DATA)); } usec_delay(PULSE_TIME); @@ -584,12 +564,10 @@ static void write_pulse(bpctl_dev_t *pbpctl_dev, (BPCTLI_CTRL_EXT_MDIO_DATA))); else { - // writel((0x8), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ; BP10G_WRITE_REG(pbpctl_dev, EODSDP, ((ctrl_ext | BP10G_MCLK_DATA_OUT) & ~BP10G_MDIO_DATA_OUT)); - // BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA)); } usec_delay(PULSE_TIME); @@ -652,12 +630,10 @@ static void write_pulse(bpctl_dev_t *pbpctl_dev, BPCTLI_CTRL_EXT_MDIO_DATA))); else { - //writel((0x0), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ; BP10G_WRITE_REG(pbpctl_dev, EODSDP, (ctrl_ext & ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT))); - //BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA)); } usec_delay(PULSE_TIME); @@ -684,7 +660,6 @@ static int read_pulse(bpctl_dev_t *pbpctl_dev, unsigned int ctrl_ext, ctrl = BP10G_READ_REG(pbpctl_dev_c, ESDP); } - //ctrl_ext=BP10G_READ_REG(pbpctl_dev,EODSDP); while (i--) { if (pbpctl_dev->bp_10g9) { @@ -735,10 +710,8 @@ static int read_pulse(bpctl_dev_t *pbpctl_dev, unsigned int ctrl_ext, BPCTLI_CTRL_EXT_MCLK_DATA))); else { - // writel(( 0/*0x1*/), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ; BP10G_WRITE_REG(pbpctl_dev, EODSDP, ((ctrl_ext | BP10G_MDIO_DATA_OUT) & ~BP10G_MCLK_DATA_OUT)); /* ? */ - // printk("0x28=0x%x\n",BP10G_READ_REG(pbpctl_dev,EODSDP);); - //BP10G_WRITE_REG(pbpctl_dev, ESDP, (ctrl &~BP10G_MDIO_DIR)); + /* printk("0x28=0x%x\n",BP10G_READ_REG(pbpctl_dev,EODSDP);); */ } @@ -791,11 +764,9 @@ static int read_pulse(bpctl_dev_t *pbpctl_dev, unsigned int ctrl_ext, (BPCTLI_CTRL_EXT_MDIO_DIR))); else { - // writel((0x8 /*|0x1*/ ), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ; BP10G_WRITE_REG(pbpctl_dev, EODSDP, (ctrl_ext | BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT)); - //BP10G_WRITE_REG(pbpctl_dev, ESDP, (ctrl &~BP10G_MDIO_DIR)); } if (pbpctl_dev->bp_10g9) { @@ -812,7 +783,6 @@ static int read_pulse(bpctl_dev_t *pbpctl_dev, unsigned int ctrl_ext, ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); else ctrl_ext = BP10G_READ_REG(pbpctl_dev, EODSDP); - //ctrl_ext =readl((void *)((pbpctl_dev)->mem_map) + 0x28); usec_delay(PULSE_TIME); if (pbpctl_dev->bp_10g9) { @@ -934,8 +904,6 @@ static void write_reg(bpctl_dev_t *pbpctl_dev, unsigned char value, BP10G_WRITE_REG(pbpctl_dev, EODSDP, (ctrl_ext & ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT))); - //BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA)); - //writel((0x0), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ; } usec_delay(CMND_INTERVAL); @@ -1001,9 +969,7 @@ static void write_reg(bpctl_dev_t *pbpctl_dev, unsigned char value, BP10G_WRITE_REG(pbpctl_dev, EODSDP, (ctrl_ext & ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT))); - // BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA)); - // writel((0x0), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ; } usec_delay(CMND_INTERVAL * 4); @@ -1109,7 +1075,7 @@ static int read_reg(bpctl_dev_t *pbpctl_dev, unsigned char addr) ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO); - //printk("2reg=%x\n", ctrl_ext); + printk("2reg=%x\n", ctrl_ext); #ifdef BP_SYNC_FLAG spin_unlock_irqrestore(&pbpctl_dev->bypass_wr_lock, flags); @@ -1136,13 +1102,11 @@ static int read_reg(bpctl_dev_t *pbpctl_dev, unsigned char addr) BPCTLI_CTRL_EXT_MCLK_DATA))); } else { - // writel((0x0), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ; ctrl = BP10G_READ_REG(pbpctl_dev, ESDP); ctrl_ext = BP10G_READ_REG(pbpctl_dev, EODSDP); BP10G_WRITE_REG(pbpctl_dev, EODSDP, (ctrl_ext & ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT))); - //BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA)); } @@ -1209,12 +1173,10 @@ static int read_reg(bpctl_dev_t *pbpctl_dev, unsigned char addr) BPCTLI_CTRL_EXT_MDIO_DATA))); else { - // writel((0x8), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ; BP10G_WRITE_REG(pbpctl_dev, EODSDP, (ctrl_ext | BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT)); - // BP10G_WRITE_REG(pbpctl_dev, ESDP, (ctrl &~(BP10G_MDIO_DATA|BP10G_MDIO_DIR))); } usec_delay(PULSE_TIME); @@ -1278,13 +1240,11 @@ static int read_reg(bpctl_dev_t *pbpctl_dev, unsigned char addr) BPCTLI_CTRL_EXT_MCLK_DATA))); } else { - //writel((0x0), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ; ctrl = BP10G_READ_REG(pbpctl_dev, ESDP); ctrl_ext = BP10G_READ_REG(pbpctl_dev, EODSDP); BP10G_WRITE_REG(pbpctl_dev, EODSDP, (ctrl_ext & ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT))); - //BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA)); } @@ -1377,13 +1337,11 @@ static int wdt_pulse(bpctl_dev_t *pbpctl_dev) BPCTLI_CTRL_EXT_MCLK_DATA))); } else { - // writel((0x0), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ; ctrl = BP10G_READ_REG(pbpctl_dev, ESDP); ctrl_ext = BP10G_READ_REG(pbpctl_dev, EODSDP); BP10G_WRITE_REG(pbpctl_dev, EODSDP, (ctrl_ext & ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT))); - //BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA)); } if (pbpctl_dev->bp_10g9) { @@ -1441,11 +1399,9 @@ static int wdt_pulse(bpctl_dev_t *pbpctl_dev) (BPCTLI_CTRL_EXT_MDIO_DATA))); else { - //writel((0x8), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ; BP10G_WRITE_REG(pbpctl_dev, EODSDP, ((ctrl_ext | BP10G_MCLK_DATA_OUT) & ~BP10G_MDIO_DATA_OUT)); - //BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA)); } @@ -1503,11 +1459,9 @@ static int wdt_pulse(bpctl_dev_t *pbpctl_dev) BPCTLI_CTRL_EXT_MDIO_DATA))); else { - //writel((0x0), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ; BP10G_WRITE_REG(pbpctl_dev, EODSDP, (ctrl_ext & ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT))); - //BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA)); } if ((pbpctl_dev->wdt_status == WDT_STATUS_EN) /*&& (pbpctl_dev->bp_ext_verbp_10g) ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL); else - //ctrl =readl((void *)((pbpctl_dev)->mem_map) + 0x20); ctrl = BP10G_READ_REG(pbpctl_dev, ESDP); if (!tx_state) @@ -2587,7 +2540,6 @@ static int set_tx(bpctl_dev_t *pbpctl_dev, int tx_state) BPCTLI_CTRL_SWDPIN0)); else - //writel((ctrl|(0x1|0x100)), (void *)(((pbpctl_dev)->mem_map) + 0x20)) ; BP10G_WRITE_REG(pbpctl_dev, ESDP, (ctrl | BP10G_SDP0_DATA | BP10G_SDP0_DIR)); @@ -2645,7 +2597,6 @@ static int set_tx(bpctl_dev_t *pbpctl_dev, int tx_state) BPCTLI_CTRL_SDP0_DIR))); } } else - //writel(((ctrl|0x100)&~0x1), (void *)(((pbpctl_dev)->mem_map) + 0x20)) ; BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl | BP10G_SDP0_DIR) & ~BP10G_SDP0_DATA)); @@ -3018,7 +2969,7 @@ int std_nic_off(bpctl_dev_t *pbpctl_dev) int wdt_time_left(bpctl_dev_t *pbpctl_dev) { - //unsigned long curr_time=((long long)(jiffies*1000))/HZ, delta_time=0,wdt_on_time=((long long)(pbpctl_dev->bypass_wdt_on_time*1000))/HZ; + /* unsigned long curr_time=((long long)(jiffies*1000))/HZ, delta_time=0,wdt_on_time=((long long)(pbpctl_dev->bypass_wdt_on_time*1000))/HZ; */ unsigned long curr_time = jiffies, delta_time = 0, wdt_on_time = pbpctl_dev->bypass_wdt_on_time, delta_time_msec = 0; int time_left = 0; @@ -3078,8 +3029,8 @@ static int wdt_timer_reload(bpctl_dev_t *pbpctl_dev) ret = wdt_pulse_int(pbpctl_dev); else ret = send_wdt_pulse(pbpctl_dev); - //if (ret==-1) - // mod_timer(&pbpctl_dev->bp_timer, jiffies+1); + /* if (ret==-1) + mod_timer(&pbpctl_dev->bp_timer, jiffies+1);*/ return 1; } return BP_NOT_CAP; @@ -3125,7 +3076,6 @@ static void wd_reset_timer(unsigned long param) } } -//#ifdef PMC_FIX_FLAG /*WAIT_AT_PWRUP 0x80 */ int bp_wait_at_pwup_en(bpctl_dev_t *pbpctl_dev) { @@ -3189,7 +3139,6 @@ int bp_hw_reset_dis(bpctl_dev_t *pbpctl_dev) return BP_NOT_CAP; } -//#endif /*PMC_FIX_FLAG*/ int wdt_exp_mode(bpctl_dev_t *pbpctl_dev, int mode) { @@ -3474,12 +3423,10 @@ static int bypass_status(bpctl_dev_t *pbpctl_dev) } if (pbpctl_dev->bp_ext_ver >= 0x8) { - //BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, (BPCTL_READ_REG(pbpctl_dev_b, CTRL_EXT))&~BPCTLI_CTRL_EXT_SDP7_DIR); if (pbpctl_dev->bp_10g9) { ctrl_ext = BP10G_READ_REG(pbpctl_dev_b, I2CCTL); BP10G_WRITE_REG(pbpctl_dev_b, I2CCTL, (ctrl_ext | BP10G_I2C_CLK_OUT)); - //return(((readl((void *)((pbpctl_dev)->mem_map) + 0x28))&0x4)!=0?0:1); return ((BP10G_READ_REG(pbpctl_dev_b, I2CCTL) & BP10G_I2C_CLK_IN) != 0 ? 0 : 1); @@ -3518,7 +3465,6 @@ static int bypass_status(bpctl_dev_t *pbpctl_dev) BP10G_WRITE_REG(pbpctl_dev_b, EODSDP, (ctrl_ext | BP10G_SDP7_DATA_OUT)); - //return(((readl((void *)((pbpctl_dev)->mem_map) + 0x28))&0x4)!=0?0:1); return ((BP10G_READ_REG(pbpctl_dev_b, EODSDP) & BP10G_SDP7_DATA_IN) != 0 ? 0 : 1); } @@ -3764,7 +3710,6 @@ int tap_status(bpctl_dev_t *pbpctl_dev) BP10G_WRITE_REG(pbpctl_dev_b, EODSDP, (ctrl_ext | BP10G_SDP6_DATA_OUT)); - // return(((readl((void *)((pbpctl_dev)->mem_map) + 0x28))&0x1)!=0?0:1); return ((BP10G_READ_REG(pbpctl_dev_b, EODSDP) & BP10G_SDP6_DATA_IN) != 0 ? 0 : 1); } @@ -3853,19 +3798,16 @@ int disc_off_status(bpctl_dev_t *pbpctl_dev) DISC_OFF_MASK) == DISC_OFF_MASK) ? 1 : 0); if (pbpctl_dev->bp_i80) { - // return((((read_reg(pbpctl_dev,STATUS_DISC_REG_ADDR)) & DISC_OFF_MASK)==DISC_OFF_MASK)?1:0); return (((BPCTL_READ_REG(pbpctl_dev_b, CTRL_EXT)) & BPCTLI_CTRL_EXT_SDP6_DATA) != 0 ? 1 : 0); } if (pbpctl_dev->bp_540) { ctrl_ext = BP10G_READ_REG(pbpctl_dev_b, ESDP); - //return(((readl((void *)((pbpctl_dev)->mem_map) + 0x28))&0x4)!=0?0:1); return ((BP10G_READ_REG(pbpctl_dev_b, ESDP) & BP10G_SDP2_DATA) != 0 ? 1 : 0); } - //if (pbpctl_dev->device==SILICOM_PXG2TBI_SSID) { if (pbpctl_dev->media_type == bp_copper) { #if 0 @@ -3876,7 +3818,6 @@ int disc_off_status(bpctl_dev_t *pbpctl_dev) return (((BPCTL_READ_REG(pbpctl_dev_b, CTRL)) & BPCTLI_CTRL_SWDPIN1) != 0 ? 1 : 0); else - // return(((readl((void *)((pbpctl_dev)->mem_map) + 0x20)) & 0x2)!=0?1:0); return ((BP10G_READ_REG(pbpctl_dev_b, ESDP) & BP10G_SDP1_DATA) != 0 ? 1 : 0); @@ -3887,7 +3828,6 @@ int disc_off_status(bpctl_dev_t *pbpctl_dev) BP10G_WRITE_REG(pbpctl_dev_b, I2CCTL, (ctrl_ext | BP10G_I2C_DATA_OUT)); - //return(((readl((void *)((pbpctl_dev)->mem_map) + 0x28))&0x4)!=0?0:1); return ((BP10G_READ_REG(pbpctl_dev_b, I2CCTL) & BP10G_I2C_DATA_IN) != 0 ? 1 : 0); @@ -3919,8 +3859,6 @@ int disc_off_status(bpctl_dev_t *pbpctl_dev) BP10G_WRITE_REG(pbpctl_dev_b, EODSDP, (ctrl_ext | BP10G_SDP6_DATA_OUT)); - // temp= (((BP10G_READ_REG(pbpctl_dev_b,EODSDP))&BP10G_SDP6_DATA_IN)!=0?1:0); - //return(((readl((void *)((pbpctl_dev)->mem_map) + 0x28)) & 0x1)!=0?1:0); return (((BP10G_READ_REG(pbpctl_dev_b, EODSDP)) & BP10G_SDP6_DATA_IN) != 0 ? 1 : 0); } @@ -4004,10 +3942,10 @@ int default_pwron_disc_port_status(bpctl_dev_t *pbpctl_dev) if (pbpctl_dev_m->bp_caps_ex & DISC_PORT_CAP_EX) { if (is_bypass_fn(pbpctl_dev) == 1) return ret; - // return((((read_reg(pbpctl_dev,STATUS_TAP_REG_ADDR)) & TX_DISA_MASK)==TX_DISA_MASK)?1:0); + /* return((((read_reg(pbpctl_dev,STATUS_TAP_REG_ADDR)) & TX_DISA_MASK)==TX_DISA_MASK)?1:0); */ else return ret; - // return((((read_reg(pbpctl_dev,STATUS_TAP_REG_ADDR)) & TX_DISA_MASK)==TX_DISA_MASK)?1:0); + /* return((((read_reg(pbpctl_dev,STATUS_TAP_REG_ADDR)) & TX_DISA_MASK)==TX_DISA_MASK)?1:0); */ } return ret; @@ -4060,7 +3998,6 @@ int tpl_hw_status(bpctl_dev_t *pbpctl_dev) return BP_NOT_CAP; } -//#ifdef PMC_FIX_FLAG int bp_wait_at_pwup_status(bpctl_dev_t *pbpctl_dev) { @@ -4086,7 +4023,6 @@ int bp_hw_reset_status(bpctl_dev_t *pbpctl_dev) return BP_NOT_CAP; } -//#endif /*PMC_FIX_FLAG*/ int std_nic_status(bpctl_dev_t *pbpctl_dev) { @@ -4182,17 +4118,13 @@ void bypass_caps_init(bpctl_dev_t *pbpctl_dev) else pbpctl_dev->media_type = bp_fiber; - } - //if (!pbpctl_dev->bp_10g) - // pbpctl_dev->media_type=((BPCTL_READ_REG(pbpctl_dev, STATUS))&BPCTLI_STATUS_TBIMODE)?bp_fiber:bp_copper; - else { + } else { if (BP10G_CX4_SERIES(pbpctl_dev->subdevice)) pbpctl_dev->media_type = bp_cx4; else pbpctl_dev->media_type = bp_fiber; } - //pbpctl_dev->bp_fw_ver=0xa8; if (is_bypass_fn(pbpctl_dev)) { pbpctl_dev->bp_caps |= BP_PWOFF_ON_CAP; @@ -5341,7 +5273,7 @@ int set_bp_wait_at_pwup_fn(bpctl_dev_t *pbpctl_dev, int tap_mode) return -1; if (pbpctl_dev->bp_caps & SW_CTL_CAP) { - //bp_lock(pbp_device_block); + /* bp_lock(pbp_device_block); */ cmnd_on(pbpctl_dev); if (!tap_mode) bp_wait_at_pwup_dis(pbpctl_dev); @@ -5349,7 +5281,7 @@ int set_bp_wait_at_pwup_fn(bpctl_dev_t *pbpctl_dev, int tap_mode) bp_wait_at_pwup_en(pbpctl_dev); cmnd_off(pbpctl_dev); - // bp_unlock(pbp_device_block); + /* bp_unlock(pbp_device_block); */ return BP_OK; } return BP_NOT_CAP; @@ -5361,9 +5293,9 @@ int get_bp_wait_at_pwup_fn(bpctl_dev_t *pbpctl_dev) if (!pbpctl_dev) return -1; - // bp_lock(pbp_device_block); + /* bp_lock(pbp_device_block); */ ret = bp_wait_at_pwup_status(pbpctl_dev); - // bp_unlock(pbp_device_block); + /* bp_unlock(pbp_device_block); */ return ret; } @@ -5374,7 +5306,7 @@ int set_bp_hw_reset_fn(bpctl_dev_t *pbpctl_dev, int tap_mode) return -1; if (pbpctl_dev->bp_caps & SW_CTL_CAP) { - // bp_lock(pbp_device_block); + /* bp_lock(pbp_device_block); */ cmnd_on(pbpctl_dev); if (!tap_mode) @@ -5382,7 +5314,7 @@ int set_bp_hw_reset_fn(bpctl_dev_t *pbpctl_dev, int tap_mode) else bp_hw_reset_en(pbpctl_dev); cmnd_off(pbpctl_dev); - // bp_unlock(pbp_device_block); + /* bp_unlock(pbp_device_block); */ return BP_OK; } return BP_NOT_CAP; @@ -5394,10 +5326,10 @@ int get_bp_hw_reset_fn(bpctl_dev_t *pbpctl_dev) if (!pbpctl_dev) return -1; - //bp_lock(pbp_device_block); + /* bp_lock(pbp_device_block); */ ret = bp_hw_reset_status(pbpctl_dev); - //bp_unlock(pbp_device_block); + /* bp_unlock(pbp_device_block); */ return ret; } @@ -5418,7 +5350,6 @@ int get_bypass_info_fn(bpctl_dev_t *pbpctl_dev, char *dev_name, int get_dev_idx_bsf(int bus, int slot, int func) { int idx_dev = 0; - //if_scan(); for (idx_dev = 0; ((bpctl_dev_arr[idx_dev].pdev != NULL) && (idx_dev < device_num)); idx_dev++) { @@ -5494,9 +5425,9 @@ static void if_scan_init(void) int idx_dev = 0; struct net_device *dev; int ifindex; - //rcu_read_lock(); - //rtnl_lock(); - //rcu_read_lock(); + /* rcu_read_lock(); */ + /* rtnl_lock(); */ + /* rcu_read_lock(); */ #if 1 #if (LINUX_VERSION_CODE >= 0x020618) for_each_netdev(&init_net, dev) @@ -5508,7 +5439,6 @@ static void if_scan_init(void) { struct ethtool_drvinfo drvinfo; - // char *str=NULL; char cbuf[32]; char *buf = NULL; char res[10]; @@ -5531,13 +5461,6 @@ static void if_scan_init(void) memcpy(&cbuf, drvinfo.bus_info, 32); buf = &cbuf[0]; - // while(*buf++){ - - /*if(*buf==':'){ - buf++; - break; - } */ - //} while (*buf++ != ':') ; for (i = 0; i < 10; i++, buf++) { if (*buf == ':') @@ -5569,8 +5492,8 @@ static void if_scan_init(void) } #endif - //rtnl_unlock(); - //rcu_read_unlock(); + /* rtnl_unlock(); */ + /* rcu_read_unlock(); */ } @@ -5595,17 +5518,17 @@ static long device_ioctl(struct file *file, /* ditto */ static bpctl_dev_t *pbpctl_dev; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)) - //lock_kernel(); + /* lock_kernel(); */ #endif lock_bpctl(); - //local_irq_save(flags); - /*if(!spin_trylock_irqsave(&bpvm_lock)){ + /* local_irq_save(flags); */ + /* if(!spin_trylock_irqsave(&bpvm_lock)){ local_irq_restore(flags); - //unlock_bpctl(); - //unlock_kernel(); + unlock_bpctl(); + unlock_kernel(); return -1; } */ - //spin_lock_irqsave(&bpvm_lock, flags); + /* spin_lock_irqsave(&bpvm_lock, flags); */ /* * Switch according to the ioctl called @@ -5632,18 +5555,19 @@ static long device_ioctl(struct file *file, /* ditto */ goto bp_exit; } - //lock_bpctl(); - //preempt_disable(); + /* lock_bpctl(); */ + /* preempt_disable(); */ local_irq_save(flags); if (!spin_trylock(&bpvm_lock)) { local_irq_restore(flags); unlock_bpctl(); - //unlock_kernel(); return -1; } -// preempt_disable(); - //rcu_read_lock(); -// spin_lock_irqsave(&bpvm_lock, flags); + +/* preempt_disable(); + rcu_read_lock(); + spin_lock_irqsave(&bpvm_lock, flags); +*/ if ((bpctl_cmd.in_param[5]) || (bpctl_cmd.in_param[6]) || (bpctl_cmd.in_param[7])) dev_idx = get_dev_idx_bsf(bpctl_cmd.in_param[5], @@ -5655,11 +5579,11 @@ static long device_ioctl(struct file *file, /* ditto */ dev_idx = get_dev_idx(bpctl_cmd.in_param[1]); if (dev_idx < 0 || dev_idx > device_num) { - //unlock_bpctl(); - //preempt_enable(); + /* unlock_bpctl(); + preempt_enable(); */ ret = -EOPNOTSUPP; - //preempt_enable(); - //rcu_read_unlock(); + /* preempt_enable(); + rcu_read_unlock(); */ spin_unlock_irqrestore(&bpvm_lock, flags); goto bp_exit; } @@ -5675,8 +5599,8 @@ static long device_ioctl(struct file *file, /* ditto */ bpctl_dev_arr[dev_idx].name); bpctl_cmd.status = -1; ret = SUCCESS; - /*preempt_enable(); */ - //rcu_read_unlock(); + /* preempt_enable(); */ + /* rcu_read_unlock(); */ spin_unlock_irqrestore(&bpvm_lock, flags); goto bp_exit; @@ -5689,8 +5613,8 @@ static long device_ioctl(struct file *file, /* ditto */ bpctl_dev_arr[dev_idx].name); bpctl_cmd.status = -1; ret = SUCCESS; - /*preempt_enable(); */ - //rcu_read_unlock(); + /* preempt_enable(); */ + /* rcu_read_unlock(); */ spin_unlock_irqrestore(&bpvm_lock, flags); goto bp_exit; } @@ -5823,12 +5747,12 @@ static long device_ioctl(struct file *file, /* ditto */ case IOCTL_TX_MSG(GET_BYPASS_CAPS): bpctl_cmd.status = get_bypass_caps_fn(pbpctl_dev); /*preempt_enable(); */ - //rcu_read_unlock(); + /*rcu_read_unlock();*/ spin_unlock_irqrestore(&bpvm_lock, flags); if (copy_to_user (argp, (void *)&bpctl_cmd, sizeof(struct bpctl_cmd))) { - //unlock_bpctl(); - //preempt_enable(); + /*unlock_bpctl(); */ + /*preempt_enable(); */ ret = -EFAULT; goto bp_exit; } @@ -5903,7 +5827,6 @@ static long device_ioctl(struct file *file, /* ditto */ case IOCTL_TX_MSG(GET_TPL): bpctl_cmd.status = get_tpl_fn(pbpctl_dev); break; -//#ifdef PMC_FIX_FLAG case IOCTL_TX_MSG(SET_BP_WAIT_AT_PWUP): bpctl_cmd.status = set_bp_wait_at_pwup_fn(pbpctl_dev, bpctl_cmd.in_param[2]); @@ -5920,7 +5843,6 @@ static long device_ioctl(struct file *file, /* ditto */ case IOCTL_TX_MSG(GET_BP_HW_RESET): bpctl_cmd.status = get_bp_hw_reset_fn(pbpctl_dev); break; -//#endif #ifdef BP_SELF_TEST case IOCTL_TX_MSG(SET_BP_SELF_TEST): bpctl_cmd.status = @@ -5961,29 +5883,29 @@ static long device_ioctl(struct file *file, /* ditto */ break; default: - // unlock_bpctl(); + /* unlock_bpctl(); */ ret = -EOPNOTSUPP; - /*preempt_enable(); */ - //rcu_read_unlock(); + /* preempt_enable(); */ + /* rcu_read_unlock();*/ spin_unlock_irqrestore(&bpvm_lock, flags); goto bp_exit; } - //unlock_bpctl(); - /*preempt_enable(); */ + /* unlock_bpctl(); */ + /* preempt_enable(); */ bpcmd_exit: - //rcu_read_unlock(); + /* rcu_read_unlock(); */ spin_unlock_irqrestore(&bpvm_lock, flags); if (copy_to_user(argp, (void *)&bpctl_cmd, sizeof(struct bpctl_cmd))) ret = -EFAULT; ret = SUCCESS; bp_exit: #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)) - //unlock_kernel(); + /* unlock_kernel(); */ #endif - //spin_unlock_irqrestore(&bpvm_lock, flags); + /* spin_unlock_irqrestore(&bpvm_lock, flags); */ unlock_bpctl(); - //unlock_kernel(); + /* unlock_kernel(); */ return ret; } @@ -6481,7 +6403,7 @@ static bpmod_info_t tx_ctl_pci_tbl[] = { {BROADCOM_VID, BROADCOM_PE10G2_PID, SILICOM_SVID, SILICOM_PE10G2BPTT_SSID, PE10G2BPTT, "PE10G2BPTT"}, - //{BROADCOM_VID, BROADCOM_PE10G2_PID, PCI_ANY_ID, PCI_ANY_ID, PE10G2BPTCX4, "PE10G2BPTCX4"}, + /* {BROADCOM_VID, BROADCOM_PE10G2_PID, PCI_ANY_ID, PCI_ANY_ID, PE10G2BPTCX4, "PE10G2BPTCX4"}, */ {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ , SILICOM_PEG4BPI6_SSID /*PCI_ANY_ID */ , PEG4BPI6, "PEG4BPI6"}, @@ -6606,10 +6528,8 @@ static bpmod_info_t tx_ctl_pci_tbl[] = { {0x8086, 0x10F9, SILICOM_SVID /*PCI_ANY_ID */ , SILICOM_PE210G2DBi9SR_SSID, PE210G2DBi9SR, "PE210G2DBi9SR"}, - //{0x8086, 0x10F9, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_PE210G2DBi9SRRB_SSID , PE210G2DBi9SRRB, "PE210G2DBi9SRRB"}, {0x8086, 0x10F9, SILICOM_SVID /*PCI_ANY_ID */ , SILICOM_PE210G2DBi9LR_SSID, PE210G2DBi9LR, "PE210G2DBi9LR"}, - // {0x8086, 0x10F9, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_PE210G2DBi9LRRB_SSID , PE210G2DBi9LRRB, "PE210G2DBi9LRRB"}, {0x8086, 0x10F9, SILICOM_SVID /*PCI_ANY_ID */ , SILICOM_PE310G4DBi940SR_SSID, PE310G4DBi940SR, "PE310G4DBi9SR"}, @@ -6671,9 +6591,6 @@ static bpmod_info_t tx_ctl_pci_tbl[] = { {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , SILICOM_PE2G6BPi35_SSID /*PCI_ANY_ID */ , PE2G6BPi35, "PE2G6BPi35"}, - // {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID*/,0xaa0,PE2G6BPi35CX,"PE2G6BPi35CX"}, - // {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID*/,0xaa1,PE2G6BPi35CX,"PE2G6BPi35CX"}, - // {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID*/,0xaa2,PE2G6BPi35CX,"PE2G6BPi35CX"}, {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa0, PE2G6BPi35CX, "PE2G6BPi35CX"}, @@ -6891,7 +6808,7 @@ static int __init bypass_init_module(void) tx_ctl_pci_tbl[idx].subdevice; bpctl_dev_arr[idx_dev].subvendor = tx_ctl_pci_tbl[idx].subvendor; - //bpctl_dev_arr[idx_dev].pdev=pdev1; + /* bpctl_dev_arr[idx_dev].pdev=pdev1; */ bpctl_dev_arr[idx_dev].func = PCI_FUNC(pdev1->devfn); bpctl_dev_arr[idx_dev].slot = PCI_SLOT(pdev1->devfn); bpctl_dev_arr[idx_dev].bus = pdev1->bus->number; @@ -7002,7 +6919,7 @@ static int __init bypass_init_module(void) } } - //bpctl_dev_arr[idx_dev].bp_fw_ver=0xa8; + /* bpctl_dev_arr[idx_dev].bp_fw_ver=0xa8; */ printk("firmware version: 0x%x\n", bpctl_dev_arr[idx_dev]. bp_fw_ver); @@ -7173,23 +7090,22 @@ static int __init bypass_init_module(void) #ifdef BP_PROC_SUPPORT { int i = 0; - //unsigned long flags; - //rcu_read_lock(); + /* unsigned long flags; */ + /* rcu_read_lock(); */ bp_proc_create(); for (i = 0; i < device_num; i++) { if (bpctl_dev_arr[i].ifindex) { - //spin_lock_irqsave(&bpvm_lock, flags); + /* spin_lock_irqsave(&bpvm_lock, flags); */ bypass_proc_remove_dev_sd(&bpctl_dev_arr[i]); bypass_proc_create_dev_sd(&bpctl_dev_arr[i]); - //spin_unlock_irqrestore(&bpvm_lock, flags); + /* spin_unlock_irqrestore(&bpvm_lock, flags); */ } } - //rcu_read_unlock(); + /* rcu_read_unlock(); */ } #endif - //register_netdevice_notifier(&bp_notifier_block); return 0; } @@ -7252,13 +7168,13 @@ static void __exit bypass_cleanup_module(void) #endif for (i = 0; i < device_num; i++) { - //unsigned long flags; + /* unsigned long flags; */ #ifdef BP_PROC_SUPPORT -//spin_lock_irqsave(&bpvm_lock, flags); -//rcu_read_lock(); +/* spin_lock_irqsave(&bpvm_lock, flags); + rcu_read_lock(); */ bypass_proc_remove_dev_sd(&bpctl_dev_arr[i]); -//spin_unlock_irqrestore(&bpvm_lock, flags); -//rcu_read_unlock(); +/* spin_unlock_irqrestore(&bpvm_lock, flags); + rcu_read_unlock(); */ #endif remove_bypass_wd_auto(&bpctl_dev_arr[i]); bpctl_dev_arr[i].reset_time = 0; -- cgit v0.10.2 From 8f413fe6c59b7cab704bc1a36c66c05deee99c33 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Tue, 18 Sep 2012 21:37:44 -0400 Subject: Staging: bcm: Fix all white space issues in cntrl_SignalingInterface.h This patch fixes all white space issues as reported by checkpatch.pl. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/cntrl_SignalingInterface.h b/drivers/staging/bcm/cntrl_SignalingInterface.h index 41d732d..38bed28 100644 --- a/drivers/staging/bcm/cntrl_SignalingInterface.h +++ b/drivers/staging/bcm/cntrl_SignalingInterface.h @@ -1,321 +1,259 @@ #ifndef CNTRL_SIGNALING_INTERFACE_ #define CNTRL_SIGNALING_INTERFACE_ - - - -#define DSA_REQ 11 -#define DSA_RSP 12 -#define DSA_ACK 13 -#define DSC_REQ 14 -#define DSC_RSP 15 -#define DSC_ACK 16 -#define DSD_REQ 17 -#define DSD_RSP 18 -#define DSD_ACK 19 -#define MAX_CLASSIFIERS_IN_SF 4 - - -#define MAX_STRING_LEN 20 -#define MAX_PHS_LENGTHS 255 -#define VENDOR_PHS_PARAM_LENGTH 10 -#define MAX_NUM_ACTIVE_BS 10 -#define AUTH_TOKEN_LENGTH 10 -#define NUM_HARQ_CHANNELS 16 //Changed from 10 to 16 to accommodate all HARQ channels -#define VENDOR_CLASSIFIER_PARAM_LENGTH 1 //Changed the size to 1 byte since we dnt use it -#define VENDOR_SPECIF_QOS_PARAM 1 -#define VENDOR_PHS_PARAM_LENGTH 10 -#define MBS_CONTENTS_ID_LENGTH 10 -#define GLOBAL_SF_CLASSNAME_LENGTH 6 - -#define TYPE_OF_SERVICE_LENGTH 3 -#define IP_MASKED_SRC_ADDRESS_LENGTH 32 -#define IP_MASKED_DEST_ADDRESS_LENGTH 32 -#define PROTOCOL_SRC_PORT_RANGE_LENGTH 4 -#define PROTOCOL_DEST_PORT_RANGE_LENGTH 4 -#define ETHERNET_DEST_MAC_ADDR_LENGTH 12 -#define ETHERNET_SRC_MAC_ADDR_LENGTH 12 -#define NUM_ETHERTYPE_BYTES 3 -#define NUM_IPV6_FLOWLABLE_BYTES 3 - +#define DSA_REQ 11 +#define DSA_RSP 12 +#define DSA_ACK 13 +#define DSC_REQ 14 +#define DSC_RSP 15 +#define DSC_ACK 16 +#define DSD_REQ 17 +#define DSD_RSP 18 +#define DSD_ACK 19 +#define MAX_CLASSIFIERS_IN_SF 4 + +#define MAX_STRING_LEN 20 +#define MAX_PHS_LENGTHS 255 +#define VENDOR_PHS_PARAM_LENGTH 10 +#define MAX_NUM_ACTIVE_BS 10 +#define AUTH_TOKEN_LENGTH 10 +#define NUM_HARQ_CHANNELS 16 //Changed from 10 to 16 to accommodate all HARQ channels +#define VENDOR_CLASSIFIER_PARAM_LENGTH 1 //Changed the size to 1 byte since we dnt use it +#define VENDOR_SPECIF_QOS_PARAM 1 +#define VENDOR_PHS_PARAM_LENGTH 10 +#define MBS_CONTENTS_ID_LENGTH 10 +#define GLOBAL_SF_CLASSNAME_LENGTH 6 + +#define TYPE_OF_SERVICE_LENGTH 3 +#define IP_MASKED_SRC_ADDRESS_LENGTH 32 +#define IP_MASKED_DEST_ADDRESS_LENGTH 32 +#define PROTOCOL_SRC_PORT_RANGE_LENGTH 4 +#define PROTOCOL_DEST_PORT_RANGE_LENGTH 4 +#define ETHERNET_DEST_MAC_ADDR_LENGTH 12 +#define ETHERNET_SRC_MAC_ADDR_LENGTH 12 +#define NUM_ETHERTYPE_BYTES 3 +#define NUM_IPV6_FLOWLABLE_BYTES 3 //////////////////////////////////////////////////////////////////////////////// ////////////////////////structure Definitions/////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /// \brief class cCPacketClassificationRule -struct _stCPacketClassificationRuleSI{ - +struct _stCPacketClassificationRuleSI { /** 16bit UserPriority Of The Service Flow*/ - B_UINT16 u16UserPriority; + B_UINT16 u16UserPriority; /** 16bit VLANID Of The Service Flow*/ - B_UINT16 u16VLANID; + B_UINT16 u16VLANID; /** 16bit Packet Classification RuleIndex Of The Service Flow*/ - B_UINT16 u16PacketClassificationRuleIndex; + B_UINT16 u16PacketClassificationRuleIndex; /** 8bit Classifier Rule Priority Of The Service Flow*/ - B_UINT8 u8ClassifierRulePriority; + B_UINT8 u8ClassifierRulePriority; /** Length of IP TypeOfService field*/ - B_UINT8 u8IPTypeOfServiceLength; + B_UINT8 u8IPTypeOfServiceLength; /** 3bytes IP TypeOfService */ - B_UINT8 u8IPTypeOfService[TYPE_OF_SERVICE_LENGTH]; + B_UINT8 u8IPTypeOfService[TYPE_OF_SERVICE_LENGTH]; /** Protocol used in classification of Service Flow*/ - B_UINT8 u8Protocol; + B_UINT8 u8Protocol; /** Length of IP Masked Source Address */ - B_UINT8 u8IPMaskedSourceAddressLength; + B_UINT8 u8IPMaskedSourceAddressLength; /** IP Masked Source Address used in classification for the Service Flow*/ - B_UINT8 u8IPMaskedSourceAddress[IP_MASKED_SRC_ADDRESS_LENGTH]; + B_UINT8 u8IPMaskedSourceAddress[IP_MASKED_SRC_ADDRESS_LENGTH]; /** Length of IP Destination Address */ - B_UINT8 u8IPDestinationAddressLength; + B_UINT8 u8IPDestinationAddressLength; /** IP Destination Address used in classification for the Service Flow*/ - B_UINT8 u8IPDestinationAddress[IP_MASKED_DEST_ADDRESS_LENGTH]; + B_UINT8 u8IPDestinationAddress[IP_MASKED_DEST_ADDRESS_LENGTH]; /** Length of Protocol Source Port Range */ - B_UINT8 u8ProtocolSourcePortRangeLength; + B_UINT8 u8ProtocolSourcePortRangeLength; /** Protocol Source Port Range used in the Service Flow*/ - B_UINT8 u8ProtocolSourcePortRange[PROTOCOL_SRC_PORT_RANGE_LENGTH]; + B_UINT8 u8ProtocolSourcePortRange[PROTOCOL_SRC_PORT_RANGE_LENGTH]; /** Length of Protocol Dest Port Range */ - B_UINT8 u8ProtocolDestPortRangeLength; + B_UINT8 u8ProtocolDestPortRangeLength; /** Protocol Dest Port Range used in the Service Flow*/ - B_UINT8 u8ProtocolDestPortRange[PROTOCOL_DEST_PORT_RANGE_LENGTH]; + B_UINT8 u8ProtocolDestPortRange[PROTOCOL_DEST_PORT_RANGE_LENGTH]; /** Length of Ethernet Destination MAC Address */ - B_UINT8 u8EthernetDestMacAddressLength; + B_UINT8 u8EthernetDestMacAddressLength; /** Ethernet Destination MAC Address used in classification of the Service Flow*/ - B_UINT8 u8EthernetDestMacAddress[ETHERNET_DEST_MAC_ADDR_LENGTH]; + B_UINT8 u8EthernetDestMacAddress[ETHERNET_DEST_MAC_ADDR_LENGTH]; /** Length of Ethernet Source MAC Address */ - B_UINT8 u8EthernetSourceMACAddressLength; + B_UINT8 u8EthernetSourceMACAddressLength; /** Ethernet Source MAC Address used in classification of the Service Flow*/ - B_UINT8 u8EthernetSourceMACAddress[ETHERNET_SRC_MAC_ADDR_LENGTH]; + B_UINT8 u8EthernetSourceMACAddress[ETHERNET_SRC_MAC_ADDR_LENGTH]; /** Length of Ethertype */ - B_UINT8 u8EthertypeLength; + B_UINT8 u8EthertypeLength; /** 3bytes Ethertype Of The Service Flow*/ - B_UINT8 u8Ethertype[NUM_ETHERTYPE_BYTES]; + B_UINT8 u8Ethertype[NUM_ETHERTYPE_BYTES]; /** 8bit Associated PHSI Of The Service Flow*/ - B_UINT8 u8AssociatedPHSI; + B_UINT8 u8AssociatedPHSI; /** Length of Vendor Specific Classifier Param length Of The Service Flow*/ - B_UINT8 u8VendorSpecificClassifierParamLength; + B_UINT8 u8VendorSpecificClassifierParamLength; /** Vendor Specific Classifier Param Of The Service Flow*/ - B_UINT8 u8VendorSpecificClassifierParam[VENDOR_CLASSIFIER_PARAM_LENGTH]; - /** Length Of IPv6 Flow Lable of the Service Flow*/ - B_UINT8 u8IPv6FlowLableLength; + B_UINT8 u8VendorSpecificClassifierParam[VENDOR_CLASSIFIER_PARAM_LENGTH]; + /** Length Of IPv6 Flow Lable of the Service Flow*/ + B_UINT8 u8IPv6FlowLableLength; /** IPv6 Flow Lable Of The Service Flow*/ - B_UINT8 u8IPv6FlowLable[NUM_IPV6_FLOWLABLE_BYTES]; + B_UINT8 u8IPv6FlowLable[NUM_IPV6_FLOWLABLE_BYTES]; /** Action associated with the classifier rule*/ - B_UINT8 u8ClassifierActionRule; - B_UINT16 u16ValidityBitMap; + B_UINT8 u8ClassifierActionRule; + B_UINT16 u16ValidityBitMap; }; -typedef struct _stCPacketClassificationRuleSI CCPacketClassificationRuleSI,stCPacketClassificationRuleSI, *pstCPacketClassificationRuleSI; +typedef struct _stCPacketClassificationRuleSI CCPacketClassificationRuleSI, stCPacketClassificationRuleSI, *pstCPacketClassificationRuleSI; /// \brief class CPhsRuleSI typedef struct _stPhsRuleSI { /** 8bit PHS Index Of The Service Flow*/ - B_UINT8 u8PHSI; + B_UINT8 u8PHSI; /** PHSF Length Of The Service Flow*/ - B_UINT8 u8PHSFLength; - /** String of bytes containing header information to be suppressed by the sending CS and reconstructed by the receiving CS*/ - B_UINT8 u8PHSF[MAX_PHS_LENGTHS]; + B_UINT8 u8PHSFLength; + /** String of bytes containing header information to be suppressed by the sending CS and reconstructed by the receiving CS*/ + B_UINT8 u8PHSF[MAX_PHS_LENGTHS]; /** PHSM Length Of The Service Flow*/ - B_UINT8 u8PHSMLength; + B_UINT8 u8PHSMLength; /** PHS Mask for the SF*/ - B_UINT8 u8PHSM[MAX_PHS_LENGTHS]; + B_UINT8 u8PHSM[MAX_PHS_LENGTHS]; /** 8bit Total number of bytes to be suppressed for the Service Flow*/ - B_UINT8 u8PHSS; + B_UINT8 u8PHSS; /** 8bit Indicates whether or not Packet Header contents need to be verified prior to suppression */ - B_UINT8 u8PHSV; + B_UINT8 u8PHSV; /** Vendor Specific PHS param Length Of The Service Flow*/ - B_UINT8 u8VendorSpecificPHSParamsLength; + B_UINT8 u8VendorSpecificPHSParamsLength; /** Vendor Specific PHS param Of The Service Flow*/ - B_UINT8 u8VendorSpecificPHSParams[VENDOR_PHS_PARAM_LENGTH]; - - B_UINT8 u8Padding[2]; -}stPhsRuleSI,*pstPhsRuleSI; + B_UINT8 u8VendorSpecificPHSParams[VENDOR_PHS_PARAM_LENGTH]; + B_UINT8 u8Padding[2]; +} stPhsRuleSI, *pstPhsRuleSI; typedef stPhsRuleSI CPhsRuleSI; /// \brief structure cConvergenceSLTypes -struct _stConvergenceSLTypes{ +struct _stConvergenceSLTypes { /** 8bit Phs Classfier Action Of The Service Flow*/ - B_UINT8 u8ClassfierDSCAction; + B_UINT8 u8ClassfierDSCAction; /** 8bit Phs DSC Action Of The Service Flow*/ - B_UINT8 u8PhsDSCAction; + B_UINT8 u8PhsDSCAction; /** 16bit Padding */ - B_UINT8 u8Padding[2]; - /// \brief class cCPacketClassificationRule - stCPacketClassificationRuleSI cCPacketClassificationRule; - /// \brief class CPhsRuleSI - struct _stPhsRuleSI cPhsRule; + B_UINT8 u8Padding[2]; + /// \brief class cCPacketClassificationRule + stCPacketClassificationRuleSI cCPacketClassificationRule; + /// \brief class CPhsRuleSI + struct _stPhsRuleSI cPhsRule; }; -typedef struct _stConvergenceSLTypes stConvergenceSLTypes,CConvergenceSLTypes, *pstConvergenceSLTypes; - +typedef struct _stConvergenceSLTypes stConvergenceSLTypes, CConvergenceSLTypes, *pstConvergenceSLTypes; /// \brief structure CServiceFlowParamSI -typedef struct _stServiceFlowParamSI{ - - /** 32bitSFID Of The Service Flow*/ - B_UINT32 u32SFID; - - /** 32bit Maximum Sustained Traffic Rate of the Service Flow*/ - B_UINT32 u32MaxSustainedTrafficRate; - - /** 32bit Maximum Traffic Burst allowed for the Service Flow*/ - B_UINT32 u32MaxTrafficBurst; - - /** 32bit Minimum Reserved Traffic Rate of the Service Flow*/ - B_UINT32 u32MinReservedTrafficRate; - +typedef struct _stServiceFlowParamSI { + /** 32bitSFID Of The Service Flow*/ + B_UINT32 u32SFID; + /** 32bit Maximum Sustained Traffic Rate of the Service Flow*/ + B_UINT32 u32MaxSustainedTrafficRate; + /** 32bit Maximum Traffic Burst allowed for the Service Flow*/ + B_UINT32 u32MaxTrafficBurst; + /** 32bit Minimum Reserved Traffic Rate of the Service Flow*/ + B_UINT32 u32MinReservedTrafficRate; /** 32bit Tolerated Jitter of the Service Flow*/ - B_UINT32 u32ToleratedJitter; - - /** 32bit Maximum Latency of the Service Flow*/ - B_UINT32 u32MaximumLatency; - + B_UINT32 u32ToleratedJitter; + /** 32bit Maximum Latency of the Service Flow*/ + B_UINT32 u32MaximumLatency; /** 16bitCID Of The Service Flow*/ - B_UINT16 u16CID; - - /** 16bit SAID on which the service flow being set up shall be mapped*/ - B_UINT16 u16TargetSAID; - + B_UINT16 u16CID; + /** 16bit SAID on which the service flow being set up shall be mapped*/ + B_UINT16 u16TargetSAID; /** 16bit ARQ window size negotiated*/ - B_UINT16 u16ARQWindowSize; - - /** 16bit Total Tx delay incl sending, receiving & processing delays */ - B_UINT16 u16ARQRetryTxTimeOut; - - /** 16bit Total Rx delay incl sending, receiving & processing delays */ - B_UINT16 u16ARQRetryRxTimeOut; - - /** 16bit ARQ block lifetime */ - B_UINT16 u16ARQBlockLifeTime; - + B_UINT16 u16ARQWindowSize; + /** 16bit Total Tx delay incl sending, receiving & processing delays */ + B_UINT16 u16ARQRetryTxTimeOut; + /** 16bit Total Rx delay incl sending, receiving & processing delays */ + B_UINT16 u16ARQRetryRxTimeOut; + /** 16bit ARQ block lifetime */ + B_UINT16 u16ARQBlockLifeTime; /** 16bit ARQ Sync loss timeout*/ - B_UINT16 u16ARQSyncLossTimeOut; - - /** 16bit ARQ Purge timeout */ - B_UINT16 u16ARQRxPurgeTimeOut; + B_UINT16 u16ARQSyncLossTimeOut; + /** 16bit ARQ Purge timeout */ + B_UINT16 u16ARQRxPurgeTimeOut; //TODO::Remove this once we move to a new CORR2 driver - /// \brief Size of an ARQ block - B_UINT16 u16ARQBlockSize; - + /// \brief Size of an ARQ block + B_UINT16 u16ARQBlockSize; //#endif /** 16bit Nominal interval b/w consecutive SDU arrivals at MAC SAP*/ - B_UINT16 u16SDUInterArrivalTime; - - /** 16bit Specifies the time base for rate measurement */ - B_UINT16 u16TimeBase; - - /** 16bit Interval b/w Successive Grant oppurtunities*/ - B_UINT16 u16UnsolicitedGrantInterval; - + B_UINT16 u16SDUInterArrivalTime; + /** 16bit Specifies the time base for rate measurement */ + B_UINT16 u16TimeBase; + /** 16bit Interval b/w Successive Grant oppurtunities*/ + B_UINT16 u16UnsolicitedGrantInterval; /** 16bit Interval b/w Successive Polling grant oppurtunities*/ - B_UINT16 u16UnsolicitedPollingInterval; - - /** internal var to get the overhead */ - B_UINT16 u16MacOverhead; - - /** MBS contents Identifier*/ - B_UINT16 u16MBSContentsID[MBS_CONTENTS_ID_LENGTH]; - + B_UINT16 u16UnsolicitedPollingInterval; + /** internal var to get the overhead */ + B_UINT16 u16MacOverhead; + /** MBS contents Identifier*/ + B_UINT16 u16MBSContentsID[MBS_CONTENTS_ID_LENGTH]; /** MBS contents Identifier length*/ - B_UINT8 u8MBSContentsIDLength; - + B_UINT8 u8MBSContentsIDLength; /** ServiceClassName Length Of The Service Flow*/ - B_UINT8 u8ServiceClassNameLength; - + B_UINT8 u8ServiceClassNameLength; /** 32bytes ServiceClassName Of The Service Flow*/ - B_UINT8 u8ServiceClassName[32]; - + B_UINT8 u8ServiceClassName[32]; /** 8bit Indicates whether or not MBS service is requested for this Serivce Flow*/ - B_UINT8 u8MBSService; - - /** 8bit QOS Parameter Set specifies proper application of QoS parameters to Provisioned, Admitted and Active sets*/ - B_UINT8 u8QosParamSet; - - /** 8bit Traffic Priority Of the Service Flow */ - B_UINT8 u8TrafficPriority; - - /** 8bit Uplink Grant Scheduling Type of The Service Flow */ - B_UINT8 u8ServiceFlowSchedulingType; - - /** 8bit Request transmission Policy of the Service Flow*/ - B_UINT8 u8RequesttransmissionPolicy; - + B_UINT8 u8MBSService; + /** 8bit QOS Parameter Set specifies proper application of QoS parameters to Provisioned, Admitted and Active sets*/ + B_UINT8 u8QosParamSet; + /** 8bit Traffic Priority Of the Service Flow */ + B_UINT8 u8TrafficPriority; + /** 8bit Uplink Grant Scheduling Type of The Service Flow */ + B_UINT8 u8ServiceFlowSchedulingType; + /** 8bit Request transmission Policy of the Service Flow*/ + B_UINT8 u8RequesttransmissionPolicy; /** 8bit Specifies whether SDUs for this Service flow are of FixedLength or Variable length */ - B_UINT8 u8FixedLengthVSVariableLengthSDUIndicator; - + B_UINT8 u8FixedLengthVSVariableLengthSDUIndicator; /** 8bit Length of the SDU for a fixed length SDU service flow*/ - B_UINT8 u8SDUSize; - - /** 8bit Indicates whether or not ARQ is requested for this connection*/ - B_UINT8 u8ARQEnable; - + B_UINT8 u8SDUSize; + /** 8bit Indicates whether or not ARQ is requested for this connection*/ + B_UINT8 u8ARQEnable; /**< 8bit Indicates whether or not data has tobe delivered in order to higher layer*/ - B_UINT8 u8ARQDeliverInOrder; - + B_UINT8 u8ARQDeliverInOrder; /** 8bit Receiver ARQ ACK processing time */ - B_UINT8 u8RxARQAckProcessingTime; - + B_UINT8 u8RxARQAckProcessingTime; /** 8bit Convergence Sublayer Specification Of The Service Flow*/ - B_UINT8 u8CSSpecification; - - /** 8 bit Type of data delivery service*/ - B_UINT8 u8TypeOfDataDeliveryService; - + B_UINT8 u8CSSpecification; + /** 8 bit Type of data delivery service*/ + B_UINT8 u8TypeOfDataDeliveryService; /** 8bit Specifies whether a service flow may generate Paging */ - B_UINT8 u8PagingPreference; - + B_UINT8 u8PagingPreference; /** 8bit Indicates the MBS Zone through which the connection or virtual connection is valid */ - B_UINT8 u8MBSZoneIdentifierassignment; - - /** 8bit Specifies whether traffic on SF should generate MOB_TRF_IND to MS in sleep mode*/ - B_UINT8 u8TrafficIndicationPreference; - + B_UINT8 u8MBSZoneIdentifierassignment; + /** 8bit Specifies whether traffic on SF should generate MOB_TRF_IND to MS in sleep mode*/ + B_UINT8 u8TrafficIndicationPreference; /** 8bit Speciifes the length of predefined Global QoS parameter set encoding for this SF */ - B_UINT8 u8GlobalServicesClassNameLength; - - /** 6 byte Speciifes the predefined Global QoS parameter set encoding for this SF */ - B_UINT8 u8GlobalServicesClassName[GLOBAL_SF_CLASSNAME_LENGTH]; - - /** 8bit Indicates whether or not SN feedback is enabled for the conn */ - B_UINT8 u8SNFeedbackEnabled; - - /** Indicates the size of the Fragment Sequence Number for the connection */ - B_UINT8 u8FSNSize; - - /** 8bit Number of CIDs in active BS list */ - B_UINT8 u8CIDAllocation4activeBSsLength; - + B_UINT8 u8GlobalServicesClassNameLength; + /** 6 byte Speciifes the predefined Global QoS parameter set encoding for this SF */ + B_UINT8 u8GlobalServicesClassName[GLOBAL_SF_CLASSNAME_LENGTH]; + /** 8bit Indicates whether or not SN feedback is enabled for the conn */ + B_UINT8 u8SNFeedbackEnabled; + /** Indicates the size of the Fragment Sequence Number for the connection */ + B_UINT8 u8FSNSize; + /** 8bit Number of CIDs in active BS list */ + B_UINT8 u8CIDAllocation4activeBSsLength; /** CIDs of BS in the active list */ - B_UINT8 u8CIDAllocation4activeBSs[MAX_NUM_ACTIVE_BS]; - - /** Specifies if PDU extended subheader should be applied on every PDU on this conn*/ - B_UINT8 u8PDUSNExtendedSubheader4HarqReordering; - - /** 8bit Specifies whether the connection uses HARQ or not */ - B_UINT8 u8HARQServiceFlows; - + B_UINT8 u8CIDAllocation4activeBSs[MAX_NUM_ACTIVE_BS]; + /** Specifies if PDU extended subheader should be applied on every PDU on this conn*/ + B_UINT8 u8PDUSNExtendedSubheader4HarqReordering; + /** 8bit Specifies whether the connection uses HARQ or not */ + B_UINT8 u8HARQServiceFlows; /** Specifies the length of Authorization token*/ - B_UINT8 u8AuthTokenLength; - + B_UINT8 u8AuthTokenLength; /** Specifies the Authorization token*/ - B_UINT8 u8AuthToken[AUTH_TOKEN_LENGTH]; - + B_UINT8 u8AuthToken[AUTH_TOKEN_LENGTH]; /** specifes Number of HARQ channels used to carry data length*/ - B_UINT8 u8HarqChannelMappingLength; - - /** specifes HARQ channels used to carry data*/ - B_UINT8 u8HARQChannelMapping[NUM_HARQ_CHANNELS]; - + B_UINT8 u8HarqChannelMappingLength; + /** specifes HARQ channels used to carry data*/ + B_UINT8 u8HARQChannelMapping[NUM_HARQ_CHANNELS]; /** 8bit Length of Vendor Specific QoS Params */ - B_UINT8 u8VendorSpecificQoSParamLength; - + B_UINT8 u8VendorSpecificQoSParamLength; /** 1byte Vendor Specific QoS Param Of The Service Flow*/ - B_UINT8 u8VendorSpecificQoSParam[VENDOR_SPECIF_QOS_PARAM]; - + B_UINT8 u8VendorSpecificQoSParam[VENDOR_SPECIF_QOS_PARAM]; // indicates total classifiers in the SF - B_UINT8 u8TotalClassifiers; /**< Total number of valid classifiers*/ - B_UINT8 bValid; /**< Validity flag */ - B_UINT8 u8Padding; /**< Padding byte*/ - + B_UINT8 u8TotalClassifiers; /**< Total number of valid classifiers*/ + B_UINT8 bValid; /**< Validity flag */ + B_UINT8 u8Padding; /**< Padding byte*/ /** Structure for Convergence SubLayer Types with a maximum of 4 classifiers */ - stConvergenceSLTypes cConvergenceSLTypes[MAX_CLASSIFIERS_IN_SF]; + stConvergenceSLTypes cConvergenceSLTypes[MAX_CLASSIFIERS_IN_SF]; } stServiceFlowParamSI, *pstServiceFlowParamSI; typedef stServiceFlowParamSI CServiceFlowParamSI; @@ -323,52 +261,44 @@ typedef stServiceFlowParamSI CServiceFlowParamSI; /** structure stLocalSFAddRequest */ -typedef struct _stLocalSFAddRequest{ - - B_UINT8 u8Type; /**< Type*/ - B_UINT8 eConnectionDir; /**< Connection direction*/ +typedef struct _stLocalSFAddRequest { + B_UINT8 u8Type; /**< Type*/ + B_UINT8 eConnectionDir; /**< Connection direction*/ /// \brief 16 bit TID - B_UINT16 u16TID; /**< 16bit TID*/ + B_UINT16 u16TID; /**< 16bit TID*/ /// \brief 16bitCID - B_UINT16 u16CID; /**< 16bit CID*/ + B_UINT16 u16CID; /**< 16bit CID*/ /// \brief 16bitVCID - B_UINT16 u16VCID; /**< 16bit VCID*/ - /// \brief structure ParameterSet - - stServiceFlowParamSI *psfParameterSet; /**< structure ParameterSet*/ - -}stLocalSFAddRequest, *pstLocalSFAddRequest; + B_UINT16 u16VCID; /**< 16bit VCID*/ + /// \brief structure ParameterSet + stServiceFlowParamSI *psfParameterSet; /**< structure ParameterSet */ +} stLocalSFAddRequest, *pstLocalSFAddRequest; /** structure stLocalSFAddIndication */ -typedef struct _stLocalSFAddIndication{ - - B_UINT8 u8Type; /**< Type*/ - B_UINT8 eConnectionDir; /**< Connection Direction*/ +typedef struct _stLocalSFAddIndication { + B_UINT8 u8Type; /**< Type*/ + B_UINT8 eConnectionDir; /**< Connection Direction*/ /// \brief 16 bit TID - B_UINT16 u16TID; /**< TID*/ - /// \brief 16bitCID - B_UINT16 u16CID; /**< 16bitCID*/ - /// \brief 16bitVCID - B_UINT16 u16VCID; /**< 16bitVCID*/ - - - /// \brief structure AuthorizedSet - /// \brief structure AuthorizedSet - stServiceFlowParamSI *psfAuthorizedSet; /**< AuthorizedSet of type stServiceFlowParamSI*/ - /// \brief structure AdmittedSet - stServiceFlowParamSI *psfAdmittedSet; /**< AdmittedSet of type stServiceFlowParamSI*/ - /// \brief structure ActiveSet - stServiceFlowParamSI *psfActiveSet; /**< sfActiveSet of type stServiceFlowParamSI*/ - B_UINT8 u8CC; /**< Confirmation Code*/ - B_UINT8 u8Padd; /**< 8-bit Padding */ - - B_UINT16 u16Padd; /**< 16 bit Padding */ - -}stLocalSFAddIndication; - + B_UINT16 u16TID; /**< TID*/ + /// \brief 16bitCID + B_UINT16 u16CID; /**< 16bitCID*/ + /// \brief 16bitVCID + B_UINT16 u16VCID; /**< 16bitVCID*/ + /// \brief structure AuthorizedSet + /// \brief structure AuthorizedSet + stServiceFlowParamSI *psfAuthorizedSet; /**< AuthorizedSet of type stServiceFlowParamSI */ + /// \brief structure AdmittedSet + stServiceFlowParamSI *psfAdmittedSet; /**< AdmittedSet of type stServiceFlowParamSI */ + /// \brief structure ActiveSet + stServiceFlowParamSI *psfActiveSet; /**< sfActiveSet of type stServiceFlowParamSI */ + B_UINT8 u8CC; /** Date: Tue, 18 Sep 2012 21:37:45 -0400 Subject: Staging: bcm: Properly format comments in cntrl_SignalingInterface.h This patch properly formats comments as reported by checkpatch.pl. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/cntrl_SignalingInterface.h b/drivers/staging/bcm/cntrl_SignalingInterface.h index 38bed28..ffc5456 100644 --- a/drivers/staging/bcm/cntrl_SignalingInterface.h +++ b/drivers/staging/bcm/cntrl_SignalingInterface.h @@ -17,8 +17,8 @@ #define VENDOR_PHS_PARAM_LENGTH 10 #define MAX_NUM_ACTIVE_BS 10 #define AUTH_TOKEN_LENGTH 10 -#define NUM_HARQ_CHANNELS 16 //Changed from 10 to 16 to accommodate all HARQ channels -#define VENDOR_CLASSIFIER_PARAM_LENGTH 1 //Changed the size to 1 byte since we dnt use it +#define NUM_HARQ_CHANNELS 16 /* Changed from 10 to 16 to accommodate all HARQ channels */ +#define VENDOR_CLASSIFIER_PARAM_LENGTH 1 /* Changed the size to 1 byte since we dnt use it */ #define VENDOR_SPECIF_QOS_PARAM 1 #define VENDOR_PHS_PARAM_LENGTH 10 #define MBS_CONTENTS_ID_LENGTH 10 @@ -34,319 +34,321 @@ #define NUM_ETHERTYPE_BYTES 3 #define NUM_IPV6_FLOWLABLE_BYTES 3 -//////////////////////////////////////////////////////////////////////////////// -////////////////////////structure Definitions/////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -/// \brief class cCPacketClassificationRule +/* + * structure Definitions + * + * brief class cCPacketClassificationRule + */ struct _stCPacketClassificationRuleSI { - /** 16bit UserPriority Of The Service Flow*/ + /* 16bit UserPriority Of The Service Flow */ B_UINT16 u16UserPriority; - /** 16bit VLANID Of The Service Flow*/ + /* 16bit VLANID Of The Service Flow */ B_UINT16 u16VLANID; - /** 16bit Packet Classification RuleIndex Of The Service Flow*/ + /* 16bit Packet Classification RuleIndex Of The Service Flow */ B_UINT16 u16PacketClassificationRuleIndex; - /** 8bit Classifier Rule Priority Of The Service Flow*/ + /* 8bit Classifier Rule Priority Of The Service Flow */ B_UINT8 u8ClassifierRulePriority; - /** Length of IP TypeOfService field*/ + /* Length of IP TypeOfService field */ B_UINT8 u8IPTypeOfServiceLength; - /** 3bytes IP TypeOfService */ + /* 3bytes IP TypeOfService */ B_UINT8 u8IPTypeOfService[TYPE_OF_SERVICE_LENGTH]; - /** Protocol used in classification of Service Flow*/ + /* Protocol used in classification of Service Flow */ B_UINT8 u8Protocol; - /** Length of IP Masked Source Address */ + /* Length of IP Masked Source Address */ B_UINT8 u8IPMaskedSourceAddressLength; - /** IP Masked Source Address used in classification for the Service Flow*/ + /* IP Masked Source Address used in classification for the Service Flow */ B_UINT8 u8IPMaskedSourceAddress[IP_MASKED_SRC_ADDRESS_LENGTH]; - /** Length of IP Destination Address */ + /* Length of IP Destination Address */ B_UINT8 u8IPDestinationAddressLength; - /** IP Destination Address used in classification for the Service Flow*/ + /* IP Destination Address used in classification for the Service Flow */ B_UINT8 u8IPDestinationAddress[IP_MASKED_DEST_ADDRESS_LENGTH]; - /** Length of Protocol Source Port Range */ + /* Length of Protocol Source Port Range */ B_UINT8 u8ProtocolSourcePortRangeLength; - /** Protocol Source Port Range used in the Service Flow*/ + /* Protocol Source Port Range used in the Service Flow */ B_UINT8 u8ProtocolSourcePortRange[PROTOCOL_SRC_PORT_RANGE_LENGTH]; - /** Length of Protocol Dest Port Range */ + /* Length of Protocol Dest Port Range */ B_UINT8 u8ProtocolDestPortRangeLength; - /** Protocol Dest Port Range used in the Service Flow*/ + /* Protocol Dest Port Range used in the Service Flow */ B_UINT8 u8ProtocolDestPortRange[PROTOCOL_DEST_PORT_RANGE_LENGTH]; - /** Length of Ethernet Destination MAC Address */ + /* Length of Ethernet Destination MAC Address */ B_UINT8 u8EthernetDestMacAddressLength; - /** Ethernet Destination MAC Address used in classification of the Service Flow*/ + /* Ethernet Destination MAC Address used in classification of the Service Flow */ B_UINT8 u8EthernetDestMacAddress[ETHERNET_DEST_MAC_ADDR_LENGTH]; - /** Length of Ethernet Source MAC Address */ + /* Length of Ethernet Source MAC Address */ B_UINT8 u8EthernetSourceMACAddressLength; - /** Ethernet Source MAC Address used in classification of the Service Flow*/ + /* Ethernet Source MAC Address used in classification of the Service Flow */ B_UINT8 u8EthernetSourceMACAddress[ETHERNET_SRC_MAC_ADDR_LENGTH]; - /** Length of Ethertype */ + /* Length of Ethertype */ B_UINT8 u8EthertypeLength; - /** 3bytes Ethertype Of The Service Flow*/ + /* 3bytes Ethertype Of The Service Flow */ B_UINT8 u8Ethertype[NUM_ETHERTYPE_BYTES]; - /** 8bit Associated PHSI Of The Service Flow*/ + /* 8bit Associated PHSI Of The Service Flow */ B_UINT8 u8AssociatedPHSI; - /** Length of Vendor Specific Classifier Param length Of The Service Flow*/ + /* Length of Vendor Specific Classifier Param length Of The Service Flow */ B_UINT8 u8VendorSpecificClassifierParamLength; - /** Vendor Specific Classifier Param Of The Service Flow*/ + /* Vendor Specific Classifier Param Of The Service Flow */ B_UINT8 u8VendorSpecificClassifierParam[VENDOR_CLASSIFIER_PARAM_LENGTH]; - /** Length Of IPv6 Flow Lable of the Service Flow*/ + /* Length Of IPv6 Flow Lable of the Service Flow */ B_UINT8 u8IPv6FlowLableLength; - /** IPv6 Flow Lable Of The Service Flow*/ + /* IPv6 Flow Lable Of The Service Flow */ B_UINT8 u8IPv6FlowLable[NUM_IPV6_FLOWLABLE_BYTES]; - /** Action associated with the classifier rule*/ + /* Action associated with the classifier rule */ B_UINT8 u8ClassifierActionRule; B_UINT16 u16ValidityBitMap; }; typedef struct _stCPacketClassificationRuleSI CCPacketClassificationRuleSI, stCPacketClassificationRuleSI, *pstCPacketClassificationRuleSI; -/// \brief class CPhsRuleSI +/* brief class CPhsRuleSI */ typedef struct _stPhsRuleSI { - /** 8bit PHS Index Of The Service Flow*/ + /* 8bit PHS Index Of The Service Flow */ B_UINT8 u8PHSI; - /** PHSF Length Of The Service Flow*/ + /* PHSF Length Of The Service Flow */ B_UINT8 u8PHSFLength; - /** String of bytes containing header information to be suppressed by the sending CS and reconstructed by the receiving CS*/ + /* String of bytes containing header information to be suppressed by the sending CS and reconstructed by the receiving CS */ B_UINT8 u8PHSF[MAX_PHS_LENGTHS]; - /** PHSM Length Of The Service Flow*/ + /* PHSM Length Of The Service Flow */ B_UINT8 u8PHSMLength; - /** PHS Mask for the SF*/ + /* PHS Mask for the SF */ B_UINT8 u8PHSM[MAX_PHS_LENGTHS]; - /** 8bit Total number of bytes to be suppressed for the Service Flow*/ + /* 8bit Total number of bytes to be suppressed for the Service Flow */ B_UINT8 u8PHSS; - /** 8bit Indicates whether or not Packet Header contents need to be verified prior to suppression */ + /* 8bit Indicates whether or not Packet Header contents need to be verified prior to suppression */ B_UINT8 u8PHSV; - /** Vendor Specific PHS param Length Of The Service Flow*/ + /* Vendor Specific PHS param Length Of The Service Flow */ B_UINT8 u8VendorSpecificPHSParamsLength; - /** Vendor Specific PHS param Of The Service Flow*/ + /* Vendor Specific PHS param Of The Service Flow */ B_UINT8 u8VendorSpecificPHSParams[VENDOR_PHS_PARAM_LENGTH]; B_UINT8 u8Padding[2]; } stPhsRuleSI, *pstPhsRuleSI; typedef stPhsRuleSI CPhsRuleSI; -/// \brief structure cConvergenceSLTypes +/* brief structure cConvergenceSLTypes */ struct _stConvergenceSLTypes { - /** 8bit Phs Classfier Action Of The Service Flow*/ + /* 8bit Phs Classfier Action Of The Service Flow */ B_UINT8 u8ClassfierDSCAction; - /** 8bit Phs DSC Action Of The Service Flow*/ + /* 8bit Phs DSC Action Of The Service Flow */ B_UINT8 u8PhsDSCAction; - /** 16bit Padding */ + /* 16bit Padding */ B_UINT8 u8Padding[2]; - /// \brief class cCPacketClassificationRule + /* brief class cCPacketClassificationRule */ stCPacketClassificationRuleSI cCPacketClassificationRule; - /// \brief class CPhsRuleSI + /* brief class CPhsRuleSI */ struct _stPhsRuleSI cPhsRule; }; typedef struct _stConvergenceSLTypes stConvergenceSLTypes, CConvergenceSLTypes, *pstConvergenceSLTypes; -/// \brief structure CServiceFlowParamSI +/* brief structure CServiceFlowParamSI */ typedef struct _stServiceFlowParamSI { - /** 32bitSFID Of The Service Flow*/ + /* 32bitSFID Of The Service Flow */ B_UINT32 u32SFID; - /** 32bit Maximum Sustained Traffic Rate of the Service Flow*/ + /* 32bit Maximum Sustained Traffic Rate of the Service Flow */ B_UINT32 u32MaxSustainedTrafficRate; - /** 32bit Maximum Traffic Burst allowed for the Service Flow*/ + /* 32bit Maximum Traffic Burst allowed for the Service Flow */ B_UINT32 u32MaxTrafficBurst; - /** 32bit Minimum Reserved Traffic Rate of the Service Flow*/ + /* 32bit Minimum Reserved Traffic Rate of the Service Flow */ B_UINT32 u32MinReservedTrafficRate; - /** 32bit Tolerated Jitter of the Service Flow*/ + /* 32bit Tolerated Jitter of the Service Flow */ B_UINT32 u32ToleratedJitter; - /** 32bit Maximum Latency of the Service Flow*/ + /* 32bit Maximum Latency of the Service Flow */ B_UINT32 u32MaximumLatency; - /** 16bitCID Of The Service Flow*/ + /* 16bitCID Of The Service Flow */ B_UINT16 u16CID; - /** 16bit SAID on which the service flow being set up shall be mapped*/ + /* 16bit SAID on which the service flow being set up shall be mapped */ B_UINT16 u16TargetSAID; - /** 16bit ARQ window size negotiated*/ + /* 16bit ARQ window size negotiated */ B_UINT16 u16ARQWindowSize; - /** 16bit Total Tx delay incl sending, receiving & processing delays */ + /* 16bit Total Tx delay incl sending, receiving & processing delays */ B_UINT16 u16ARQRetryTxTimeOut; - /** 16bit Total Rx delay incl sending, receiving & processing delays */ + /* 16bit Total Rx delay incl sending, receiving & processing delays */ B_UINT16 u16ARQRetryRxTimeOut; - /** 16bit ARQ block lifetime */ + /* 16bit ARQ block lifetime */ B_UINT16 u16ARQBlockLifeTime; - /** 16bit ARQ Sync loss timeout*/ + /* 16bit ARQ Sync loss timeout */ B_UINT16 u16ARQSyncLossTimeOut; - /** 16bit ARQ Purge timeout */ + /* 16bit ARQ Purge timeout */ B_UINT16 u16ARQRxPurgeTimeOut; -//TODO::Remove this once we move to a new CORR2 driver - /// \brief Size of an ARQ block + /* TODO::Remove this once we move to a new CORR2 driver + * brief Size of an ARQ block + */ B_UINT16 u16ARQBlockSize; -//#endif - /** 16bit Nominal interval b/w consecutive SDU arrivals at MAC SAP*/ + /* #endif */ + /* 16bit Nominal interval b/w consecutive SDU arrivals at MAC SAP */ B_UINT16 u16SDUInterArrivalTime; - /** 16bit Specifies the time base for rate measurement */ + /* 16bit Specifies the time base for rate measurement */ B_UINT16 u16TimeBase; - /** 16bit Interval b/w Successive Grant oppurtunities*/ + /* 16bit Interval b/w Successive Grant oppurtunities */ B_UINT16 u16UnsolicitedGrantInterval; - /** 16bit Interval b/w Successive Polling grant oppurtunities*/ + /* 16bit Interval b/w Successive Polling grant oppurtunities */ B_UINT16 u16UnsolicitedPollingInterval; - /** internal var to get the overhead */ + /* internal var to get the overhead */ B_UINT16 u16MacOverhead; - /** MBS contents Identifier*/ + /* MBS contents Identifier */ B_UINT16 u16MBSContentsID[MBS_CONTENTS_ID_LENGTH]; - /** MBS contents Identifier length*/ + /* MBS contents Identifier length */ B_UINT8 u8MBSContentsIDLength; - /** ServiceClassName Length Of The Service Flow*/ + /* ServiceClassName Length Of The Service Flow */ B_UINT8 u8ServiceClassNameLength; - /** 32bytes ServiceClassName Of The Service Flow*/ + /* 32bytes ServiceClassName Of The Service Flow */ B_UINT8 u8ServiceClassName[32]; - /** 8bit Indicates whether or not MBS service is requested for this Serivce Flow*/ + /* 8bit Indicates whether or not MBS service is requested for this Serivce Flow */ B_UINT8 u8MBSService; - /** 8bit QOS Parameter Set specifies proper application of QoS parameters to Provisioned, Admitted and Active sets*/ + /* 8bit QOS Parameter Set specifies proper application of QoS parameters to Provisioned, Admitted and Active sets */ B_UINT8 u8QosParamSet; - /** 8bit Traffic Priority Of the Service Flow */ + /* 8bit Traffic Priority Of the Service Flow */ B_UINT8 u8TrafficPriority; - /** 8bit Uplink Grant Scheduling Type of The Service Flow */ + /* 8bit Uplink Grant Scheduling Type of The Service Flow */ B_UINT8 u8ServiceFlowSchedulingType; - /** 8bit Request transmission Policy of the Service Flow*/ + /* 8bit Request transmission Policy of the Service Flow */ B_UINT8 u8RequesttransmissionPolicy; - /** 8bit Specifies whether SDUs for this Service flow are of FixedLength or Variable length */ + /* 8bit Specifies whether SDUs for this Service flow are of FixedLength or Variable length */ B_UINT8 u8FixedLengthVSVariableLengthSDUIndicator; - /** 8bit Length of the SDU for a fixed length SDU service flow*/ + /* 8bit Length of the SDU for a fixed length SDU service flow */ B_UINT8 u8SDUSize; - /** 8bit Indicates whether or not ARQ is requested for this connection*/ + /* 8bit Indicates whether or not ARQ is requested for this connection */ B_UINT8 u8ARQEnable; - /**< 8bit Indicates whether or not data has tobe delivered in order to higher layer*/ + /* < 8bit Indicates whether or not data has tobe delivered in order to higher layer */ B_UINT8 u8ARQDeliverInOrder; - /** 8bit Receiver ARQ ACK processing time */ + /* 8bit Receiver ARQ ACK processing time */ B_UINT8 u8RxARQAckProcessingTime; - /** 8bit Convergence Sublayer Specification Of The Service Flow*/ + /* 8bit Convergence Sublayer Specification Of The Service Flow */ B_UINT8 u8CSSpecification; - /** 8 bit Type of data delivery service*/ + /* 8 bit Type of data delivery service */ B_UINT8 u8TypeOfDataDeliveryService; - /** 8bit Specifies whether a service flow may generate Paging */ + /* 8bit Specifies whether a service flow may generate Paging */ B_UINT8 u8PagingPreference; - /** 8bit Indicates the MBS Zone through which the connection or virtual connection is valid */ + /* 8bit Indicates the MBS Zone through which the connection or virtual connection is valid */ B_UINT8 u8MBSZoneIdentifierassignment; - /** 8bit Specifies whether traffic on SF should generate MOB_TRF_IND to MS in sleep mode*/ + /* 8bit Specifies whether traffic on SF should generate MOB_TRF_IND to MS in sleep mode */ B_UINT8 u8TrafficIndicationPreference; - /** 8bit Speciifes the length of predefined Global QoS parameter set encoding for this SF */ + /* 8bit Speciifes the length of predefined Global QoS parameter set encoding for this SF */ B_UINT8 u8GlobalServicesClassNameLength; - /** 6 byte Speciifes the predefined Global QoS parameter set encoding for this SF */ + /* 6 byte Speciifes the predefined Global QoS parameter set encoding for this SF */ B_UINT8 u8GlobalServicesClassName[GLOBAL_SF_CLASSNAME_LENGTH]; - /** 8bit Indicates whether or not SN feedback is enabled for the conn */ + /* 8bit Indicates whether or not SN feedback is enabled for the conn */ B_UINT8 u8SNFeedbackEnabled; - /** Indicates the size of the Fragment Sequence Number for the connection */ + /* Indicates the size of the Fragment Sequence Number for the connection */ B_UINT8 u8FSNSize; - /** 8bit Number of CIDs in active BS list */ + /* 8bit Number of CIDs in active BS list */ B_UINT8 u8CIDAllocation4activeBSsLength; - /** CIDs of BS in the active list */ + /* CIDs of BS in the active list */ B_UINT8 u8CIDAllocation4activeBSs[MAX_NUM_ACTIVE_BS]; - /** Specifies if PDU extended subheader should be applied on every PDU on this conn*/ + /* Specifies if PDU extended subheader should be applied on every PDU on this conn */ B_UINT8 u8PDUSNExtendedSubheader4HarqReordering; - /** 8bit Specifies whether the connection uses HARQ or not */ + /* 8bit Specifies whether the connection uses HARQ or not */ B_UINT8 u8HARQServiceFlows; - /** Specifies the length of Authorization token*/ + /* Specifies the length of Authorization token */ B_UINT8 u8AuthTokenLength; - /** Specifies the Authorization token*/ + /* Specifies the Authorization token */ B_UINT8 u8AuthToken[AUTH_TOKEN_LENGTH]; - /** specifes Number of HARQ channels used to carry data length*/ + /* specifes Number of HARQ channels used to carry data length */ B_UINT8 u8HarqChannelMappingLength; - /** specifes HARQ channels used to carry data*/ + /* specifes HARQ channels used to carry data */ B_UINT8 u8HARQChannelMapping[NUM_HARQ_CHANNELS]; - /** 8bit Length of Vendor Specific QoS Params */ + /* 8bit Length of Vendor Specific QoS Params */ B_UINT8 u8VendorSpecificQoSParamLength; - /** 1byte Vendor Specific QoS Param Of The Service Flow*/ + /* 1byte Vendor Specific QoS Param Of The Service Flow */ B_UINT8 u8VendorSpecificQoSParam[VENDOR_SPECIF_QOS_PARAM]; - // indicates total classifiers in the SF - B_UINT8 u8TotalClassifiers; /**< Total number of valid classifiers*/ - B_UINT8 bValid; /**< Validity flag */ - B_UINT8 u8Padding; /**< Padding byte*/ -/** -Structure for Convergence SubLayer Types with a maximum of 4 classifiers -*/ + /* indicates total classifiers in the SF */ + B_UINT8 u8TotalClassifiers; /* < Total number of valid classifiers */ + B_UINT8 bValid; /* < Validity flag */ + B_UINT8 u8Padding; /* < Padding byte */ +/* + * Structure for Convergence SubLayer Types with a maximum of 4 classifiers + */ stConvergenceSLTypes cConvergenceSLTypes[MAX_CLASSIFIERS_IN_SF]; } stServiceFlowParamSI, *pstServiceFlowParamSI; typedef stServiceFlowParamSI CServiceFlowParamSI; -/** -structure stLocalSFAddRequest -*/ +/* + * structure stLocalSFAddRequest + */ typedef struct _stLocalSFAddRequest { - B_UINT8 u8Type; /**< Type*/ - B_UINT8 eConnectionDir; /**< Connection direction*/ - /// \brief 16 bit TID - B_UINT16 u16TID; /**< 16bit TID*/ - /// \brief 16bitCID - B_UINT16 u16CID; /**< 16bit CID*/ - /// \brief 16bitVCID - B_UINT16 u16VCID; /**< 16bit VCID*/ - /// \brief structure ParameterSet - stServiceFlowParamSI *psfParameterSet; /**< structure ParameterSet */ + B_UINT8 u8Type; /* < Type */ + B_UINT8 eConnectionDir; /* < Connection direction */ + /* brief 16 bit TID */ + B_UINT16 u16TID; /* < 16bit TID */ + /* brief 16bitCID */ + B_UINT16 u16CID; /* < 16bit CID */ + /* brief 16bitVCID */ + B_UINT16 u16VCID; /* < 16bit VCID */ + /* brief structure ParameterSet */ + stServiceFlowParamSI *psfParameterSet; /* < structure ParameterSet */ } stLocalSFAddRequest, *pstLocalSFAddRequest; -/** -structure stLocalSFAddIndication -*/ +/* + * structure stLocalSFAddIndication + */ typedef struct _stLocalSFAddIndication { - B_UINT8 u8Type; /**< Type*/ - B_UINT8 eConnectionDir; /**< Connection Direction*/ - /// \brief 16 bit TID - B_UINT16 u16TID; /**< TID*/ - /// \brief 16bitCID - B_UINT16 u16CID; /**< 16bitCID*/ - /// \brief 16bitVCID - B_UINT16 u16VCID; /**< 16bitVCID*/ - /// \brief structure AuthorizedSet - /// \brief structure AuthorizedSet - stServiceFlowParamSI *psfAuthorizedSet; /**< AuthorizedSet of type stServiceFlowParamSI */ - /// \brief structure AdmittedSet - stServiceFlowParamSI *psfAdmittedSet; /**< AdmittedSet of type stServiceFlowParamSI */ - /// \brief structure ActiveSet - stServiceFlowParamSI *psfActiveSet; /**< sfActiveSet of type stServiceFlowParamSI */ - B_UINT8 u8CC; /** Date: Tue, 18 Sep 2012 21:37:46 -0400 Subject: Staging: bcm: Properly format braces in cntrl_SignalingInterface.h This patch cuddles braces as reported by checkpatch.pl. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/cntrl_SignalingInterface.h b/drivers/staging/bcm/cntrl_SignalingInterface.h index ffc5456..451664b 100644 --- a/drivers/staging/bcm/cntrl_SignalingInterface.h +++ b/drivers/staging/bcm/cntrl_SignalingInterface.h @@ -341,8 +341,7 @@ typedef struct stLocalSFDeleteIndication { B_UINT8 u8Padding1[3]; /* < 3 byte Padding */ } stLocalSFDeleteIndication; -typedef struct _stIM_SFHostNotify -{ +typedef struct _stIM_SFHostNotify { B_UINT32 SFID; /* SFID of the service flow */ B_UINT16 newCID; /* the new/changed CID */ B_UINT16 VCID; /* Get new Vcid if the flow has been made active in CID update TLV, but was inactive earlier or the orig vcid */ -- cgit v0.10.2 From 3d9562a6ed5389cd92deafa3e357e197b1ff136d Mon Sep 17 00:00:00 2001 From: Fengguang Wu Date: Wed, 19 Sep 2012 09:37:32 +0800 Subject: staging: ozwpan: compare pointer to NULL rather than 0 Generated by: scripts/coccinelle/null/badzero.cocci Signed-off-by: Fengguang Wu Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ozwpan/ozcdev.c b/drivers/staging/ozwpan/ozcdev.c index 758ce0a..64913ae 100644 --- a/drivers/staging/ozwpan/ozcdev.c +++ b/drivers/staging/ozwpan/ozcdev.c @@ -104,10 +104,10 @@ ssize_t oz_cdev_read(struct file *filp, char __user *buf, size_t count, if (pd) oz_pd_get(pd); spin_unlock_bh(&g_cdev.lock); - if (pd == 0) + if (pd == NULL) return -1; ctx = oz_cdev_claim_ctx(pd); - if (ctx == 0) + if (ctx == NULL) goto out2; n = ctx->rd_in - ctx->rd_out; if (n < 0) @@ -157,11 +157,11 @@ ssize_t oz_cdev_write(struct file *filp, const char __user *buf, size_t count, if (pd) oz_pd_get(pd); spin_unlock_bh(&g_cdev.lock); - if (pd == 0) + if (pd == NULL) return -1; eb = &pd->elt_buff; ei = oz_elt_info_alloc(eb); - if (ei == 0) { + if (ei == NULL) { count = 0; goto out; } @@ -410,7 +410,7 @@ int oz_cdev_start(struct oz_pd *pd, int resume) return 0; } ctx = kzalloc(sizeof(struct oz_serial_ctx), GFP_ATOMIC); - if (ctx == 0) + if (ctx == NULL) return -ENOMEM; atomic_set(&ctx->ref_count, 1); ctx->tx_seq_num = 1; @@ -424,7 +424,7 @@ int oz_cdev_start(struct oz_pd *pd, int resume) spin_unlock_bh(&pd->app_lock[OZ_APPID_SERIAL-1]); } spin_lock(&g_cdev.lock); - if ((g_cdev.active_pd == 0) && + if ((g_cdev.active_pd == NULL) && (memcmp(pd->mac_addr, g_cdev.active_addr, ETH_ALEN) == 0)) { oz_pd_get(pd); g_cdev.active_pd = pd; @@ -477,7 +477,7 @@ void oz_cdev_rx(struct oz_pd *pd, struct oz_elt *elt) int ix; ctx = oz_cdev_claim_ctx(pd); - if (ctx == 0) { + if (ctx == NULL) { oz_trace("Cannot claim serial context.\n"); return; } -- cgit v0.10.2 From 5d5d7c3b938d0c365e65180f2b9d6ffad4973cee Mon Sep 17 00:00:00 2001 From: Emil Goode Date: Tue, 18 Sep 2012 18:04:07 +0200 Subject: staging: wlan-ng: Fix dereference before NULL check Smatch is warning about a dereference before we check for NULL. This patch moves the dereference to after the NULL check. Smatch warning: drivers/staging/wlan-ng/cfg80211.c:345 prism2_scan() warn: variable dereferenced before check 'request' (see line 332) Signed-off-by: Emil Goode Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlan-ng/cfg80211.c b/drivers/staging/wlan-ng/cfg80211.c index 0970127..57a2b05 100644 --- a/drivers/staging/wlan-ng/cfg80211.c +++ b/drivers/staging/wlan-ng/cfg80211.c @@ -329,9 +329,9 @@ int prism2_get_station(struct wiphy *wiphy, struct net_device *dev, int prism2_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) { - struct net_device *dev = request->wdev->netdev; + struct net_device *dev; struct prism2_wiphy_private *priv = wiphy_priv(wiphy); - wlandevice_t *wlandev = dev->ml_priv; + wlandevice_t *wlandev; struct p80211msg_dot11req_scan msg1; struct p80211msg_dot11req_scan_results msg2; struct cfg80211_bss *bss; @@ -345,6 +345,9 @@ int prism2_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) if (!request) return -EINVAL; + dev = request->wdev->netdev; + wlandev = dev->ml_priv; + if (priv->scan_request && priv->scan_request != request) return -EBUSY; -- cgit v0.10.2 From 25b73c783dd87de66383ea16606a8c4f8ebb1e0a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 18 Sep 2012 11:40:15 -0700 Subject: staging: comedi: comedi.h: remove the extra indents The extra indents in this file cause git diff to not know the section where changes are being made. This results in diff outputs like: @@ -365,7 +365,10 @@ instead of the more informational: @@ -365,6 +365,7 @@ struct comedi_cmd { Remove all the extra indents. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/comedi.h b/drivers/staging/comedi/comedi.h index 8ea55ae..76cdb2c 100644 --- a/drivers/staging/comedi/comedi.h +++ b/drivers/staging/comedi/comedi.h @@ -208,92 +208,92 @@ /* subdevice types */ - enum comedi_subdevice_type { - COMEDI_SUBD_UNUSED, /* unused by driver */ - COMEDI_SUBD_AI, /* analog input */ - COMEDI_SUBD_AO, /* analog output */ - COMEDI_SUBD_DI, /* digital input */ - COMEDI_SUBD_DO, /* digital output */ - COMEDI_SUBD_DIO, /* digital input/output */ - COMEDI_SUBD_COUNTER, /* counter */ - COMEDI_SUBD_TIMER, /* timer */ - COMEDI_SUBD_MEMORY, /* memory, EEPROM, DPRAM */ - COMEDI_SUBD_CALIB, /* calibration DACs */ - COMEDI_SUBD_PROC, /* processor, DSP */ - COMEDI_SUBD_SERIAL, /* serial IO */ - COMEDI_SUBD_PWM /* PWM */ - }; +enum comedi_subdevice_type { + COMEDI_SUBD_UNUSED, /* unused by driver */ + COMEDI_SUBD_AI, /* analog input */ + COMEDI_SUBD_AO, /* analog output */ + COMEDI_SUBD_DI, /* digital input */ + COMEDI_SUBD_DO, /* digital output */ + COMEDI_SUBD_DIO, /* digital input/output */ + COMEDI_SUBD_COUNTER, /* counter */ + COMEDI_SUBD_TIMER, /* timer */ + COMEDI_SUBD_MEMORY, /* memory, EEPROM, DPRAM */ + COMEDI_SUBD_CALIB, /* calibration DACs */ + COMEDI_SUBD_PROC, /* processor, DSP */ + COMEDI_SUBD_SERIAL, /* serial IO */ + COMEDI_SUBD_PWM /* PWM */ +}; /* configuration instructions */ - enum configuration_ids { - INSN_CONFIG_DIO_INPUT = 0, - INSN_CONFIG_DIO_OUTPUT = 1, - INSN_CONFIG_DIO_OPENDRAIN = 2, - INSN_CONFIG_ANALOG_TRIG = 16, +enum configuration_ids { + INSN_CONFIG_DIO_INPUT = 0, + INSN_CONFIG_DIO_OUTPUT = 1, + INSN_CONFIG_DIO_OPENDRAIN = 2, + INSN_CONFIG_ANALOG_TRIG = 16, /* INSN_CONFIG_WAVEFORM = 17, */ /* INSN_CONFIG_TRIG = 18, */ /* INSN_CONFIG_COUNTER = 19, */ - INSN_CONFIG_ALT_SOURCE = 20, - INSN_CONFIG_DIGITAL_TRIG = 21, - INSN_CONFIG_BLOCK_SIZE = 22, - INSN_CONFIG_TIMER_1 = 23, - INSN_CONFIG_FILTER = 24, - INSN_CONFIG_CHANGE_NOTIFY = 25, - - /*ALPHA*/ INSN_CONFIG_SERIAL_CLOCK = 26, - INSN_CONFIG_BIDIRECTIONAL_DATA = 27, - INSN_CONFIG_DIO_QUERY = 28, - INSN_CONFIG_PWM_OUTPUT = 29, - INSN_CONFIG_GET_PWM_OUTPUT = 30, - INSN_CONFIG_ARM = 31, - INSN_CONFIG_DISARM = 32, - INSN_CONFIG_GET_COUNTER_STATUS = 33, - INSN_CONFIG_RESET = 34, - /* Use CTR as single pulsegenerator */ - INSN_CONFIG_GPCT_SINGLE_PULSE_GENERATOR = 1001, - /* Use CTR as pulsetraingenerator */ - INSN_CONFIG_GPCT_PULSE_TRAIN_GENERATOR = 1002, - /* Use the counter as encoder */ - INSN_CONFIG_GPCT_QUADRATURE_ENCODER = 1003, - INSN_CONFIG_SET_GATE_SRC = 2001, /* Set gate source */ - INSN_CONFIG_GET_GATE_SRC = 2002, /* Get gate source */ - /* Set master clock source */ - INSN_CONFIG_SET_CLOCK_SRC = 2003, - INSN_CONFIG_GET_CLOCK_SRC = 2004, /* Get master clock source */ - INSN_CONFIG_SET_OTHER_SRC = 2005, /* Set other source */ - /* INSN_CONFIG_GET_OTHER_SRC = 2006,*//* Get other source */ - /* Get size in bytes of subdevice's on-board fifos used during - * streaming input/output */ - INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE = 2006, - INSN_CONFIG_SET_COUNTER_MODE = 4097, - /* INSN_CONFIG_8254_SET_MODE is deprecated */ - INSN_CONFIG_8254_SET_MODE = INSN_CONFIG_SET_COUNTER_MODE, - INSN_CONFIG_8254_READ_STATUS = 4098, - INSN_CONFIG_SET_ROUTING = 4099, - INSN_CONFIG_GET_ROUTING = 4109, -/* PWM */ - INSN_CONFIG_PWM_SET_PERIOD = 5000, /* sets frequency */ - INSN_CONFIG_PWM_GET_PERIOD = 5001, /* gets frequency */ - INSN_CONFIG_GET_PWM_STATUS = 5002, /* is it running? */ - /* sets H bridge: duty cycle and sign bit for a relay at the - * same time */ - INSN_CONFIG_PWM_SET_H_BRIDGE = 5003, - /* gets H bridge data: duty cycle and the sign bit */ - INSN_CONFIG_PWM_GET_H_BRIDGE = 5004 - }; - - enum comedi_io_direction { - COMEDI_INPUT = 0, - COMEDI_OUTPUT = 1, - COMEDI_OPENDRAIN = 2 - }; - - enum comedi_support_level { - COMEDI_UNKNOWN_SUPPORT = 0, - COMEDI_SUPPORTED, - COMEDI_UNSUPPORTED - }; + INSN_CONFIG_ALT_SOURCE = 20, + INSN_CONFIG_DIGITAL_TRIG = 21, + INSN_CONFIG_BLOCK_SIZE = 22, + INSN_CONFIG_TIMER_1 = 23, + INSN_CONFIG_FILTER = 24, + INSN_CONFIG_CHANGE_NOTIFY = 25, + + INSN_CONFIG_SERIAL_CLOCK = 26, /*ALPHA*/ + INSN_CONFIG_BIDIRECTIONAL_DATA = 27, + INSN_CONFIG_DIO_QUERY = 28, + INSN_CONFIG_PWM_OUTPUT = 29, + INSN_CONFIG_GET_PWM_OUTPUT = 30, + INSN_CONFIG_ARM = 31, + INSN_CONFIG_DISARM = 32, + INSN_CONFIG_GET_COUNTER_STATUS = 33, + INSN_CONFIG_RESET = 34, + /* Use CTR as single pulsegenerator */ + INSN_CONFIG_GPCT_SINGLE_PULSE_GENERATOR = 1001, + /* Use CTR as pulsetraingenerator */ + INSN_CONFIG_GPCT_PULSE_TRAIN_GENERATOR = 1002, + /* Use the counter as encoder */ + INSN_CONFIG_GPCT_QUADRATURE_ENCODER = 1003, + INSN_CONFIG_SET_GATE_SRC = 2001, /* Set gate source */ + INSN_CONFIG_GET_GATE_SRC = 2002, /* Get gate source */ + /* Set master clock source */ + INSN_CONFIG_SET_CLOCK_SRC = 2003, + INSN_CONFIG_GET_CLOCK_SRC = 2004, /* Get master clock source */ + INSN_CONFIG_SET_OTHER_SRC = 2005, /* Set other source */ + /* INSN_CONFIG_GET_OTHER_SRC = 2006,*//* Get other source */ + /* Get size in bytes of subdevice's on-board fifos used during + * streaming input/output */ + INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE = 2006, + INSN_CONFIG_SET_COUNTER_MODE = 4097, + /* INSN_CONFIG_8254_SET_MODE is deprecated */ + INSN_CONFIG_8254_SET_MODE = INSN_CONFIG_SET_COUNTER_MODE, + INSN_CONFIG_8254_READ_STATUS = 4098, + INSN_CONFIG_SET_ROUTING = 4099, + INSN_CONFIG_GET_ROUTING = 4109, + /* PWM */ + INSN_CONFIG_PWM_SET_PERIOD = 5000, /* sets frequency */ + INSN_CONFIG_PWM_GET_PERIOD = 5001, /* gets frequency */ + INSN_CONFIG_GET_PWM_STATUS = 5002, /* is it running? */ + /* sets H bridge: duty cycle and sign bit for a relay at the + * same time */ + INSN_CONFIG_PWM_SET_H_BRIDGE = 5003, + /* gets H bridge data: duty cycle and the sign bit */ + INSN_CONFIG_PWM_GET_H_BRIDGE = 5004 +}; + +enum comedi_io_direction { + COMEDI_INPUT = 0, + COMEDI_OUTPUT = 1, + COMEDI_OPENDRAIN = 2 +}; + +enum comedi_support_level { + COMEDI_UNKNOWN_SUPPORT = 0, + COMEDI_SUPPORTED, + COMEDI_UNSUPPORTED +}; /* ioctls */ @@ -317,133 +317,133 @@ /* structures */ - struct comedi_trig { - unsigned int subdev; /* subdevice */ - unsigned int mode; /* mode */ - unsigned int flags; - unsigned int n_chan; /* number of channels */ - unsigned int *chanlist; /* channel/range list */ - short *data; /* data list, size depends on subd flags */ - unsigned int n; /* number of scans */ - unsigned int trigsrc; - unsigned int trigvar; - unsigned int trigvar1; - unsigned int data_len; - unsigned int unused[3]; - }; - - struct comedi_insn { - unsigned int insn; - unsigned int n; - unsigned int __user *data; - unsigned int subdev; - unsigned int chanspec; - unsigned int unused[3]; - }; - - struct comedi_insnlist { - unsigned int n_insns; - struct comedi_insn __user *insns; - }; - - struct comedi_cmd { - unsigned int subdev; - unsigned int flags; - - unsigned int start_src; - unsigned int start_arg; - - unsigned int scan_begin_src; - unsigned int scan_begin_arg; - - unsigned int convert_src; - unsigned int convert_arg; - - unsigned int scan_end_src; - unsigned int scan_end_arg; - - unsigned int stop_src; - unsigned int stop_arg; - - unsigned int __user *chanlist; /* channel/range list */ - unsigned int chanlist_len; - - short __user *data; /* data list, size depends on subd flags */ - unsigned int data_len; - }; - - struct comedi_chaninfo { - unsigned int subdev; - unsigned int __user *maxdata_list; - unsigned int __user *flaglist; - unsigned int __user *rangelist; - unsigned int unused[4]; - }; - - struct comedi_rangeinfo { - unsigned int range_type; - void __user *range_ptr; - }; - - struct comedi_krange { - int min; /* fixed point, multiply by 1e-6 */ - int max; /* fixed point, multiply by 1e-6 */ - unsigned int flags; - }; - - struct comedi_subdinfo { - unsigned int type; - unsigned int n_chan; - unsigned int subd_flags; - unsigned int timer_type; - unsigned int len_chanlist; - unsigned int maxdata; - unsigned int flags; /* channel flags */ - unsigned int range_type; /* lookup in kernel */ - unsigned int settling_time_0; - /* see support_level enum for values */ - unsigned insn_bits_support; - unsigned int unused[8]; - }; - - struct comedi_devinfo { - unsigned int version_code; - unsigned int n_subdevs; - char driver_name[COMEDI_NAMELEN]; - char board_name[COMEDI_NAMELEN]; - int read_subdevice; - int write_subdevice; - int unused[30]; - }; - - struct comedi_devconfig { - char board_name[COMEDI_NAMELEN]; - int options[COMEDI_NDEVCONFOPTS]; - }; - - struct comedi_bufconfig { - unsigned int subdevice; - unsigned int flags; - - unsigned int maximum_size; - unsigned int size; - - unsigned int unused[4]; - }; - - struct comedi_bufinfo { - unsigned int subdevice; - unsigned int bytes_read; - - unsigned int buf_write_ptr; - unsigned int buf_read_ptr; - unsigned int buf_write_count; - unsigned int buf_read_count; - - unsigned int bytes_written; - - unsigned int unused[4]; - }; +struct comedi_trig { + unsigned int subdev; /* subdevice */ + unsigned int mode; /* mode */ + unsigned int flags; + unsigned int n_chan; /* number of channels */ + unsigned int *chanlist; /* channel/range list */ + short *data; /* data list, size depends on subd flags */ + unsigned int n; /* number of scans */ + unsigned int trigsrc; + unsigned int trigvar; + unsigned int trigvar1; + unsigned int data_len; + unsigned int unused[3]; +}; + +struct comedi_insn { + unsigned int insn; + unsigned int n; + unsigned int __user *data; + unsigned int subdev; + unsigned int chanspec; + unsigned int unused[3]; +}; + +struct comedi_insnlist { + unsigned int n_insns; + struct comedi_insn __user *insns; +}; + +struct comedi_cmd { + unsigned int subdev; + unsigned int flags; + + unsigned int start_src; + unsigned int start_arg; + + unsigned int scan_begin_src; + unsigned int scan_begin_arg; + + unsigned int convert_src; + unsigned int convert_arg; + + unsigned int scan_end_src; + unsigned int scan_end_arg; + + unsigned int stop_src; + unsigned int stop_arg; + + unsigned int __user *chanlist; /* channel/range list */ + unsigned int chanlist_len; + + short __user *data; /* data list, size depends on subd flags */ + unsigned int data_len; +}; + +struct comedi_chaninfo { + unsigned int subdev; + unsigned int __user *maxdata_list; + unsigned int __user *flaglist; + unsigned int __user *rangelist; + unsigned int unused[4]; +}; + +struct comedi_rangeinfo { + unsigned int range_type; + void __user *range_ptr; +}; + +struct comedi_krange { + int min; /* fixed point, multiply by 1e-6 */ + int max; /* fixed point, multiply by 1e-6 */ + unsigned int flags; +}; + +struct comedi_subdinfo { + unsigned int type; + unsigned int n_chan; + unsigned int subd_flags; + unsigned int timer_type; + unsigned int len_chanlist; + unsigned int maxdata; + unsigned int flags; /* channel flags */ + unsigned int range_type; /* lookup in kernel */ + unsigned int settling_time_0; + /* see support_level enum for values */ + unsigned insn_bits_support; + unsigned int unused[8]; +}; + +struct comedi_devinfo { + unsigned int version_code; + unsigned int n_subdevs; + char driver_name[COMEDI_NAMELEN]; + char board_name[COMEDI_NAMELEN]; + int read_subdevice; + int write_subdevice; + int unused[30]; +}; + +struct comedi_devconfig { + char board_name[COMEDI_NAMELEN]; + int options[COMEDI_NDEVCONFOPTS]; +}; + +struct comedi_bufconfig { + unsigned int subdevice; + unsigned int flags; + + unsigned int maximum_size; + unsigned int size; + + unsigned int unused[4]; +}; + +struct comedi_bufinfo { + unsigned int subdevice; + unsigned int bytes_read; + + unsigned int buf_write_ptr; + unsigned int buf_read_ptr; + unsigned int buf_write_count; + unsigned int buf_read_count; + + unsigned int bytes_written; + + unsigned int unused[4]; +}; /* range stuff */ @@ -495,306 +495,306 @@ */ - enum i8254_mode { - I8254_MODE0 = (0 << 1), /* Interrupt on terminal count */ - I8254_MODE1 = (1 << 1), /* Hardware retriggerable one-shot */ - I8254_MODE2 = (2 << 1), /* Rate generator */ - I8254_MODE3 = (3 << 1), /* Square wave mode */ - I8254_MODE4 = (4 << 1), /* Software triggered strobe */ - I8254_MODE5 = (5 << 1), /* Hardware triggered strobe - * (retriggerable) */ - I8254_BCD = 1, /* use binary-coded decimal instead of binary +enum i8254_mode { + I8254_MODE0 = (0 << 1), /* Interrupt on terminal count */ + I8254_MODE1 = (1 << 1), /* Hardware retriggerable one-shot */ + I8254_MODE2 = (2 << 1), /* Rate generator */ + I8254_MODE3 = (3 << 1), /* Square wave mode */ + I8254_MODE4 = (4 << 1), /* Software triggered strobe */ + I8254_MODE5 = (5 << 1), /* Hardware triggered strobe + * (retriggerable) */ + I8254_BCD = 1, /* use binary-coded decimal instead of binary * (pretty useless) */ - I8254_BINARY = 0 - }; - - static inline unsigned NI_USUAL_PFI_SELECT(unsigned pfi_channel) - { - if (pfi_channel < 10) - return 0x1 + pfi_channel; - else - return 0xb + pfi_channel; - } - - static inline unsigned NI_USUAL_RTSI_SELECT(unsigned rtsi_channel) - { - if (rtsi_channel < 7) - return 0xb + rtsi_channel; - else - return 0x1b; - } + I8254_BINARY = 0 +}; + +static inline unsigned NI_USUAL_PFI_SELECT(unsigned pfi_channel) +{ + if (pfi_channel < 10) + return 0x1 + pfi_channel; + else + return 0xb + pfi_channel; +} + +static inline unsigned NI_USUAL_RTSI_SELECT(unsigned rtsi_channel) +{ + if (rtsi_channel < 7) + return 0xb + rtsi_channel; + else + return 0x1b; +} /* mode bits for NI general-purpose counters, set with * INSN_CONFIG_SET_COUNTER_MODE */ #define NI_GPCT_COUNTING_MODE_SHIFT 16 #define NI_GPCT_INDEX_PHASE_BITSHIFT 20 #define NI_GPCT_COUNTING_DIRECTION_SHIFT 24 - enum ni_gpct_mode_bits { - NI_GPCT_GATE_ON_BOTH_EDGES_BIT = 0x4, - NI_GPCT_EDGE_GATE_MODE_MASK = 0x18, - NI_GPCT_EDGE_GATE_STARTS_STOPS_BITS = 0x0, - NI_GPCT_EDGE_GATE_STOPS_STARTS_BITS = 0x8, - NI_GPCT_EDGE_GATE_STARTS_BITS = 0x10, - NI_GPCT_EDGE_GATE_NO_STARTS_NO_STOPS_BITS = 0x18, - NI_GPCT_STOP_MODE_MASK = 0x60, - NI_GPCT_STOP_ON_GATE_BITS = 0x00, - NI_GPCT_STOP_ON_GATE_OR_TC_BITS = 0x20, - NI_GPCT_STOP_ON_GATE_OR_SECOND_TC_BITS = 0x40, - NI_GPCT_LOAD_B_SELECT_BIT = 0x80, - NI_GPCT_OUTPUT_MODE_MASK = 0x300, - NI_GPCT_OUTPUT_TC_PULSE_BITS = 0x100, - NI_GPCT_OUTPUT_TC_TOGGLE_BITS = 0x200, - NI_GPCT_OUTPUT_TC_OR_GATE_TOGGLE_BITS = 0x300, - NI_GPCT_HARDWARE_DISARM_MASK = 0xc00, - NI_GPCT_NO_HARDWARE_DISARM_BITS = 0x000, - NI_GPCT_DISARM_AT_TC_BITS = 0x400, - NI_GPCT_DISARM_AT_GATE_BITS = 0x800, - NI_GPCT_DISARM_AT_TC_OR_GATE_BITS = 0xc00, - NI_GPCT_LOADING_ON_TC_BIT = 0x1000, - NI_GPCT_LOADING_ON_GATE_BIT = 0x4000, - NI_GPCT_COUNTING_MODE_MASK = 0x7 << NI_GPCT_COUNTING_MODE_SHIFT, - NI_GPCT_COUNTING_MODE_NORMAL_BITS = - 0x0 << NI_GPCT_COUNTING_MODE_SHIFT, - NI_GPCT_COUNTING_MODE_QUADRATURE_X1_BITS = - 0x1 << NI_GPCT_COUNTING_MODE_SHIFT, - NI_GPCT_COUNTING_MODE_QUADRATURE_X2_BITS = - 0x2 << NI_GPCT_COUNTING_MODE_SHIFT, - NI_GPCT_COUNTING_MODE_QUADRATURE_X4_BITS = - 0x3 << NI_GPCT_COUNTING_MODE_SHIFT, - NI_GPCT_COUNTING_MODE_TWO_PULSE_BITS = - 0x4 << NI_GPCT_COUNTING_MODE_SHIFT, - NI_GPCT_COUNTING_MODE_SYNC_SOURCE_BITS = - 0x6 << NI_GPCT_COUNTING_MODE_SHIFT, - NI_GPCT_INDEX_PHASE_MASK = 0x3 << NI_GPCT_INDEX_PHASE_BITSHIFT, - NI_GPCT_INDEX_PHASE_LOW_A_LOW_B_BITS = - 0x0 << NI_GPCT_INDEX_PHASE_BITSHIFT, - NI_GPCT_INDEX_PHASE_LOW_A_HIGH_B_BITS = - 0x1 << NI_GPCT_INDEX_PHASE_BITSHIFT, - NI_GPCT_INDEX_PHASE_HIGH_A_LOW_B_BITS = - 0x2 << NI_GPCT_INDEX_PHASE_BITSHIFT, - NI_GPCT_INDEX_PHASE_HIGH_A_HIGH_B_BITS = - 0x3 << NI_GPCT_INDEX_PHASE_BITSHIFT, - NI_GPCT_INDEX_ENABLE_BIT = 0x400000, - NI_GPCT_COUNTING_DIRECTION_MASK = - 0x3 << NI_GPCT_COUNTING_DIRECTION_SHIFT, - NI_GPCT_COUNTING_DIRECTION_DOWN_BITS = - 0x00 << NI_GPCT_COUNTING_DIRECTION_SHIFT, - NI_GPCT_COUNTING_DIRECTION_UP_BITS = - 0x1 << NI_GPCT_COUNTING_DIRECTION_SHIFT, - NI_GPCT_COUNTING_DIRECTION_HW_UP_DOWN_BITS = - 0x2 << NI_GPCT_COUNTING_DIRECTION_SHIFT, - NI_GPCT_COUNTING_DIRECTION_HW_GATE_BITS = - 0x3 << NI_GPCT_COUNTING_DIRECTION_SHIFT, - NI_GPCT_RELOAD_SOURCE_MASK = 0xc000000, - NI_GPCT_RELOAD_SOURCE_FIXED_BITS = 0x0, - NI_GPCT_RELOAD_SOURCE_SWITCHING_BITS = 0x4000000, - NI_GPCT_RELOAD_SOURCE_GATE_SELECT_BITS = 0x8000000, - NI_GPCT_OR_GATE_BIT = 0x10000000, - NI_GPCT_INVERT_OUTPUT_BIT = 0x20000000 - }; +enum ni_gpct_mode_bits { + NI_GPCT_GATE_ON_BOTH_EDGES_BIT = 0x4, + NI_GPCT_EDGE_GATE_MODE_MASK = 0x18, + NI_GPCT_EDGE_GATE_STARTS_STOPS_BITS = 0x0, + NI_GPCT_EDGE_GATE_STOPS_STARTS_BITS = 0x8, + NI_GPCT_EDGE_GATE_STARTS_BITS = 0x10, + NI_GPCT_EDGE_GATE_NO_STARTS_NO_STOPS_BITS = 0x18, + NI_GPCT_STOP_MODE_MASK = 0x60, + NI_GPCT_STOP_ON_GATE_BITS = 0x00, + NI_GPCT_STOP_ON_GATE_OR_TC_BITS = 0x20, + NI_GPCT_STOP_ON_GATE_OR_SECOND_TC_BITS = 0x40, + NI_GPCT_LOAD_B_SELECT_BIT = 0x80, + NI_GPCT_OUTPUT_MODE_MASK = 0x300, + NI_GPCT_OUTPUT_TC_PULSE_BITS = 0x100, + NI_GPCT_OUTPUT_TC_TOGGLE_BITS = 0x200, + NI_GPCT_OUTPUT_TC_OR_GATE_TOGGLE_BITS = 0x300, + NI_GPCT_HARDWARE_DISARM_MASK = 0xc00, + NI_GPCT_NO_HARDWARE_DISARM_BITS = 0x000, + NI_GPCT_DISARM_AT_TC_BITS = 0x400, + NI_GPCT_DISARM_AT_GATE_BITS = 0x800, + NI_GPCT_DISARM_AT_TC_OR_GATE_BITS = 0xc00, + NI_GPCT_LOADING_ON_TC_BIT = 0x1000, + NI_GPCT_LOADING_ON_GATE_BIT = 0x4000, + NI_GPCT_COUNTING_MODE_MASK = 0x7 << NI_GPCT_COUNTING_MODE_SHIFT, + NI_GPCT_COUNTING_MODE_NORMAL_BITS = + 0x0 << NI_GPCT_COUNTING_MODE_SHIFT, + NI_GPCT_COUNTING_MODE_QUADRATURE_X1_BITS = + 0x1 << NI_GPCT_COUNTING_MODE_SHIFT, + NI_GPCT_COUNTING_MODE_QUADRATURE_X2_BITS = + 0x2 << NI_GPCT_COUNTING_MODE_SHIFT, + NI_GPCT_COUNTING_MODE_QUADRATURE_X4_BITS = + 0x3 << NI_GPCT_COUNTING_MODE_SHIFT, + NI_GPCT_COUNTING_MODE_TWO_PULSE_BITS = + 0x4 << NI_GPCT_COUNTING_MODE_SHIFT, + NI_GPCT_COUNTING_MODE_SYNC_SOURCE_BITS = + 0x6 << NI_GPCT_COUNTING_MODE_SHIFT, + NI_GPCT_INDEX_PHASE_MASK = 0x3 << NI_GPCT_INDEX_PHASE_BITSHIFT, + NI_GPCT_INDEX_PHASE_LOW_A_LOW_B_BITS = + 0x0 << NI_GPCT_INDEX_PHASE_BITSHIFT, + NI_GPCT_INDEX_PHASE_LOW_A_HIGH_B_BITS = + 0x1 << NI_GPCT_INDEX_PHASE_BITSHIFT, + NI_GPCT_INDEX_PHASE_HIGH_A_LOW_B_BITS = + 0x2 << NI_GPCT_INDEX_PHASE_BITSHIFT, + NI_GPCT_INDEX_PHASE_HIGH_A_HIGH_B_BITS = + 0x3 << NI_GPCT_INDEX_PHASE_BITSHIFT, + NI_GPCT_INDEX_ENABLE_BIT = 0x400000, + NI_GPCT_COUNTING_DIRECTION_MASK = + 0x3 << NI_GPCT_COUNTING_DIRECTION_SHIFT, + NI_GPCT_COUNTING_DIRECTION_DOWN_BITS = + 0x00 << NI_GPCT_COUNTING_DIRECTION_SHIFT, + NI_GPCT_COUNTING_DIRECTION_UP_BITS = + 0x1 << NI_GPCT_COUNTING_DIRECTION_SHIFT, + NI_GPCT_COUNTING_DIRECTION_HW_UP_DOWN_BITS = + 0x2 << NI_GPCT_COUNTING_DIRECTION_SHIFT, + NI_GPCT_COUNTING_DIRECTION_HW_GATE_BITS = + 0x3 << NI_GPCT_COUNTING_DIRECTION_SHIFT, + NI_GPCT_RELOAD_SOURCE_MASK = 0xc000000, + NI_GPCT_RELOAD_SOURCE_FIXED_BITS = 0x0, + NI_GPCT_RELOAD_SOURCE_SWITCHING_BITS = 0x4000000, + NI_GPCT_RELOAD_SOURCE_GATE_SELECT_BITS = 0x8000000, + NI_GPCT_OR_GATE_BIT = 0x10000000, + NI_GPCT_INVERT_OUTPUT_BIT = 0x20000000 +}; /* Bits for setting a clock source with * INSN_CONFIG_SET_CLOCK_SRC when using NI general-purpose counters. */ - enum ni_gpct_clock_source_bits { - NI_GPCT_CLOCK_SRC_SELECT_MASK = 0x3f, - NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS = 0x0, - NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS = 0x1, - NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS = 0x2, - NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS = 0x3, - NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS = 0x4, - NI_GPCT_NEXT_TC_CLOCK_SRC_BITS = 0x5, - /* NI 660x-specific */ - NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS = 0x6, - NI_GPCT_PXI10_CLOCK_SRC_BITS = 0x7, - NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS = 0x8, - NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS = 0x9, - NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK = 0x30000000, - NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS = 0x0, - /* divide source by 2 */ - NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS = 0x10000000, - /* divide source by 8 */ - NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS = 0x20000000, - NI_GPCT_INVERT_CLOCK_SRC_BIT = 0x80000000 - }; - static inline unsigned NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(unsigned n) - { - /* NI 660x-specific */ - return 0x10 + n; - } - static inline unsigned NI_GPCT_RTSI_CLOCK_SRC_BITS(unsigned n) - { - return 0x18 + n; - } - static inline unsigned NI_GPCT_PFI_CLOCK_SRC_BITS(unsigned n) - { - /* no pfi on NI 660x */ - return 0x20 + n; - } +enum ni_gpct_clock_source_bits { + NI_GPCT_CLOCK_SRC_SELECT_MASK = 0x3f, + NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS = 0x0, + NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS = 0x1, + NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS = 0x2, + NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS = 0x3, + NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS = 0x4, + NI_GPCT_NEXT_TC_CLOCK_SRC_BITS = 0x5, + /* NI 660x-specific */ + NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS = 0x6, + NI_GPCT_PXI10_CLOCK_SRC_BITS = 0x7, + NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS = 0x8, + NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS = 0x9, + NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK = 0x30000000, + NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS = 0x0, + /* divide source by 2 */ + NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS = 0x10000000, + /* divide source by 8 */ + NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS = 0x20000000, + NI_GPCT_INVERT_CLOCK_SRC_BIT = 0x80000000 +}; +static inline unsigned NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(unsigned n) +{ + /* NI 660x-specific */ + return 0x10 + n; +} +static inline unsigned NI_GPCT_RTSI_CLOCK_SRC_BITS(unsigned n) +{ + return 0x18 + n; +} +static inline unsigned NI_GPCT_PFI_CLOCK_SRC_BITS(unsigned n) +{ + /* no pfi on NI 660x */ + return 0x20 + n; +} /* Possibilities for setting a gate source with INSN_CONFIG_SET_GATE_SRC when using NI general-purpose counters. May be bitwise-or'd with CR_EDGE or CR_INVERT. */ - enum ni_gpct_gate_select { - /* m-series gates */ - NI_GPCT_TIMESTAMP_MUX_GATE_SELECT = 0x0, - NI_GPCT_AI_START2_GATE_SELECT = 0x12, - NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT = 0x13, - NI_GPCT_NEXT_OUT_GATE_SELECT = 0x14, - NI_GPCT_AI_START1_GATE_SELECT = 0x1c, - NI_GPCT_NEXT_SOURCE_GATE_SELECT = 0x1d, - NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT = 0x1e, - NI_GPCT_LOGIC_LOW_GATE_SELECT = 0x1f, - /* more gates for 660x */ - NI_GPCT_SOURCE_PIN_i_GATE_SELECT = 0x100, - NI_GPCT_GATE_PIN_i_GATE_SELECT = 0x101, - /* more gates for 660x "second gate" */ - NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT = 0x201, - NI_GPCT_SELECTED_GATE_GATE_SELECT = 0x21e, - /* m-series "second gate" sources are unknown, - * we should add them here with an offset of 0x300 when - * known. */ - NI_GPCT_DISABLED_GATE_SELECT = 0x8000, - }; - static inline unsigned NI_GPCT_GATE_PIN_GATE_SELECT(unsigned n) - { - return 0x102 + n; - } - static inline unsigned NI_GPCT_RTSI_GATE_SELECT(unsigned n) - { - return NI_USUAL_RTSI_SELECT(n); - } - static inline unsigned NI_GPCT_PFI_GATE_SELECT(unsigned n) - { - return NI_USUAL_PFI_SELECT(n); - } - static inline unsigned NI_GPCT_UP_DOWN_PIN_GATE_SELECT(unsigned n) - { - return 0x202 + n; - } +enum ni_gpct_gate_select { + /* m-series gates */ + NI_GPCT_TIMESTAMP_MUX_GATE_SELECT = 0x0, + NI_GPCT_AI_START2_GATE_SELECT = 0x12, + NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT = 0x13, + NI_GPCT_NEXT_OUT_GATE_SELECT = 0x14, + NI_GPCT_AI_START1_GATE_SELECT = 0x1c, + NI_GPCT_NEXT_SOURCE_GATE_SELECT = 0x1d, + NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT = 0x1e, + NI_GPCT_LOGIC_LOW_GATE_SELECT = 0x1f, + /* more gates for 660x */ + NI_GPCT_SOURCE_PIN_i_GATE_SELECT = 0x100, + NI_GPCT_GATE_PIN_i_GATE_SELECT = 0x101, + /* more gates for 660x "second gate" */ + NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT = 0x201, + NI_GPCT_SELECTED_GATE_GATE_SELECT = 0x21e, + /* m-series "second gate" sources are unknown, + * we should add them here with an offset of 0x300 when + * known. */ + NI_GPCT_DISABLED_GATE_SELECT = 0x8000, +}; +static inline unsigned NI_GPCT_GATE_PIN_GATE_SELECT(unsigned n) +{ + return 0x102 + n; +} +static inline unsigned NI_GPCT_RTSI_GATE_SELECT(unsigned n) +{ + return NI_USUAL_RTSI_SELECT(n); +} +static inline unsigned NI_GPCT_PFI_GATE_SELECT(unsigned n) +{ + return NI_USUAL_PFI_SELECT(n); +} +static inline unsigned NI_GPCT_UP_DOWN_PIN_GATE_SELECT(unsigned n) +{ + return 0x202 + n; +} /* Possibilities for setting a source with INSN_CONFIG_SET_OTHER_SRC when using NI general-purpose counters. */ - enum ni_gpct_other_index { - NI_GPCT_SOURCE_ENCODER_A, - NI_GPCT_SOURCE_ENCODER_B, - NI_GPCT_SOURCE_ENCODER_Z - }; - enum ni_gpct_other_select { - /* m-series gates */ - /* Still unknown, probably only need NI_GPCT_PFI_OTHER_SELECT */ - NI_GPCT_DISABLED_OTHER_SELECT = 0x8000, - }; - static inline unsigned NI_GPCT_PFI_OTHER_SELECT(unsigned n) - { - return NI_USUAL_PFI_SELECT(n); - } +enum ni_gpct_other_index { + NI_GPCT_SOURCE_ENCODER_A, + NI_GPCT_SOURCE_ENCODER_B, + NI_GPCT_SOURCE_ENCODER_Z +}; +enum ni_gpct_other_select { + /* m-series gates */ + /* Still unknown, probably only need NI_GPCT_PFI_OTHER_SELECT */ + NI_GPCT_DISABLED_OTHER_SELECT = 0x8000, +}; +static inline unsigned NI_GPCT_PFI_OTHER_SELECT(unsigned n) +{ + return NI_USUAL_PFI_SELECT(n); +} /* start sources for ni general-purpose counters for use with INSN_CONFIG_ARM */ - enum ni_gpct_arm_source { - NI_GPCT_ARM_IMMEDIATE = 0x0, - NI_GPCT_ARM_PAIRED_IMMEDIATE = 0x1, /* Start both the counter - * and the adjacent paired - * counter simultaneously */ - /* NI doesn't document bits for selecting hardware arm triggers. - * If the NI_GPCT_ARM_UNKNOWN bit is set, we will pass the least - * significant bits (3 bits for 660x or 5 bits for m-series) - * through to the hardware. This will at least allow someone to - * figure out what the bits do later. */ - NI_GPCT_ARM_UNKNOWN = 0x1000, - }; +enum ni_gpct_arm_source { + NI_GPCT_ARM_IMMEDIATE = 0x0, + NI_GPCT_ARM_PAIRED_IMMEDIATE = 0x1, /* Start both the counter + * and the adjacent paired + * counter simultaneously */ + /* NI doesn't document bits for selecting hardware arm triggers. + * If the NI_GPCT_ARM_UNKNOWN bit is set, we will pass the least + * significant bits (3 bits for 660x or 5 bits for m-series) + * through to the hardware. This will at least allow someone to + * figure out what the bits do later. */ + NI_GPCT_ARM_UNKNOWN = 0x1000, +}; /* digital filtering options for ni 660x for use with INSN_CONFIG_FILTER. */ - enum ni_gpct_filter_select { - NI_GPCT_FILTER_OFF = 0x0, - NI_GPCT_FILTER_TIMEBASE_3_SYNC = 0x1, - NI_GPCT_FILTER_100x_TIMEBASE_1 = 0x2, - NI_GPCT_FILTER_20x_TIMEBASE_1 = 0x3, - NI_GPCT_FILTER_10x_TIMEBASE_1 = 0x4, - NI_GPCT_FILTER_2x_TIMEBASE_1 = 0x5, - NI_GPCT_FILTER_2x_TIMEBASE_3 = 0x6 - }; +enum ni_gpct_filter_select { + NI_GPCT_FILTER_OFF = 0x0, + NI_GPCT_FILTER_TIMEBASE_3_SYNC = 0x1, + NI_GPCT_FILTER_100x_TIMEBASE_1 = 0x2, + NI_GPCT_FILTER_20x_TIMEBASE_1 = 0x3, + NI_GPCT_FILTER_10x_TIMEBASE_1 = 0x4, + NI_GPCT_FILTER_2x_TIMEBASE_1 = 0x5, + NI_GPCT_FILTER_2x_TIMEBASE_3 = 0x6 +}; /* PFI digital filtering options for ni m-series for use with * INSN_CONFIG_FILTER. */ - enum ni_pfi_filter_select { - NI_PFI_FILTER_OFF = 0x0, - NI_PFI_FILTER_125ns = 0x1, - NI_PFI_FILTER_6425ns = 0x2, - NI_PFI_FILTER_2550us = 0x3 - }; +enum ni_pfi_filter_select { + NI_PFI_FILTER_OFF = 0x0, + NI_PFI_FILTER_125ns = 0x1, + NI_PFI_FILTER_6425ns = 0x2, + NI_PFI_FILTER_2550us = 0x3 +}; /* master clock sources for ni mio boards and INSN_CONFIG_SET_CLOCK_SRC */ - enum ni_mio_clock_source { - NI_MIO_INTERNAL_CLOCK = 0, - NI_MIO_RTSI_CLOCK = 1, /* doesn't work for m-series, use - NI_MIO_PLL_RTSI_CLOCK() */ - /* the NI_MIO_PLL_* sources are m-series only */ - NI_MIO_PLL_PXI_STAR_TRIGGER_CLOCK = 2, - NI_MIO_PLL_PXI10_CLOCK = 3, - NI_MIO_PLL_RTSI0_CLOCK = 4 - }; - static inline unsigned NI_MIO_PLL_RTSI_CLOCK(unsigned rtsi_channel) - { - return NI_MIO_PLL_RTSI0_CLOCK + rtsi_channel; - } +enum ni_mio_clock_source { + NI_MIO_INTERNAL_CLOCK = 0, + NI_MIO_RTSI_CLOCK = 1, /* doesn't work for m-series, use + NI_MIO_PLL_RTSI_CLOCK() */ + /* the NI_MIO_PLL_* sources are m-series only */ + NI_MIO_PLL_PXI_STAR_TRIGGER_CLOCK = 2, + NI_MIO_PLL_PXI10_CLOCK = 3, + NI_MIO_PLL_RTSI0_CLOCK = 4 +}; +static inline unsigned NI_MIO_PLL_RTSI_CLOCK(unsigned rtsi_channel) +{ + return NI_MIO_PLL_RTSI0_CLOCK + rtsi_channel; +} /* Signals which can be routed to an NI RTSI pin with INSN_CONFIG_SET_ROUTING. The numbers assigned are not arbitrary, they correspond to the bits required to program the board. */ - enum ni_rtsi_routing { - NI_RTSI_OUTPUT_ADR_START1 = 0, - NI_RTSI_OUTPUT_ADR_START2 = 1, - NI_RTSI_OUTPUT_SCLKG = 2, - NI_RTSI_OUTPUT_DACUPDN = 3, - NI_RTSI_OUTPUT_DA_START1 = 4, - NI_RTSI_OUTPUT_G_SRC0 = 5, - NI_RTSI_OUTPUT_G_GATE0 = 6, - NI_RTSI_OUTPUT_RGOUT0 = 7, - NI_RTSI_OUTPUT_RTSI_BRD_0 = 8, - NI_RTSI_OUTPUT_RTSI_OSC = 12 /* pre-m-series always have RTSI - * clock on line 7 */ - }; - static inline unsigned NI_RTSI_OUTPUT_RTSI_BRD(unsigned n) - { - return NI_RTSI_OUTPUT_RTSI_BRD_0 + n; - } +enum ni_rtsi_routing { + NI_RTSI_OUTPUT_ADR_START1 = 0, + NI_RTSI_OUTPUT_ADR_START2 = 1, + NI_RTSI_OUTPUT_SCLKG = 2, + NI_RTSI_OUTPUT_DACUPDN = 3, + NI_RTSI_OUTPUT_DA_START1 = 4, + NI_RTSI_OUTPUT_G_SRC0 = 5, + NI_RTSI_OUTPUT_G_GATE0 = 6, + NI_RTSI_OUTPUT_RGOUT0 = 7, + NI_RTSI_OUTPUT_RTSI_BRD_0 = 8, + NI_RTSI_OUTPUT_RTSI_OSC = 12 /* pre-m-series always have RTSI + * clock on line 7 */ +}; +static inline unsigned NI_RTSI_OUTPUT_RTSI_BRD(unsigned n) +{ + return NI_RTSI_OUTPUT_RTSI_BRD_0 + n; +} /* Signals which can be routed to an NI PFI pin on an m-series board with * INSN_CONFIG_SET_ROUTING. These numbers are also returned by * INSN_CONFIG_GET_ROUTING on pre-m-series boards, even though their routing * cannot be changed. The numbers assigned are not arbitrary, they correspond * to the bits required to program the board. */ - enum ni_pfi_routing { - NI_PFI_OUTPUT_PFI_DEFAULT = 0, - NI_PFI_OUTPUT_AI_START1 = 1, - NI_PFI_OUTPUT_AI_START2 = 2, - NI_PFI_OUTPUT_AI_CONVERT = 3, - NI_PFI_OUTPUT_G_SRC1 = 4, - NI_PFI_OUTPUT_G_GATE1 = 5, - NI_PFI_OUTPUT_AO_UPDATE_N = 6, - NI_PFI_OUTPUT_AO_START1 = 7, - NI_PFI_OUTPUT_AI_START_PULSE = 8, - NI_PFI_OUTPUT_G_SRC0 = 9, - NI_PFI_OUTPUT_G_GATE0 = 10, - NI_PFI_OUTPUT_EXT_STROBE = 11, - NI_PFI_OUTPUT_AI_EXT_MUX_CLK = 12, - NI_PFI_OUTPUT_GOUT0 = 13, - NI_PFI_OUTPUT_GOUT1 = 14, - NI_PFI_OUTPUT_FREQ_OUT = 15, - NI_PFI_OUTPUT_PFI_DO = 16, - NI_PFI_OUTPUT_I_ATRIG = 17, - NI_PFI_OUTPUT_RTSI0 = 18, - NI_PFI_OUTPUT_PXI_STAR_TRIGGER_IN = 26, - NI_PFI_OUTPUT_SCXI_TRIG1 = 27, - NI_PFI_OUTPUT_DIO_CHANGE_DETECT_RTSI = 28, - NI_PFI_OUTPUT_CDI_SAMPLE = 29, - NI_PFI_OUTPUT_CDO_UPDATE = 30 - }; - static inline unsigned NI_PFI_OUTPUT_RTSI(unsigned rtsi_channel) - { - return NI_PFI_OUTPUT_RTSI0 + rtsi_channel; - } +enum ni_pfi_routing { + NI_PFI_OUTPUT_PFI_DEFAULT = 0, + NI_PFI_OUTPUT_AI_START1 = 1, + NI_PFI_OUTPUT_AI_START2 = 2, + NI_PFI_OUTPUT_AI_CONVERT = 3, + NI_PFI_OUTPUT_G_SRC1 = 4, + NI_PFI_OUTPUT_G_GATE1 = 5, + NI_PFI_OUTPUT_AO_UPDATE_N = 6, + NI_PFI_OUTPUT_AO_START1 = 7, + NI_PFI_OUTPUT_AI_START_PULSE = 8, + NI_PFI_OUTPUT_G_SRC0 = 9, + NI_PFI_OUTPUT_G_GATE0 = 10, + NI_PFI_OUTPUT_EXT_STROBE = 11, + NI_PFI_OUTPUT_AI_EXT_MUX_CLK = 12, + NI_PFI_OUTPUT_GOUT0 = 13, + NI_PFI_OUTPUT_GOUT1 = 14, + NI_PFI_OUTPUT_FREQ_OUT = 15, + NI_PFI_OUTPUT_PFI_DO = 16, + NI_PFI_OUTPUT_I_ATRIG = 17, + NI_PFI_OUTPUT_RTSI0 = 18, + NI_PFI_OUTPUT_PXI_STAR_TRIGGER_IN = 26, + NI_PFI_OUTPUT_SCXI_TRIG1 = 27, + NI_PFI_OUTPUT_DIO_CHANGE_DETECT_RTSI = 28, + NI_PFI_OUTPUT_CDI_SAMPLE = 29, + NI_PFI_OUTPUT_CDO_UPDATE = 30 +}; +static inline unsigned NI_PFI_OUTPUT_RTSI(unsigned rtsi_channel) +{ + return NI_PFI_OUTPUT_RTSI0 + rtsi_channel; +} /* Signals which can be routed to output on a NI PFI pin on a 660x board with INSN_CONFIG_SET_ROUTING. The numbers assigned are @@ -802,113 +802,112 @@ INSN_CONFIG_ARM */ to program the board. Lines 0 to 7 can only be set to NI_660X_PFI_OUTPUT_DIO. Lines 32 to 39 can only be set to NI_660X_PFI_OUTPUT_COUNTER. */ - enum ni_660x_pfi_routing { - NI_660X_PFI_OUTPUT_COUNTER = 1, /* counter */ - NI_660X_PFI_OUTPUT_DIO = 2, /* static digital output */ - }; +enum ni_660x_pfi_routing { + NI_660X_PFI_OUTPUT_COUNTER = 1, /* counter */ + NI_660X_PFI_OUTPUT_DIO = 2, /* static digital output */ +}; /* NI External Trigger lines. These values are not arbitrary, but are related * to the bits required to program the board (offset by 1 for historical * reasons). */ - static inline unsigned NI_EXT_PFI(unsigned pfi_channel) - { - return NI_USUAL_PFI_SELECT(pfi_channel) - 1; - } - static inline unsigned NI_EXT_RTSI(unsigned rtsi_channel) - { - return NI_USUAL_RTSI_SELECT(rtsi_channel) - 1; - } +static inline unsigned NI_EXT_PFI(unsigned pfi_channel) +{ + return NI_USUAL_PFI_SELECT(pfi_channel) - 1; +} +static inline unsigned NI_EXT_RTSI(unsigned rtsi_channel) +{ + return NI_USUAL_RTSI_SELECT(rtsi_channel) - 1; +} /* status bits for INSN_CONFIG_GET_COUNTER_STATUS */ - enum comedi_counter_status_flags { - COMEDI_COUNTER_ARMED = 0x1, - COMEDI_COUNTER_COUNTING = 0x2, - COMEDI_COUNTER_TERMINAL_COUNT = 0x4, - }; +enum comedi_counter_status_flags { + COMEDI_COUNTER_ARMED = 0x1, + COMEDI_COUNTER_COUNTING = 0x2, + COMEDI_COUNTER_TERMINAL_COUNT = 0x4, +}; /* Clock sources for CDIO subdevice on NI m-series boards. Used as the * scan_begin_arg for a comedi_command. These sources may also be bitwise-or'd * with CR_INVERT to change polarity. */ - enum ni_m_series_cdio_scan_begin_src { - NI_CDIO_SCAN_BEGIN_SRC_GROUND = 0, - NI_CDIO_SCAN_BEGIN_SRC_AI_START = 18, - NI_CDIO_SCAN_BEGIN_SRC_AI_CONVERT = 19, - NI_CDIO_SCAN_BEGIN_SRC_PXI_STAR_TRIGGER = 20, - NI_CDIO_SCAN_BEGIN_SRC_G0_OUT = 28, - NI_CDIO_SCAN_BEGIN_SRC_G1_OUT = 29, - NI_CDIO_SCAN_BEGIN_SRC_ANALOG_TRIGGER = 30, - NI_CDIO_SCAN_BEGIN_SRC_AO_UPDATE = 31, - NI_CDIO_SCAN_BEGIN_SRC_FREQ_OUT = 32, - NI_CDIO_SCAN_BEGIN_SRC_DIO_CHANGE_DETECT_IRQ = 33 - }; - static inline unsigned NI_CDIO_SCAN_BEGIN_SRC_PFI(unsigned pfi_channel) - { - return NI_USUAL_PFI_SELECT(pfi_channel); - } - static inline unsigned - NI_CDIO_SCAN_BEGIN_SRC_RTSI(unsigned rtsi_channel) - { - return NI_USUAL_RTSI_SELECT(rtsi_channel); - } +enum ni_m_series_cdio_scan_begin_src { + NI_CDIO_SCAN_BEGIN_SRC_GROUND = 0, + NI_CDIO_SCAN_BEGIN_SRC_AI_START = 18, + NI_CDIO_SCAN_BEGIN_SRC_AI_CONVERT = 19, + NI_CDIO_SCAN_BEGIN_SRC_PXI_STAR_TRIGGER = 20, + NI_CDIO_SCAN_BEGIN_SRC_G0_OUT = 28, + NI_CDIO_SCAN_BEGIN_SRC_G1_OUT = 29, + NI_CDIO_SCAN_BEGIN_SRC_ANALOG_TRIGGER = 30, + NI_CDIO_SCAN_BEGIN_SRC_AO_UPDATE = 31, + NI_CDIO_SCAN_BEGIN_SRC_FREQ_OUT = 32, + NI_CDIO_SCAN_BEGIN_SRC_DIO_CHANGE_DETECT_IRQ = 33 +}; +static inline unsigned NI_CDIO_SCAN_BEGIN_SRC_PFI(unsigned pfi_channel) +{ + return NI_USUAL_PFI_SELECT(pfi_channel); +} +static inline unsigned NI_CDIO_SCAN_BEGIN_SRC_RTSI(unsigned rtsi_channel) +{ + return NI_USUAL_RTSI_SELECT(rtsi_channel); +} /* scan_begin_src for scan_begin_arg==TRIG_EXT with analog output command on NI * boards. These scan begin sources can also be bitwise-or'd with CR_INVERT to * change polarity. */ - static inline unsigned NI_AO_SCAN_BEGIN_SRC_PFI(unsigned pfi_channel) - { - return NI_USUAL_PFI_SELECT(pfi_channel); - } - static inline unsigned NI_AO_SCAN_BEGIN_SRC_RTSI(unsigned rtsi_channel) - { - return NI_USUAL_RTSI_SELECT(rtsi_channel); - } +static inline unsigned NI_AO_SCAN_BEGIN_SRC_PFI(unsigned pfi_channel) +{ + return NI_USUAL_PFI_SELECT(pfi_channel); +} +static inline unsigned NI_AO_SCAN_BEGIN_SRC_RTSI(unsigned rtsi_channel) +{ + return NI_USUAL_RTSI_SELECT(rtsi_channel); +} /* Bits for setting a clock source with * INSN_CONFIG_SET_CLOCK_SRC when using NI frequency output subdevice. */ - enum ni_freq_out_clock_source_bits { - NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC, /* 10 MHz */ - NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC /* 100 KHz */ - }; +enum ni_freq_out_clock_source_bits { + NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC, /* 10 MHz */ + NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC /* 100 KHz */ +}; /* Values for setting a clock source with INSN_CONFIG_SET_CLOCK_SRC for * 8254 counter subdevices on Amplicon DIO boards (amplc_dio200 driver). */ - enum amplc_dio_clock_source { - AMPLC_DIO_CLK_CLKN, /* per channel external clock - input/output pin (pin is only an - input when clock source set to this - value, otherwise it is an output) */ - AMPLC_DIO_CLK_10MHZ, /* 10 MHz internal clock */ - AMPLC_DIO_CLK_1MHZ, /* 1 MHz internal clock */ - AMPLC_DIO_CLK_100KHZ, /* 100 kHz internal clock */ - AMPLC_DIO_CLK_10KHZ, /* 10 kHz internal clock */ - AMPLC_DIO_CLK_1KHZ, /* 1 kHz internal clock */ - AMPLC_DIO_CLK_OUTNM1, /* output of preceding counter channel - (for channel 0, preceding counter - channel is channel 2 on preceding - counter subdevice, for first counter - subdevice, preceding counter - subdevice is the last counter - subdevice) */ - AMPLC_DIO_CLK_EXT /* per chip external input pin */ - }; +enum amplc_dio_clock_source { + AMPLC_DIO_CLK_CLKN, /* per channel external clock + input/output pin (pin is only an + input when clock source set to this + value, otherwise it is an output) */ + AMPLC_DIO_CLK_10MHZ, /* 10 MHz internal clock */ + AMPLC_DIO_CLK_1MHZ, /* 1 MHz internal clock */ + AMPLC_DIO_CLK_100KHZ, /* 100 kHz internal clock */ + AMPLC_DIO_CLK_10KHZ, /* 10 kHz internal clock */ + AMPLC_DIO_CLK_1KHZ, /* 1 kHz internal clock */ + AMPLC_DIO_CLK_OUTNM1, /* output of preceding counter channel + (for channel 0, preceding counter + channel is channel 2 on preceding + counter subdevice, for first counter + subdevice, preceding counter + subdevice is the last counter + subdevice) */ + AMPLC_DIO_CLK_EXT /* per chip external input pin */ +}; /* Values for setting a gate source with INSN_CONFIG_SET_GATE_SRC for * 8254 counter subdevices on Amplicon DIO boards (amplc_dio200 driver). */ - enum amplc_dio_gate_source { - AMPLC_DIO_GAT_VCC, /* internal high logic level */ - AMPLC_DIO_GAT_GND, /* internal low logic level */ - AMPLC_DIO_GAT_GATN, /* per channel external gate input */ - AMPLC_DIO_GAT_NOUTNM2, /* negated output of counter channel - minus 2 (for channels 0 or 1, - channel minus 2 is channel 1 or 2 on - the preceding counter subdevice, for - the first counter subdevice the - preceding counter subdevice is the - last counter subdevice) */ - AMPLC_DIO_GAT_RESERVED4, - AMPLC_DIO_GAT_RESERVED5, - AMPLC_DIO_GAT_RESERVED6, - AMPLC_DIO_GAT_RESERVED7 - }; +enum amplc_dio_gate_source { + AMPLC_DIO_GAT_VCC, /* internal high logic level */ + AMPLC_DIO_GAT_GND, /* internal low logic level */ + AMPLC_DIO_GAT_GATN, /* per channel external gate input */ + AMPLC_DIO_GAT_NOUTNM2, /* negated output of counter channel + minus 2 (for channels 0 or 1, + channel minus 2 is channel 1 or 2 on + the preceding counter subdevice, for + the first counter subdevice the + preceding counter subdevice is the + last counter subdevice) */ + AMPLC_DIO_GAT_RESERVED4, + AMPLC_DIO_GAT_RESERVED5, + AMPLC_DIO_GAT_RESERVED6, + AMPLC_DIO_GAT_RESERVED7 +}; #endif /* _COMEDI_H */ -- cgit v0.10.2 From 9be56c6432633b706ab4bb961997f1d851b39535 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 18 Sep 2012 11:41:04 -0700 Subject: staging: comedi: comedi.h: remove __user tag from chanlist The 'chanlist' is passed to the kernel from user space with the COMEDI_CMD and COMEDI_CMDTEST ioctls. The do_cmd_ioctl() and do_cmdtest_ioctl() functions in comedi_fops.c copy this data to/from user space to kernel space correctly. Unfortunately, this data is copied back into a struct comedi_cmd so when the cmd is passed down to the drivers they still see the pointer as __user data. This results is a number of sparse errors such as: warning: dereference of noderef expression warning: incorrect type in argument 2 (different address spaces) expected void const * got unsigned int [noderef] *chanlist warning: incorrect type in argument 3 (different address spaces) expected unsigned int *chanlist got unsigned int [noderef] *chanlist warning: incorrect type in assignment (different address spaces) expected unsigned int *ai_chanlist got unsigned int [noderef] *chanlist The two functions in comedi_fops are the only ones that need the __user tag. Remove the tag so that all the drivers see the chanlist pointer in the correct address space. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/comedi.h b/drivers/staging/comedi/comedi.h index 76cdb2c..133f013 100644 --- a/drivers/staging/comedi/comedi.h +++ b/drivers/staging/comedi/comedi.h @@ -365,7 +365,7 @@ struct comedi_cmd { unsigned int stop_src; unsigned int stop_arg; - unsigned int __user *chanlist; /* channel/range list */ + unsigned int *chanlist; /* channel/range list */ unsigned int chanlist_len; short __user *data; /* data list, size depends on subd flags */ -- cgit v0.10.2 From cbe01f723e9287adb70410b69bedfdc87cd820b4 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 18 Sep 2012 11:41:54 -0700 Subject: staging: comedi: comedi_fops: rename the __user *cmd param in do_cmd_ioctl This parameter is actually the unsigned long arg passed in the ioctl. comedi_unlocked_ioctl() casts it as a (struct comedi_cmd __user *) when calling do_cmd_ioctl(). Rename the variable to keep this clear. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 00d8d1f..04e299a 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -1131,7 +1131,7 @@ static void comedi_set_subdevice_runflags(struct comedi_subdevice *s, } static int do_cmd_ioctl(struct comedi_device *dev, - struct comedi_cmd __user *cmd, void *file) + struct comedi_cmd __user *arg, void *file) { struct comedi_cmd user_cmd; struct comedi_subdevice *s; @@ -1139,7 +1139,7 @@ static int do_cmd_ioctl(struct comedi_device *dev, int ret = 0; unsigned int __user *chanlist_saver = NULL; - if (copy_from_user(&user_cmd, cmd, sizeof(struct comedi_cmd))) { + if (copy_from_user(&user_cmd, arg, sizeof(struct comedi_cmd))) { DPRINTK("bad cmd address\n"); return -EFAULT; } @@ -1230,7 +1230,7 @@ static int do_cmd_ioctl(struct comedi_device *dev, /* restore chanlist pointer before copying back */ user_cmd.chanlist = chanlist_saver; user_cmd.data = NULL; - if (copy_to_user(cmd, &user_cmd, sizeof(struct comedi_cmd))) { + if (copy_to_user(arg, &user_cmd, sizeof(struct comedi_cmd))) { DPRINTK("fault writing cmd\n"); ret = -EFAULT; goto cleanup; -- cgit v0.10.2 From 88bc0574ba6a7cb38f4b5ea2f0e5ed9fe4ab7e27 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 18 Sep 2012 11:42:37 -0700 Subject: staging: comedi: comedi_fops: rename user_cmd in do_cmd_ioctl This local variable is used to hold the comedi_cmd that is passed to the kernel as the argument to the COMEDI_CMD ioctl. Its filled in with a copy_from_user() call. The name 'user_cmd' is a bit confusing since it's actually kernel data. Rename the local variable to 'cmd' to avoid the confusion. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 04e299a..a240e66 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -1133,35 +1133,35 @@ static void comedi_set_subdevice_runflags(struct comedi_subdevice *s, static int do_cmd_ioctl(struct comedi_device *dev, struct comedi_cmd __user *arg, void *file) { - struct comedi_cmd user_cmd; + struct comedi_cmd cmd; struct comedi_subdevice *s; struct comedi_async *async; int ret = 0; unsigned int __user *chanlist_saver = NULL; - if (copy_from_user(&user_cmd, arg, sizeof(struct comedi_cmd))) { + if (copy_from_user(&cmd, arg, sizeof(struct comedi_cmd))) { DPRINTK("bad cmd address\n"); return -EFAULT; } /* save user's chanlist pointer so it can be restored later */ - chanlist_saver = user_cmd.chanlist; + chanlist_saver = cmd.chanlist; - if (user_cmd.subdev >= dev->n_subdevices) { - DPRINTK("%d no such subdevice\n", user_cmd.subdev); + if (cmd.subdev >= dev->n_subdevices) { + DPRINTK("%d no such subdevice\n", cmd.subdev); return -ENODEV; } - s = &dev->subdevices[user_cmd.subdev]; + s = &dev->subdevices[cmd.subdev]; async = s->async; if (s->type == COMEDI_SUBD_UNUSED) { - DPRINTK("%d not valid subdevice\n", user_cmd.subdev); + DPRINTK("%d not valid subdevice\n", cmd.subdev); return -EIO; } if (!s->do_cmd || !s->do_cmdtest || !s->async) { DPRINTK("subdevice %i does not support commands\n", - user_cmd.subdev); + cmd.subdev); return -EIO; } @@ -1179,23 +1179,23 @@ static int do_cmd_ioctl(struct comedi_device *dev, s->busy = file; /* make sure channel/gain list isn't too long */ - if (user_cmd.chanlist_len > s->len_chanlist) { + if (cmd.chanlist_len > s->len_chanlist) { DPRINTK("channel/gain list too long %u > %d\n", - user_cmd.chanlist_len, s->len_chanlist); + cmd.chanlist_len, s->len_chanlist); ret = -EINVAL; goto cleanup; } /* make sure channel/gain list isn't too short */ - if (user_cmd.chanlist_len < 1) { + if (cmd.chanlist_len < 1) { DPRINTK("channel/gain list too short %u < 1\n", - user_cmd.chanlist_len); + cmd.chanlist_len); ret = -EINVAL; goto cleanup; } kfree(async->cmd.chanlist); - async->cmd = user_cmd; + async->cmd = cmd; async->cmd.data = NULL; /* load channel/gain list */ async->cmd.chanlist = @@ -1206,7 +1206,7 @@ static int do_cmd_ioctl(struct comedi_device *dev, goto cleanup; } - if (copy_from_user(async->cmd.chanlist, user_cmd.chanlist, + if (copy_from_user(async->cmd.chanlist, cmd.chanlist, async->cmd.chanlist_len * sizeof(int))) { DPRINTK("fault reading chanlist\n"); ret = -EFAULT; @@ -1226,11 +1226,11 @@ static int do_cmd_ioctl(struct comedi_device *dev, if (async->cmd.flags & TRIG_BOGUS || ret) { DPRINTK("test returned %d\n", ret); - user_cmd = async->cmd; + cmd = async->cmd; /* restore chanlist pointer before copying back */ - user_cmd.chanlist = chanlist_saver; - user_cmd.data = NULL; - if (copy_to_user(arg, &user_cmd, sizeof(struct comedi_cmd))) { + cmd.chanlist = chanlist_saver; + cmd.data = NULL; + if (copy_to_user(arg, &cmd, sizeof(struct comedi_cmd))) { DPRINTK("fault writing cmd\n"); ret = -EFAULT; goto cleanup; -- cgit v0.10.2 From f8348677b1fffff801d5323db7ccadfdb2b290d0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 18 Sep 2012 11:43:13 -0700 Subject: staging: comedi: comedi_fops: rename user_cmd in do_cmdtest_ioctl This local variable is used to hold the comedi_cmd that is passed to the kernel as the argument to the COMEDI_CMDTEST ioctl. Its filled in with a copy_from_user() call. The name 'user_cmd' is a bit confusing since it's actually kernel data. Rename the local variable to 'cmd' to avoid the confusion. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index a240e66..df627c8 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -1283,77 +1283,77 @@ cleanup: static int do_cmdtest_ioctl(struct comedi_device *dev, struct comedi_cmd __user *arg, void *file) { - struct comedi_cmd user_cmd; + struct comedi_cmd cmd; struct comedi_subdevice *s; int ret = 0; unsigned int *chanlist = NULL; unsigned int __user *chanlist_saver = NULL; - if (copy_from_user(&user_cmd, arg, sizeof(struct comedi_cmd))) { + if (copy_from_user(&cmd, arg, sizeof(struct comedi_cmd))) { DPRINTK("bad cmd address\n"); return -EFAULT; } /* save user's chanlist pointer so it can be restored later */ - chanlist_saver = user_cmd.chanlist; + chanlist_saver = cmd.chanlist; - if (user_cmd.subdev >= dev->n_subdevices) { - DPRINTK("%d no such subdevice\n", user_cmd.subdev); + if (cmd.subdev >= dev->n_subdevices) { + DPRINTK("%d no such subdevice\n", cmd.subdev); return -ENODEV; } - s = &dev->subdevices[user_cmd.subdev]; + s = &dev->subdevices[cmd.subdev]; if (s->type == COMEDI_SUBD_UNUSED) { - DPRINTK("%d not valid subdevice\n", user_cmd.subdev); + DPRINTK("%d not valid subdevice\n", cmd.subdev); return -EIO; } if (!s->do_cmd || !s->do_cmdtest) { DPRINTK("subdevice %i does not support commands\n", - user_cmd.subdev); + cmd.subdev); return -EIO; } /* make sure channel/gain list isn't too long */ - if (user_cmd.chanlist_len > s->len_chanlist) { + if (cmd.chanlist_len > s->len_chanlist) { DPRINTK("channel/gain list too long %d > %d\n", - user_cmd.chanlist_len, s->len_chanlist); + cmd.chanlist_len, s->len_chanlist); ret = -EINVAL; goto cleanup; } /* load channel/gain list */ - if (user_cmd.chanlist) { + if (cmd.chanlist) { chanlist = - kmalloc(user_cmd.chanlist_len * sizeof(int), GFP_KERNEL); + kmalloc(cmd.chanlist_len * sizeof(int), GFP_KERNEL); if (!chanlist) { DPRINTK("allocation failed\n"); ret = -ENOMEM; goto cleanup; } - if (copy_from_user(chanlist, user_cmd.chanlist, - user_cmd.chanlist_len * sizeof(int))) { + if (copy_from_user(chanlist, cmd.chanlist, + cmd.chanlist_len * sizeof(int))) { DPRINTK("fault reading chanlist\n"); ret = -EFAULT; goto cleanup; } /* make sure each element in channel/gain list is valid */ - ret = comedi_check_chanlist(s, user_cmd.chanlist_len, chanlist); + ret = comedi_check_chanlist(s, cmd.chanlist_len, chanlist); if (ret < 0) { DPRINTK("bad chanlist\n"); goto cleanup; } - user_cmd.chanlist = chanlist; + cmd.chanlist = chanlist; } - ret = s->do_cmdtest(dev, s, &user_cmd); + ret = s->do_cmdtest(dev, s, &cmd); /* restore chanlist pointer before copying back */ - user_cmd.chanlist = chanlist_saver; + cmd.chanlist = chanlist_saver; - if (copy_to_user(arg, &user_cmd, sizeof(struct comedi_cmd))) { + if (copy_to_user(arg, &cmd, sizeof(struct comedi_cmd))) { DPRINTK("bad cmd address\n"); ret = -EFAULT; goto cleanup; -- cgit v0.10.2 From 95bc359f98a077a5cfc34feb0a333d11a4124b1c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 18 Sep 2012 11:43:52 -0700 Subject: staging: comedi: comedi_fops: cast the cmd->chanlist to the correct address space Rename 'chanlist_saver' to 'user_chanlist' to avoid confusion that it's actually a __user *. The chanlist pointer in comedi_cmd is still a user space pointer when the comedi_cmd is copied with copy_from_user() in do_cmd_ioctl() and do_cmdtest_ioctl(). This pointer needs to be cast when it is saved in user_chanlist in order to preserve its address space. The copy_from_user() call to copy the chanlist to the kernel space comedi_command requires the second parameter to be a __user pointer. Use the correctly cast user_chanlist instead of cmd->chanlist. Before the comedi_cmd is copied back to user space, the saved user_chanlist pointer is restored. Cast the user_chanlist again so that the address space matches the comedi_cmd. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index df627c8..626fa72 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -1137,14 +1137,14 @@ static int do_cmd_ioctl(struct comedi_device *dev, struct comedi_subdevice *s; struct comedi_async *async; int ret = 0; - unsigned int __user *chanlist_saver = NULL; + unsigned int __user *user_chanlist; if (copy_from_user(&cmd, arg, sizeof(struct comedi_cmd))) { DPRINTK("bad cmd address\n"); return -EFAULT; } /* save user's chanlist pointer so it can be restored later */ - chanlist_saver = cmd.chanlist; + user_chanlist = (unsigned int __user *)cmd.chanlist; if (cmd.subdev >= dev->n_subdevices) { DPRINTK("%d no such subdevice\n", cmd.subdev); @@ -1206,7 +1206,7 @@ static int do_cmd_ioctl(struct comedi_device *dev, goto cleanup; } - if (copy_from_user(async->cmd.chanlist, cmd.chanlist, + if (copy_from_user(async->cmd.chanlist, user_chanlist, async->cmd.chanlist_len * sizeof(int))) { DPRINTK("fault reading chanlist\n"); ret = -EFAULT; @@ -1228,7 +1228,7 @@ static int do_cmd_ioctl(struct comedi_device *dev, DPRINTK("test returned %d\n", ret); cmd = async->cmd; /* restore chanlist pointer before copying back */ - cmd.chanlist = chanlist_saver; + cmd.chanlist = (unsigned int __force *)user_chanlist; cmd.data = NULL; if (copy_to_user(arg, &cmd, sizeof(struct comedi_cmd))) { DPRINTK("fault writing cmd\n"); @@ -1287,14 +1287,14 @@ static int do_cmdtest_ioctl(struct comedi_device *dev, struct comedi_subdevice *s; int ret = 0; unsigned int *chanlist = NULL; - unsigned int __user *chanlist_saver = NULL; + unsigned int __user *user_chanlist; if (copy_from_user(&cmd, arg, sizeof(struct comedi_cmd))) { DPRINTK("bad cmd address\n"); return -EFAULT; } /* save user's chanlist pointer so it can be restored later */ - chanlist_saver = cmd.chanlist; + user_chanlist = (unsigned int __user *)cmd.chanlist; if (cmd.subdev >= dev->n_subdevices) { DPRINTK("%d no such subdevice\n", cmd.subdev); @@ -1331,7 +1331,7 @@ static int do_cmdtest_ioctl(struct comedi_device *dev, goto cleanup; } - if (copy_from_user(chanlist, cmd.chanlist, + if (copy_from_user(chanlist, user_chanlist, cmd.chanlist_len * sizeof(int))) { DPRINTK("fault reading chanlist\n"); ret = -EFAULT; @@ -1351,7 +1351,7 @@ static int do_cmdtest_ioctl(struct comedi_device *dev, ret = s->do_cmdtest(dev, s, &cmd); /* restore chanlist pointer before copying back */ - cmd.chanlist = chanlist_saver; + cmd.chanlist = (unsigned int __force *)user_chanlist; if (copy_to_user(arg, &cmd, sizeof(struct comedi_cmd))) { DPRINTK("bad cmd address\n"); -- cgit v0.10.2 From f657b14aecaf5f9fb59f4838f7112ab963d7b2ba Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 18 Sep 2012 18:46:23 -0700 Subject: staging: comedi: daqboard2000: remove struct daqboard2000_hw In this driver the PCI bar 2 resource is being ioremap'ed to a void * in the private data. This void * is then being cast to a struct daqboard2000_hw * that defines all the registers used by the driver. This is causing a number of sparse warnings similar to: warning: incorrect type in argument 1 (different address space) expected void const volatile [noderef] *addr got void * Change the type in the private data to void __iomem * to correctly store the ioremap'ed address. Remove struct daqboard2000_hw and change the contents to #define's for the register memory map. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index 39a2b1e..88f0a277 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -173,55 +173,38 @@ static const struct comedi_lrange range_daqboard2000_ao = { 1, { } }; -struct daqboard2000_hw { - volatile u16 acqControl; /* 0x00 */ - volatile u16 acqScanListFIFO; /* 0x02 */ - volatile u32 acqPacerClockDivLow; /* 0x04 */ - - volatile u16 acqScanCounter; /* 0x08 */ - volatile u16 acqPacerClockDivHigh; /* 0x0a */ - volatile u16 acqTriggerCount; /* 0x0c */ - volatile u16 fill2; /* 0x0e */ - volatile u16 acqResultsFIFO; /* 0x10 */ - volatile u16 fill3; /* 0x12 */ - volatile u16 acqResultsShadow; /* 0x14 */ - volatile u16 fill4; /* 0x16 */ - volatile u16 acqAdcResult; /* 0x18 */ - volatile u16 fill5; /* 0x1a */ - volatile u16 dacScanCounter; /* 0x1c */ - volatile u16 fill6; /* 0x1e */ - - volatile u16 dacControl; /* 0x20 */ - volatile u16 fill7; /* 0x22 */ - volatile s16 dacFIFO; /* 0x24 */ - volatile u16 fill8[2]; /* 0x26 */ - volatile u16 dacPacerClockDiv; /* 0x2a */ - volatile u16 refDacs; /* 0x2c */ - volatile u16 fill9; /* 0x2e */ - - volatile u16 dioControl; /* 0x30 */ - volatile s16 dioP3hsioData; /* 0x32 */ - volatile u16 dioP3Control; /* 0x34 */ - volatile u16 calEepromControl; /* 0x36 */ - volatile s16 dacSetting[4]; /* 0x38 */ - volatile s16 dioP2ExpansionIO8Bit[32]; /* 0x40 */ - - volatile u16 ctrTmrControl; /* 0x80 */ - volatile u16 fill10[3]; /* 0x82 */ - volatile s16 ctrInput[4]; /* 0x88 */ - volatile u16 fill11[8]; /* 0x90 */ - volatile u16 timerDivisor[2]; /* 0xa0 */ - volatile u16 fill12[6]; /* 0xa4 */ - - volatile u16 dmaControl; /* 0xb0 */ - volatile u16 trigControl; /* 0xb2 */ - volatile u16 fill13[2]; /* 0xb4 */ - volatile u16 calEeprom; /* 0xb8 */ - volatile u16 acqDigitalMark; /* 0xba */ - volatile u16 trigDacs; /* 0xbc */ - volatile u16 fill14; /* 0xbe */ - volatile s16 dioP2ExpansionIO16Bit[32]; /* 0xc0 */ -}; +/* + * Register Memory Map + */ +#define acqControl 0x00 /* u16 */ +#define acqScanListFIFO 0x02 /* u16 */ +#define acqPacerClockDivLow 0x04 /* u32 */ +#define acqScanCounter 0x08 /* u16 */ +#define acqPacerClockDivHigh 0x0a /* u16 */ +#define acqTriggerCount 0x0c /* u16 */ +#define acqResultsFIFO 0x10 /* u16 */ +#define acqResultsShadow 0x14 /* u16 */ +#define acqAdcResult 0x18 /* u16 */ +#define dacScanCounter 0x1c /* u16 */ +#define dacControl 0x20 /* u16 */ +#define dacFIFO 0x24 /* s16 */ +#define dacPacerClockDiv 0x2a /* u16 */ +#define refDacs 0x2c /* u16 */ +#define dioControl 0x30 /* u16 */ +#define dioP3hsioData 0x32 /* s16 */ +#define dioP3Control 0x34 /* u16 */ +#define calEepromControl 0x36 /* u16 */ +#define dacSetting(x) (0x38 + (x)*2) /* s16 */ +#define dioP2ExpansionIO8Bit 0x40 /* s16 */ +#define ctrTmrControl 0x80 /* u16 */ +#define ctrInput(x) (0x88 + (x)*2) /* s16 */ +#define timerDivisor(x) (0xa0 + (x)*2) /* u16 */ +#define dmaControl 0xb0 /* u16 */ +#define trigControl 0xb2 /* u16 */ +#define calEeprom 0xb8 /* u16 */ +#define acqDigitalMark 0xba /* u16 */ +#define trigDacs 0xbc /* u16 */ +#define dioP2ExpansionIO16Bit(x) (0xc0 + (x)*2) /* s16 */ /* Scan Sequencer programming */ #define DAQBOARD2000_SeqStartScanList 0x0011 @@ -317,7 +300,7 @@ struct daqboard2000_private { enum { card_daqboard_2000 } card; - void *daq; + void __iomem *daq; void __iomem *plx; unsigned int ao_readback[2]; }; @@ -326,12 +309,10 @@ struct daqboard2000_private { static void writeAcqScanListEntry(struct comedi_device *dev, u16 entry) { - struct daqboard2000_hw *fpga = devpriv->daq; - -/* udelay(4); */ - fpga->acqScanListFIFO = entry & 0x00ff; -/* udelay(4); */ - fpga->acqScanListFIFO = (entry >> 8) & 0x00ff; + /* udelay(4); */ + writew(entry & 0x00ff, devpriv->daq + acqScanListFIFO); + /* udelay(4); */ + writew((entry >> 8) & 0x00ff, devpriv->daq + acqScanListFIFO); } static void setup_sampling(struct comedi_device *dev, int chan, int gain) @@ -384,21 +365,21 @@ static int daqboard2000_ai_insn_read(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - int i; - struct daqboard2000_hw *fpga = devpriv->daq; + unsigned int val; int gain, chan, timeout; + int i; - fpga->acqControl = - DAQBOARD2000_AcqResetScanListFifo | - DAQBOARD2000_AcqResetResultsFifo | DAQBOARD2000_AcqResetConfigPipe; + writew(DAQBOARD2000_AcqResetScanListFifo | + DAQBOARD2000_AcqResetResultsFifo | + DAQBOARD2000_AcqResetConfigPipe, devpriv->daq + acqControl); /* * If pacer clock is not set to some high value (> 10 us), we * risk multiple samples to be put into the result FIFO. */ /* 1 second, should be long enough */ - fpga->acqPacerClockDivLow = 1000000; - fpga->acqPacerClockDivHigh = 0; + writel(1000000, devpriv->daq + acqPacerClockDivLow); + writew(0, devpriv->daq + acqPacerClockDivHigh); gain = CR_RANGE(insn->chanspec); chan = CR_CHAN(insn->chanspec); @@ -410,28 +391,30 @@ static int daqboard2000_ai_insn_read(struct comedi_device *dev, for (i = 0; i < insn->n; i++) { setup_sampling(dev, chan, gain); /* Enable reading from the scanlist FIFO */ - fpga->acqControl = DAQBOARD2000_SeqStartScanList; + writew(DAQBOARD2000_SeqStartScanList, + devpriv->daq + acqControl); for (timeout = 0; timeout < 20; timeout++) { - if (fpga->acqControl & DAQBOARD2000_AcqConfigPipeFull) + val = readw(devpriv->daq + acqControl); + if (val & DAQBOARD2000_AcqConfigPipeFull) break; /* udelay(2); */ } - fpga->acqControl = DAQBOARD2000_AdcPacerEnable; + writew(DAQBOARD2000_AdcPacerEnable, devpriv->daq + acqControl); for (timeout = 0; timeout < 20; timeout++) { - if (fpga->acqControl & DAQBOARD2000_AcqLogicScanning) + val = readw(devpriv->daq + acqControl); + if (val & DAQBOARD2000_AcqLogicScanning) break; /* udelay(2); */ } for (timeout = 0; timeout < 20; timeout++) { - if (fpga->acqControl & - DAQBOARD2000_AcqResultsFIFOHasValidData) { + val = readw(devpriv->daq + acqControl); + if (val & DAQBOARD2000_AcqResultsFIFOHasValidData) break; - } /* udelay(2); */ } - data[i] = fpga->acqResultsFIFO; - fpga->acqControl = DAQBOARD2000_AdcPacerDisable; - fpga->acqControl = DAQBOARD2000_SeqStopScanList; + data[i] = readw(devpriv->daq + acqResultsFIFO); + writew(DAQBOARD2000_AdcPacerDisable, devpriv->daq + acqControl); + writew(DAQBOARD2000_SeqStopScanList, devpriv->daq + acqControl); } return i; @@ -456,28 +439,38 @@ static int daqboard2000_ao_insn_write(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - int i; int chan = CR_CHAN(insn->chanspec); - struct daqboard2000_hw *fpga = devpriv->daq; + unsigned int val; int timeout; + int i; for (i = 0; i < insn->n; i++) { +#if 0 /* - * OK, since it works OK without enabling the DAC's, let's keep - * it as simple as possible... + * OK, since it works OK without enabling the DAC's, + * let's keep it as simple as possible... */ - /* fpga->dacControl = (chan + 2) * 0x0010 | 0x0001; udelay(1000); */ - fpga->dacSetting[chan] = data[i]; + writew((chan + 2) * 0x0010 | 0x0001, + devpriv->daq + dacControl); + udelay(1000); +#endif + writew(data[i], devpriv->daq + dacSetting(chan)); for (timeout = 0; timeout < 20; timeout++) { - if ((fpga->dacControl & ((chan + 1) * 0x0010)) == 0) + val = readw(devpriv->daq + dacControl); + if ((val & ((chan + 1) * 0x0010)) == 0) break; /* udelay(2); */ } devpriv->ao_readback[chan] = data[i]; +#if 0 /* - * Since we never enabled the DAC's, we don't need to disable it... - * fpga->dacControl = (chan + 2) * 0x0010 | 0x0000; udelay(1000); + * Since we never enabled the DAC's, we don't need + * to disable it... */ + writew((chan + 2) * 0x0010 | 0x0000, + devpriv->daq + dacControl); + udelay(1000); +#endif } return i; @@ -608,21 +601,21 @@ static void daqboard2000_adcStopDmaTransfer(struct comedi_device *dev) static void daqboard2000_adcDisarm(struct comedi_device *dev) { - struct daqboard2000_hw *fpga = devpriv->daq; - /* Disable hardware triggers */ udelay(2); - fpga->trigControl = DAQBOARD2000_TrigAnalog | DAQBOARD2000_TrigDisable; + writew(DAQBOARD2000_TrigAnalog | DAQBOARD2000_TrigDisable, + devpriv->daq + trigControl); udelay(2); - fpga->trigControl = DAQBOARD2000_TrigTTL | DAQBOARD2000_TrigDisable; + writew(DAQBOARD2000_TrigTTL | DAQBOARD2000_TrigDisable, + devpriv->daq + trigControl); /* Stop the scan list FIFO from loading the configuration pipe */ udelay(2); - fpga->acqControl = DAQBOARD2000_SeqStopScanList; + writew(DAQBOARD2000_SeqStopScanList, devpriv->daq + acqControl); /* Stop the pacer clock */ udelay(2); - fpga->acqControl = DAQBOARD2000_AdcPacerDisable; + writew(DAQBOARD2000_AdcPacerDisable, devpriv->daq + acqControl); /* Stop the input dma (abort channel 1) */ daqboard2000_adcStopDmaTransfer(dev); @@ -630,22 +623,24 @@ static void daqboard2000_adcDisarm(struct comedi_device *dev) static void daqboard2000_activateReferenceDacs(struct comedi_device *dev) { - struct daqboard2000_hw *fpga = devpriv->daq; + unsigned int val; int timeout; /* Set the + reference dac value in the FPGA */ - fpga->refDacs = 0x80 | DAQBOARD2000_PosRefDacSelect; + writew(0x80 | DAQBOARD2000_PosRefDacSelect, devpriv->daq + refDacs); for (timeout = 0; timeout < 20; timeout++) { - if ((fpga->dacControl & DAQBOARD2000_RefBusy) == 0) + val = readw(devpriv->daq + dacControl); + if ((val & DAQBOARD2000_RefBusy) == 0) break; udelay(2); } /* printk("DAQBOARD2000_PosRefDacSelect %d\n", timeout);*/ /* Set the - reference dac value in the FPGA */ - fpga->refDacs = 0x80 | DAQBOARD2000_NegRefDacSelect; + writew(0x80 | DAQBOARD2000_NegRefDacSelect, devpriv->daq + refDacs); for (timeout = 0; timeout < 20; timeout++) { - if ((fpga->dacControl & DAQBOARD2000_RefBusy) == 0) + val = readw(devpriv->daq + dacControl); + if ((val & DAQBOARD2000_RefBusy) == 0) break; udelay(2); } @@ -689,18 +684,14 @@ rmmod daqboard2000 ; rmmod comedi; make install ; modprobe daqboard2000; /usr/sb static int daqboard2000_8255_cb(int dir, int port, int data, unsigned long ioaddr) { - int result = 0; + void __iomem *mmio_base = (void __iomem *)ioaddr; + if (dir) { - writew(data, ((void *)ioaddr) + port * 2); - result = 0; + writew(data, mmio_base + port * 2); + return 0; } else { - result = readw(((void *)ioaddr) + port * 2); + return readw(mmio_base + port * 2); } -/* - printk("daqboard2000_8255_cb %x %d %d %2.2x -> %2.2x\n", - arg, dir, port, data, result); -*/ - return result; } static struct pci_dev *daqboard2000_find_pci_dev(struct comedi_device *dev, @@ -825,7 +816,7 @@ static int daqboard2000_attach(struct comedi_device *dev, s = &dev->subdevices[2]; result = subdev_8255_init(dev, s, daqboard2000_8255_cb, - (unsigned long)(devpriv->daq + 0x40)); + (unsigned long)(devpriv->daq + dioP2ExpansionIO8Bit)); out: return result; -- cgit v0.10.2 From ad375f775836d481acd663e64eeab08c1a948974 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 18 Sep 2012 18:46:41 -0700 Subject: staging: comedi: daqboard2000: remove this_board and devpriv macros These macros rely on a local variable having a specific name. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index 88f0a277..0daa83d 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -294,8 +294,6 @@ static const struct daq200_boardtype boardtypes[] = { {"ids4", DAQBOARD2000_SUBSYSTEM_IDS4}, }; -#define this_board ((const struct daq200_boardtype *)dev->board_ptr) - struct daqboard2000_private { enum { card_daqboard_2000 @@ -305,10 +303,10 @@ struct daqboard2000_private { unsigned int ao_readback[2]; }; -#define devpriv ((struct daqboard2000_private *)dev->private) - static void writeAcqScanListEntry(struct comedi_device *dev, u16 entry) { + struct daqboard2000_private *devpriv = dev->private; + /* udelay(4); */ writew(entry & 0x00ff, devpriv->daq + acqScanListFIFO); /* udelay(4); */ @@ -365,6 +363,7 @@ static int daqboard2000_ai_insn_read(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct daqboard2000_private *devpriv = dev->private; unsigned int val; int gain, chan, timeout; int i; @@ -425,8 +424,9 @@ static int daqboard2000_ao_insn_read(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - int i; + struct daqboard2000_private *devpriv = dev->private; int chan = CR_CHAN(insn->chanspec); + int i; for (i = 0; i < insn->n; i++) data[i] = devpriv->ao_readback[chan]; @@ -439,6 +439,7 @@ static int daqboard2000_ao_insn_write(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct daqboard2000_private *devpriv = dev->private; int chan = CR_CHAN(insn->chanspec); unsigned int val; int timeout; @@ -478,6 +479,8 @@ static int daqboard2000_ao_insn_write(struct comedi_device *dev, static void daqboard2000_resetLocalBus(struct comedi_device *dev) { + struct daqboard2000_private *devpriv = dev->private; + dev_dbg(dev->class_dev, "daqboard2000_resetLocalBus\n"); writel(DAQBOARD2000_SECRLocalBusHi, devpriv->plx + 0x6c); udelay(10000); @@ -487,6 +490,8 @@ static void daqboard2000_resetLocalBus(struct comedi_device *dev) static void daqboard2000_reloadPLX(struct comedi_device *dev) { + struct daqboard2000_private *devpriv = dev->private; + dev_dbg(dev->class_dev, "daqboard2000_reloadPLX\n"); writel(DAQBOARD2000_SECRReloadLo, devpriv->plx + 0x6c); udelay(10000); @@ -498,6 +503,8 @@ static void daqboard2000_reloadPLX(struct comedi_device *dev) static void daqboard2000_pulseProgPin(struct comedi_device *dev) { + struct daqboard2000_private *devpriv = dev->private; + dev_dbg(dev->class_dev, "daqboard2000_pulseProgPin 1\n"); writel(DAQBOARD2000_SECRProgPinHi, devpriv->plx + 0x6c); udelay(10000); @@ -507,6 +514,7 @@ static void daqboard2000_pulseProgPin(struct comedi_device *dev) static int daqboard2000_pollCPLD(struct comedi_device *dev, int mask) { + struct daqboard2000_private *devpriv = dev->private; int result = 0; int i; int cpld; @@ -526,6 +534,7 @@ static int daqboard2000_pollCPLD(struct comedi_device *dev, int mask) static int daqboard2000_writeCPLD(struct comedi_device *dev, int data) { + struct daqboard2000_private *devpriv = dev->private; int result = 0; udelay(10); @@ -540,6 +549,7 @@ static int daqboard2000_writeCPLD(struct comedi_device *dev, int data) static int initialize_daqboard2000(struct comedi_device *dev, unsigned char *cpld_array, int len) { + struct daqboard2000_private *devpriv = dev->private; int result = -EIO; /* Read the serial EEPROM control register */ int secr; @@ -601,6 +611,8 @@ static void daqboard2000_adcStopDmaTransfer(struct comedi_device *dev) static void daqboard2000_adcDisarm(struct comedi_device *dev) { + struct daqboard2000_private *devpriv = dev->private; + /* Disable hardware triggers */ udelay(2); writew(DAQBOARD2000_TrigAnalog | DAQBOARD2000_TrigDisable, @@ -623,6 +635,7 @@ static void daqboard2000_adcDisarm(struct comedi_device *dev) static void daqboard2000_activateReferenceDacs(struct comedi_device *dev) { + struct daqboard2000_private *devpriv = dev->private; unsigned int val; int timeout; @@ -729,6 +742,8 @@ static struct pci_dev *daqboard2000_find_pci_dev(struct comedi_device *dev, static int daqboard2000_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct daq200_boardtype *this_board; + struct daqboard2000_private *devpriv; struct pci_dev *pcidev; struct comedi_subdevice *s; resource_size_t pci_base; @@ -736,14 +751,16 @@ static int daqboard2000_attach(struct comedi_device *dev, unsigned int aux_len; int result; - result = alloc_private(dev, sizeof(struct daqboard2000_private)); + result = alloc_private(dev, sizeof(*devpriv)); if (result < 0) return -ENOMEM; + devpriv = dev->private; pcidev = daqboard2000_find_pci_dev(dev, it); if (!pcidev) return -EIO; comedi_set_hw_dev(dev, &pcidev->dev); + this_board = comedi_board(dev); result = comedi_pci_enable(pcidev, "daqboard2000"); if (result < 0) { @@ -825,6 +842,7 @@ out: static void daqboard2000_detach(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct daqboard2000_private *devpriv = dev->private; if (dev->subdevices) subdev_8255_cleanup(dev, &dev->subdevices[2]); -- cgit v0.10.2 From 63ad597e2d1da6472f381f9709bc87eecbe30328 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 18 Sep 2012 18:46:57 -0700 Subject: staging: comedi: daqboard2000: use request_firmware() This driver requires loading a firmware file for the cpld. This is currently being done by passing the firmware data using the COMEDI_DEVCONFIG ioctl through the attach() hook in the driver. This does not work for auto-configured PCI devices due to the firmware loading options not being set in the comedi_devconfig parameter passed to the driver. Change the driver so it gets the firmware using request_firmware() and ignore any firmware options passed in the comedi_devconfig. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index 0daa83d..d85f58e 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -117,9 +117,12 @@ Configuration options: #include #include +#include #include "8255.h" +#define DAQBOARD2000_FIRMWARE "daqboard2000_firmware.bin" + #define PCI_VENDOR_ID_IOTECH 0x1616 #define DAQBOARD2000_SUBSYSTEM_IDS2 0x0002 /* Daqboard/2000 - 2 Dacs */ @@ -547,14 +550,14 @@ static int daqboard2000_writeCPLD(struct comedi_device *dev, int data) } static int initialize_daqboard2000(struct comedi_device *dev, - unsigned char *cpld_array, int len) + const u8 *cpld_array, size_t len) { struct daqboard2000_private *devpriv = dev->private; int result = -EIO; /* Read the serial EEPROM control register */ int secr; int retry; - int i; + size_t i; /* Check to make sure the serial eeprom is present on the board */ secr = readl(devpriv->plx + 0x6c); @@ -604,6 +607,22 @@ static int initialize_daqboard2000(struct comedi_device *dev, return result; } +static int daqboard2000_upload_firmware(struct comedi_device *dev) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + const struct firmware *fw; + int ret; + + ret = request_firmware(&fw, DAQBOARD2000_FIRMWARE, &pcidev->dev); + if (ret) + return ret; + + ret = initialize_daqboard2000(dev, fw->data, fw->size); + release_firmware(fw); + + return ret; +} + static void daqboard2000_adcStopDmaTransfer(struct comedi_device *dev) { /* printk("Implement: daqboard2000_adcStopDmaTransfer\n");*/ @@ -747,8 +766,6 @@ static int daqboard2000_attach(struct comedi_device *dev, struct pci_dev *pcidev; struct comedi_subdevice *s; resource_size_t pci_base; - void *aux_data; - unsigned int aux_len; int result; result = alloc_private(dev, sizeof(*devpriv)); @@ -790,18 +807,10 @@ static int daqboard2000_attach(struct comedi_device *dev, printk("Interrupt before is: %x\n", interrupt); */ - aux_data = comedi_aux_data(it->options, 0); - aux_len = it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]; - - if (aux_data && aux_len) { - result = initialize_daqboard2000(dev, aux_data, aux_len); - } else { - dev_dbg(dev->class_dev, - "no FPGA initialization code, aborting\n"); - result = -EIO; - } + result = daqboard2000_upload_firmware(dev); if (result < 0) - goto out; + return result; + daqboard2000_initializeAdc(dev); daqboard2000_initializeDac(dev); /* @@ -835,7 +844,6 @@ static int daqboard2000_attach(struct comedi_device *dev, result = subdev_8255_init(dev, s, daqboard2000_8255_cb, (unsigned long)(devpriv->daq + dioP2ExpansionIO8Bit)); -out: return result; } @@ -896,3 +904,4 @@ module_comedi_pci_driver(daqboard2000_driver, daqboard2000_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); +MODULE_FIRMWARE(DAQBOARD2000_FIRMWARE); -- cgit v0.10.2 From 33214ce1ebdabf134e3064ca4fbdecaecefdf370 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 18 Sep 2012 18:47:15 -0700 Subject: staging: comedi: daqboard2000: use attach_pci callback Convert this PCI driver to use the comedi PCI auto config attach mechanism by adding an 'attach_pci' callback function. Since the driver does not require any external configuration options. and the legacy 'attach' callback is now optional, remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index d85f58e..687ccb1 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -31,16 +31,10 @@ Devices: [IOTech] DAQBoard/2000 (daqboard2000) Much of the functionality of this driver was determined from reading the source code for the Windows driver. -The FPGA on the board requires initialization code, which can -be loaded by comedi_config using the -i -option. The initialization code is available from http://www.comedi.org -in the comedi_nonfree_firmware tarball. - -Configuration options: - [0] - PCI bus of device (optional) - [1] - PCI slot of device (optional) - If bus/slot is not specified, the first supported - PCI device found will be used. +The FPGA on the board requires fimware, which is available from +http://www.comedi.org in the comedi_nonfree_firmware tarball. + +Configuration options: not applicable, uses PCI auto config */ /* This card was obviously never intended to leave the Windows world, @@ -726,59 +720,45 @@ static int daqboard2000_8255_cb(int dir, int port, int data, } } -static struct pci_dev *daqboard2000_find_pci_dev(struct comedi_device *dev, - struct comedi_devconfig *it) +static const void *daqboard2000_find_boardinfo(struct comedi_device *dev, + struct pci_dev *pcidev) { - struct pci_dev *pcidev = NULL; - int bus = it->options[0]; - int slot = it->options[1]; + const struct daq200_boardtype *board; int i; - for_each_pci_dev(pcidev) { - if (bus || slot) { - if (bus != pcidev->bus->number || - slot != PCI_SLOT(pcidev->devfn)) - continue; - } - if (pcidev->vendor != PCI_VENDOR_ID_IOTECH || - pcidev->device != 0x0409 || - pcidev->subsystem_device != PCI_VENDOR_ID_IOTECH) - continue; - - for (i = 0; i < ARRAY_SIZE(boardtypes); i++) { - if (boardtypes[i].id != pcidev->subsystem_device) - continue; - dev->board_ptr = boardtypes + i; - return pcidev; - } + if (pcidev->subsystem_device != PCI_VENDOR_ID_IOTECH) + return NULL; + + for (i = 0; i < ARRAY_SIZE(boardtypes); i++) { + board = &boardtypes[i]; + if (pcidev->subsystem_device == board->id) + return board; } - dev_err(dev->class_dev, - "No supported board found! (req. bus %d, slot %d)\n", - bus, slot); return NULL; } -static int daqboard2000_attach(struct comedi_device *dev, - struct comedi_devconfig *it) +static int daqboard2000_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) { - const struct daq200_boardtype *this_board; + const struct daq200_boardtype *board; struct daqboard2000_private *devpriv; - struct pci_dev *pcidev; struct comedi_subdevice *s; resource_size_t pci_base; int result; + comedi_set_hw_dev(dev, &pcidev->dev); + + board = daqboard2000_find_boardinfo(dev, pcidev); + if (!board) + return -ENODEV; + dev->board_ptr = board; + dev->board_name = board->name; + result = alloc_private(dev, sizeof(*devpriv)); if (result < 0) return -ENOMEM; devpriv = dev->private; - pcidev = daqboard2000_find_pci_dev(dev, it); - if (!pcidev) - return -EIO; - comedi_set_hw_dev(dev, &pcidev->dev); - this_board = comedi_board(dev); - result = comedi_pci_enable(pcidev, "daqboard2000"); if (result < 0) { dev_err(dev->class_dev, @@ -819,8 +799,6 @@ static int daqboard2000_attach(struct comedi_device *dev, printk("Interrupt after is: %x\n", interrupt); */ - dev->board_name = this_board->name; - s = &dev->subdevices[0]; /* ai subdevice */ s->type = COMEDI_SUBD_AI; @@ -872,7 +850,7 @@ static void daqboard2000_detach(struct comedi_device *dev) static struct comedi_driver daqboard2000_driver = { .driver_name = "daqboard2000", .module = THIS_MODULE, - .attach = daqboard2000_attach, + .attach_pci = daqboard2000_attach_pci, .detach = daqboard2000_detach, }; -- cgit v0.10.2 From 9e794ee4042ea076c3199943e98ed0c9d8b06921 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 18 Sep 2012 18:47:34 -0700 Subject: staging: comedi: daqboard2000: remove range_daqboard2000_ao This comedi_lrange is the same as the global range_bipolar10 exported by the comedi core. Use that range instead. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index 687ccb1..3ea184e 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -165,11 +165,6 @@ static const struct comedi_lrange range_daqboard2000_ai = { 13, { } }; -static const struct comedi_lrange range_daqboard2000_ao = { 1, { - RANGE(-10, 10) - } -}; - /* * Register Memory Map */ @@ -816,7 +811,7 @@ static int daqboard2000_attach_pci(struct comedi_device *dev, s->maxdata = 0xffff; s->insn_read = daqboard2000_ao_insn_read; s->insn_write = daqboard2000_ao_insn_write; - s->range_table = &range_daqboard2000_ao; + s->range_table = &range_bipolar10; s = &dev->subdevices[2]; result = subdev_8255_init(dev, s, daqboard2000_8255_cb, -- cgit v0.10.2 From 1387d4b7f05db3d3cf156861f7c942b1031df51b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 18 Sep 2012 18:47:53 -0700 Subject: staging: comedi: daqboard2000: cleanup range_daqboard2000_ai Change the whitespace of the range table to avoid the > 80 char lines and the ugly line breaks. Convert the RANGE() values into the appropriate {BIP,UNI}_RANGE(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index 3ea184e..032be98 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -140,29 +140,22 @@ Configuration options: not applicable, uses PCI auto config #define DAQBOARD2000_CPLD_INIT 0x0002 #define DAQBOARD2000_CPLD_DONE 0x0004 -/* Available ranges */ -static const struct comedi_lrange range_daqboard2000_ai = { 13, { - RANGE(-10, 10), - RANGE(-5, 5), - RANGE(-2.5, - 2.5), - RANGE(-1.25, - 1.25), - RANGE(-0.625, - 0.625), - RANGE(-0.3125, - 0.3125), - RANGE(-0.156, - 0.156), - RANGE(0, 10), - RANGE(0, 5), - RANGE(0, 2.5), - RANGE(0, 1.25), - RANGE(0, - 0.625), - RANGE(0, - 0.3125) - } +static const struct comedi_lrange range_daqboard2000_ai = { + 13, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2.5), + BIP_RANGE(1.25), + BIP_RANGE(0.625), + BIP_RANGE(0.3125), + BIP_RANGE(0.156), + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(2.5), + UNI_RANGE(1.25), + UNI_RANGE(0.625), + UNI_RANGE(0.3125) + } }; /* -- cgit v0.10.2 From 1403e797573bc9929d2a5f055dd7dba9184c47c9 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 18 Sep 2012 18:48:16 -0700 Subject: staging: comedi: daqboard2000: remove the commented out debug messages They are commented out and are are just noise anyway. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index 032be98..22d4733 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -336,7 +336,6 @@ static void setup_sampling(struct comedi_device *dev, int chan, int gain) /* These should be read from EEPROM */ word2 |= 0x0800; word3 |= 0xc000; -/* printk("%d %4.4x %4.4x %4.4x %4.4x\n", chan, word0, word1, word2, word3);*/ writeAcqScanListEntry(dev, word0); writeAcqScanListEntry(dev, word1); writeAcqScanListEntry(dev, word2); @@ -607,7 +606,6 @@ static int daqboard2000_upload_firmware(struct comedi_device *dev) static void daqboard2000_adcStopDmaTransfer(struct comedi_device *dev) { -/* printk("Implement: daqboard2000_adcStopDmaTransfer\n");*/ } static void daqboard2000_adcDisarm(struct comedi_device *dev) @@ -648,7 +646,6 @@ static void daqboard2000_activateReferenceDacs(struct comedi_device *dev) break; udelay(2); } -/* printk("DAQBOARD2000_PosRefDacSelect %d\n", timeout);*/ /* Set the - reference dac value in the FPGA */ writew(0x80 | DAQBOARD2000_NegRefDacSelect, devpriv->daq + refDacs); @@ -658,22 +655,18 @@ static void daqboard2000_activateReferenceDacs(struct comedi_device *dev) break; udelay(2); } -/* printk("DAQBOARD2000_NegRefDacSelect %d\n", timeout);*/ } static void daqboard2000_initializeCtrs(struct comedi_device *dev) { -/* printk("Implement: daqboard2000_initializeCtrs\n");*/ } static void daqboard2000_initializeTmrs(struct comedi_device *dev) { -/* printk("Implement: daqboard2000_initializeTmrs\n");*/ } static void daqboard2000_dacDisarm(struct comedi_device *dev) { -/* printk("Implement: daqboard2000_dacDisarm\n");*/ } static void daqboard2000_initializeAdc(struct comedi_device *dev) @@ -768,24 +761,12 @@ static int daqboard2000_attach_pci(struct comedi_device *dev, readl(devpriv->plx + 0x6c); - /* - u8 interrupt; - Windows code does restore interrupts, but since we don't use them... - pci_read_config_byte(pcidev, PCI_INTERRUPT_LINE, &interrupt); - printk("Interrupt before is: %x\n", interrupt); - */ - result = daqboard2000_upload_firmware(dev); if (result < 0) return result; daqboard2000_initializeAdc(dev); daqboard2000_initializeDac(dev); - /* - Windows code does restore interrupts, but since we don't use them... - pci_read_config_byte(pcidev, PCI_INTERRUPT_LINE, &interrupt); - printk("Interrupt after is: %x\n", interrupt); - */ s = &dev->subdevices[0]; /* ai subdevice */ -- cgit v0.10.2 From d8b5ad68972f68d8ce55fb89d77381238fad35b2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 18 Sep 2012 18:48:32 -0700 Subject: staging: comedi: daqboard2000: remove DEBUG_EEPROM messages DEBUG_EEPROM is not defined anywhere and these messages are just noise. Remove them. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index 22d4733..436229d 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -542,31 +542,18 @@ static int initialize_daqboard2000(struct comedi_device *dev, /* Check to make sure the serial eeprom is present on the board */ secr = readl(devpriv->plx + 0x6c); - if (!(secr & DAQBOARD2000_EEPROM_PRESENT)) { -#ifdef DEBUG_EEPROM - dev_dbg(dev->class_dev, "no serial eeprom\n"); -#endif + if (!(secr & DAQBOARD2000_EEPROM_PRESENT)) return -EIO; - } for (retry = 0; retry < 3; retry++) { -#ifdef DEBUG_EEPROM - dev_dbg(dev->class_dev, "Programming EEPROM try %x\n", retry); -#endif - daqboard2000_resetLocalBus(dev); daqboard2000_reloadPLX(dev); daqboard2000_pulseProgPin(dev); if (daqboard2000_pollCPLD(dev, DAQBOARD2000_CPLD_INIT)) { for (i = 0; i < len; i++) { - if (cpld_array[i] == 0xff - && cpld_array[i + 1] == 0x20) { -#ifdef DEBUG_EEPROM - dev_dbg(dev->class_dev, - "Preamble found at %d\n", i); -#endif + if (cpld_array[i] == 0xff && + cpld_array[i + 1] == 0x20) break; - } } for (; i < len; i += 2) { int data = @@ -575,9 +562,6 @@ static int initialize_daqboard2000(struct comedi_device *dev, break; } if (i >= len) { -#ifdef DEBUG_EEPROM - dev_dbg(dev->class_dev, "Programmed\n"); -#endif daqboard2000_resetLocalBus(dev); daqboard2000_reloadPLX(dev); result = 0; -- cgit v0.10.2 From fefb09e8acd3e264ca725d3790ae32c6008de676 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 18 Sep 2012 18:48:50 -0700 Subject: staging: comedi: daqboard2000: remove the dev_printk function trace These kernel messages are just noise and should be removed in the final driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index 436229d..f25f604 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -465,7 +465,6 @@ static void daqboard2000_resetLocalBus(struct comedi_device *dev) { struct daqboard2000_private *devpriv = dev->private; - dev_dbg(dev->class_dev, "daqboard2000_resetLocalBus\n"); writel(DAQBOARD2000_SECRLocalBusHi, devpriv->plx + 0x6c); udelay(10000); writel(DAQBOARD2000_SECRLocalBusLo, devpriv->plx + 0x6c); @@ -476,7 +475,6 @@ static void daqboard2000_reloadPLX(struct comedi_device *dev) { struct daqboard2000_private *devpriv = dev->private; - dev_dbg(dev->class_dev, "daqboard2000_reloadPLX\n"); writel(DAQBOARD2000_SECRReloadLo, devpriv->plx + 0x6c); udelay(10000); writel(DAQBOARD2000_SECRReloadHi, devpriv->plx + 0x6c); @@ -489,7 +487,6 @@ static void daqboard2000_pulseProgPin(struct comedi_device *dev) { struct daqboard2000_private *devpriv = dev->private; - dev_dbg(dev->class_dev, "daqboard2000_pulseProgPin 1\n"); writel(DAQBOARD2000_SECRProgPinHi, devpriv->plx + 0x6c); udelay(10000); writel(DAQBOARD2000_SECRProgPinLo, devpriv->plx + 0x6c); @@ -725,11 +722,8 @@ static int daqboard2000_attach_pci(struct comedi_device *dev, devpriv = dev->private; result = comedi_pci_enable(pcidev, "daqboard2000"); - if (result < 0) { - dev_err(dev->class_dev, - "failed to enable PCI device and request regions\n"); - return -EIO; - } + if (result < 0) + return result; dev->iobase = 1; /* the "detach" needs this */ pci_base = pci_resource_start(pcidev, 0); -- cgit v0.10.2 From 235960ed744dcd1a22d0667190758f37de9fb15a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 18 Sep 2012 18:49:09 -0700 Subject: staging: comedi: daqboard2000: remove the "test command" comment This driver no longer uses comedi_config to attach so this comment does not apply. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index f25f604..00360e4 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -663,12 +663,6 @@ static void daqboard2000_initializeDac(struct comedi_device *dev) daqboard2000_dacDisarm(dev); } -/* -The test command, REMOVE!!: - -rmmod daqboard2000 ; rmmod comedi; make install ; modprobe daqboard2000; /usr/sbin/comedi_config /dev/comedi0 daqboard/2000 ; tail -40 /var/log/messages -*/ - static int daqboard2000_8255_cb(int dir, int port, int data, unsigned long ioaddr) { -- cgit v0.10.2 From 3dc031dd21ffb8d389c329e3429888212df467aa Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 18 Sep 2012 18:49:28 -0700 Subject: staging: comedi: daqboard2000: use the driver name for the resource name Use the dev->driver->driver_name instead of the literal string for the reqource name passed to comedi_pci_enable(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index 00360e4..ff81829 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -715,7 +715,7 @@ static int daqboard2000_attach_pci(struct comedi_device *dev, return -ENOMEM; devpriv = dev->private; - result = comedi_pci_enable(pcidev, "daqboard2000"); + result = comedi_pci_enable(pcidev, dev->driver->driver_name); if (result < 0) return result; dev->iobase = 1; /* the "detach" needs this */ -- cgit v0.10.2 From 8a3f3d37c58ea44a2441fe8be4d8cd0996fc0c3c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 18 Sep 2012 18:49:46 -0700 Subject: staging: comedi: daqboard2000: add a dev_info message after attach After a successful attach, output a simple dev_info message. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index ff81829..88037ae 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -762,8 +762,13 @@ static int daqboard2000_attach_pci(struct comedi_device *dev, s = &dev->subdevices[2]; result = subdev_8255_init(dev, s, daqboard2000_8255_cb, (unsigned long)(devpriv->daq + dioP2ExpansionIO8Bit)); + if (result) + return result; - return result; + dev_info(dev->class_dev, "%s: %s attached\n", + dev->driver->driver_name, dev->board_name); + + return 0; } static void daqboard2000_detach(struct comedi_device *dev) -- cgit v0.10.2 From bdf7c9dc10912dbad3a5052ee824546535e0b4c1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 18 Sep 2012 18:50:05 -0700 Subject: staging: comedi: daqboard2000: use the pci_resource_len() Use pci_resource_len() when doing the ioremap instead of assuming the resource size. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index 88037ae..69bc0e5 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -122,9 +122,6 @@ Configuration options: not applicable, uses PCI auto config #define DAQBOARD2000_SUBSYSTEM_IDS2 0x0002 /* Daqboard/2000 - 2 Dacs */ #define DAQBOARD2000_SUBSYSTEM_IDS4 0x0004 /* Daqboard/2000 - 4 Dacs */ -#define DAQBOARD2000_DAQ_SIZE 0x1002 -#define DAQBOARD2000_PLX_SIZE 0x100 - /* Initialization bits for the Serial EEPROM Control Register */ #define DAQBOARD2000_SECRProgPinHi 0x8001767e #define DAQBOARD2000_SECRProgPinLo 0x8000767e @@ -721,9 +718,9 @@ static int daqboard2000_attach_pci(struct comedi_device *dev, dev->iobase = 1; /* the "detach" needs this */ pci_base = pci_resource_start(pcidev, 0); - devpriv->plx = ioremap(pci_base, DAQBOARD2000_PLX_SIZE); + devpriv->plx = ioremap(pci_base, pci_resource_len(pcidev, 0)); pci_base = pci_resource_start(pcidev, 2); - devpriv->daq = ioremap(pci_base, DAQBOARD2000_DAQ_SIZE); + devpriv->daq = ioremap(pci_base, pci_resource_len(pcidev, 2)); if (!devpriv->plx || !devpriv->daq) return -ENOMEM; -- cgit v0.10.2 From 0352b932be274d0d67b02f93fe94e30e57265f85 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 18 Sep 2012 18:50:23 -0700 Subject: staging: comedi: daqboard2000: remove local variable in daqboard2000_attach_pci() The 'pci_base' variable is only used to hold the pci_resource_start() value used to ioremap the pci bars. Remove the local variable and just use pci_resource_start() directly in the ioremap. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index 69bc0e5..d13c8c5 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -696,7 +696,6 @@ static int daqboard2000_attach_pci(struct comedi_device *dev, const struct daq200_boardtype *board; struct daqboard2000_private *devpriv; struct comedi_subdevice *s; - resource_size_t pci_base; int result; comedi_set_hw_dev(dev, &pcidev->dev); @@ -717,10 +716,10 @@ static int daqboard2000_attach_pci(struct comedi_device *dev, return result; dev->iobase = 1; /* the "detach" needs this */ - pci_base = pci_resource_start(pcidev, 0); - devpriv->plx = ioremap(pci_base, pci_resource_len(pcidev, 0)); - pci_base = pci_resource_start(pcidev, 2); - devpriv->daq = ioremap(pci_base, pci_resource_len(pcidev, 2)); + devpriv->plx = ioremap(pci_resource_start(pcidev, 0), + pci_resource_len(pcidev, 0)); + devpriv->daq = ioremap(pci_resource_start(pcidev, 2), + pci_resource_len(pcidev, 2)); if (!devpriv->plx || !devpriv->daq) return -ENOMEM; -- cgit v0.10.2 From dc881f294eb957bded69b5e7f2f72831e2d00ac4 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Tue, 18 Sep 2012 19:46:57 +0100 Subject: staging: comedi: fix sparse warning in do_devconfig_ioctl() For the COMEDI_DEVCONFIG ioctl, the user application may embed a pointer to firmware data within a designated element (or two elements for 64-bit pointers) of the `options[]` array in the `struct comedi_devconfig`. `do_devconfig_ioctl()` calls `comedi_aux_data()` to extract the pointer value. It needs to be treated as a `__user` pointer so the firmware data can be copied into kernel memory, so cast the result of `comedi_aux_data()` to avoid a "sparse" warning. This is not ideal but `comedi_aux_data()` is called elsewhere in a wholly kernel memory context so we can't just change its return type to include the `__user` tag. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 626fa72..9b9d4e8 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -370,7 +370,8 @@ static int do_devconfig_ioctl(struct comedi_device *dev, return -ENOMEM; if (copy_from_user(aux_data, - comedi_aux_data(it.options, 0), aux_len)) { + (unsigned char __user * + )comedi_aux_data(it.options, 0), aux_len)) { vfree(aux_data); return -EFAULT; } -- cgit v0.10.2 From 9f82e95773f0f02cfc948c8346a61d161f4eb61b Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Tue, 18 Sep 2012 19:46:59 +0100 Subject: staging: comedi: sparse warning in insn_rw_emulate_bits() `insn_rw_emulate_bits()` is used to emulate the `INSN_READ` and `INSN_WRITE` comedi instructions for subdevices that don't have an `insn_read()` or `insn_write()` handler but do have an `insn_bits()` handler. The function fills in a temporary `struct comedi_insn` called `new_insn` to pass to the subdevice's `insn_bits()` handler. In doing so, it sets the `new_insn.data` pointer to point to a temporary data array. This results in a warning from "sparse" because the `data` pointer in `struct comedi_insn` has the `__user` tag. The subdevice's `insn_bits()` handler ignores it anyway as it gets passed a pointer to the temporary data array in a separate parameter. Don't bother setting `new_insn.data`; just leave it set to `NULL` (done by an earlier `memset()`). Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 2c21dbd..1db6bfd 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -415,7 +415,6 @@ static int insn_rw_emulate_bits(struct comedi_device *dev, new_insn.insn = INSN_BITS; new_insn.chanspec = base_bitfield_channel; new_insn.n = 2; - new_insn.data = new_data; new_insn.subdev = insn->subdev; if (insn->insn == INSN_WRITE) { -- cgit v0.10.2 From 5d06e3df280bd230e2eadc16372e62818c63e894 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Tue, 18 Sep 2012 19:46:58 +0100 Subject: staging: comedi: don't dereference user memory for INSN_INTTRIG `parse_insn()` is dereferencing the user-space pointer `insn->data` directly when handling the `INSN_INTTRIG` comedi instruction. It shouldn't be using `insn->data` at all; it should be using the separate `data` pointer passed to the function. Fix it. Cc: stable Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 9b9d4e8..f496f4d 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -950,7 +950,7 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, ret = -EAGAIN; break; } - ret = s->async->inttrig(dev, s, insn->data[0]); + ret = s->async->inttrig(dev, s, data[0]); if (ret >= 0) ret = 1; break; -- cgit v0.10.2 From b7caecb8c93c0112c060f60f6e0c195da054e309 Mon Sep 17 00:00:00 2001 From: navin Date: Wed, 19 Sep 2012 17:07:27 +0530 Subject: staging: usbip: stub_dev: Fixed oops during removal of usbip_host stub_shutdown_connection() should set kernel thread pointers to NULL after killing them. so that at the time of usbip_host removal stub_shutdown_connection() doesn't try to kill kernel threads which are already killed. [ 1504.312158] BUG: unable to handle kernel NULL pointer dereference at (null) [ 1504.315833] IP: [] exit_creds+0x1f/0x70 [ 1504.317688] PGD 41f1c067 PUD 41d0f067 PMD 0 [ 1504.319611] Oops: 0000 [#2] SMP [ 1504.321480] Modules linked in: vhci_hcd(O) usbip_host(O-) usbip_core(O) uas usb_storage joydev parport_pc bnep rfcomm ppdev binfmt_misc snd_hda_codec_hdmi snd_hda_codec_conexant snd_hda_intel snd_hda_codec snd_hwdep snd_pcm snd_seq_midi arc4 snd_rawmidi snd_seq_midi_event snd_seq ath9k mac80211 ath9k_common ath9k_hw snd_timer snd_seq_device snd ath i915 drm_kms_helper drm psmouse cfg80211 coretemp soundcore lpc_ich i2c_algo_bit snd_page_alloc video intel_ips wmi btusb mac_hid bluetooth ideapad_laptop lp sparse_keymap serio_raw mei microcode parport r8169 [ 1504.329666] CPU 1 [ 1504.329687] Pid: 2434, comm: usbip_eh Tainted: G D O 3.6.0-rc31+ #2 LENOVO 20042 /Base Board Product Name [ 1504.333502] RIP: 0010:[] [] exit_creds+0x1f/0x70 [ 1504.335371] RSP: 0018:ffff880041c7fdd0 EFLAGS: 00010282 [ 1504.337226] RAX: 0000000000000000 RBX: ffff880041c2db40 RCX: ffff880041e4ae50 [ 1504.339101] RDX: 0000000000000044 RSI: 0000000000000286 RDI: 0000000000000000 [ 1504.341027] RBP: ffff880041c7fde0 R08: ffff880041c7e000 R09: 0000000000000000 [ 1504.342934] R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000000 [ 1504.344840] R13: 0000000000000000 R14: ffff88004d448000 R15: ffff880041c7fea0 [ 1504.346743] FS: 0000000000000000(0000) GS:ffff880077440000(0000) knlGS:0000000000000000 [ 1504.348671] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b [ 1504.350612] CR2: 0000000000000000 CR3: 0000000041d0d000 CR4: 00000000000007e0 [ 1504.352723] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 1504.354734] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 [ 1504.356737] Process usbip_eh (pid: 2434, threadinfo ffff880041c7e000, task ffff88004d448000) [ 1504.358711] Stack: [ 1504.360635] ffff880041c7fde0 ffff880041c2db40 ffff880041c7fe00 ffffffff81052aaa [ 1504.362589] ffff880041c2db40 0000000000000000 ffff880041c7fe30 ffffffff8107a148 [ 1504.364539] ffff880041e4ae10 ffff880041e4ae00 ffff88004d448000 ffff88004d448000 [ 1504.366470] Call Trace: [ 1504.368368] [] __put_task_struct+0x4a/0x140 [ 1504.370307] [] kthread_stop+0x108/0x110 [ 1504.370312] [] stub_shutdown_connection+0x3e/0x1b0 [usbip_host] [ 1504.370315] [] event_handler_loop+0x70/0x140 [usbip_core] [ 1504.370318] [] ? add_wait_queue+0x60/0x60 [ 1504.370320] [] ? usbip_stop_eh+0x30/0x30 [usbip_core] [ 1504.370322] [] kthread+0x93/0xa0 [ 1504.370327] [] kernel_thread_helper+0x4/0x10 [ 1504.370330] [] ? flush_kthread_worker+0xb0/0xb0 [ 1504.370332] [] ? gs_change+0x13/0x13 [ 1504.370351] Code: 0b 0f 0b 66 0f 1f 84 00 00 00 00 00 55 48 89 e5 53 48 83 ec 08 66 66 66 66 90 48 8b 87 58 04 00 00 48 89 fb 48 8b bf 50 04 00 00 <8b> 00 48 c7 83 50 04 00 00 00 00 00 00 f0 ff 0f 0f 94 c0 84 c0 [ 1504.370353] RIP [] exit_creds+0x1f/0x70 [ 1504.370353] RSP [ 1504.370354] CR2: 0000000000000000 [ 1504.401376] ---[ end trace 1971ce612a16727a ]--- Signed-off-by: navin patidar Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/usbip/stub_dev.c b/drivers/staging/usbip/stub_dev.c index 92ced35..c8d79a7 100644 --- a/drivers/staging/usbip/stub_dev.c +++ b/drivers/staging/usbip/stub_dev.c @@ -187,10 +187,14 @@ static void stub_shutdown_connection(struct usbip_device *ud) } /* 1. stop threads */ - if (ud->tcp_rx) + if (ud->tcp_rx) { kthread_stop_put(ud->tcp_rx); - if (ud->tcp_tx) + ud->tcp_rx = NULL; + } + if (ud->tcp_tx) { kthread_stop_put(ud->tcp_tx); + ud->tcp_tx = NULL; + } /* * 2. close the socket -- cgit v0.10.2 From cbf7d122cc50bd88cb9fd745c8341a009de0796d Mon Sep 17 00:00:00 2001 From: navin Date: Wed, 19 Sep 2012 17:04:51 +0530 Subject: staging: usbip: vhci_hcd: Fixed oops during removal of vhci_hcd In response to "usbip detach -p [port_number]" user command,vhci_shutdown_connection() gets executed which kills tcp_tx,tcp_rx kernel threads but doesn't set thread pointers to NULL. so, at the time of vhci_hcd removal vhci_shutdown_connection() again tries to kill kernel threads which are already killed. [ 312.220259] BUG: unable to handle kernel NULL pointer dereference at (null) [ 312.220313] IP: [] exit_creds+0x1f/0x70 [ 312.220349] PGD 5b7be067 PUD 5b7dc067 PMD 0 [ 312.220388] Oops: 0000 [#1] SMP [ 312.220415] Modules linked in: vhci_hcd(O-) usbip_host(O) usbip_core(O) uas usb_storage joydev parport_pc bnep rfcomm ppdev binfmt_misc snd_hda_codec_hdmi snd_hda_codec_conexant snd_hda_intel snd_hda_codec snd_hwdep snd_pcm snd_seq_midi arc4 snd_rawmidi snd_seq_midi_event snd_seq ath9k mac80211 ath9k_common ath9k_hw snd_timer snd_seq_device snd ath i915 drm_kms_helper drm psmouse cfg80211 coretemp soundcore lpc_ich i2c_algo_bit snd_page_alloc video intel_ips wmi btusb mac_hid bluetooth ideapad_laptop lp sparse_keymap serio_raw mei microcode parport r8169 [ 312.220862] CPU 0 [ 312.220882] Pid: 2095, comm: usbip_eh Tainted: G O 3.6.0-rc3+ #2 LENOVO 20042 /Base Board Product Name [ 312.220938] RIP: 0010:[] [] exit_creds+0x1f/0x70 [ 312.220979] RSP: 0018:ffff88004d6ebdb0 EFLAGS: 00010282 [ 312.221008] RAX: 0000000000000000 RBX: ffff880041c4db40 RCX: ffff88005ad52230 [ 312.221041] RDX: 0000000000000034 RSI: 0000000000000286 RDI: 0000000000000000 [ 312.221074] RBP: ffff88004d6ebdc0 R08: ffff88004d6ea000 R09: 0000000000000000 [ 312.221107] R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000000 [ 312.221144] R13: 0000000000000000 R14: ffff88005ad521d8 R15: ffff88004d6ebea0 [ 312.221177] FS: 0000000000000000(0000) GS:ffff880077400000(0000) knlGS:0000000000000000 [ 312.221214] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b [ 312.221241] CR2: 0000000000000000 CR3: 000000005b7b9000 CR4: 00000000000007f0 [ 312.221277] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 312.221309] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 [ 312.221342] Process usbip_eh (pid: 2095, threadinfo ffff88004d6ea000, task ffff88004d44db40) [ 312.221384] Stack: [ 312.221396] ffff88004d6ebdc0 ffff880041c4db40 ffff88004d6ebde0 ffffffff81052aaa [ 312.221442] ffff880041c4db40 0000000000000000 ffff88004d6ebe10 ffffffff8107a148 [ 312.221487] ffff88005ad521f0 ffff88005ad52228 ffff88004d44db40 ffff88005ad521d8 [ 312.221536] Call Trace: [ 312.221556] [] __put_task_struct+0x4a/0x140 [ 312.221587] [] kthread_stop+0x108/0x110 [ 312.221616] [] vhci_shutdown_connection+0x49/0x2b4 [vhci_hcd] [ 312.221657] [] event_handler_loop+0x70/0x140 [usbip_core] [ 312.221692] [] ? add_wait_queue+0x60/0x60 [ 312.221721] [] ? usbip_stop_eh+0x30/0x30 [usbip_core] [ 312.221754] [] kthread+0x93/0xa0 [ 312.221784] [] kernel_thread_helper+0x4/0x10 [ 312.221814] [] ? flush_kthread_worker+0xb0/0xb0 [ 312.223589] [] ? gs_change+0x13/0x13 [ 312.225360] Code: 0b 0f 0b 66 0f 1f 84 00 00 00 00 00 55 48 89 e5 53 48 83 ec 08 66 66 66 66 90 48 8b 87 58 04 00 00 48 89 fb 48 8b bf 50 04 00 00 <8b> 00 48 c7 83 50 04 00 00 00 00 00 00 f0 ff 0f 0f 94 c0 84 c0 [ 312.229663] RIP [] exit_creds+0x1f/0x70 [ 312.231696] RSP [ 312.233648] CR2: 0000000000000000 [ 312.256464] ---[ end trace 1971ce612a167279 ]--- Signed-off-by: navin patidar Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c index bd79d18..620d1be 100644 --- a/drivers/staging/usbip/vhci_hcd.c +++ b/drivers/staging/usbip/vhci_hcd.c @@ -814,11 +814,14 @@ static void vhci_shutdown_connection(struct usbip_device *ud) } /* kill threads related to this sdev, if v.c. exists */ - if (vdev->ud.tcp_rx) + if (vdev->ud.tcp_rx) { kthread_stop_put(vdev->ud.tcp_rx); - if (vdev->ud.tcp_tx) + vdev->ud.tcp_rx = NULL; + } + if (vdev->ud.tcp_tx) { kthread_stop_put(vdev->ud.tcp_tx); - + vdev->ud.tcp_tx = NULL; + } pr_info("stop threads\n"); /* active connection is closed */ -- cgit v0.10.2 From 463bf503bdab90bf269ad2a70656fe8536ff4933 Mon Sep 17 00:00:00 2001 From: Radhesh Fadnis Date: Wed, 19 Sep 2012 20:07:49 +0300 Subject: staging: omap-thermal: bandgap: fix setting of alert thresholds There was an error in check for the valid temperature in function temp_to_adc_conversion. The temperature value was compared with higher limit for less than condition as well, resulting in returning -EINVAL. Corrected the check condition to properly check for lower and higher temperature limits. Signed-off-by: Radhesh Fadnis Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index ff93c15..368a2e1 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -157,7 +157,7 @@ static int temp_to_adc_conversion(long temp, struct omap_bandgap *bg_ptr, int i, high = ts_data->adc_end_val - ts_data->adc_start_val; mid = (high + low) / 2; - if (temp < bg_ptr->conv_table[high] || temp > bg_ptr->conv_table[high]) + if (temp < bg_ptr->conv_table[low] || temp > bg_ptr->conv_table[high]) return -EINVAL; while (low < high) { -- cgit v0.10.2 From 8fb0aebddffa1f3ef97a18dde98cf8003ce8d6c8 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 19 Sep 2012 10:58:28 -0700 Subject: staging: fix silicom dependencies and build errors Fix kconfig dependencies in silicom. Fixes these build errors: ERROR: "init_net" [drivers/staging/silicom/bypasslib/bypass.ko] undefined! ERROR: "register_netdevice_notifier" [drivers/staging/silicom/bpctl_mod.ko] undefined! ERROR: "unregister_netdevice_notifier" [drivers/staging/silicom/bpctl_mod.ko] undefined! ERROR: "init_net" [drivers/staging/silicom/bpctl_mod.ko] undefined! ERROR: "netdev_info" [drivers/net/mii.ko] undefined! ERROR: "netif_carrier_on" [drivers/net/mii.ko] undefined! ERROR: "netif_carrier_off" [drivers/net/mii.ko] undefined! Signed-off-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/silicom/Kconfig b/drivers/staging/silicom/Kconfig index cb07a0d..eda2e7d 100644 --- a/drivers/staging/silicom/Kconfig +++ b/drivers/staging/silicom/Kconfig @@ -19,7 +19,7 @@ if NET_VENDOR_SILICOM config SBYPASS tristate "Silicom BypassCTL library support" - depends on PCI + depends on PCI && NET depends on m ---help--- If you have a network (Ethernet) controller of this type, say Y @@ -29,7 +29,7 @@ config SBYPASS config BPCTL tristate "Silicom BypassCTL net support" - depends on PCI + depends on PCI && NET depends on m select SBYPASS select NET_CORE -- cgit v0.10.2 From f2635894e8e786d7c93a21f24efb690981d15842 Mon Sep 17 00:00:00 2001 From: Adam Buchbinder Date: Wed, 19 Sep 2012 21:51:07 -0400 Subject: staging: Fix misspellings of "whether". "Whether" is spelled "wether" in several places. This fixes those that are in the staging tree. Signed-off-by: Adam Buchbinder Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c index f7426b4..6e9f709 100644 --- a/drivers/staging/panel/panel.c +++ b/drivers/staging/panel/panel.c @@ -1197,7 +1197,7 @@ static inline int handle_lcd_special_code(void) break; } - /* Check wether one flag was changed */ + /* Check whether one flag was changed */ if (oldflags != lcd_flags) { /* check whether one of B,C,D flags were changed */ if ((oldflags ^ lcd_flags) & @@ -1212,7 +1212,7 @@ static inline int handle_lcd_special_code(void) lcd_write_cmd(0x30 | ((lcd_flags & LCD_FLAG_F) ? 4 : 0) | ((lcd_flags & LCD_FLAG_N) ? 8 : 0)); - /* check wether L flag was changed */ + /* check whether L flag was changed */ else if ((oldflags ^ lcd_flags) & (LCD_FLAG_L)) { if (lcd_flags & (LCD_FLAG_L)) lcd_backlight(1); diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c index 99e907d..4feecec 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac.c +++ b/drivers/staging/rtl8192e/rtllib_softmac.c @@ -267,7 +267,7 @@ inline void softmac_mgmt_xmit(struct sk_buff *skb, struct rtllib_device *ieee) else ieee->seq_ctrl[0]++; - /* check wether the managed packet queued greater than 5 */ + /* check whether the managed packet queued greater than 5 */ if (!ieee->check_nic_enough_desc(ieee->dev, tcb_desc->queue_index) || (skb_queue_len(&ieee->skb_waitQ[tcb_desc->queue_index]) != 0) || (ieee->queue_stop)) { diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c index 9f625bc..7a07078 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c @@ -271,7 +271,7 @@ inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee else ieee->seq_ctrl[0]++; - /* check wether the managed packet queued greater than 5 */ + /* check whether the managed packet queued greater than 5 */ if(!ieee->check_nic_enough_desc(ieee->dev,tcb_desc->queue_index)||\ (skb_queue_len(&ieee->skb_waitQ[tcb_desc->queue_index]) != 0)||\ (ieee->queue_stop) ) { -- cgit v0.10.2 From bff6c3e00ca7e56ca82e19ffb722159cf1216d20 Mon Sep 17 00:00:00 2001 From: Adam Buchbinder Date: Wed, 19 Sep 2012 21:51:08 -0400 Subject: staging: Fix spelling of "asynchronous" in comments. "Asychronous" is misspelled in some comments. No code changes. Signed-off-by: Adam Buchbinder Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 58f5922..d0e4844 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -964,7 +964,7 @@ static int rtd_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s) /* cmdtest tests a particular command to see if it is valid. Using the cmdtest ioctl, a user can create a valid cmd - and then have it executed by the cmd ioctl (asyncronously). + and then have it executed by the cmd ioctl (asynchronously). cmdtest returns 1,2,3,4 or 0, depending on which tests the command passes. diff --git a/drivers/staging/csr/sme_blocking.c b/drivers/staging/csr/sme_blocking.c index acf0f0f..543e8f2 100644 --- a/drivers/staging/csr/sme_blocking.c +++ b/drivers/staging/csr/sme_blocking.c @@ -18,10 +18,10 @@ /* - * This file also contains the implementation of the asyncronous + * This file also contains the implementation of the asynchronous * requests to the SME. * - * Before calling an asyncronous SME function, we call sme_init_request() + * Before calling an asynchronous SME function, we call sme_init_request() * which gets hold of the SME semaphore and updates the request status. * The semaphore makes sure that there is only one pending request to * the SME at a time. diff --git a/drivers/staging/telephony/ixj.c b/drivers/staging/telephony/ixj.c index b303c91..1cfa0b0 100644 --- a/drivers/staging/telephony/ixj.c +++ b/drivers/staging/telephony/ixj.c @@ -7057,7 +7057,7 @@ static int ixj_selfprobe(IXJ *j) printk(KERN_INFO "Enable Line Monitor\n"); if (ixjdebug & 0x0002) - printk(KERN_INFO "Set Line Monitor to Asyncronous Mode\n"); + printk(KERN_INFO "Set Line Monitor to Asynchronous Mode\n"); if (ixj_WriteDSPCommand(0x7E01, j)) /* Asynchronous Line Monitor */ return -1; @@ -7068,7 +7068,7 @@ static int ixj_selfprobe(IXJ *j) if (ixj_WriteDSPCommand(0x5151, j)) /* Enable DTMF detection */ return -1; - if (ixj_WriteDSPCommand(0x6E01, j)) /* Set Asyncronous Tone Generation */ + if (ixj_WriteDSPCommand(0x6E01, j)) /* Set Asynchronous Tone Generation */ return -1; set_rec_depth(j, 2); /* Set Record Channel Limit to 2 frames */ -- cgit v0.10.2 From 428ed14f366276550a70014ed80be941d7e721d5 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 20 Sep 2012 11:43:54 +0300 Subject: Staging: ced1401: fix a couple off by one checks nArea is used as an offset into the ->rTransDef[] array which has MAX_TRANSAREAS elements. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ced1401/ced_ioc.c b/drivers/staging/ced1401/ced_ioc.c index 693c454..c9492ed 100644 --- a/drivers/staging/ced1401/ced_ioc.c +++ b/drivers/staging/ced1401/ced_ioc.c @@ -837,7 +837,7 @@ int SetEvent(DEVICE_EXTENSION * pdx, TRANSFEREVENT __user * pTE) int WaitEvent(DEVICE_EXTENSION * pdx, int nArea, int msTimeOut) { int iReturn; - if ((unsigned)nArea > MAX_TRANSAREAS) + if ((unsigned)nArea >= MAX_TRANSAREAS) return U14ERR_BADAREA; else { int iWait; @@ -884,7 +884,7 @@ int WaitEvent(DEVICE_EXTENSION * pdx, int nArea, int msTimeOut) int TestEvent(DEVICE_EXTENSION * pdx, int nArea) { int iReturn; - if ((unsigned)nArea > MAX_TRANSAREAS) + if ((unsigned)nArea >= MAX_TRANSAREAS) iReturn = U14ERR_BADAREA; else { TRANSAREA *pTA = &pdx->rTransDef[nArea]; -- cgit v0.10.2 From 814394100d5bfd5b33cddede907a4e0a216b93b6 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Thu, 20 Sep 2012 20:58:20 +0900 Subject: staging/rts_pstor: Delete some lines (dev_info() and dev_err()) in rtsx.c fixed some coccinelle warnings. + drivers/staging/rts_pstor/rtsx.c:397:16-19: ERROR: dev is NULL but dereferenced. drivers/staging/rts_pstor/rtsx.c:447:16-19: ERROR: dev is NULL but dereferenced. drivers/staging/rts_pstor/rtsx.c:358:16-19: ERROR: dev is NULL but dereferenced. Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/rtsx.c b/drivers/staging/rts_pstor/rtsx.c index 213829e..afe9c2e 100644 --- a/drivers/staging/rts_pstor/rtsx.c +++ b/drivers/staging/rts_pstor/rtsx.c @@ -352,12 +352,8 @@ static int rtsx_suspend(struct pci_dev *pci, pm_message_t state) struct rtsx_dev *dev = (struct rtsx_dev *)pci_get_drvdata(pci); struct rtsx_chip *chip; - dev_info(&dev->pci->dev, "Ready to suspend\n"); - - if (!dev) { - dev_err(&dev->pci->dev, "Invalid memory\n"); + if (!dev) return 0; - } /* lock the device pointers */ mutex_lock(&(dev->dev_mutex)); @@ -391,12 +387,8 @@ static int rtsx_resume(struct pci_dev *pci) struct rtsx_dev *dev = (struct rtsx_dev *)pci_get_drvdata(pci); struct rtsx_chip *chip; - dev_info(&dev->pci->dev, "Ready to resume\n"); - - if (!dev) { - dev_err(&dev->pci->dev, "Invalid memory\n"); + if (!dev) return 0; - } chip = dev->chip; @@ -441,12 +433,8 @@ static void rtsx_shutdown(struct pci_dev *pci) struct rtsx_dev *dev = (struct rtsx_dev *)pci_get_drvdata(pci); struct rtsx_chip *chip; - dev_info(&dev->pci->dev, "Ready to shutdown\n"); - - if (!dev) { - dev_err(&dev->pci->dev, "Invalid memory\n"); + if (!dev) return; - } chip = dev->chip; -- cgit v0.10.2 From 2341111f6dcfad5f81d3de21acc43c97ce56ec60 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Thu, 20 Sep 2012 12:06:35 -0400 Subject: staging:ced1401: use module_usb_driver macro the module init and exit functions that are doing usb_register and usb_deregister respectively can be replaced with module_usb_driver code Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ced1401/usb1401.c b/drivers/staging/ced1401/usb1401.c index 69b7f20..59d69b4 100644 --- a/drivers/staging/ced1401/usb1401.c +++ b/drivers/staging/ced1401/usb1401.c @@ -1653,19 +1653,5 @@ static struct usb_driver ced_driver = { .supports_autosuspend = 1, }; -static int __init usb_skel_init(void) -{ - /* register this driver with the USB subsystem */ - return usb_register(&ced_driver); -} - -static void __exit usb_skel_exit(void) -{ - /* deregister this driver with the USB subsystem */ - usb_deregister(&ced_driver); -} - -module_init(usb_skel_init); -module_exit(usb_skel_exit); - +module_usb_driver(ced_driver); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From bae95b09076abeecd193a8efbc34c00f4309d3f6 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Thu, 20 Sep 2012 12:10:57 -0400 Subject: staging:ced1401: remove read write callbacks from fops As the driver says that read and writes should not be performed and instead the user to kernel transactions are performed through ioctl interface, remove these functions as they are not required Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ced1401/usb1401.c b/drivers/staging/ced1401/usb1401.c index 59d69b4..6ba0ef6 100644 --- a/drivers/staging/ced1401/usb1401.c +++ b/drivers/staging/ced1401/usb1401.c @@ -261,24 +261,6 @@ static int ced_flush(struct file *file, fl_owner_t id) return res; } -static ssize_t ced_read(struct file *file, char *buffer, size_t count, - loff_t * ppos) -{ - DEVICE_EXTENSION *pdx = file->private_data; - dev_err(&pdx->interface->dev, "%s called: use ioctl for cedusb", - __func__); - return 0; // as we do not do reads this way -} - -static ssize_t ced_write(struct file *file, const char *user_buffer, - size_t count, loff_t * ppos) -{ - DEVICE_EXTENSION *pdx = file->private_data; - dev_err(&pdx->interface->dev, "%s called: use ioctl for cedusb", - __func__); - return 0; -} - /*************************************************************************** ** CanAcceptIoRequests ** If the device is removed, interface is set NULL. We also clear our pointer @@ -1402,8 +1384,6 @@ static int ced_ioctl(struct inode *node, struct file *file, unsigned int cmd, static const struct file_operations ced_fops = { .owner = THIS_MODULE, - .read = ced_read, - .write = ced_write, .open = ced_open, .release = ced_release, .flush = ced_flush, -- cgit v0.10.2 From a00979cccb9cc9727b8357f8fdf1c1924c9b73ef Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Wed, 19 Sep 2012 05:16:08 -0400 Subject: staging: sbe-2t3e3: use -ve error return codes in dc_init_descriptor_list the dc_init_descriptor_list actually returns a +ve error return codes, which is abnormal as other functions in kernel return -ve error codes on failure. so replace the return codes of this function with -ve values to make the consistency with the other functions in kernel. Also make the dc_init_descriptor_list static as its never called anywhere except in this file and move the function prototype from the headerfile into the c file as its referred only in this c file. Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/sbe-2t3e3/2t3e3.h b/drivers/staging/sbe-2t3e3/2t3e3.h index 383f2cf..ccad049 100644 --- a/drivers/staging/sbe-2t3e3/2t3e3.h +++ b/drivers/staging/sbe-2t3e3/2t3e3.h @@ -789,7 +789,6 @@ void dc_restart(struct channel *); void dc_receiver_onoff(struct channel *, u32); void dc_transmitter_onoff(struct channel *, u32); void dc_set_loopback(struct channel *, u32); -u32 dc_init_descriptor_list(struct channel *); void dc_clear_descriptor_list(struct channel *); void dc_drop_descriptor_list(struct channel *); void dc_set_output_port(struct channel *); diff --git a/drivers/staging/sbe-2t3e3/dc.c b/drivers/staging/sbe-2t3e3/dc.c index 9e81d90..daadd6e 100644 --- a/drivers/staging/sbe-2t3e3/dc.c +++ b/drivers/staging/sbe-2t3e3/dc.c @@ -17,6 +17,8 @@ #include "2t3e3.h" #include "ctrl.h" +static int dc_init_descriptor_list(struct channel *sc); + void dc_init(struct channel *sc) { u32 val; @@ -307,7 +309,7 @@ void dc_set_loopback(struct channel *sc, u32 mode) SBE_2T3E3_21143_VAL_FULL_DUPLEX_MODE); } -u32 dc_init_descriptor_list(struct channel *sc) +static int dc_init_descriptor_list(struct channel *sc) { u32 i, j; struct sk_buff *m; @@ -317,7 +319,7 @@ u32 dc_init_descriptor_list(struct channel *sc) sizeof(t3e3_rx_desc_t), GFP_KERNEL); if (sc->ether.rx_ring == NULL) { dev_err(&sc->pdev->dev, "SBE 2T3E3: no buffer space for RX ring\n"); - return ENOMEM; + return -ENOMEM; } if (sc->ether.tx_ring == NULL) @@ -327,7 +329,7 @@ u32 dc_init_descriptor_list(struct channel *sc) kfree(sc->ether.rx_ring); sc->ether.rx_ring = NULL; dev_err(&sc->pdev->dev, "SBE 2T3E3: no buffer space for RX ring\n"); - return ENOMEM; + return -ENOMEM; } @@ -351,7 +353,7 @@ u32 dc_init_descriptor_list(struct channel *sc) sc->ether.tx_ring = NULL; dev_err(&sc->pdev->dev, "SBE 2T3E3: token_alloc err:" " no buffer space for RX ring\n"); - return ENOBUFS; + return -ENOBUFS; } sc->ether.rx_data[i] = m; } -- cgit v0.10.2 From b0ba76785eef21ecfa3bcd2f6358f9cebbd8a9db Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 21 Sep 2012 14:00:04 +0800 Subject: staging: tidspbridge: fix return value check in dsp_wdt_init() In case of error, the function clk_get() returns ERR_PTR() and never returns NULL pointer. The NULL test in the error handling should be replaced with IS_ERR(). dpatch engine is used to auto generated this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/tidspbridge/core/wdt.c b/drivers/staging/tidspbridge/core/wdt.c index 1ed1474..e5adad0 100644 --- a/drivers/staging/tidspbridge/core/wdt.c +++ b/drivers/staging/tidspbridge/core/wdt.c @@ -62,9 +62,9 @@ int dsp_wdt_init(void) dsp_wdt.fclk = clk_get(NULL, "wdt3_fck"); - if (dsp_wdt.fclk) { + if (!IS_ERR(dsp_wdt.fclk)) { dsp_wdt.iclk = clk_get(NULL, "wdt3_ick"); - if (!dsp_wdt.iclk) { + if (IS_ERR(dsp_wdt.iclk)) { clk_put(dsp_wdt.fclk); dsp_wdt.fclk = NULL; ret = -EFAULT; -- cgit v0.10.2 From f34170c762e88512796be7f94df80f294d12de95 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Thu, 20 Sep 2012 22:43:44 -0400 Subject: Staging: bcm: Remove typedef for _stIM_sfHostNotify and call directly. This patch removes typedef for _stIM_sfHostNotify, changes the name of the struct from _stIM_sfHostNotify to bcm_stim_sfhostnotify. In addition, any calls to the following typedef "stIM_sfHostNotify" are changed to call the struct directly. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c index b6c20a9..25aa20a 100644 --- a/drivers/staging/bcm/CmHost.c +++ b/drivers/staging/bcm/CmHost.c @@ -1913,7 +1913,7 @@ int get_dsx_sf_data_to_application(struct bcm_mini_adapter *Adapter, UINT uiSFId VOID OverrideServiceFlowParams(struct bcm_mini_adapter *Adapter, PUINT puiBuffer) { B_UINT32 u32NumofSFsinMsg = ntohl(*(puiBuffer + 1)); - stIM_SFHostNotify *pHostInfo = NULL; + struct bcm_stim_sfhostnotify *pHostInfo = NULL; UINT uiSearchRuleIndex = 0; ULONG ulSFID = 0; @@ -1922,7 +1922,7 @@ VOID OverrideServiceFlowParams(struct bcm_mini_adapter *Adapter, PUINT puiBuffer while (u32NumofSFsinMsg != 0 && u32NumofSFsinMsg < NO_OF_QUEUES) { u32NumofSFsinMsg--; - pHostInfo = (stIM_SFHostNotify *)puiBuffer; + pHostInfo = (struct bcm_stim_sfhostnotify *)puiBuffer; puiBuffer = (PUINT)(pHostInfo + 1); ulSFID = ntohl(pHostInfo->SFID); diff --git a/drivers/staging/bcm/cntrl_SignalingInterface.h b/drivers/staging/bcm/cntrl_SignalingInterface.h index 451664b..11b3181 100644 --- a/drivers/staging/bcm/cntrl_SignalingInterface.h +++ b/drivers/staging/bcm/cntrl_SignalingInterface.h @@ -341,13 +341,13 @@ typedef struct stLocalSFDeleteIndication { B_UINT8 u8Padding1[3]; /* < 3 byte Padding */ } stLocalSFDeleteIndication; -typedef struct _stIM_SFHostNotify { +struct bcm_stim_sfhostnotify { B_UINT32 SFID; /* SFID of the service flow */ B_UINT16 newCID; /* the new/changed CID */ B_UINT16 VCID; /* Get new Vcid if the flow has been made active in CID update TLV, but was inactive earlier or the orig vcid */ B_UINT8 RetainSF; /* Indication to Host if the SF is to be retained or deleted; if TRUE-retain else delete */ B_UINT8 QoSParamSet; /* QoS paramset of the retained SF */ B_UINT16 u16reserved; /* For byte alignment */ -} stIM_SFHostNotify; +}; #endif -- cgit v0.10.2 From e692da4d0e587f549ba101015e5f89903ba20b67 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 21 Sep 2012 10:07:47 +0200 Subject: staging: drm/imx: Add i.MX drm core support This patch adds the i.MX glue stuff between i.MX and drm. Signed-off-by: Sascha Hauer Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 025d8c9..0f51a15 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -140,4 +140,6 @@ source "drivers/staging/silicom/Kconfig" source "drivers/staging/ced1401/Kconfig" +source "drivers/staging/imx-drm/Kconfig" + endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 08e9667..f4b2bc4 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -62,3 +62,4 @@ obj-$(CONFIG_OMAP_BANDGAP) += omap-thermal/ obj-$(CONFIG_ZCACHE2) += ramster/ obj-$(CONFIG_NET_VENDOR_SILICOM) += silicom/ obj-$(CONFIG_CED1401) += ced1401/ +obj-$(CONFIG_DRM_IMX) += imx-drm/ diff --git a/drivers/staging/imx-drm/Kconfig b/drivers/staging/imx-drm/Kconfig new file mode 100644 index 0000000..2ef867b --- /dev/null +++ b/drivers/staging/imx-drm/Kconfig @@ -0,0 +1,17 @@ +config DRM_IMX + tristate "DRM Support for Freescale i.MX" + select DRM_KMS_HELPER + select DRM_GEM_CMA_HELPER + select DRM_KMS_CMA_HELPER + depends on DRM && ARCH_MXC + help + enable i.MX graphics support + +config DRM_IMX_FB_HELPER + tristate "provide legacy framebuffer /dev/fb0" + select DRM_KMS_CMA_HELPER + depends on DRM_IMX + help + The DRM framework can provide a legacy /dev/fb0 framebuffer + for your device. This is necessary to get a framebuffer console + and also for appplications using the legacy framebuffer API diff --git a/drivers/staging/imx-drm/Makefile b/drivers/staging/imx-drm/Makefile new file mode 100644 index 0000000..ff825f7 --- /dev/null +++ b/drivers/staging/imx-drm/Makefile @@ -0,0 +1,6 @@ + +imxdrm-objs := imx-drm-core.o imx-fb.o + +obj-$(CONFIG_DRM_IMX) += imxdrm.o + +obj-$(CONFIG_DRM_IMX_FB_HELPER) += imx-fbdev.o diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c new file mode 100644 index 0000000..225e835 --- /dev/null +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -0,0 +1,882 @@ +/* + * Freescale i.MX drm driver + * + * Copyright (C) 2011 Sascha Hauer, Pengutronix + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "imx-drm.h" + +#define MAX_CRTC 4 + +struct crtc_cookie { + void *cookie; + int id; + struct list_head list; +}; + +struct imx_drm_device { + struct drm_device *drm; + struct device *dev; + struct list_head crtc_list; + struct list_head encoder_list; + struct list_head connector_list; + struct mutex mutex; + int references; + int pipes; + struct drm_fbdev_cma *fbhelper; +}; + +struct imx_drm_crtc { + struct drm_crtc *crtc; + struct list_head list; + struct imx_drm_device *imxdrm; + int pipe; + struct imx_drm_crtc_helper_funcs imx_drm_helper_funcs; + struct module *owner; + struct crtc_cookie cookie; +}; + +struct imx_drm_encoder { + struct drm_encoder *encoder; + struct list_head list; + struct module *owner; + struct list_head possible_crtcs; +}; + +struct imx_drm_connector { + struct drm_connector *connector; + struct list_head list; + struct module *owner; +}; + +static int imx_drm_driver_firstopen(struct drm_device *drm) +{ + if (!imx_drm_device_get()) + return -EINVAL; + + return 0; +} + +static void imx_drm_driver_lastclose(struct drm_device *drm) +{ + struct imx_drm_device *imxdrm = drm->dev_private; + + if (imxdrm->fbhelper) + drm_fbdev_cma_restore_mode(imxdrm->fbhelper); + + imx_drm_device_put(); +} + +static int imx_drm_driver_unload(struct drm_device *drm) +{ + struct imx_drm_device *imxdrm = drm->dev_private; + + drm_mode_config_cleanup(imxdrm->drm); + drm_kms_helper_poll_fini(imxdrm->drm); + + return 0; +} + +/* + * We don't care at all for crtc numbers, but the core expects the + * crtcs to be numbered + */ +static struct imx_drm_crtc *imx_drm_crtc_by_num(struct imx_drm_device *imxdrm, + int num) +{ + struct imx_drm_crtc *imx_drm_crtc; + + list_for_each_entry(imx_drm_crtc, &imxdrm->crtc_list, list) + if (imx_drm_crtc->pipe == num) + return imx_drm_crtc; + return NULL; +} + +int imx_drm_crtc_panel_format(struct drm_crtc *crtc, u32 encoder_type, + u32 interface_pix_fmt) +{ + struct imx_drm_device *imxdrm = crtc->dev->dev_private; + struct imx_drm_crtc *imx_crtc; + struct imx_drm_crtc_helper_funcs *helper; + + mutex_lock(&imxdrm->mutex); + + list_for_each_entry(imx_crtc, &imxdrm->crtc_list, list) + if (imx_crtc->crtc == crtc) + goto found; + + mutex_unlock(&imxdrm->mutex); + + return -EINVAL; +found: + mutex_unlock(&imxdrm->mutex); + + helper = &imx_crtc->imx_drm_helper_funcs; + if (helper->set_interface_pix_fmt) + return helper->set_interface_pix_fmt(crtc, + encoder_type, interface_pix_fmt); + return 0; +} + +int imx_drm_crtc_vblank_get(struct imx_drm_crtc *imx_drm_crtc) +{ + return drm_vblank_get(imx_drm_crtc->imxdrm->drm, imx_drm_crtc->pipe); +} +EXPORT_SYMBOL_GPL(imx_drm_crtc_vblank_get); + +void imx_drm_crtc_vblank_put(struct imx_drm_crtc *imx_drm_crtc) +{ + drm_vblank_put(imx_drm_crtc->imxdrm->drm, imx_drm_crtc->pipe); +} +EXPORT_SYMBOL_GPL(imx_drm_crtc_vblank_put); + +void imx_drm_handle_vblank(struct imx_drm_crtc *imx_drm_crtc) +{ + drm_handle_vblank(imx_drm_crtc->imxdrm->drm, imx_drm_crtc->pipe); +} +EXPORT_SYMBOL_GPL(imx_drm_handle_vblank); + +static int imx_drm_enable_vblank(struct drm_device *drm, int crtc) +{ + struct imx_drm_device *imxdrm = drm->dev_private; + struct imx_drm_crtc *imx_drm_crtc; + int ret; + + imx_drm_crtc = imx_drm_crtc_by_num(imxdrm, crtc); + if (!imx_drm_crtc) + return -EINVAL; + + if (!imx_drm_crtc->imx_drm_helper_funcs.enable_vblank) + return -ENOSYS; + + ret = imx_drm_crtc->imx_drm_helper_funcs.enable_vblank( + imx_drm_crtc->crtc); + + return ret; +} + +static void imx_drm_disable_vblank(struct drm_device *drm, int crtc) +{ + struct imx_drm_device *imxdrm = drm->dev_private; + struct imx_drm_crtc *imx_drm_crtc; + + imx_drm_crtc = imx_drm_crtc_by_num(imxdrm, crtc); + if (!imx_drm_crtc) + return; + + if (!imx_drm_crtc->imx_drm_helper_funcs.disable_vblank) + return; + + imx_drm_crtc->imx_drm_helper_funcs.disable_vblank(imx_drm_crtc->crtc); +} + +static const struct file_operations imx_drm_driver_fops = { + .owner = THIS_MODULE, + .open = drm_open, + .release = drm_release, + .unlocked_ioctl = drm_ioctl, + .mmap = drm_gem_cma_mmap, + .poll = drm_poll, + .fasync = drm_fasync, + .read = drm_read, + .llseek = noop_llseek, +}; + +static struct imx_drm_device *imx_drm_device; + +static struct imx_drm_device *__imx_drm_device(void) +{ + return imx_drm_device; +} + +struct drm_device *imx_drm_device_get(void) +{ + struct imx_drm_device *imxdrm = __imx_drm_device(); + struct imx_drm_encoder *enc; + struct imx_drm_connector *con; + struct imx_drm_crtc *crtc; + + mutex_lock(&imxdrm->mutex); + + list_for_each_entry(enc, &imxdrm->encoder_list, list) { + if (!try_module_get(enc->owner)) { + dev_err(imxdrm->dev, "could not get module %s\n", + module_name(enc->owner)); + goto unwind_enc; + } + } + + list_for_each_entry(con, &imxdrm->connector_list, list) { + if (!try_module_get(con->owner)) { + dev_err(imxdrm->dev, "could not get module %s\n", + module_name(con->owner)); + goto unwind_con; + } + } + + list_for_each_entry(crtc, &imxdrm->crtc_list, list) { + if (!try_module_get(crtc->owner)) { + dev_err(imxdrm->dev, "could not get module %s\n", + module_name(crtc->owner)); + goto unwind_crtc; + } + } + + imxdrm->references++; + + mutex_unlock(&imxdrm->mutex); + + return imxdrm->drm; + +unwind_crtc: + list_for_each_entry_continue_reverse(crtc, &imxdrm->crtc_list, list) + module_put(crtc->owner); +unwind_con: + list_for_each_entry_continue_reverse(con, &imxdrm->connector_list, list) + module_put(con->owner); +unwind_enc: + list_for_each_entry_continue_reverse(enc, &imxdrm->encoder_list, list) + module_put(enc->owner); + + mutex_unlock(&imxdrm->mutex); + + return NULL; + +} +EXPORT_SYMBOL_GPL(imx_drm_device_get); + +void imx_drm_device_put(void) +{ + struct imx_drm_device *imxdrm = __imx_drm_device(); + struct imx_drm_encoder *enc; + struct imx_drm_connector *con; + struct imx_drm_crtc *crtc; + + mutex_lock(&imxdrm->mutex); + + list_for_each_entry(crtc, &imxdrm->crtc_list, list) + module_put(crtc->owner); + + list_for_each_entry(con, &imxdrm->connector_list, list) + module_put(con->owner); + + list_for_each_entry(enc, &imxdrm->encoder_list, list) + module_put(enc->owner); + + imxdrm->references--; + + mutex_unlock(&imxdrm->mutex); +} +EXPORT_SYMBOL_GPL(imx_drm_device_put); + +static int drm_mode_group_reinit(struct drm_device *dev) +{ + struct drm_mode_group *group = &dev->primary->mode_group; + uint32_t *id_list = group->id_list; + int ret; + + ret = drm_mode_group_init_legacy_group(dev, group); + if (ret < 0) + return ret; + + kfree(id_list); + return 0; +} + +/* + * register an encoder to the drm core + */ +static int imx_drm_encoder_register(struct imx_drm_encoder *imx_drm_encoder) +{ + struct imx_drm_device *imxdrm = __imx_drm_device(); + + INIT_LIST_HEAD(&imx_drm_encoder->possible_crtcs); + + drm_encoder_init(imxdrm->drm, imx_drm_encoder->encoder, + imx_drm_encoder->encoder->funcs, + imx_drm_encoder->encoder->encoder_type); + + drm_mode_group_reinit(imxdrm->drm); + + return 0; +} + +/* + * unregister an encoder from the drm core + */ +static void imx_drm_encoder_unregister(struct imx_drm_encoder + *imx_drm_encoder) +{ + struct imx_drm_device *imxdrm = __imx_drm_device(); + + drm_encoder_cleanup(imx_drm_encoder->encoder); + + drm_mode_group_reinit(imxdrm->drm); +} + +/* + * register a connector to the drm core + */ +static int imx_drm_connector_register( + struct imx_drm_connector *imx_drm_connector) +{ + struct imx_drm_device *imxdrm = __imx_drm_device(); + + drm_connector_init(imxdrm->drm, imx_drm_connector->connector, + imx_drm_connector->connector->funcs, + imx_drm_connector->connector->connector_type); + drm_mode_group_reinit(imxdrm->drm); + + return drm_sysfs_connector_add(imx_drm_connector->connector); +} + +/* + * unregister a connector from the drm core + */ +static void imx_drm_connector_unregister( + struct imx_drm_connector *imx_drm_connector) +{ + struct imx_drm_device *imxdrm = __imx_drm_device(); + + drm_sysfs_connector_remove(imx_drm_connector->connector); + drm_connector_cleanup(imx_drm_connector->connector); + + drm_mode_group_reinit(imxdrm->drm); +} + +/* + * register a crtc to the drm core + */ +static int imx_drm_crtc_register(struct imx_drm_crtc *imx_drm_crtc) +{ + struct imx_drm_device *imxdrm = __imx_drm_device(); + int ret; + + drm_crtc_init(imxdrm->drm, imx_drm_crtc->crtc, + imx_drm_crtc->imx_drm_helper_funcs.crtc_funcs); + ret = drm_mode_crtc_set_gamma_size(imx_drm_crtc->crtc, 256); + if (ret) + return ret; + + drm_crtc_helper_add(imx_drm_crtc->crtc, + imx_drm_crtc->imx_drm_helper_funcs.crtc_helper_funcs); + + drm_mode_group_reinit(imxdrm->drm); + + return 0; +} + +/* + * Called by the CRTC driver when all CRTCs are registered. This + * puts all the pieces together and initializes the driver. + * Once this is called no more CRTCs can be registered since + * the drm core has hardcoded the number of crtcs in several + * places. + */ +static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags) +{ + struct imx_drm_device *imxdrm = __imx_drm_device(); + int ret; + + imxdrm->drm = drm; + + drm->dev_private = imxdrm; + + /* + * enable drm irq mode. + * - with irq_enabled = 1, we can use the vblank feature. + * + * P.S. note that we wouldn't use drm irq handler but + * just specific driver own one instead because + * drm framework supports only one irq handler and + * drivers can well take care of their interrupts + */ + drm->irq_enabled = 1; + + drm_mode_config_init(drm); + imx_drm_mode_config_init(drm); + + mutex_lock(&imxdrm->mutex); + + drm_kms_helper_poll_init(imxdrm->drm); + + /* setup the grouping for the legacy output */ + ret = drm_mode_group_init_legacy_group(imxdrm->drm, + &imxdrm->drm->primary->mode_group); + if (ret) + goto err_init; + + ret = drm_vblank_init(imxdrm->drm, MAX_CRTC); + if (ret) + goto err_init; + + /* + * with vblank_disable_allowed = 1, vblank interrupt will be disabled + * by drm timer once a current process gives up ownership of + * vblank event.(after drm_vblank_put function is called) + */ + imxdrm->drm->vblank_disable_allowed = 1; + + ret = 0; + +err_init: + mutex_unlock(&imxdrm->mutex); + + return ret; +} + +static void imx_drm_update_possible_crtcs(void) +{ + struct imx_drm_device *imxdrm = __imx_drm_device(); + struct imx_drm_crtc *imx_drm_crtc; + struct imx_drm_encoder *enc; + struct crtc_cookie *cookie; + + list_for_each_entry(enc, &imxdrm->encoder_list, list) { + u32 possible_crtcs = 0; + + list_for_each_entry(cookie, &enc->possible_crtcs, list) { + list_for_each_entry(imx_drm_crtc, &imxdrm->crtc_list, list) { + if (imx_drm_crtc->cookie.cookie == cookie->cookie && + imx_drm_crtc->cookie.id == cookie->id) { + possible_crtcs |= 1 << imx_drm_crtc->pipe; + } + } + } + enc->encoder->possible_crtcs = possible_crtcs; + enc->encoder->possible_clones = possible_crtcs; + } +} + +/* + * imx_drm_add_crtc - add a new crtc + * + * The return value if !NULL is a cookie for the caller to pass to + * imx_drm_remove_crtc later. + */ +int imx_drm_add_crtc(struct drm_crtc *crtc, + struct imx_drm_crtc **new_crtc, + const struct imx_drm_crtc_helper_funcs *imx_drm_helper_funcs, + struct module *owner, void *cookie, int id) +{ + struct imx_drm_device *imxdrm = __imx_drm_device(); + struct imx_drm_crtc *imx_drm_crtc; + const struct drm_crtc_funcs *crtc_funcs; + int ret; + + mutex_lock(&imxdrm->mutex); + + if (imxdrm->references) { + ret = -EBUSY; + goto err_busy; + } + + imx_drm_crtc = kzalloc(sizeof(*imx_drm_crtc), GFP_KERNEL); + if (!imx_drm_crtc) { + ret = -ENOMEM; + goto err_alloc; + } + + imx_drm_crtc->imx_drm_helper_funcs = *imx_drm_helper_funcs; + imx_drm_crtc->pipe = imxdrm->pipes++; + imx_drm_crtc->cookie.cookie = cookie; + imx_drm_crtc->cookie.id = id; + + crtc_funcs = imx_drm_helper_funcs->crtc_funcs; + + imx_drm_crtc->crtc = crtc; + imx_drm_crtc->imxdrm = imxdrm; + + imx_drm_crtc->owner = owner; + + list_add_tail(&imx_drm_crtc->list, &imxdrm->crtc_list); + + *new_crtc = imx_drm_crtc; + + ret = imx_drm_crtc_register(imx_drm_crtc); + if (ret) + goto err_register; + + imx_drm_update_possible_crtcs(); + + mutex_unlock(&imxdrm->mutex); + + return 0; + +err_register: + kfree(imx_drm_crtc); +err_alloc: +err_busy: + mutex_unlock(&imxdrm->mutex); + return ret; +} +EXPORT_SYMBOL_GPL(imx_drm_add_crtc); + +/* + * imx_drm_remove_crtc - remove a crtc + */ +int imx_drm_remove_crtc(struct imx_drm_crtc *imx_drm_crtc) +{ + struct imx_drm_device *imxdrm = imx_drm_crtc->imxdrm; + + mutex_lock(&imxdrm->mutex); + + drm_crtc_cleanup(imx_drm_crtc->crtc); + + list_del(&imx_drm_crtc->list); + + drm_mode_group_reinit(imxdrm->drm); + + mutex_unlock(&imxdrm->mutex); + + kfree(imx_drm_crtc); + + return 0; +} +EXPORT_SYMBOL_GPL(imx_drm_remove_crtc); + +/* + * imx_drm_add_encoder - add a new encoder + */ +int imx_drm_add_encoder(struct drm_encoder *encoder, + struct imx_drm_encoder **newenc, struct module *owner) +{ + struct imx_drm_device *imxdrm = __imx_drm_device(); + struct imx_drm_encoder *imx_drm_encoder; + int ret; + + mutex_lock(&imxdrm->mutex); + + if (imxdrm->references) { + ret = -EBUSY; + goto err_busy; + } + + imx_drm_encoder = kzalloc(sizeof(*imx_drm_encoder), GFP_KERNEL); + if (!imx_drm_encoder) { + ret = -ENOMEM; + goto err_alloc; + } + + imx_drm_encoder->encoder = encoder; + imx_drm_encoder->owner = owner; + + ret = imx_drm_encoder_register(imx_drm_encoder); + if (ret) { + kfree(imx_drm_encoder); + ret = -ENOMEM; + goto err_register; + } + + list_add_tail(&imx_drm_encoder->list, &imxdrm->encoder_list); + + *newenc = imx_drm_encoder; + + mutex_unlock(&imxdrm->mutex); + + return 0; + +err_register: + kfree(imx_drm_encoder); +err_alloc: +err_busy: + mutex_unlock(&imxdrm->mutex); + + return ret; +} +EXPORT_SYMBOL_GPL(imx_drm_add_encoder); + +int imx_drm_encoder_add_possible_crtcs( + struct imx_drm_encoder *imx_drm_encoder, + struct device_node *np) +{ + struct imx_drm_device *imxdrm = __imx_drm_device(); + struct of_phandle_args args; + struct crtc_cookie *c; + int ret = 0; + int i; + + if (!list_empty(&imx_drm_encoder->possible_crtcs)) + return -EBUSY; + + for (i = 0; !ret; i++) { + ret = of_parse_phandle_with_args(np, "crtcs", + "#crtc-cells", i, &args); + if (ret < 0) + break; + + c = kzalloc(sizeof(*c), GFP_KERNEL); + if (!c) { + of_node_put(args.np); + return -ENOMEM; + } + + c->cookie = args.np; + c->id = args.args_count > 0 ? args.args[0] : 0; + + of_node_put(args.np); + + mutex_lock(&imxdrm->mutex); + + list_add_tail(&c->list, &imx_drm_encoder->possible_crtcs); + + mutex_unlock(&imxdrm->mutex); + } + + imx_drm_update_possible_crtcs(); + + return 0; +} + +int imx_drm_encoder_get_mux_id(struct imx_drm_encoder *imx_drm_encoder, + struct drm_crtc *crtc) +{ + struct imx_drm_device *imxdrm = __imx_drm_device(); + struct imx_drm_crtc *imx_crtc; + int i = 0; + + mutex_lock(&imxdrm->mutex); + + list_for_each_entry(imx_crtc, &imxdrm->crtc_list, list) { + if (imx_crtc->crtc == crtc) + goto found; + i++; + } + + mutex_unlock(&imxdrm->mutex); + + return -EINVAL; +found: + mutex_unlock(&imxdrm->mutex); + + return i; +} + +/* + * imx_drm_remove_encoder - remove an encoder + */ +int imx_drm_remove_encoder(struct imx_drm_encoder *imx_drm_encoder) +{ + struct imx_drm_device *imxdrm = __imx_drm_device(); + struct crtc_cookie *c, *tmp; + + mutex_lock(&imxdrm->mutex); + + imx_drm_encoder_unregister(imx_drm_encoder); + + list_del(&imx_drm_encoder->list); + + list_for_each_entry_safe(c, tmp, &imx_drm_encoder->possible_crtcs, + list) + kfree(c); + + mutex_unlock(&imxdrm->mutex); + + kfree(imx_drm_encoder); + + return 0; +} +EXPORT_SYMBOL_GPL(imx_drm_remove_encoder); + +/* + * imx_drm_add_connector - add a connector + */ +int imx_drm_add_connector(struct drm_connector *connector, + struct imx_drm_connector **new_con, + struct module *owner) +{ + struct imx_drm_device *imxdrm = __imx_drm_device(); + struct imx_drm_connector *imx_drm_connector; + int ret; + + mutex_lock(&imxdrm->mutex); + + if (imxdrm->references) { + ret = -EBUSY; + goto err_busy; + } + + imx_drm_connector = kzalloc(sizeof(*imx_drm_connector), GFP_KERNEL); + if (!imx_drm_connector) { + ret = -ENOMEM; + goto err_alloc; + } + + imx_drm_connector->connector = connector; + imx_drm_connector->owner = owner; + + ret = imx_drm_connector_register(imx_drm_connector); + if (ret) + goto err_register; + + list_add_tail(&imx_drm_connector->list, &imxdrm->connector_list); + + *new_con = imx_drm_connector; + + mutex_unlock(&imxdrm->mutex); + + return 0; + +err_register: + kfree(imx_drm_connector); +err_alloc: +err_busy: + mutex_unlock(&imxdrm->mutex); + + return ret; +} +EXPORT_SYMBOL_GPL(imx_drm_add_connector); + +void imx_drm_fb_helper_set(struct drm_fbdev_cma *fbdev_helper) +{ + struct imx_drm_device *imxdrm = __imx_drm_device(); + + imxdrm->fbhelper = fbdev_helper; +} +EXPORT_SYMBOL_GPL(imx_drm_fb_helper_set); + +/* + * imx_drm_remove_connector - remove a connector + */ +int imx_drm_remove_connector(struct imx_drm_connector *imx_drm_connector) +{ + struct imx_drm_device *imxdrm = __imx_drm_device(); + + mutex_lock(&imxdrm->mutex); + + imx_drm_connector_unregister(imx_drm_connector); + + list_del(&imx_drm_connector->list); + + mutex_unlock(&imxdrm->mutex); + + kfree(imx_drm_connector); + + return 0; +} +EXPORT_SYMBOL_GPL(imx_drm_remove_connector); + +static struct drm_ioctl_desc imx_drm_ioctls[] = { + /* none so far */ +}; + +static struct drm_driver imx_drm_driver = { + .driver_features = DRIVER_MODESET | DRIVER_GEM, + .load = imx_drm_driver_load, + .unload = imx_drm_driver_unload, + .firstopen = imx_drm_driver_firstopen, + .lastclose = imx_drm_driver_lastclose, + .gem_free_object = drm_gem_cma_free_object, + .gem_vm_ops = &drm_gem_cma_vm_ops, + .dumb_create = drm_gem_cma_dumb_create, + .dumb_map_offset = drm_gem_cma_dumb_map_offset, + .dumb_destroy = drm_gem_cma_dumb_destroy, + + .get_vblank_counter = drm_vblank_count, + .enable_vblank = imx_drm_enable_vblank, + .disable_vblank = imx_drm_disable_vblank, + .ioctls = imx_drm_ioctls, + .num_ioctls = ARRAY_SIZE(imx_drm_ioctls), + .fops = &imx_drm_driver_fops, + .name = "imx-drm", + .desc = "i.MX DRM graphics", + .date = "20120507", + .major = 1, + .minor = 0, + .patchlevel = 0, +}; + +static int imx_drm_platform_probe(struct platform_device *pdev) +{ + imx_drm_device->dev = &pdev->dev; + + return drm_platform_init(&imx_drm_driver, pdev); +} + +static int imx_drm_platform_remove(struct platform_device *pdev) +{ + drm_platform_exit(&imx_drm_driver, pdev); + + return 0; +} + +static struct platform_driver imx_drm_pdrv = { + .probe = imx_drm_platform_probe, + .remove = __devexit_p(imx_drm_platform_remove), + .driver = { + .owner = THIS_MODULE, + .name = "imx-drm", + }, +}; + +static struct platform_device *imx_drm_pdev; + +static int __init imx_drm_init(void) +{ + int ret; + + imx_drm_device = kzalloc(sizeof(*imx_drm_device), GFP_KERNEL); + if (!imx_drm_device) + return -ENOMEM; + + mutex_init(&imx_drm_device->mutex); + INIT_LIST_HEAD(&imx_drm_device->crtc_list); + INIT_LIST_HEAD(&imx_drm_device->connector_list); + INIT_LIST_HEAD(&imx_drm_device->encoder_list); + + imx_drm_pdev = platform_device_register_simple("imx-drm", -1, NULL, 0); + if (!imx_drm_pdev) { + ret = -EINVAL; + goto err_pdev; + } + + imx_drm_pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32), + + ret = platform_driver_register(&imx_drm_pdrv); + if (ret) + goto err_pdrv; + + return 0; + +err_pdrv: + platform_device_unregister(imx_drm_pdev); +err_pdev: + kfree(imx_drm_device); + + return ret; +} + +static void __exit imx_drm_exit(void) +{ + platform_device_unregister(imx_drm_pdev); + platform_driver_unregister(&imx_drm_pdrv); + + kfree(imx_drm_device); +} + +module_init(imx_drm_init); +module_exit(imx_drm_exit); + +MODULE_AUTHOR("Sascha Hauer "); +MODULE_DESCRIPTION("i.MX drm driver core"); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/imx-drm/imx-drm.h b/drivers/staging/imx-drm/imx-drm.h new file mode 100644 index 0000000..ae28a49 --- /dev/null +++ b/drivers/staging/imx-drm/imx-drm.h @@ -0,0 +1,58 @@ +#ifndef _IMX_DRM_H_ +#define _IMX_DRM_H_ + +struct imx_drm_crtc; +struct drm_fbdev_cma; + +struct imx_drm_crtc_helper_funcs { + int (*enable_vblank)(struct drm_crtc *crtc); + void (*disable_vblank)(struct drm_crtc *crtc); + int (*set_interface_pix_fmt)(struct drm_crtc *crtc, u32 encoder_type, + u32 pix_fmt); + const struct drm_crtc_helper_funcs *crtc_helper_funcs; + const struct drm_crtc_funcs *crtc_funcs; +}; + +int imx_drm_add_crtc(struct drm_crtc *crtc, + struct imx_drm_crtc **new_crtc, + const struct imx_drm_crtc_helper_funcs *imx_helper_funcs, + struct module *owner, void *cookie, int id); +int imx_drm_remove_crtc(struct imx_drm_crtc *); +int imx_drm_init_drm(struct platform_device *pdev, + int preferred_bpp); +int imx_drm_exit_drm(void); + +int imx_drm_crtc_vblank_get(struct imx_drm_crtc *imx_drm_crtc); +void imx_drm_crtc_vblank_put(struct imx_drm_crtc *imx_drm_crtc); +void imx_drm_handle_vblank(struct imx_drm_crtc *imx_drm_crtc); + +struct imx_drm_encoder; +int imx_drm_add_encoder(struct drm_encoder *encoder, + struct imx_drm_encoder **new_enc, + struct module *owner); +int imx_drm_remove_encoder(struct imx_drm_encoder *); + +struct imx_drm_connector; +int imx_drm_add_connector(struct drm_connector *connector, + struct imx_drm_connector **new_con, + struct module *owner); +int imx_drm_remove_connector(struct imx_drm_connector *); + +void imx_drm_mode_config_init(struct drm_device *drm); + +struct drm_gem_cma_object *imx_drm_fb_get_obj(struct drm_framebuffer *fb); + +struct drm_device *imx_drm_device_get(void); +void imx_drm_device_put(void); +int imx_drm_crtc_panel_format(struct drm_crtc *crtc, u32 encoder_type, + u32 interface_pix_fmt); +void imx_drm_fb_helper_set(struct drm_fbdev_cma *fbdev_helper); + +struct device_node; + +int imx_drm_encoder_get_mux_id(struct imx_drm_encoder *imx_drm_encoder, + struct drm_crtc *crtc); +int imx_drm_encoder_add_possible_crtcs(struct imx_drm_encoder *imx_drm_encoder, + struct device_node *np); + +#endif /* _IMX_DRM_H_ */ diff --git a/drivers/staging/imx-drm/imx-fb.c b/drivers/staging/imx-drm/imx-fb.c new file mode 100644 index 0000000..03a7b4e --- /dev/null +++ b/drivers/staging/imx-drm/imx-fb.c @@ -0,0 +1,47 @@ +/* + * i.MX drm driver + * + * Copyright (C) 2012 Sascha Hauer, Pengutronix + * + * Based on Samsung Exynos code + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include + +#include "imx-drm.h" + +static struct drm_mode_config_funcs imx_drm_mode_config_funcs = { + .fb_create = drm_fb_cma_create, +}; + +void imx_drm_mode_config_init(struct drm_device *dev) +{ + dev->mode_config.min_width = 64; + dev->mode_config.min_height = 64; + + /* + * set max width and height as default value(4096x4096). + * this value would be used to check framebuffer size limitation + * at drm_mode_addfb(). + */ + dev->mode_config.max_width = 4096; + dev->mode_config.max_height = 4096; + + dev->mode_config.funcs = &imx_drm_mode_config_funcs; +} diff --git a/drivers/staging/imx-drm/imx-fbdev.c b/drivers/staging/imx-drm/imx-fbdev.c new file mode 100644 index 0000000..8331739 --- /dev/null +++ b/drivers/staging/imx-drm/imx-fbdev.c @@ -0,0 +1,74 @@ +/* + * i.MX drm driver + * + * Copyright (C) 2012 Sascha Hauer, Pengutronix + * + * Based on Samsung Exynos code + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include + +#include "imx-drm.h" + +#define MAX_CONNECTOR 4 +#define PREFERRED_BPP 16 + +static struct drm_fbdev_cma *fbdev_cma; + +static int legacyfb_depth = 16; + +module_param(legacyfb_depth, int, 0444); + +static int __init imx_fb_helper_init(void) +{ + struct drm_device *drm = imx_drm_device_get(); + + if (!drm) + return -EINVAL; + + if (legacyfb_depth != 16 && legacyfb_depth != 32) { + pr_warn("i.MX legacyfb: invalid legacyfb_depth setting. defaulting to 16bpp\n"); + legacyfb_depth = 16; + } + + fbdev_cma = drm_fbdev_cma_init(drm, legacyfb_depth, + drm->mode_config.num_crtc, MAX_CONNECTOR); + + if (IS_ERR(fbdev_cma)) { + imx_drm_device_put(); + return PTR_ERR(fbdev_cma); + } + + imx_drm_fb_helper_set(fbdev_cma); + + return 0; +} + +static void __exit imx_fb_helper_exit(void) +{ + imx_drm_fb_helper_set(NULL); + drm_fbdev_cma_fini(fbdev_cma); + imx_drm_device_put(); +} + +late_initcall(imx_fb_helper_init); +module_exit(imx_fb_helper_exit); + +MODULE_DESCRIPTION("Freescale i.MX legacy fb driver"); +MODULE_AUTHOR("Sascha Hauer, Pengutronix"); +MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 19022aaae677dfa171a719e9d1ff04823ce65a65 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 21 Sep 2012 10:07:48 +0200 Subject: staging: drm/imx: Add parallel display support This adds support for parallel displays for i.MX. It consists of a drm encoder/connector pair which eventually passes EDID data from the devicetree to the drm core. Signed-off-by: Sascha Hauer Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/imx-drm/Kconfig b/drivers/staging/imx-drm/Kconfig index 2ef867b..9e27012 100644 --- a/drivers/staging/imx-drm/Kconfig +++ b/drivers/staging/imx-drm/Kconfig @@ -15,3 +15,7 @@ config DRM_IMX_FB_HELPER The DRM framework can provide a legacy /dev/fb0 framebuffer for your device. This is necessary to get a framebuffer console and also for appplications using the legacy framebuffer API + +config DRM_IMX_PARALLEL_DISPLAY + tristate "Support for parallel displays" + depends on DRM_IMX diff --git a/drivers/staging/imx-drm/Makefile b/drivers/staging/imx-drm/Makefile index ff825f7..c8f582e 100644 --- a/drivers/staging/imx-drm/Makefile +++ b/drivers/staging/imx-drm/Makefile @@ -3,4 +3,5 @@ imxdrm-objs := imx-drm-core.o imx-fb.o obj-$(CONFIG_DRM_IMX) += imxdrm.o +obj-$(CONFIG_DRM_IMX_PARALLEL_DISPLAY) += parallel-display.o obj-$(CONFIG_DRM_IMX_FB_HELPER) += imx-fbdev.o diff --git a/drivers/staging/imx-drm/parallel-display.c b/drivers/staging/imx-drm/parallel-display.c new file mode 100644 index 0000000..9b51d73 --- /dev/null +++ b/drivers/staging/imx-drm/parallel-display.c @@ -0,0 +1,261 @@ +/* + * i.MX drm driver - parallel display implementation + * + * Copyright (C) 2012 Sascha Hauer, Pengutronix + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include + +#include "imx-drm.h" + +#define con_to_imxpd(x) container_of(x, struct imx_parallel_display, connector) +#define enc_to_imxpd(x) container_of(x, struct imx_parallel_display, encoder) + +struct imx_parallel_display { + struct drm_connector connector; + struct imx_drm_connector *imx_drm_connector; + struct drm_encoder encoder; + struct imx_drm_encoder *imx_drm_encoder; + struct device *dev; + void *edid; + int edid_len; + u32 interface_pix_fmt; + int mode_valid; + struct drm_display_mode mode; +}; + +static enum drm_connector_status imx_pd_connector_detect( + struct drm_connector *connector, bool force) +{ + return connector_status_connected; +} + +static void imx_pd_connector_destroy(struct drm_connector *connector) +{ + /* do not free here */ +} + +static int imx_pd_connector_get_modes(struct drm_connector *connector) +{ + struct imx_parallel_display *imxpd = con_to_imxpd(connector); + int num_modes = 0; + + if (imxpd->edid) { + drm_mode_connector_update_edid_property(connector, imxpd->edid); + num_modes = drm_add_edid_modes(connector, imxpd->edid); + } + + if (imxpd->mode_valid) { + struct drm_display_mode *mode = drm_mode_create(connector->dev); + drm_mode_copy(mode, &imxpd->mode); + mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, + drm_mode_probed_add(connector, mode); + num_modes++; + } + + return num_modes; +} + +static int imx_pd_connector_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) +{ + return 0; +} + +static struct drm_encoder *imx_pd_connector_best_encoder( + struct drm_connector *connector) +{ + struct imx_parallel_display *imxpd = con_to_imxpd(connector); + + return &imxpd->encoder; +} + +static void imx_pd_encoder_dpms(struct drm_encoder *encoder, int mode) +{ +} + +static bool imx_pd_encoder_mode_fixup(struct drm_encoder *encoder, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + return true; +} + +static void imx_pd_encoder_prepare(struct drm_encoder *encoder) +{ + struct imx_parallel_display *imxpd = enc_to_imxpd(encoder); + + imx_drm_crtc_panel_format(encoder->crtc, DRM_MODE_ENCODER_NONE, + imxpd->interface_pix_fmt); +} + +static void imx_pd_encoder_commit(struct drm_encoder *encoder) +{ +} + +static void imx_pd_encoder_mode_set(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ +} + +static void imx_pd_encoder_disable(struct drm_encoder *encoder) +{ +} + +static void imx_pd_encoder_destroy(struct drm_encoder *encoder) +{ + /* do not free here */ +} + +static struct drm_connector_funcs imx_pd_connector_funcs = { + .dpms = drm_helper_connector_dpms, + .fill_modes = drm_helper_probe_single_connector_modes, + .detect = imx_pd_connector_detect, + .destroy = imx_pd_connector_destroy, +}; + +static struct drm_connector_helper_funcs imx_pd_connector_helper_funcs = { + .get_modes = imx_pd_connector_get_modes, + .best_encoder = imx_pd_connector_best_encoder, + .mode_valid = imx_pd_connector_mode_valid, +}; + +static struct drm_encoder_funcs imx_pd_encoder_funcs = { + .destroy = imx_pd_encoder_destroy, +}; + +static struct drm_encoder_helper_funcs imx_pd_encoder_helper_funcs = { + .dpms = imx_pd_encoder_dpms, + .mode_fixup = imx_pd_encoder_mode_fixup, + .prepare = imx_pd_encoder_prepare, + .commit = imx_pd_encoder_commit, + .mode_set = imx_pd_encoder_mode_set, + .disable = imx_pd_encoder_disable, +}; + +static int imx_pd_register(struct imx_parallel_display *imxpd) +{ + int ret; + + drm_mode_connector_attach_encoder(&imxpd->connector, &imxpd->encoder); + + imxpd->connector.funcs = &imx_pd_connector_funcs; + imxpd->encoder.funcs = &imx_pd_encoder_funcs; + + imxpd->encoder.encoder_type = DRM_MODE_ENCODER_NONE; + imxpd->connector.connector_type = DRM_MODE_CONNECTOR_VGA; + + drm_encoder_helper_add(&imxpd->encoder, &imx_pd_encoder_helper_funcs); + ret = imx_drm_add_encoder(&imxpd->encoder, &imxpd->imx_drm_encoder, + THIS_MODULE); + if (ret) { + dev_err(imxpd->dev, "adding encoder failed with %d\n", ret); + return ret; + } + + drm_connector_helper_add(&imxpd->connector, + &imx_pd_connector_helper_funcs); + + ret = imx_drm_add_connector(&imxpd->connector, + &imxpd->imx_drm_connector, THIS_MODULE); + if (ret) { + imx_drm_remove_encoder(imxpd->imx_drm_encoder); + dev_err(imxpd->dev, "adding connector failed with %d\n", ret); + return ret; + } + + imxpd->connector.encoder = &imxpd->encoder; + + return 0; +} + +static int __devinit imx_pd_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + const u8 *edidp; + struct imx_parallel_display *imxpd; + int ret; + const char *fmt; + + imxpd = devm_kzalloc(&pdev->dev, sizeof(*imxpd), GFP_KERNEL); + if (!imxpd) + return -ENOMEM; + + edidp = of_get_property(np, "edid", &imxpd->edid_len); + if (edidp) + imxpd->edid = kmemdup(edidp, imxpd->edid_len, GFP_KERNEL); + + ret = of_property_read_string(np, "interface-pix-fmt", &fmt); + if (!ret) { + if (!strcmp(fmt, "rgb24")) + imxpd->interface_pix_fmt = V4L2_PIX_FMT_RGB24; + else if (!strcmp(fmt, "rgb565")) + imxpd->interface_pix_fmt = V4L2_PIX_FMT_RGB565; + } + + imxpd->dev = &pdev->dev; + + ret = imx_pd_register(imxpd); + if (ret) + return ret; + + ret = imx_drm_encoder_add_possible_crtcs(imxpd->imx_drm_encoder, np); + + platform_set_drvdata(pdev, imxpd); + + return 0; +} + +static int __devexit imx_pd_remove(struct platform_device *pdev) +{ + struct imx_parallel_display *imxpd = platform_get_drvdata(pdev); + struct drm_connector *connector = &imxpd->connector; + struct drm_encoder *encoder = &imxpd->encoder; + + drm_mode_connector_detach_encoder(connector, encoder); + + imx_drm_remove_connector(imxpd->imx_drm_connector); + imx_drm_remove_encoder(imxpd->imx_drm_encoder); + + return 0; +} + +static const struct of_device_id imx_pd_dt_ids[] = { + { .compatible = "fsl,imx-parallel-display", }, + { /* sentinel */ } +}; + +static struct platform_driver imx_pd_driver = { + .probe = imx_pd_probe, + .remove = __devexit_p(imx_pd_remove), + .driver = { + .of_match_table = imx_pd_dt_ids, + .name = "imx-parallel-display", + .owner = THIS_MODULE, + }, +}; + +module_platform_driver(imx_pd_driver); + +MODULE_DESCRIPTION("i.MX parallel display driver"); +MODULE_AUTHOR("Sascha Hauer, Pengutronix"); +MODULE_LICENSE("GPL"); -- cgit v0.10.2 From aecfbdb1803b60bc26616ada7e432c8f9a58ba42 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 21 Sep 2012 10:07:49 +0200 Subject: staging: drm/imx: add i.MX IPUv3 base driver The IPU is the Image Processing Unit found on i.MX51/53/6 SoCs. It features several units for image processing, this patch adds support for the units needed for Framebuffer support, namely: - Display Controller (dc) - Display Interface (di) - Display Multi Fifo Controller (dmfc) - Display Processor (dp) - Image DMA Controller (idmac) This patch is based on the Freescale driver, but follows a different approach. The Freescale code implements logical idmac channels and the handling of the subunits is hidden in common idmac code pathes in big switch/case statements. This patch instead just provides code and resource management for the different subunits. The user, in this case the framebuffer driver, decides how the different units play together. The IPU has other units missing in this patch: - CMOS Sensor Interface (csi) - Video Deinterlacer (vdi) - Sensor Multi FIFO Controler (smfc) - Image Converter (ic) - Image Rotator (irt) Signed-off-by: Sascha Hauer Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/imx-drm/Kconfig b/drivers/staging/imx-drm/Kconfig index 9e27012..4849bfa 100644 --- a/drivers/staging/imx-drm/Kconfig +++ b/drivers/staging/imx-drm/Kconfig @@ -19,3 +19,11 @@ config DRM_IMX_FB_HELPER config DRM_IMX_PARALLEL_DISPLAY tristate "Support for parallel displays" depends on DRM_IMX + +config DRM_IMX_IPUV3_CORE + tristate "IPUv3 core support" + depends on DRM_IMX + help + Choose this if you have a i.MX5/6 system and want + to use the IPU. This option only enables IPU base + support. diff --git a/drivers/staging/imx-drm/Makefile b/drivers/staging/imx-drm/Makefile index c8f582e..e3a5b6f 100644 --- a/drivers/staging/imx-drm/Makefile +++ b/drivers/staging/imx-drm/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_DRM_IMX) += imxdrm.o obj-$(CONFIG_DRM_IMX_PARALLEL_DISPLAY) += parallel-display.o obj-$(CONFIG_DRM_IMX_FB_HELPER) += imx-fbdev.o +obj-$(CONFIG_DRM_IMX_IPUV3_CORE) += ipu-v3/ diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index 225e835..1913199 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -137,6 +137,7 @@ found: encoder_type, interface_pix_fmt); return 0; } +EXPORT_SYMBOL_GPL(imx_drm_crtc_panel_format); int imx_drm_crtc_vblank_get(struct imx_drm_crtc *imx_drm_crtc) { @@ -647,6 +648,7 @@ int imx_drm_encoder_add_possible_crtcs( return 0; } +EXPORT_SYMBOL_GPL(imx_drm_encoder_add_possible_crtcs); int imx_drm_encoder_get_mux_id(struct imx_drm_encoder *imx_drm_encoder, struct drm_crtc *crtc) diff --git a/drivers/staging/imx-drm/ipu-v3/Makefile b/drivers/staging/imx-drm/ipu-v3/Makefile new file mode 100644 index 0000000..28ed72e --- /dev/null +++ b/drivers/staging/imx-drm/ipu-v3/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_DRM_IMX_IPUV3_CORE) += imx-ipu-v3.o + +imx-ipu-v3-objs := ipu-common.o ipu-dc.o ipu-di.o ipu-dp.o ipu-dmfc.o diff --git a/drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h b/drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h new file mode 100644 index 0000000..74158dd --- /dev/null +++ b/drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h @@ -0,0 +1,318 @@ +/* + * Copyright 2005-2009 Freescale Semiconductor, Inc. + * + * The code contained herein is licensed under the GNU Lesser General + * Public License. You may obtain a copy of the GNU Lesser General + * Public License Version 2.1 or later at the following locations: + * + * http://www.opensource.org/licenses/lgpl-license.html + * http://www.gnu.org/copyleft/lgpl.html + */ + +#ifndef __DRM_IPU_H__ +#define __DRM_IPU_H__ + +#include +#include +#include +#include +#include + +struct ipu_soc; + +enum ipuv3_type { + IPUV3EX, + IPUV3M, + IPUV3H, +}; + +/* + * Bitfield of Display Interface signal polarities. + */ +struct ipu_di_signal_cfg { + unsigned datamask_en:1; + unsigned interlaced:1; + unsigned odd_field_first:1; + unsigned clksel_en:1; + unsigned clkidle_en:1; + unsigned data_pol:1; /* true = inverted */ + unsigned clk_pol:1; /* true = rising edge */ + unsigned enable_pol:1; + unsigned Hsync_pol:1; /* true = active high */ + unsigned Vsync_pol:1; + + u16 width; + u16 height; + u32 pixel_fmt; + u16 h_start_width; + u16 h_sync_width; + u16 h_end_width; + u16 v_start_width; + u16 v_sync_width; + u16 v_end_width; + u32 v_to_h_sync; + unsigned long pixelclock; +#define IPU_DI_CLKMODE_SYNC (1 << 0) +#define IPU_DI_CLKMODE_EXT (1 << 1) + unsigned long clkflags; +}; + +enum ipu_color_space { + IPUV3_COLORSPACE_RGB, + IPUV3_COLORSPACE_YUV, + IPUV3_COLORSPACE_UNKNOWN, +}; + +struct ipuv3_channel; + +enum ipu_channel_irq { + IPU_IRQ_EOF = 0, + IPU_IRQ_NFACK = 64, + IPU_IRQ_NFB4EOF = 128, + IPU_IRQ_EOS = 192, +}; + +int ipu_idmac_channel_irq(struct ipu_soc *ipu, struct ipuv3_channel *channel, + enum ipu_channel_irq irq); + +#define IPU_IRQ_DP_SF_START (448 + 2) +#define IPU_IRQ_DP_SF_END (448 + 3) +#define IPU_IRQ_BG_SF_END IPU_IRQ_DP_SF_END, +#define IPU_IRQ_DC_FC_0 (448 + 8) +#define IPU_IRQ_DC_FC_1 (448 + 9) +#define IPU_IRQ_DC_FC_2 (448 + 10) +#define IPU_IRQ_DC_FC_3 (448 + 11) +#define IPU_IRQ_DC_FC_4 (448 + 12) +#define IPU_IRQ_DC_FC_6 (448 + 13) +#define IPU_IRQ_VSYNC_PRE_0 (448 + 14) +#define IPU_IRQ_VSYNC_PRE_1 (448 + 15) + +/* + * IPU Image DMA Controller (idmac) functions + */ +struct ipuv3_channel *ipu_idmac_get(struct ipu_soc *ipu, unsigned channel); +void ipu_idmac_put(struct ipuv3_channel *); + +int ipu_idmac_enable_channel(struct ipuv3_channel *channel); +int ipu_idmac_disable_channel(struct ipuv3_channel *channel); + +void ipu_idmac_set_double_buffer(struct ipuv3_channel *channel, + bool doublebuffer); +void ipu_idmac_select_buffer(struct ipuv3_channel *channel, u32 buf_num); + +/* + * IPU Display Controller (dc) functions + */ +struct ipu_dc; +struct ipu_di; +struct ipu_dc *ipu_dc_get(struct ipu_soc *ipu, int channel); +void ipu_dc_put(struct ipu_dc *dc); +int ipu_dc_init_sync(struct ipu_dc *dc, struct ipu_di *di, bool interlaced, + u32 pixel_fmt, u32 width); +void ipu_dc_enable_channel(struct ipu_dc *dc); +void ipu_dc_disable_channel(struct ipu_dc *dc); + +/* + * IPU Display Interface (di) functions + */ +struct ipu_di *ipu_di_get(struct ipu_soc *ipu, int disp); +void ipu_di_put(struct ipu_di *); +int ipu_di_disable(struct ipu_di *); +int ipu_di_enable(struct ipu_di *); +int ipu_di_get_num(struct ipu_di *); +int ipu_di_init_sync_panel(struct ipu_di *, struct ipu_di_signal_cfg *sig); + +/* + * IPU Display Multi FIFO Controller (dmfc) functions + */ +struct dmfc_channel; +int ipu_dmfc_enable_channel(struct dmfc_channel *dmfc); +void ipu_dmfc_disable_channel(struct dmfc_channel *dmfc); +int ipu_dmfc_alloc_bandwidth(struct dmfc_channel *dmfc, + unsigned long bandwidth_mbs, int burstsize); +void ipu_dmfc_free_bandwidth(struct dmfc_channel *dmfc); +int ipu_dmfc_init_channel(struct dmfc_channel *dmfc, int width); +struct dmfc_channel *ipu_dmfc_get(struct ipu_soc *ipu, int ipuv3_channel); +void ipu_dmfc_put(struct dmfc_channel *dmfc); + +/* + * IPU Display Processor (dp) functions + */ +#define IPU_DP_FLOW_SYNC_BG 0 +#define IPU_DP_FLOW_SYNC_FG 1 +#define IPU_DP_FLOW_ASYNC0_BG 2 +#define IPU_DP_FLOW_ASYNC0_FG 3 +#define IPU_DP_FLOW_ASYNC1_BG 4 +#define IPU_DP_FLOW_ASYNC1_FG 5 + +struct ipu_dp *ipu_dp_get(struct ipu_soc *ipu, unsigned int flow); +void ipu_dp_put(struct ipu_dp *); +int ipu_dp_enable_channel(struct ipu_dp *dp); +void ipu_dp_disable_channel(struct ipu_dp *dp); +int ipu_dp_setup_channel(struct ipu_dp *dp, + enum ipu_color_space in, enum ipu_color_space out); +int ipu_dp_set_window_pos(struct ipu_dp *, u16 x_pos, u16 y_pos); +int ipu_dp_set_global_alpha(struct ipu_dp *dp, bool enable, u8 alpha, + bool bg_chan); + +#define IPU_CPMEM_WORD(word, ofs, size) ((((word) * 160 + (ofs)) << 8) | (size)) + +#define IPU_FIELD_UBO IPU_CPMEM_WORD(0, 46, 22) +#define IPU_FIELD_VBO IPU_CPMEM_WORD(0, 68, 22) +#define IPU_FIELD_IOX IPU_CPMEM_WORD(0, 90, 4) +#define IPU_FIELD_RDRW IPU_CPMEM_WORD(0, 94, 1) +#define IPU_FIELD_SO IPU_CPMEM_WORD(0, 113, 1) +#define IPU_FIELD_SLY IPU_CPMEM_WORD(1, 102, 14) +#define IPU_FIELD_SLUV IPU_CPMEM_WORD(1, 128, 14) + +#define IPU_FIELD_XV IPU_CPMEM_WORD(0, 0, 10) +#define IPU_FIELD_YV IPU_CPMEM_WORD(0, 10, 9) +#define IPU_FIELD_XB IPU_CPMEM_WORD(0, 19, 13) +#define IPU_FIELD_YB IPU_CPMEM_WORD(0, 32, 12) +#define IPU_FIELD_NSB_B IPU_CPMEM_WORD(0, 44, 1) +#define IPU_FIELD_CF IPU_CPMEM_WORD(0, 45, 1) +#define IPU_FIELD_SX IPU_CPMEM_WORD(0, 46, 12) +#define IPU_FIELD_SY IPU_CPMEM_WORD(0, 58, 11) +#define IPU_FIELD_NS IPU_CPMEM_WORD(0, 69, 10) +#define IPU_FIELD_SDX IPU_CPMEM_WORD(0, 79, 7) +#define IPU_FIELD_SM IPU_CPMEM_WORD(0, 86, 10) +#define IPU_FIELD_SCC IPU_CPMEM_WORD(0, 96, 1) +#define IPU_FIELD_SCE IPU_CPMEM_WORD(0, 97, 1) +#define IPU_FIELD_SDY IPU_CPMEM_WORD(0, 98, 7) +#define IPU_FIELD_SDRX IPU_CPMEM_WORD(0, 105, 1) +#define IPU_FIELD_SDRY IPU_CPMEM_WORD(0, 106, 1) +#define IPU_FIELD_BPP IPU_CPMEM_WORD(0, 107, 3) +#define IPU_FIELD_DEC_SEL IPU_CPMEM_WORD(0, 110, 2) +#define IPU_FIELD_DIM IPU_CPMEM_WORD(0, 112, 1) +#define IPU_FIELD_BNDM IPU_CPMEM_WORD(0, 114, 3) +#define IPU_FIELD_BM IPU_CPMEM_WORD(0, 117, 2) +#define IPU_FIELD_ROT IPU_CPMEM_WORD(0, 119, 1) +#define IPU_FIELD_HF IPU_CPMEM_WORD(0, 120, 1) +#define IPU_FIELD_VF IPU_CPMEM_WORD(0, 121, 1) +#define IPU_FIELD_THE IPU_CPMEM_WORD(0, 122, 1) +#define IPU_FIELD_CAP IPU_CPMEM_WORD(0, 123, 1) +#define IPU_FIELD_CAE IPU_CPMEM_WORD(0, 124, 1) +#define IPU_FIELD_FW IPU_CPMEM_WORD(0, 125, 13) +#define IPU_FIELD_FH IPU_CPMEM_WORD(0, 138, 12) +#define IPU_FIELD_EBA0 IPU_CPMEM_WORD(1, 0, 29) +#define IPU_FIELD_EBA1 IPU_CPMEM_WORD(1, 29, 29) +#define IPU_FIELD_ILO IPU_CPMEM_WORD(1, 58, 20) +#define IPU_FIELD_NPB IPU_CPMEM_WORD(1, 78, 7) +#define IPU_FIELD_PFS IPU_CPMEM_WORD(1, 85, 4) +#define IPU_FIELD_ALU IPU_CPMEM_WORD(1, 89, 1) +#define IPU_FIELD_ALBM IPU_CPMEM_WORD(1, 90, 3) +#define IPU_FIELD_ID IPU_CPMEM_WORD(1, 93, 2) +#define IPU_FIELD_TH IPU_CPMEM_WORD(1, 95, 7) +#define IPU_FIELD_SL IPU_CPMEM_WORD(1, 102, 14) +#define IPU_FIELD_WID0 IPU_CPMEM_WORD(1, 116, 3) +#define IPU_FIELD_WID1 IPU_CPMEM_WORD(1, 119, 3) +#define IPU_FIELD_WID2 IPU_CPMEM_WORD(1, 122, 3) +#define IPU_FIELD_WID3 IPU_CPMEM_WORD(1, 125, 3) +#define IPU_FIELD_OFS0 IPU_CPMEM_WORD(1, 128, 5) +#define IPU_FIELD_OFS1 IPU_CPMEM_WORD(1, 133, 5) +#define IPU_FIELD_OFS2 IPU_CPMEM_WORD(1, 138, 5) +#define IPU_FIELD_OFS3 IPU_CPMEM_WORD(1, 143, 5) +#define IPU_FIELD_SXYS IPU_CPMEM_WORD(1, 148, 1) +#define IPU_FIELD_CRE IPU_CPMEM_WORD(1, 149, 1) +#define IPU_FIELD_DEC_SEL2 IPU_CPMEM_WORD(1, 150, 1) + +struct ipu_cpmem_word { + u32 data[5]; + u32 res[3]; +}; + +struct ipu_ch_param { + struct ipu_cpmem_word word[2]; +}; + +void ipu_ch_param_write_field(struct ipu_ch_param __iomem *base, u32 wbs, u32 v); +u32 ipu_ch_param_read_field(struct ipu_ch_param __iomem *base, u32 wbs); +struct ipu_ch_param __iomem *ipu_get_cpmem(struct ipuv3_channel *channel); +void ipu_ch_param_dump(struct ipu_ch_param __iomem *p); + +static inline void ipu_ch_param_zero(struct ipu_ch_param __iomem *p) +{ + int i; + void __iomem *base = p; + + for (i = 0; i < sizeof(*p) / sizeof(u32); i++) + writel(0, base + i * sizeof(u32)); +} + +static inline void ipu_cpmem_set_buffer(struct ipu_ch_param __iomem *p, + int bufnum, dma_addr_t buf) +{ + if (bufnum) + ipu_ch_param_write_field(p, IPU_FIELD_EBA1, buf >> 3); + else + ipu_ch_param_write_field(p, IPU_FIELD_EBA0, buf >> 3); +} + +static inline void ipu_cpmem_set_resolution(struct ipu_ch_param __iomem *p, + int xres, int yres) +{ + ipu_ch_param_write_field(p, IPU_FIELD_FW, xres - 1); + ipu_ch_param_write_field(p, IPU_FIELD_FH, yres - 1); +} + +static inline void ipu_cpmem_set_stride(struct ipu_ch_param __iomem *p, + int stride) +{ + ipu_ch_param_write_field(p, IPU_FIELD_SLY, stride - 1); +} + +void ipu_cpmem_set_high_priority(struct ipuv3_channel *channel); + +struct ipu_rgb { + struct fb_bitfield red; + struct fb_bitfield green; + struct fb_bitfield blue; + struct fb_bitfield transp; + int bits_per_pixel; +}; + +struct ipu_image { + struct v4l2_pix_format pix; + struct v4l2_rect rect; + dma_addr_t phys; +}; + +int ipu_cpmem_set_format_passthrough(struct ipu_ch_param __iomem *p, + int width); + +int ipu_cpmem_set_format_rgb(struct ipu_ch_param __iomem *, + struct ipu_rgb *rgb); + +static inline void ipu_cpmem_interlaced_scan(struct ipu_ch_param *p, + int stride) +{ + ipu_ch_param_write_field(p, IPU_FIELD_SO, 1); + ipu_ch_param_write_field(p, IPU_FIELD_ILO, stride / 8); + ipu_ch_param_write_field(p, IPU_FIELD_SLY, (stride * 2) - 1); +}; + +void ipu_cpmem_set_yuv_planar(struct ipu_ch_param __iomem *p, u32 pixel_format, + int stride, int height); +void ipu_cpmem_set_yuv_planar_full(struct ipu_ch_param __iomem *p, + u32 pixel_format, int stride, int u_offset, int v_offset); +int ipu_cpmem_set_fmt(struct ipu_ch_param __iomem *cpmem, u32 pixelformat); +int ipu_cpmem_set_image(struct ipu_ch_param __iomem *cpmem, + struct ipu_image *image); + +enum ipu_color_space ipu_pixelformat_to_colorspace(u32 pixelformat); + +static inline void ipu_cpmem_set_burstsize(struct ipu_ch_param __iomem *p, + int burstsize) +{ + ipu_ch_param_write_field(p, IPU_FIELD_NPB, burstsize - 1); +}; + +struct ipu_client_platformdata { + int di; + int dc; + int dp; + int dmfc; + int dma[2]; +}; + +#endif /* __DRM_IPU_H__ */ diff --git a/drivers/staging/imx-drm/ipu-v3/ipu-common.c b/drivers/staging/imx-drm/ipu-v3/ipu-common.c new file mode 100644 index 0000000..f381960 --- /dev/null +++ b/drivers/staging/imx-drm/ipu-v3/ipu-common.c @@ -0,0 +1,1143 @@ +/* + * Copyright (c) 2010 Sascha Hauer + * Copyright (C) 2005-2009 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "imx-ipu-v3.h" +#include "ipu-prv.h" + +static inline u32 ipu_cm_read(struct ipu_soc *ipu, unsigned offset) +{ + return readl(ipu->cm_reg + offset); +} + +static inline void ipu_cm_write(struct ipu_soc *ipu, u32 value, unsigned offset) +{ + writel(value, ipu->cm_reg + offset); +} + +static inline u32 ipu_idmac_read(struct ipu_soc *ipu, unsigned offset) +{ + return readl(ipu->idmac_reg + offset); +} + +static inline void ipu_idmac_write(struct ipu_soc *ipu, u32 value, + unsigned offset) +{ + writel(value, ipu->idmac_reg + offset); +} + +void ipu_srm_dp_sync_update(struct ipu_soc *ipu) +{ + u32 val; + + val = ipu_cm_read(ipu, IPU_SRM_PRI2); + val |= 0x8; + ipu_cm_write(ipu, val, IPU_SRM_PRI2); +} +EXPORT_SYMBOL_GPL(ipu_srm_dp_sync_update); + +struct ipu_ch_param __iomem *ipu_get_cpmem(struct ipuv3_channel *channel) +{ + struct ipu_soc *ipu = channel->ipu; + + return ipu->cpmem_base + channel->num; +} +EXPORT_SYMBOL_GPL(ipu_get_cpmem); + +void ipu_cpmem_set_high_priority(struct ipuv3_channel *channel) +{ + struct ipu_soc *ipu = channel->ipu; + struct ipu_ch_param __iomem *p = ipu_get_cpmem(channel); + u32 val; + + if (ipu->ipu_type == IPUV3EX) + ipu_ch_param_write_field(p, IPU_FIELD_ID, 1); + + val = ipu_idmac_read(ipu, IDMAC_CHA_PRI(channel->num)); + val |= 1 << (channel->num % 32); + ipu_idmac_write(ipu, val, IDMAC_CHA_PRI(channel->num)); +}; +EXPORT_SYMBOL_GPL(ipu_cpmem_set_high_priority); + +void ipu_ch_param_write_field(struct ipu_ch_param __iomem *base, u32 wbs, u32 v) +{ + u32 bit = (wbs >> 8) % 160; + u32 size = wbs & 0xff; + u32 word = (wbs >> 8) / 160; + u32 i = bit / 32; + u32 ofs = bit % 32; + u32 mask = (1 << size) - 1; + u32 val; + + pr_debug("%s %d %d %d\n", __func__, word, bit , size); + + val = readl(&base->word[word].data[i]); + val &= ~(mask << ofs); + val |= v << ofs; + writel(val, &base->word[word].data[i]); + + if ((bit + size - 1) / 32 > i) { + val = readl(&base->word[word].data[i + 1]); + val &= ~(mask >> (ofs ? (32 - ofs) : 0)); + val |= v >> (ofs ? (32 - ofs) : 0); + writel(val, &base->word[word].data[i + 1]); + } +} +EXPORT_SYMBOL_GPL(ipu_ch_param_write_field); + +u32 ipu_ch_param_read_field(struct ipu_ch_param __iomem *base, u32 wbs) +{ + u32 bit = (wbs >> 8) % 160; + u32 size = wbs & 0xff; + u32 word = (wbs >> 8) / 160; + u32 i = bit / 32; + u32 ofs = bit % 32; + u32 mask = (1 << size) - 1; + u32 val = 0; + + pr_debug("%s %d %d %d\n", __func__, word, bit , size); + + val = (readl(&base->word[word].data[i]) >> ofs) & mask; + + if ((bit + size - 1) / 32 > i) { + u32 tmp; + tmp = readl(&base->word[word].data[i + 1]); + tmp &= mask >> (ofs ? (32 - ofs) : 0); + val |= tmp << (ofs ? (32 - ofs) : 0); + } + + return val; +} +EXPORT_SYMBOL_GPL(ipu_ch_param_read_field); + +int ipu_cpmem_set_format_rgb(struct ipu_ch_param __iomem *p, + struct ipu_rgb *rgb) +{ + int bpp = 0, npb = 0, ro, go, bo, to; + + ro = rgb->bits_per_pixel - rgb->red.length - rgb->red.offset; + go = rgb->bits_per_pixel - rgb->green.length - rgb->green.offset; + bo = rgb->bits_per_pixel - rgb->blue.length - rgb->blue.offset; + to = rgb->bits_per_pixel - rgb->transp.length - rgb->transp.offset; + + ipu_ch_param_write_field(p, IPU_FIELD_WID0, rgb->red.length - 1); + ipu_ch_param_write_field(p, IPU_FIELD_OFS0, ro); + ipu_ch_param_write_field(p, IPU_FIELD_WID1, rgb->green.length - 1); + ipu_ch_param_write_field(p, IPU_FIELD_OFS1, go); + ipu_ch_param_write_field(p, IPU_FIELD_WID2, rgb->blue.length - 1); + ipu_ch_param_write_field(p, IPU_FIELD_OFS2, bo); + + if (rgb->transp.length) { + ipu_ch_param_write_field(p, IPU_FIELD_WID3, + rgb->transp.length - 1); + ipu_ch_param_write_field(p, IPU_FIELD_OFS3, to); + } else { + ipu_ch_param_write_field(p, IPU_FIELD_WID3, 7); + ipu_ch_param_write_field(p, IPU_FIELD_OFS3, + rgb->bits_per_pixel); + } + + switch (rgb->bits_per_pixel) { + case 32: + bpp = 0; + npb = 15; + break; + case 24: + bpp = 1; + npb = 19; + break; + case 16: + bpp = 3; + npb = 31; + break; + case 8: + bpp = 5; + npb = 63; + break; + default: + return -EINVAL; + } + ipu_ch_param_write_field(p, IPU_FIELD_BPP, bpp); + ipu_ch_param_write_field(p, IPU_FIELD_NPB, npb); + ipu_ch_param_write_field(p, IPU_FIELD_PFS, 7); /* rgb mode */ + + return 0; +} +EXPORT_SYMBOL_GPL(ipu_cpmem_set_format_rgb); + +int ipu_cpmem_set_format_passthrough(struct ipu_ch_param __iomem *p, + int width) +{ + int bpp = 0, npb = 0; + + switch (width) { + case 32: + bpp = 0; + npb = 15; + break; + case 24: + bpp = 1; + npb = 19; + break; + case 16: + bpp = 3; + npb = 31; + break; + case 8: + bpp = 5; + npb = 63; + break; + default: + return -EINVAL; + } + + ipu_ch_param_write_field(p, IPU_FIELD_BPP, bpp); + ipu_ch_param_write_field(p, IPU_FIELD_NPB, npb); + ipu_ch_param_write_field(p, IPU_FIELD_PFS, 6); /* raw mode */ + + return 0; +} +EXPORT_SYMBOL_GPL(ipu_cpmem_set_format_passthrough); + +void ipu_cpmem_set_yuv_planar_full(struct ipu_ch_param __iomem *p, + u32 pixel_format, int stride, int u_offset, int v_offset) +{ + switch (pixel_format) { + case V4L2_PIX_FMT_YUV420: + ipu_ch_param_write_field(p, IPU_FIELD_SLUV, (stride / 2) - 1); + ipu_ch_param_write_field(p, IPU_FIELD_UBO, u_offset / 8); + ipu_ch_param_write_field(p, IPU_FIELD_VBO, v_offset / 8); + break; + } +} +EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_planar_full); + +void ipu_cpmem_set_yuv_planar(struct ipu_ch_param __iomem *p, u32 pixel_format, + int stride, int height) +{ + int u_offset, v_offset; + int uv_stride = 0; + + switch (pixel_format) { + case V4L2_PIX_FMT_YUV420: + uv_stride = stride / 2; + u_offset = stride * height; + v_offset = u_offset + (uv_stride * height / 2); + ipu_cpmem_set_yuv_planar_full(p, V4L2_PIX_FMT_YUV420, stride, + u_offset, v_offset); + break; + } +} +EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_planar); + +static struct ipu_rgb def_rgb_32 = { + .red = { .offset = 16, .length = 8, }, + .green = { .offset = 8, .length = 8, }, + .blue = { .offset = 0, .length = 8, }, + .transp = { .offset = 24, .length = 8, }, + .bits_per_pixel = 32, +}; + +static struct ipu_rgb def_bgr_32 = { + .red = { .offset = 16, .length = 8, }, + .green = { .offset = 8, .length = 8, }, + .blue = { .offset = 0, .length = 8, }, + .transp = { .offset = 24, .length = 8, }, + .bits_per_pixel = 32, +}; + +static struct ipu_rgb def_rgb_24 = { + .red = { .offset = 0, .length = 8, }, + .green = { .offset = 8, .length = 8, }, + .blue = { .offset = 16, .length = 8, }, + .transp = { .offset = 0, .length = 0, }, + .bits_per_pixel = 24, +}; + +static struct ipu_rgb def_bgr_24 = { + .red = { .offset = 16, .length = 8, }, + .green = { .offset = 8, .length = 8, }, + .blue = { .offset = 0, .length = 8, }, + .transp = { .offset = 0, .length = 0, }, + .bits_per_pixel = 24, +}; + +static struct ipu_rgb def_rgb_16 = { + .red = { .offset = 11, .length = 5, }, + .green = { .offset = 5, .length = 6, }, + .blue = { .offset = 0, .length = 5, }, + .transp = { .offset = 0, .length = 0, }, + .bits_per_pixel = 16, +}; + +#define Y_OFFSET(pix, x, y) ((x) + pix->width * (y)) +#define U_OFFSET(pix, x, y) ((pix->width * pix->height) + \ + (pix->width * (y) / 4) + (x) / 2) +#define V_OFFSET(pix, x, y) ((pix->width * pix->height) + \ + (pix->width * pix->height / 4) + \ + (pix->width * (y) / 4) + (x) / 2) + +int ipu_cpmem_set_fmt(struct ipu_ch_param __iomem *cpmem, u32 pixelformat) +{ + switch (pixelformat) { + case V4L2_PIX_FMT_YUV420: + /* pix format */ + ipu_ch_param_write_field(cpmem, IPU_FIELD_PFS, 2); + /* burst size */ + ipu_ch_param_write_field(cpmem, IPU_FIELD_NPB, 63); + break; + case V4L2_PIX_FMT_UYVY: + /* bits/pixel */ + ipu_ch_param_write_field(cpmem, IPU_FIELD_BPP, 3); + /* pix format */ + ipu_ch_param_write_field(cpmem, IPU_FIELD_PFS, 0xA); + /* burst size */ + ipu_ch_param_write_field(cpmem, IPU_FIELD_NPB, 31); + break; + case V4L2_PIX_FMT_YUYV: + /* bits/pixel */ + ipu_ch_param_write_field(cpmem, IPU_FIELD_BPP, 3); + /* pix format */ + ipu_ch_param_write_field(cpmem, IPU_FIELD_PFS, 0x8); + /* burst size */ + ipu_ch_param_write_field(cpmem, IPU_FIELD_NPB, 31); + break; + case V4L2_PIX_FMT_RGB32: + ipu_cpmem_set_format_rgb(cpmem, &def_rgb_32); + break; + case V4L2_PIX_FMT_RGB565: + ipu_cpmem_set_format_rgb(cpmem, &def_rgb_16); + break; + case V4L2_PIX_FMT_BGR32: + ipu_cpmem_set_format_rgb(cpmem, &def_bgr_32); + break; + case V4L2_PIX_FMT_RGB24: + ipu_cpmem_set_format_rgb(cpmem, &def_rgb_24); + break; + case V4L2_PIX_FMT_BGR24: + ipu_cpmem_set_format_rgb(cpmem, &def_bgr_24); + break; + default: + return -EINVAL; + } + + return 0; +} +EXPORT_SYMBOL_GPL(ipu_cpmem_set_fmt); + +int ipu_cpmem_set_image(struct ipu_ch_param __iomem *cpmem, + struct ipu_image *image) +{ + struct v4l2_pix_format *pix = &image->pix; + int y_offset, u_offset, v_offset; + + pr_debug("%s: resolution: %dx%d stride: %d\n", + __func__, pix->width, pix->height, + pix->bytesperline); + + ipu_cpmem_set_resolution(cpmem, image->rect.width, + image->rect.height); + ipu_cpmem_set_stride(cpmem, pix->bytesperline); + + ipu_cpmem_set_fmt(cpmem, pix->pixelformat); + + switch (pix->pixelformat) { + case V4L2_PIX_FMT_YUV420: + y_offset = Y_OFFSET(pix, image->rect.left, image->rect.top); + u_offset = U_OFFSET(pix, image->rect.left, + image->rect.top) - y_offset; + v_offset = V_OFFSET(pix, image->rect.left, + image->rect.top) - y_offset; + + ipu_cpmem_set_yuv_planar_full(cpmem, pix->pixelformat, + pix->bytesperline, u_offset, v_offset); + ipu_cpmem_set_buffer(cpmem, 0, image->phys + y_offset); + break; + case V4L2_PIX_FMT_UYVY: + ipu_cpmem_set_buffer(cpmem, 0, image->phys + + image->rect.left * 2 + + image->rect.top * image->pix.bytesperline); + break; + case V4L2_PIX_FMT_RGB32: + case V4L2_PIX_FMT_BGR32: + ipu_cpmem_set_buffer(cpmem, 0, image->phys + + image->rect.left * 4 + + image->rect.top * image->pix.bytesperline); + break; + case V4L2_PIX_FMT_RGB565: + ipu_cpmem_set_buffer(cpmem, 0, image->phys + + image->rect.left * 2 + + image->rect.top * image->pix.bytesperline); + break; + case V4L2_PIX_FMT_RGB24: + case V4L2_PIX_FMT_BGR24: + ipu_cpmem_set_buffer(cpmem, 0, image->phys + + image->rect.left * 3 + + image->rect.top * image->pix.bytesperline); + break; + default: + return -EINVAL; + } + + return 0; +} +EXPORT_SYMBOL_GPL(ipu_cpmem_set_image); + +enum ipu_color_space ipu_pixelformat_to_colorspace(u32 pixelformat) +{ + switch (pixelformat) { + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_YVYU: + return IPUV3_COLORSPACE_YUV; + case V4L2_PIX_FMT_RGB32: + case V4L2_PIX_FMT_BGR32: + case V4L2_PIX_FMT_RGB24: + case V4L2_PIX_FMT_BGR24: + case V4L2_PIX_FMT_RGB565: + return IPUV3_COLORSPACE_RGB; + default: + return IPUV3_COLORSPACE_UNKNOWN; + } +} +EXPORT_SYMBOL_GPL(ipu_pixelformat_to_colorspace); + +struct ipuv3_channel *ipu_idmac_get(struct ipu_soc *ipu, unsigned num) +{ + struct ipuv3_channel *channel; + + dev_dbg(ipu->dev, "%s %d\n", __func__, num); + + if (num > 63) + return ERR_PTR(-ENODEV); + + mutex_lock(&ipu->channel_lock); + + channel = &ipu->channel[num]; + + if (channel->busy) { + channel = ERR_PTR(-EBUSY); + goto out; + } + + channel->busy = 1; + channel->num = num; + +out: + mutex_unlock(&ipu->channel_lock); + + return channel; +} +EXPORT_SYMBOL_GPL(ipu_idmac_get); + +void ipu_idmac_put(struct ipuv3_channel *channel) +{ + struct ipu_soc *ipu = channel->ipu; + + dev_dbg(ipu->dev, "%s %d\n", __func__, channel->num); + + mutex_lock(&ipu->channel_lock); + + channel->busy = 0; + + mutex_unlock(&ipu->channel_lock); +} +EXPORT_SYMBOL_GPL(ipu_idmac_put); + +#define idma_mask(ch) (1 << (ch & 0x1f)) + +void ipu_idmac_set_double_buffer(struct ipuv3_channel *channel, + bool doublebuffer) +{ + struct ipu_soc *ipu = channel->ipu; + unsigned long flags; + u32 reg; + + spin_lock_irqsave(&ipu->lock, flags); + + reg = ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(channel->num)); + if (doublebuffer) + reg |= idma_mask(channel->num); + else + reg &= ~idma_mask(channel->num); + ipu_cm_write(ipu, reg, IPU_CHA_DB_MODE_SEL(channel->num)); + + spin_unlock_irqrestore(&ipu->lock, flags); +} +EXPORT_SYMBOL_GPL(ipu_idmac_set_double_buffer); + +int ipu_module_enable(struct ipu_soc *ipu, u32 mask) +{ + unsigned long lock_flags; + u32 val; + + spin_lock_irqsave(&ipu->lock, lock_flags); + + val = ipu_cm_read(ipu, IPU_DISP_GEN); + + if (mask & IPU_CONF_DI0_EN) + val |= IPU_DI0_COUNTER_RELEASE; + if (mask & IPU_CONF_DI1_EN) + val |= IPU_DI1_COUNTER_RELEASE; + + ipu_cm_write(ipu, val, IPU_DISP_GEN); + + val = ipu_cm_read(ipu, IPU_CONF); + val |= mask; + ipu_cm_write(ipu, val, IPU_CONF); + + spin_unlock_irqrestore(&ipu->lock, lock_flags); + + return 0; +} +EXPORT_SYMBOL_GPL(ipu_module_enable); + +int ipu_module_disable(struct ipu_soc *ipu, u32 mask) +{ + unsigned long lock_flags; + u32 val; + + spin_lock_irqsave(&ipu->lock, lock_flags); + + val = ipu_cm_read(ipu, IPU_CONF); + val &= ~mask; + ipu_cm_write(ipu, val, IPU_CONF); + + val = ipu_cm_read(ipu, IPU_DISP_GEN); + + if (mask & IPU_CONF_DI0_EN) + val &= ~IPU_DI0_COUNTER_RELEASE; + if (mask & IPU_CONF_DI1_EN) + val &= ~IPU_DI1_COUNTER_RELEASE; + + ipu_cm_write(ipu, val, IPU_DISP_GEN); + + spin_unlock_irqrestore(&ipu->lock, lock_flags); + + return 0; +} +EXPORT_SYMBOL_GPL(ipu_module_disable); + +void ipu_idmac_select_buffer(struct ipuv3_channel *channel, u32 buf_num) +{ + struct ipu_soc *ipu = channel->ipu; + unsigned int chno = channel->num; + unsigned long flags; + + spin_lock_irqsave(&ipu->lock, flags); + + /* Mark buffer as ready. */ + if (buf_num == 0) + ipu_cm_write(ipu, idma_mask(chno), IPU_CHA_BUF0_RDY(chno)); + else + ipu_cm_write(ipu, idma_mask(chno), IPU_CHA_BUF1_RDY(chno)); + + spin_unlock_irqrestore(&ipu->lock, flags); +} +EXPORT_SYMBOL_GPL(ipu_idmac_select_buffer); + +int ipu_idmac_enable_channel(struct ipuv3_channel *channel) +{ + struct ipu_soc *ipu = channel->ipu; + u32 val; + unsigned long flags; + + spin_lock_irqsave(&ipu->lock, flags); + + val = ipu_idmac_read(ipu, IDMAC_CHA_EN(channel->num)); + val |= idma_mask(channel->num); + ipu_idmac_write(ipu, val, IDMAC_CHA_EN(channel->num)); + + spin_unlock_irqrestore(&ipu->lock, flags); + + return 0; +} +EXPORT_SYMBOL_GPL(ipu_idmac_enable_channel); + +int ipu_idmac_disable_channel(struct ipuv3_channel *channel) +{ + struct ipu_soc *ipu = channel->ipu; + u32 val; + unsigned long flags; + unsigned long timeout; + + timeout = jiffies + msecs_to_jiffies(50); + while (ipu_idmac_read(ipu, IDMAC_CHA_BUSY(channel->num)) & + idma_mask(channel->num)) { + if (time_after(jiffies, timeout)) { + dev_warn(ipu->dev, "disabling busy idmac channel %d\n", + channel->num); + break; + } + cpu_relax(); + } + + spin_lock_irqsave(&ipu->lock, flags); + + /* Disable DMA channel(s) */ + val = ipu_idmac_read(ipu, IDMAC_CHA_EN(channel->num)); + val &= ~idma_mask(channel->num); + ipu_idmac_write(ipu, val, IDMAC_CHA_EN(channel->num)); + + /* Set channel buffers NOT to be ready */ + ipu_cm_write(ipu, 0xf0000000, IPU_GPR); /* write one to clear */ + + if (ipu_cm_read(ipu, IPU_CHA_BUF0_RDY(channel->num)) & + idma_mask(channel->num)) { + ipu_cm_write(ipu, idma_mask(channel->num), + IPU_CHA_BUF0_RDY(channel->num)); + } + + if (ipu_cm_read(ipu, IPU_CHA_BUF1_RDY(channel->num)) & + idma_mask(channel->num)) { + ipu_cm_write(ipu, idma_mask(channel->num), + IPU_CHA_BUF1_RDY(channel->num)); + } + + ipu_cm_write(ipu, 0x0, IPU_GPR); /* write one to set */ + + /* Reset the double buffer */ + val = ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(channel->num)); + val &= ~idma_mask(channel->num); + ipu_cm_write(ipu, val, IPU_CHA_DB_MODE_SEL(channel->num)); + + spin_unlock_irqrestore(&ipu->lock, flags); + + return 0; +} +EXPORT_SYMBOL_GPL(ipu_idmac_disable_channel); + +static int ipu_reset(struct ipu_soc *ipu) +{ + unsigned long timeout; + + ipu_cm_write(ipu, 0x807FFFFF, IPU_MEM_RST); + + timeout = jiffies + msecs_to_jiffies(1000); + while (ipu_cm_read(ipu, IPU_MEM_RST) & 0x80000000) { + if (time_after(jiffies, timeout)) + return -ETIME; + cpu_relax(); + } + + mdelay(300); + + return 0; +} + +struct ipu_devtype { + const char *name; + unsigned long cm_ofs; + unsigned long cpmem_ofs; + unsigned long srm_ofs; + unsigned long tpm_ofs; + unsigned long disp0_ofs; + unsigned long disp1_ofs; + unsigned long dc_tmpl_ofs; + unsigned long vdi_ofs; + enum ipuv3_type type; +}; + +static struct ipu_devtype ipu_type_imx51 = { + .name = "IPUv3EX", + .cm_ofs = 0x1e000000, + .cpmem_ofs = 0x1f000000, + .srm_ofs = 0x1f040000, + .tpm_ofs = 0x1f060000, + .disp0_ofs = 0x1e040000, + .disp1_ofs = 0x1e048000, + .dc_tmpl_ofs = 0x1f080000, + .vdi_ofs = 0x1e068000, + .type = IPUV3EX, +}; + +static struct ipu_devtype ipu_type_imx53 = { + .name = "IPUv3M", + .cm_ofs = 0x06000000, + .cpmem_ofs = 0x07000000, + .srm_ofs = 0x07040000, + .tpm_ofs = 0x07060000, + .disp0_ofs = 0x06040000, + .disp1_ofs = 0x06048000, + .dc_tmpl_ofs = 0x07080000, + .vdi_ofs = 0x06068000, + .type = IPUV3M, +}; + +static struct ipu_devtype ipu_type_imx6q = { + .name = "IPUv3H", + .cm_ofs = 0x00200000, + .cpmem_ofs = 0x00300000, + .srm_ofs = 0x00340000, + .tpm_ofs = 0x00360000, + .disp0_ofs = 0x00240000, + .disp1_ofs = 0x00248000, + .dc_tmpl_ofs = 0x00380000, + .vdi_ofs = 0x00268000, + .type = IPUV3H, +}; + +static const struct of_device_id imx_ipu_dt_ids[] = { + { .compatible = "fsl,imx51-ipu", .data = &ipu_type_imx51, }, + { .compatible = "fsl,imx53-ipu", .data = &ipu_type_imx53, }, + { .compatible = "fsl,imx6q-ipu", .data = &ipu_type_imx6q, }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, imx_ipu_dt_ids); + +static int ipu_submodules_init(struct ipu_soc *ipu, + struct platform_device *pdev, unsigned long ipu_base, + struct clk *ipu_clk) +{ + char *unit; + int ret; + struct device *dev = &pdev->dev; + const struct ipu_devtype *devtype = ipu->devtype; + + ret = ipu_di_init(ipu, dev, 0, ipu_base + devtype->disp0_ofs, + IPU_CONF_DI0_EN, ipu_clk); + if (ret) { + unit = "di0"; + goto err_di_0; + } + + ret = ipu_di_init(ipu, dev, 1, ipu_base + devtype->disp1_ofs, + IPU_CONF_DI1_EN, ipu_clk); + if (ret) { + unit = "di1"; + goto err_di_1; + } + + ret = ipu_dc_init(ipu, dev, ipu_base + devtype->cm_ofs + + IPU_CM_DC_REG_OFS, ipu_base + devtype->dc_tmpl_ofs); + if (ret) { + unit = "dc_template"; + goto err_dc; + } + + ret = ipu_dmfc_init(ipu, dev, ipu_base + + devtype->cm_ofs + IPU_CM_DMFC_REG_OFS, ipu_clk); + if (ret) { + unit = "dmfc"; + goto err_dmfc; + } + + ret = ipu_dp_init(ipu, dev, ipu_base + devtype->srm_ofs); + if (ret) { + unit = "dp"; + goto err_dp; + } + + return 0; + +err_dp: + ipu_dmfc_exit(ipu); +err_dmfc: + ipu_dc_exit(ipu); +err_dc: + ipu_di_exit(ipu, 1); +err_di_1: + ipu_di_exit(ipu, 0); +err_di_0: + dev_err(&pdev->dev, "init %s failed with %d\n", unit, ret); + return ret; +} + +static void ipu_irq_handle(struct ipu_soc *ipu, const int *regs, int num_regs) +{ + unsigned long status; + int i, bit, irq_base; + + for (i = 0; i < num_regs; i++) { + + status = ipu_cm_read(ipu, IPU_INT_STAT(regs[i])); + status &= ipu_cm_read(ipu, IPU_INT_CTRL(regs[i])); + + irq_base = ipu->irq_start + regs[i] * 32; + for_each_set_bit(bit, &status, 32) + generic_handle_irq(irq_base + bit); + } +} + +static void ipu_irq_handler(unsigned int irq, struct irq_desc *desc) +{ + struct ipu_soc *ipu = irq_desc_get_handler_data(desc); + const int int_reg[] = { 0, 1, 2, 3, 10, 11, 12, 13, 14}; + struct irq_chip *chip = irq_get_chip(irq); + + chained_irq_enter(chip, desc); + + ipu_irq_handle(ipu, int_reg, ARRAY_SIZE(int_reg)); + + chained_irq_exit(chip, desc); +} + +static void ipu_err_irq_handler(unsigned int irq, struct irq_desc *desc) +{ + struct ipu_soc *ipu = irq_desc_get_handler_data(desc); + const int int_reg[] = { 4, 5, 8, 9}; + struct irq_chip *chip = irq_get_chip(irq); + + chained_irq_enter(chip, desc); + + ipu_irq_handle(ipu, int_reg, ARRAY_SIZE(int_reg)); + + chained_irq_exit(chip, desc); +} + +static void ipu_ack_irq(struct irq_data *d) +{ + struct ipu_soc *ipu = irq_data_get_irq_chip_data(d); + unsigned int irq = d->irq - ipu->irq_start; + + ipu_cm_write(ipu, 1 << (irq % 32), IPU_INT_STAT(irq / 32)); +} + +static void ipu_unmask_irq(struct irq_data *d) +{ + struct ipu_soc *ipu = irq_data_get_irq_chip_data(d); + unsigned int irq = d->irq - ipu->irq_start; + unsigned long flags; + u32 reg; + + spin_lock_irqsave(&ipu->lock, flags); + + reg = ipu_cm_read(ipu, IPU_INT_CTRL(irq / 32)); + reg |= 1 << (irq % 32); + ipu_cm_write(ipu, reg, IPU_INT_CTRL(irq / 32)); + + spin_unlock_irqrestore(&ipu->lock, flags); +} + +static void ipu_mask_irq(struct irq_data *d) +{ + struct ipu_soc *ipu = irq_data_get_irq_chip_data(d); + unsigned int irq = d->irq - ipu->irq_start; + unsigned long flags; + u32 reg; + + spin_lock_irqsave(&ipu->lock, flags); + + reg = ipu_cm_read(ipu, IPU_INT_CTRL(irq / 32)); + reg &= ~(1 << (irq % 32)); + ipu_cm_write(ipu, reg, IPU_INT_CTRL(irq / 32)); + + spin_unlock_irqrestore(&ipu->lock, flags); +} + +static struct irq_chip ipu_irq_chip = { + .name = "IPU", + .irq_ack = ipu_ack_irq, + .irq_mask = ipu_mask_irq, + .irq_unmask = ipu_unmask_irq, +}; + +int ipu_idmac_channel_irq(struct ipu_soc *ipu, struct ipuv3_channel *channel, + enum ipu_channel_irq irq_type) +{ + return ipu->irq_start + irq_type + channel->num; +} +EXPORT_SYMBOL_GPL(ipu_idmac_channel_irq); + +static void ipu_submodules_exit(struct ipu_soc *ipu) +{ + ipu_dp_exit(ipu); + ipu_dmfc_exit(ipu); + ipu_dc_exit(ipu); + ipu_di_exit(ipu, 1); + ipu_di_exit(ipu, 0); +} + +static int platform_remove_devices_fn(struct device *dev, void *unused) +{ + struct platform_device *pdev = to_platform_device(dev); + + platform_device_unregister(pdev); + + return 0; +} + +static void platform_device_unregister_children(struct platform_device *pdev) +{ + device_for_each_child(&pdev->dev, NULL, platform_remove_devices_fn); +} + +struct ipu_platform_reg { + struct ipu_client_platformdata pdata; + const char *name; +}; + +static const struct ipu_platform_reg client_reg[] = { + { + .pdata = { + .di = 0, + .dc = 5, + .dp = IPU_DP_FLOW_SYNC_BG, + .dma[0] = IPUV3_CHANNEL_MEM_BG_SYNC, + .dma[1] = -EINVAL, + }, + .name = "imx-ipuv3-crtc", + }, { + .pdata = { + .di = 1, + .dc = 1, + .dp = -EINVAL, + .dma[0] = IPUV3_CHANNEL_MEM_DC_SYNC, + .dma[1] = -EINVAL, + }, + .name = "imx-ipuv3-crtc", + }, +}; + +static int ipu_client_id; + +static int ipu_add_subdevice_pdata(struct device *dev, + const struct ipu_platform_reg *reg) +{ + struct platform_device *pdev; + + pdev = platform_device_register_data(dev, reg->name, ipu_client_id++, + ®->pdata, sizeof(struct ipu_platform_reg)); + + return pdev ? 0 : -EINVAL; +} + +static int ipu_add_client_devices(struct ipu_soc *ipu) +{ + int ret; + int i; + + for (i = 0; i < ARRAY_SIZE(client_reg); i++) { + const struct ipu_platform_reg *reg = &client_reg[i]; + ret = ipu_add_subdevice_pdata(ipu->dev, reg); + if (ret) + goto err_register; + } + + return 0; + +err_register: + platform_device_unregister_children(to_platform_device(ipu->dev)); + + return ret; +} + +static int ipu_irq_init(struct ipu_soc *ipu) +{ + int i; + + ipu->irq_start = irq_alloc_descs(-1, 0, IPU_NUM_IRQS, 0); + if (ipu->irq_start < 0) + return ipu->irq_start; + + for (i = ipu->irq_start; i < ipu->irq_start + IPU_NUM_IRQS; i++) { + irq_set_chip_and_handler(i, &ipu_irq_chip, handle_level_irq); + set_irq_flags(i, IRQF_VALID); + irq_set_chip_data(i, ipu); + } + + irq_set_chained_handler(ipu->irq_sync, ipu_irq_handler); + irq_set_handler_data(ipu->irq_sync, ipu); + irq_set_chained_handler(ipu->irq_err, ipu_err_irq_handler); + irq_set_handler_data(ipu->irq_err, ipu); + + return 0; +} + +static void ipu_irq_exit(struct ipu_soc *ipu) +{ + int i; + + irq_set_chained_handler(ipu->irq_err, NULL); + irq_set_handler_data(ipu->irq_err, NULL); + irq_set_chained_handler(ipu->irq_sync, NULL); + irq_set_handler_data(ipu->irq_sync, NULL); + + for (i = ipu->irq_start; i < ipu->irq_start + IPU_NUM_IRQS; i++) { + set_irq_flags(i, 0); + irq_set_chip(i, NULL); + irq_set_chip_data(i, NULL); + } + + irq_free_descs(ipu->irq_start, IPU_NUM_IRQS); +} + +static int __devinit ipu_probe(struct platform_device *pdev) +{ + const struct of_device_id *of_id = + of_match_device(imx_ipu_dt_ids, &pdev->dev); + struct ipu_soc *ipu; + struct resource *res; + unsigned long ipu_base; + int i, ret, irq_sync, irq_err; + const struct ipu_devtype *devtype; + + devtype = of_id->data; + + dev_info(&pdev->dev, "Initializing %s\n", devtype->name); + + irq_sync = platform_get_irq(pdev, 0); + irq_err = platform_get_irq(pdev, 1); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + dev_info(&pdev->dev, "irq_sync: %d irq_err: %d\n", + irq_sync, irq_err); + + if (!res || irq_sync < 0 || irq_err < 0) + return -ENODEV; + + ipu_base = res->start; + + ipu = devm_kzalloc(&pdev->dev, sizeof(*ipu), GFP_KERNEL); + if (!ipu) + return -ENODEV; + + for (i = 0; i < 64; i++) + ipu->channel[i].ipu = ipu; + ipu->devtype = devtype; + ipu->ipu_type = devtype->type; + + spin_lock_init(&ipu->lock); + mutex_init(&ipu->channel_lock); + + dev_info(&pdev->dev, "cm_reg: 0x%08lx\n", + ipu_base + devtype->cm_ofs); + dev_info(&pdev->dev, "idmac: 0x%08lx\n", + ipu_base + devtype->cm_ofs + IPU_CM_IDMAC_REG_OFS); + dev_info(&pdev->dev, "cpmem: 0x%08lx\n", + ipu_base + devtype->cpmem_ofs); + dev_info(&pdev->dev, "disp0: 0x%08lx\n", + ipu_base + devtype->disp0_ofs); + dev_info(&pdev->dev, "disp1: 0x%08lx\n", + ipu_base + devtype->disp1_ofs); + dev_info(&pdev->dev, "srm: 0x%08lx\n", + ipu_base + devtype->srm_ofs); + dev_info(&pdev->dev, "tpm: 0x%08lx\n", + ipu_base + devtype->tpm_ofs); + dev_info(&pdev->dev, "dc: 0x%08lx\n", + ipu_base + devtype->cm_ofs + IPU_CM_DC_REG_OFS); + dev_info(&pdev->dev, "ic: 0x%08lx\n", + ipu_base + devtype->cm_ofs + IPU_CM_IC_REG_OFS); + dev_info(&pdev->dev, "dmfc: 0x%08lx\n", + ipu_base + devtype->cm_ofs + IPU_CM_DMFC_REG_OFS); + dev_info(&pdev->dev, "vdi: 0x%08lx\n", + ipu_base + devtype->vdi_ofs); + + ipu->cm_reg = devm_ioremap(&pdev->dev, + ipu_base + devtype->cm_ofs, PAGE_SIZE); + ipu->idmac_reg = devm_ioremap(&pdev->dev, + ipu_base + devtype->cm_ofs + IPU_CM_IDMAC_REG_OFS, + PAGE_SIZE); + ipu->cpmem_base = devm_ioremap(&pdev->dev, + ipu_base + devtype->cpmem_ofs, PAGE_SIZE); + + if (!ipu->cm_reg || !ipu->idmac_reg || !ipu->cpmem_base) { + ret = -ENOMEM; + goto failed_ioremap; + } + + ipu->clk = devm_clk_get(&pdev->dev, "bus"); + if (IS_ERR(ipu->clk)) { + ret = PTR_ERR(ipu->clk); + dev_err(&pdev->dev, "clk_get failed with %d", ret); + goto failed_clk_get; + } + + platform_set_drvdata(pdev, ipu); + + clk_prepare_enable(ipu->clk); + + ipu->dev = &pdev->dev; + ipu->irq_sync = irq_sync; + ipu->irq_err = irq_err; + + ret = ipu_irq_init(ipu); + if (ret) + goto out_failed_irq; + + ipu_reset(ipu); + + /* Set MCU_T to divide MCU access window into 2 */ + ipu_cm_write(ipu, 0x00400000L | (IPU_MCU_T_DEFAULT << 18), + IPU_DISP_GEN); + + ret = ipu_submodules_init(ipu, pdev, ipu_base, ipu->clk); + if (ret) + goto failed_submodules_init; + + ret = ipu_add_client_devices(ipu); + if (ret) { + dev_err(&pdev->dev, "adding client devices failed with %d\n", + ret); + goto failed_add_clients; + } + + return 0; + +failed_add_clients: + ipu_submodules_exit(ipu); +failed_submodules_init: + ipu_irq_exit(ipu); +out_failed_irq: + clk_disable_unprepare(ipu->clk); +failed_clk_get: +failed_ioremap: + return ret; +} + +static int __devexit ipu_remove(struct platform_device *pdev) +{ + struct ipu_soc *ipu = platform_get_drvdata(pdev); + struct resource *res; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + platform_device_unregister_children(pdev); + ipu_submodules_exit(ipu); + ipu_irq_exit(ipu); + + clk_disable_unprepare(ipu->clk); + + return 0; +} + +static struct platform_driver imx_ipu_driver = { + .driver = { + .name = "imx-ipuv3", + .of_match_table = imx_ipu_dt_ids, + }, + .probe = ipu_probe, + .remove = __devexit_p(ipu_remove), +}; + +module_platform_driver(imx_ipu_driver); + +MODULE_DESCRIPTION("i.MX IPU v3 driver"); +MODULE_AUTHOR("Sascha Hauer "); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/imx-drm/ipu-v3/ipu-dc.c b/drivers/staging/imx-drm/ipu-v3/ipu-dc.c new file mode 100644 index 0000000..93c7579 --- /dev/null +++ b/drivers/staging/imx-drm/ipu-v3/ipu-dc.c @@ -0,0 +1,372 @@ +/* + * Copyright (c) 2010 Sascha Hauer + * Copyright (C) 2005-2009 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include +#include +#include +#include +#include +#include + +#include "imx-ipu-v3.h" +#include "ipu-prv.h" + +#define DC_MAP_CONF_PTR(n) (0x108 + ((n) & ~0x1) * 2) +#define DC_MAP_CONF_VAL(n) (0x144 + ((n) & ~0x1) * 2) + +#define DC_EVT_NF 0 +#define DC_EVT_NL 1 +#define DC_EVT_EOF 2 +#define DC_EVT_NFIELD 3 +#define DC_EVT_EOL 4 +#define DC_EVT_EOFIELD 5 +#define DC_EVT_NEW_ADDR 6 +#define DC_EVT_NEW_CHAN 7 +#define DC_EVT_NEW_DATA 8 + +#define DC_EVT_NEW_ADDR_W_0 0 +#define DC_EVT_NEW_ADDR_W_1 1 +#define DC_EVT_NEW_CHAN_W_0 2 +#define DC_EVT_NEW_CHAN_W_1 3 +#define DC_EVT_NEW_DATA_W_0 4 +#define DC_EVT_NEW_DATA_W_1 5 +#define DC_EVT_NEW_ADDR_R_0 6 +#define DC_EVT_NEW_ADDR_R_1 7 +#define DC_EVT_NEW_CHAN_R_0 8 +#define DC_EVT_NEW_CHAN_R_1 9 +#define DC_EVT_NEW_DATA_R_0 10 +#define DC_EVT_NEW_DATA_R_1 11 + +#define DC_WR_CH_CONF 0x0 +#define DC_WR_CH_ADDR 0x4 +#define DC_RL_CH(evt) (8 + ((evt) & ~0x1) * 2) + +#define DC_GEN 0xd4 +#define DC_DISP_CONF1(disp) (0xd8 + (disp) * 4) +#define DC_DISP_CONF2(disp) (0xe8 + (disp) * 4) +#define DC_STAT 0x1c8 + +#define WROD(lf) (0x18 | ((lf) << 1)) +#define WRG 0x01 + +#define SYNC_WAVE 0 + +#define DC_GEN_SYNC_1_6_SYNC (2 << 1) +#define DC_GEN_SYNC_PRIORITY_1 (1 << 7) + +#define DC_WR_CH_CONF_WORD_SIZE_8 (0 << 0) +#define DC_WR_CH_CONF_WORD_SIZE_16 (1 << 0) +#define DC_WR_CH_CONF_WORD_SIZE_24 (2 << 0) +#define DC_WR_CH_CONF_WORD_SIZE_32 (3 << 0) +#define DC_WR_CH_CONF_DISP_ID_PARALLEL(i) (((i) & 0x1) << 3) +#define DC_WR_CH_CONF_DISP_ID_SERIAL (2 << 3) +#define DC_WR_CH_CONF_DISP_ID_ASYNC (3 << 4) +#define DC_WR_CH_CONF_FIELD_MODE (1 << 9) +#define DC_WR_CH_CONF_PROG_TYPE_NORMAL (4 << 5) +#define DC_WR_CH_CONF_PROG_TYPE_MASK (7 << 5) +#define DC_WR_CH_CONF_PROG_DI_ID (1 << 2) +#define DC_WR_CH_CONF_PROG_DISP_ID(i) (((i) & 0x1) << 3) + +#define IPU_DC_NUM_CHANNELS 10 + +struct ipu_dc_priv; + +enum ipu_dc_map { + IPU_DC_MAP_RGB24, + IPU_DC_MAP_RGB565, +}; + +struct ipu_dc { + /* The display interface number assigned to this dc channel */ + unsigned int di; + void __iomem *base; + struct ipu_dc_priv *priv; + int chno; + bool in_use; +}; + +struct ipu_dc_priv { + void __iomem *dc_reg; + void __iomem *dc_tmpl_reg; + struct ipu_soc *ipu; + struct device *dev; + struct ipu_dc channels[IPU_DC_NUM_CHANNELS]; + struct mutex mutex; +}; + +static void dc_link_event(struct ipu_dc *dc, int event, int addr, int priority) +{ + u32 reg; + + reg = readl(dc->base + DC_RL_CH(event)); + reg &= ~(0xffff << (16 * (event & 0x1))); + reg |= ((addr << 8) | priority) << (16 * (event & 0x1)); + writel(reg, dc->base + DC_RL_CH(event)); +} + +static void dc_write_tmpl(struct ipu_dc *dc, int word, u32 opcode, u32 operand, + int map, int wave, int glue, int sync) +{ + struct ipu_dc_priv *priv = dc->priv; + u32 reg; + int stop = 1; + + reg = sync | glue << 4 | ++wave << 11 | ++map << 15 | ((operand << 20) & 0xfff00000); + writel(reg, priv->dc_tmpl_reg + word * 8); + reg = operand >> 12 | opcode << 4 | stop << 9; + writel(reg, priv->dc_tmpl_reg + word * 8 + 4); +} + +static int ipu_pixfmt_to_map(u32 fmt) +{ + switch (fmt) { + case V4L2_PIX_FMT_RGB24: + return IPU_DC_MAP_RGB24; + case V4L2_PIX_FMT_RGB565: + return IPU_DC_MAP_RGB565; + default: + return -EINVAL; + } +} + +int ipu_dc_init_sync(struct ipu_dc *dc, struct ipu_di *di, bool interlaced, + u32 pixel_fmt, u32 width) +{ + struct ipu_dc_priv *priv = dc->priv; + u32 reg = 0, map; + + dc->di = ipu_di_get_num(di); + + map = ipu_pixfmt_to_map(pixel_fmt); + if (map < 0) { + dev_dbg(priv->dev, "IPU_DISP: No MAP\n"); + return -EINVAL; + } + + if (interlaced) { + dc_link_event(dc, DC_EVT_NL, 0, 3); + dc_link_event(dc, DC_EVT_EOL, 0, 2); + dc_link_event(dc, DC_EVT_NEW_DATA, 0, 1); + + /* Init template microcode */ + dc_write_tmpl(dc, 0, WROD(0), 0, map, SYNC_WAVE, 0, 8); + } else { + if (dc->di) { + dc_link_event(dc, DC_EVT_NL, 2, 3); + dc_link_event(dc, DC_EVT_EOL, 3, 2); + dc_link_event(dc, DC_EVT_NEW_DATA, 4, 1); + /* Init template microcode */ + dc_write_tmpl(dc, 2, WROD(0), 0, map, SYNC_WAVE, 8, 5); + dc_write_tmpl(dc, 3, WROD(0), 0, map, SYNC_WAVE, 4, 5); + dc_write_tmpl(dc, 4, WROD(0), 0, map, SYNC_WAVE, 0, 5); + } else { + dc_link_event(dc, DC_EVT_NL, 5, 3); + dc_link_event(dc, DC_EVT_EOL, 6, 2); + dc_link_event(dc, DC_EVT_NEW_DATA, 7, 1); + /* Init template microcode */ + dc_write_tmpl(dc, 5, WROD(0), 0, map, SYNC_WAVE, 8, 5); + dc_write_tmpl(dc, 6, WROD(0), 0, map, SYNC_WAVE, 4, 5); + dc_write_tmpl(dc, 7, WROD(0), 0, map, SYNC_WAVE, 0, 5); + } + } + dc_link_event(dc, DC_EVT_NF, 0, 0); + dc_link_event(dc, DC_EVT_NFIELD, 0, 0); + dc_link_event(dc, DC_EVT_EOF, 0, 0); + dc_link_event(dc, DC_EVT_EOFIELD, 0, 0); + dc_link_event(dc, DC_EVT_NEW_CHAN, 0, 0); + dc_link_event(dc, DC_EVT_NEW_ADDR, 0, 0); + + reg = readl(dc->base + DC_WR_CH_CONF); + if (interlaced) + reg |= DC_WR_CH_CONF_FIELD_MODE; + else + reg &= ~DC_WR_CH_CONF_FIELD_MODE; + writel(reg, dc->base + DC_WR_CH_CONF); + + writel(0x0, dc->base + DC_WR_CH_ADDR); + writel(width, priv->dc_reg + DC_DISP_CONF2(dc->di)); + + ipu_module_enable(priv->ipu, IPU_CONF_DC_EN); + + return 0; +} +EXPORT_SYMBOL_GPL(ipu_dc_init_sync); + +void ipu_dc_enable_channel(struct ipu_dc *dc) +{ + int di; + u32 reg; + + di = dc->di; + + reg = readl(dc->base + DC_WR_CH_CONF); + reg |= DC_WR_CH_CONF_PROG_TYPE_NORMAL; + writel(reg, dc->base + DC_WR_CH_CONF); +} +EXPORT_SYMBOL_GPL(ipu_dc_enable_channel); + +void ipu_dc_disable_channel(struct ipu_dc *dc) +{ + struct ipu_dc_priv *priv = dc->priv; + u32 val; + int irq = 0, timeout = 50; + + if (dc->chno == 1) + irq = IPU_IRQ_DC_FC_1; + else if (dc->chno == 5) + irq = IPU_IRQ_DP_SF_END; + else + return; + + /* should wait for the interrupt here */ + mdelay(50); + + if (dc->di == 0) + val = 0x00000002; + else + val = 0x00000020; + + /* Wait for DC triple buffer to empty */ + while ((readl(priv->dc_reg + DC_STAT) & val) != val) { + msleep(2); + timeout -= 2; + if (timeout <= 0) + break; + } + + val = readl(dc->base + DC_WR_CH_CONF); + val &= ~DC_WR_CH_CONF_PROG_TYPE_MASK; + writel(val, dc->base + DC_WR_CH_CONF); +} +EXPORT_SYMBOL_GPL(ipu_dc_disable_channel); + +static void ipu_dc_map_config(struct ipu_dc_priv *priv, enum ipu_dc_map map, + int byte_num, int offset, int mask) +{ + int ptr = map * 3 + byte_num; + u32 reg; + + reg = readl(priv->dc_reg + DC_MAP_CONF_VAL(ptr)); + reg &= ~(0xffff << (16 * (ptr & 0x1))); + reg |= ((offset << 8) | mask) << (16 * (ptr & 0x1)); + writel(reg, priv->dc_reg + DC_MAP_CONF_VAL(ptr)); + + reg = readl(priv->dc_reg + DC_MAP_CONF_PTR(map)); + reg &= ~(0x1f << ((16 * (map & 0x1)) + (5 * byte_num))); + reg |= ptr << ((16 * (map & 0x1)) + (5 * byte_num)); + writel(reg, priv->dc_reg + DC_MAP_CONF_PTR(map)); +} + +static void ipu_dc_map_clear(struct ipu_dc_priv *priv, int map) +{ + u32 reg = readl(priv->dc_reg + DC_MAP_CONF_PTR(map)); + + writel(reg & ~(0xffff << (16 * (map & 0x1))), + priv->dc_reg + DC_MAP_CONF_PTR(map)); +} + +struct ipu_dc *ipu_dc_get(struct ipu_soc *ipu, int channel) +{ + struct ipu_dc_priv *priv = ipu->dc_priv; + struct ipu_dc *dc; + + if (channel >= IPU_DC_NUM_CHANNELS) + return ERR_PTR(-ENODEV); + + dc = &priv->channels[channel]; + + mutex_lock(&priv->mutex); + + if (dc->in_use) { + mutex_unlock(&priv->mutex); + return ERR_PTR(-EBUSY); + } + + dc->in_use = 1; + + mutex_unlock(&priv->mutex); + + return dc; +} +EXPORT_SYMBOL_GPL(ipu_dc_get); + +void ipu_dc_put(struct ipu_dc *dc) +{ + struct ipu_dc_priv *priv = dc->priv; + + mutex_lock(&priv->mutex); + dc->in_use = 0; + mutex_unlock(&priv->mutex); +} +EXPORT_SYMBOL_GPL(ipu_dc_put); + +int ipu_dc_init(struct ipu_soc *ipu, struct device *dev, + unsigned long base, unsigned long template_base) +{ + struct ipu_dc_priv *priv; + static int channel_offsets[] = { 0, 0x1c, 0x38, 0x54, 0x58, 0x5c, + 0x78, 0, 0x94, 0xb4}; + int i; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + mutex_init(&priv->mutex); + + priv->dev = dev; + priv->ipu = ipu; + priv->dc_reg = devm_ioremap(dev, base, PAGE_SIZE); + priv->dc_tmpl_reg = devm_ioremap(dev, template_base, PAGE_SIZE); + if (!priv->dc_reg || !priv->dc_tmpl_reg) + return -ENOMEM; + + for (i = 0; i < IPU_DC_NUM_CHANNELS; i++) { + priv->channels[i].chno = i; + priv->channels[i].priv = priv; + priv->channels[i].base = priv->dc_reg + channel_offsets[i]; + } + + writel(DC_WR_CH_CONF_WORD_SIZE_24 | DC_WR_CH_CONF_DISP_ID_PARALLEL(1) | + DC_WR_CH_CONF_PROG_DI_ID, + priv->channels[1].base + DC_WR_CH_CONF); + writel(DC_WR_CH_CONF_WORD_SIZE_24 | DC_WR_CH_CONF_DISP_ID_PARALLEL(0), + priv->channels[5].base + DC_WR_CH_CONF); + + writel(DC_GEN_SYNC_1_6_SYNC | DC_GEN_SYNC_PRIORITY_1, priv->dc_reg + DC_GEN); + + ipu->dc_priv = priv; + + dev_dbg(dev, "DC base: 0x%08lx template base: 0x%08lx\n", + base, template_base); + + /* rgb24 */ + ipu_dc_map_clear(priv, IPU_DC_MAP_RGB24); + ipu_dc_map_config(priv, IPU_DC_MAP_RGB24, 0, 7, 0xff); /* blue */ + ipu_dc_map_config(priv, IPU_DC_MAP_RGB24, 1, 15, 0xff); /* green */ + ipu_dc_map_config(priv, IPU_DC_MAP_RGB24, 2, 23, 0xff); /* red */ + + /* rgb565 */ + ipu_dc_map_clear(priv, IPU_DC_MAP_RGB565); + ipu_dc_map_config(priv, IPU_DC_MAP_RGB565, 0, 4, 0xf8); /* blue */ + ipu_dc_map_config(priv, IPU_DC_MAP_RGB565, 1, 10, 0xfc); /* green */ + ipu_dc_map_config(priv, IPU_DC_MAP_RGB565, 2, 15, 0xf8); /* red */ + + return 0; +} + +void ipu_dc_exit(struct ipu_soc *ipu) +{ +} diff --git a/drivers/staging/imx-drm/ipu-v3/ipu-di.c b/drivers/staging/imx-drm/ipu-v3/ipu-di.c new file mode 100644 index 0000000..67d974f --- /dev/null +++ b/drivers/staging/imx-drm/ipu-v3/ipu-di.c @@ -0,0 +1,700 @@ +/* + * Copyright (c) 2010 Sascha Hauer + * Copyright (C) 2005-2009 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "imx-ipu-v3.h" +#include "ipu-prv.h" + +struct ipu_di { + void __iomem *base; + int id; + u32 module; + struct clk *clk_di; /* display input clock */ + struct clk *clk_ipu; /* IPU bus clock */ + struct clk *clk_di_pixel; /* resulting pixel clock */ + struct clk_hw clk_hw_out; + char *clk_name; + bool inuse; + unsigned long clkflags; + struct ipu_soc *ipu; +}; + +static DEFINE_MUTEX(di_mutex); + +struct di_sync_config { + int run_count; + int run_src; + int offset_count; + int offset_src; + int repeat_count; + int cnt_clr_src; + int cnt_polarity_gen_en; + int cnt_polarity_clr_src; + int cnt_polarity_trigger_src; + int cnt_up; + int cnt_down; +}; + +enum di_pins { + DI_PIN11 = 0, + DI_PIN12 = 1, + DI_PIN13 = 2, + DI_PIN14 = 3, + DI_PIN15 = 4, + DI_PIN16 = 5, + DI_PIN17 = 6, + DI_PIN_CS = 7, + + DI_PIN_SER_CLK = 0, + DI_PIN_SER_RS = 1, +}; + +enum di_sync_wave { + DI_SYNC_NONE = 0, + DI_SYNC_CLK = 1, + DI_SYNC_INT_HSYNC = 2, + DI_SYNC_HSYNC = 3, + DI_SYNC_VSYNC = 4, + DI_SYNC_DE = 6, +}; + +#define SYNC_WAVE 0 + +#define DI_GENERAL 0x0000 +#define DI_BS_CLKGEN0 0x0004 +#define DI_BS_CLKGEN1 0x0008 +#define DI_SW_GEN0(gen) (0x000c + 4 * ((gen) - 1)) +#define DI_SW_GEN1(gen) (0x0030 + 4 * ((gen) - 1)) +#define DI_STP_REP(gen) (0x0148 + 4 * (((gen) - 1)/2)) +#define DI_SYNC_AS_GEN 0x0054 +#define DI_DW_GEN(gen) (0x0058 + 4 * (gen)) +#define DI_DW_SET(gen, set) (0x0088 + 4 * ((gen) + 0xc * (set))) +#define DI_SER_CONF 0x015c +#define DI_SSC 0x0160 +#define DI_POL 0x0164 +#define DI_AW0 0x0168 +#define DI_AW1 0x016c +#define DI_SCR_CONF 0x0170 +#define DI_STAT 0x0174 + +#define DI_SW_GEN0_RUN_COUNT(x) ((x) << 19) +#define DI_SW_GEN0_RUN_SRC(x) ((x) << 16) +#define DI_SW_GEN0_OFFSET_COUNT(x) ((x) << 3) +#define DI_SW_GEN0_OFFSET_SRC(x) ((x) << 0) + +#define DI_SW_GEN1_CNT_POL_GEN_EN(x) ((x) << 29) +#define DI_SW_GEN1_CNT_CLR_SRC(x) ((x) << 25) +#define DI_SW_GEN1_CNT_POL_TRIGGER_SRC(x) ((x) << 12) +#define DI_SW_GEN1_CNT_POL_CLR_SRC(x) ((x) << 9) +#define DI_SW_GEN1_CNT_DOWN(x) ((x) << 16) +#define DI_SW_GEN1_CNT_UP(x) (x) +#define DI_SW_GEN1_AUTO_RELOAD (0x10000000) + +#define DI_DW_GEN_ACCESS_SIZE_OFFSET 24 +#define DI_DW_GEN_COMPONENT_SIZE_OFFSET 16 + +#define DI_GEN_POLARITY_1 (1 << 0) +#define DI_GEN_POLARITY_2 (1 << 1) +#define DI_GEN_POLARITY_3 (1 << 2) +#define DI_GEN_POLARITY_4 (1 << 3) +#define DI_GEN_POLARITY_5 (1 << 4) +#define DI_GEN_POLARITY_6 (1 << 5) +#define DI_GEN_POLARITY_7 (1 << 6) +#define DI_GEN_POLARITY_8 (1 << 7) +#define DI_GEN_POLARITY_DISP_CLK (1 << 17) +#define DI_GEN_DI_CLK_EXT (1 << 20) +#define DI_GEN_DI_VSYNC_EXT (1 << 21) + +#define DI_POL_DRDY_DATA_POLARITY (1 << 7) +#define DI_POL_DRDY_POLARITY_15 (1 << 4) + +#define DI_VSYNC_SEL_OFFSET 13 + +static inline u32 ipu_di_read(struct ipu_di *di, unsigned offset) +{ + return readl(di->base + offset); +} + +static inline void ipu_di_write(struct ipu_di *di, u32 value, unsigned offset) +{ + writel(value, di->base + offset); +} + +static int ipu_di_clk_calc_div(unsigned long inrate, unsigned long outrate) +{ + u64 tmp = inrate; + int div; + + tmp *= 16; + + do_div(tmp, outrate); + + div = tmp; + + if (div < 0x10) + div = 0x10; + +#ifdef WTF_IS_THIS + /* + * Freescale has this in their Kernel. It is neither clear what + * it does nor why it does it + */ + if (div & 0x10) + div &= ~0x7; + else { + /* Round up divider if it gets us closer to desired pix clk */ + if ((div & 0xC) == 0xC) { + div += 0x10; + div &= ~0xF; + } + } +#endif + return div; +} + +static unsigned long clk_di_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct ipu_di *di = container_of(hw, struct ipu_di, clk_hw_out); + unsigned long outrate; + u32 div = ipu_di_read(di, DI_BS_CLKGEN0); + + if (div < 0x10) + div = 0x10; + + outrate = (parent_rate / div) * 16; + + return outrate; +} + +static long clk_di_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + struct ipu_di *di = container_of(hw, struct ipu_di, clk_hw_out); + unsigned long outrate; + int div; + u32 val; + + div = ipu_di_clk_calc_div(*prate, rate); + + outrate = (*prate / div) * 16; + + val = ipu_di_read(di, DI_GENERAL); + + if (!(val & DI_GEN_DI_CLK_EXT) && outrate > *prate / 2) + outrate = *prate / 2; + + dev_dbg(di->ipu->dev, + "%s: inrate: %ld div: 0x%08x outrate: %ld wanted: %ld\n", + __func__, *prate, div, outrate, rate); + + return outrate; +} + +static int clk_di_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct ipu_di *di = container_of(hw, struct ipu_di, clk_hw_out); + int div; + u32 clkgen0; + + clkgen0 = ipu_di_read(di, DI_BS_CLKGEN0) & ~0xfff; + + div = ipu_di_clk_calc_div(parent_rate, rate); + + ipu_di_write(di, clkgen0 | div, DI_BS_CLKGEN0); + + dev_dbg(di->ipu->dev, "%s: inrate: %ld desired: %ld div: 0x%08x\n", + __func__, parent_rate, rate, div); + return 0; +} + +static u8 clk_di_get_parent(struct clk_hw *hw) +{ + struct ipu_di *di = container_of(hw, struct ipu_di, clk_hw_out); + u32 val; + + val = ipu_di_read(di, DI_GENERAL); + + return val & DI_GEN_DI_CLK_EXT ? 1 : 0; +} + +static int clk_di_set_parent(struct clk_hw *hw, u8 index) +{ + struct ipu_di *di = container_of(hw, struct ipu_di, clk_hw_out); + u32 val; + + val = ipu_di_read(di, DI_GENERAL); + + if (index) + val |= DI_GEN_DI_CLK_EXT; + else + val &= ~DI_GEN_DI_CLK_EXT; + + ipu_di_write(di, val, DI_GENERAL); + + return 0; +} + +static struct clk_ops clk_di_ops = { + .round_rate = clk_di_round_rate, + .set_rate = clk_di_set_rate, + .recalc_rate = clk_di_recalc_rate, + .set_parent = clk_di_set_parent, + .get_parent = clk_di_get_parent, +}; + +static void ipu_di_data_wave_config(struct ipu_di *di, + int wave_gen, + int access_size, int component_size) +{ + u32 reg; + reg = (access_size << DI_DW_GEN_ACCESS_SIZE_OFFSET) | + (component_size << DI_DW_GEN_COMPONENT_SIZE_OFFSET); + ipu_di_write(di, reg, DI_DW_GEN(wave_gen)); +} + +static void ipu_di_data_pin_config(struct ipu_di *di, int wave_gen, int di_pin, + int set, int up, int down) +{ + u32 reg; + + reg = ipu_di_read(di, DI_DW_GEN(wave_gen)); + reg &= ~(0x3 << (di_pin * 2)); + reg |= set << (di_pin * 2); + ipu_di_write(di, reg, DI_DW_GEN(wave_gen)); + + ipu_di_write(di, (down << 16) | up, DI_DW_SET(wave_gen, set)); +} + +static void ipu_di_sync_config(struct ipu_di *di, struct di_sync_config *config, + int start, int count) +{ + u32 reg; + int i; + + for (i = 0; i < count; i++) { + struct di_sync_config *c = &config[i]; + int wave_gen = start + i + 1; + + if ((c->run_count >= 0x1000) || (c->offset_count >= 0x1000) || + (c->repeat_count >= 0x1000) || + (c->cnt_up >= 0x400) || + (c->cnt_down >= 0x400)) { + dev_err(di->ipu->dev, "DI%d counters out of range.\n", + di->id); + return; + } + + reg = DI_SW_GEN0_RUN_COUNT(c->run_count) | + DI_SW_GEN0_RUN_SRC(c->run_src) | + DI_SW_GEN0_OFFSET_COUNT(c->offset_count) | + DI_SW_GEN0_OFFSET_SRC(c->offset_src); + ipu_di_write(di, reg, DI_SW_GEN0(wave_gen)); + + reg = DI_SW_GEN1_CNT_POL_GEN_EN(c->cnt_polarity_gen_en) | + DI_SW_GEN1_CNT_CLR_SRC(c->cnt_clr_src) | + DI_SW_GEN1_CNT_POL_TRIGGER_SRC( + c->cnt_polarity_trigger_src) | + DI_SW_GEN1_CNT_POL_CLR_SRC(c->cnt_polarity_clr_src) | + DI_SW_GEN1_CNT_DOWN(c->cnt_down) | + DI_SW_GEN1_CNT_UP(c->cnt_up); + + /* Enable auto reload */ + if (c->repeat_count == 0) + reg |= DI_SW_GEN1_AUTO_RELOAD; + + ipu_di_write(di, reg, DI_SW_GEN1(wave_gen)); + + reg = ipu_di_read(di, DI_STP_REP(wave_gen)); + reg &= ~(0xffff << (16 * ((wave_gen - 1) & 0x1))); + reg |= c->repeat_count << (16 * ((wave_gen - 1) & 0x1)); + ipu_di_write(di, reg, DI_STP_REP(wave_gen)); + } +} + +static void ipu_di_sync_config_interlaced(struct ipu_di *di, + struct ipu_di_signal_cfg *sig) +{ + u32 h_total = sig->width + sig->h_sync_width + + sig->h_start_width + sig->h_end_width; + u32 v_total = sig->height + sig->v_sync_width + + sig->v_start_width + sig->v_end_width; + u32 reg; + struct di_sync_config cfg[] = { + { + .run_count = h_total / 2 - 1, + .run_src = DI_SYNC_CLK, + }, { + .run_count = h_total - 11, + .run_src = DI_SYNC_CLK, + .cnt_down = 4, + }, { + .run_count = v_total * 2 - 1, + .run_src = DI_SYNC_INT_HSYNC, + .offset_count = 1, + .offset_src = DI_SYNC_INT_HSYNC, + .cnt_down = 4, + }, { + .run_count = v_total / 2 - 1, + .run_src = DI_SYNC_HSYNC, + .offset_count = sig->v_start_width, + .offset_src = DI_SYNC_HSYNC, + .repeat_count = 2, + .cnt_clr_src = DI_SYNC_VSYNC, + }, { + .run_src = DI_SYNC_HSYNC, + .repeat_count = sig->height / 2, + .cnt_clr_src = 4, + }, { + .run_count = v_total - 1, + .run_src = DI_SYNC_HSYNC, + }, { + .run_count = v_total / 2 - 1, + .run_src = DI_SYNC_HSYNC, + .offset_count = 9, + .offset_src = DI_SYNC_HSYNC, + .repeat_count = 2, + .cnt_clr_src = DI_SYNC_VSYNC, + }, { + .run_src = DI_SYNC_CLK, + .offset_count = sig->h_start_width, + .offset_src = DI_SYNC_CLK, + .repeat_count = sig->width, + .cnt_clr_src = 5, + }, { + .run_count = v_total - 1, + .run_src = DI_SYNC_INT_HSYNC, + .offset_count = v_total / 2, + .offset_src = DI_SYNC_INT_HSYNC, + .cnt_clr_src = DI_SYNC_HSYNC, + .cnt_down = 4, + } + }; + + ipu_di_sync_config(di, cfg, 0, ARRAY_SIZE(cfg)); + + /* set gentime select and tag sel */ + reg = ipu_di_read(di, DI_SW_GEN1(9)); + reg &= 0x1FFFFFFF; + reg |= (3 - 1) << 29 | 0x00008000; + ipu_di_write(di, reg, DI_SW_GEN1(9)); + + ipu_di_write(di, v_total / 2 - 1, DI_SCR_CONF); +} + +static void ipu_di_sync_config_noninterlaced(struct ipu_di *di, + struct ipu_di_signal_cfg *sig, int div) +{ + u32 h_total = sig->width + sig->h_sync_width + sig->h_start_width + + sig->h_end_width; + u32 v_total = sig->height + sig->v_sync_width + sig->v_start_width + + sig->v_end_width; + struct di_sync_config cfg[] = { + { + .run_count = h_total - 1, + .run_src = DI_SYNC_CLK, + } , { + .run_count = h_total - 1, + .run_src = DI_SYNC_CLK, + .offset_count = div * sig->v_to_h_sync, + .offset_src = DI_SYNC_CLK, + .cnt_polarity_gen_en = 1, + .cnt_polarity_trigger_src = DI_SYNC_CLK, + .cnt_down = sig->h_sync_width * 2, + } , { + .run_count = v_total - 1, + .run_src = DI_SYNC_INT_HSYNC, + .cnt_polarity_gen_en = 1, + .cnt_polarity_trigger_src = DI_SYNC_INT_HSYNC, + .cnt_down = sig->v_sync_width * 2, + } , { + .run_src = DI_SYNC_HSYNC, + .offset_count = sig->v_sync_width + sig->v_start_width, + .offset_src = DI_SYNC_HSYNC, + .repeat_count = sig->height, + .cnt_clr_src = DI_SYNC_VSYNC, + } , { + .run_src = DI_SYNC_CLK, + .offset_count = sig->h_sync_width + sig->h_start_width, + .offset_src = DI_SYNC_CLK, + .repeat_count = sig->width, + .cnt_clr_src = 5, + } , { + /* unused */ + } , { + /* unused */ + } , { + /* unused */ + } , { + /* unused */ + }, + }; + + ipu_di_write(di, v_total - 1, DI_SCR_CONF); + ipu_di_sync_config(di, cfg, 0, ARRAY_SIZE(cfg)); +} + +int ipu_di_init_sync_panel(struct ipu_di *di, struct ipu_di_signal_cfg *sig) +{ + u32 reg; + u32 di_gen, vsync_cnt; + u32 div; + u32 h_total, v_total; + int ret; + unsigned long round; + struct clk *parent; + + dev_dbg(di->ipu->dev, "disp %d: panel size = %d x %d\n", + di->id, sig->width, sig->height); + + if ((sig->v_sync_width == 0) || (sig->h_sync_width == 0)) + return -EINVAL; + + if (sig->clkflags & IPU_DI_CLKMODE_EXT) + parent = di->clk_di; + else + parent = di->clk_ipu; + + ret = clk_set_parent(di->clk_di_pixel, parent); + if (ret) { + dev_err(di->ipu->dev, + "setting pixel clock to parent %s failed with %d\n", + __clk_get_name(parent), ret); + return ret; + } + + if (sig->clkflags & IPU_DI_CLKMODE_SYNC) + round = clk_get_rate(parent); + else + round = clk_round_rate(di->clk_di_pixel, sig->pixelclock); + + ret = clk_set_rate(di->clk_di_pixel, round); + + h_total = sig->width + sig->h_sync_width + sig->h_start_width + + sig->h_end_width; + v_total = sig->height + sig->v_sync_width + sig->v_start_width + + sig->v_end_width; + + mutex_lock(&di_mutex); + + div = ipu_di_read(di, DI_BS_CLKGEN0) & 0xfff; + div = div / 16; /* Now divider is integer portion */ + + /* Setup pixel clock timing */ + /* Down time is half of period */ + ipu_di_write(di, (div << 16), DI_BS_CLKGEN1); + + ipu_di_data_wave_config(di, SYNC_WAVE, div - 1, div - 1); + ipu_di_data_pin_config(di, SYNC_WAVE, DI_PIN15, 3, 0, div * 2); + + di_gen = ipu_di_read(di, DI_GENERAL) & DI_GEN_DI_CLK_EXT; + di_gen |= DI_GEN_DI_VSYNC_EXT; + + if (sig->interlaced) { + ipu_di_sync_config_interlaced(di, sig); + + /* set y_sel = 1 */ + di_gen |= 0x10000000; + di_gen |= DI_GEN_POLARITY_5; + di_gen |= DI_GEN_POLARITY_8; + + vsync_cnt = 7; + + if (sig->Hsync_pol) + di_gen |= DI_GEN_POLARITY_3; + if (sig->Vsync_pol) + di_gen |= DI_GEN_POLARITY_2; + } else { + ipu_di_sync_config_noninterlaced(di, sig, div); + + vsync_cnt = 3; + + if (sig->Hsync_pol) + di_gen |= DI_GEN_POLARITY_2; + if (sig->Vsync_pol) + di_gen |= DI_GEN_POLARITY_3; + } + + if (!sig->clk_pol) + di_gen |= DI_GEN_POLARITY_DISP_CLK; + + ipu_di_write(di, di_gen, DI_GENERAL); + + ipu_di_write(di, (--vsync_cnt << DI_VSYNC_SEL_OFFSET) | 0x00000002, + DI_SYNC_AS_GEN); + + reg = ipu_di_read(di, DI_POL); + reg &= ~(DI_POL_DRDY_DATA_POLARITY | DI_POL_DRDY_POLARITY_15); + + if (sig->enable_pol) + reg |= DI_POL_DRDY_POLARITY_15; + if (sig->data_pol) + reg |= DI_POL_DRDY_DATA_POLARITY; + + ipu_di_write(di, reg, DI_POL); + + mutex_unlock(&di_mutex); + + return 0; +} +EXPORT_SYMBOL_GPL(ipu_di_init_sync_panel); + +int ipu_di_enable(struct ipu_di *di) +{ + clk_prepare_enable(di->clk_di_pixel); + + ipu_module_enable(di->ipu, di->module); + + return 0; +} +EXPORT_SYMBOL_GPL(ipu_di_enable); + +int ipu_di_disable(struct ipu_di *di) +{ + ipu_module_disable(di->ipu, di->module); + + clk_disable_unprepare(di->clk_di_pixel); + + return 0; +} +EXPORT_SYMBOL_GPL(ipu_di_disable); + +int ipu_di_get_num(struct ipu_di *di) +{ + return di->id; +} +EXPORT_SYMBOL_GPL(ipu_di_get_num); + +static DEFINE_MUTEX(ipu_di_lock); + +struct ipu_di *ipu_di_get(struct ipu_soc *ipu, int disp) +{ + struct ipu_di *di; + + if (disp > 1) + return ERR_PTR(-EINVAL); + + di = ipu->di_priv[disp]; + + mutex_lock(&ipu_di_lock); + + if (di->inuse) { + di = ERR_PTR(-EBUSY); + goto out; + } + + di->inuse = true; +out: + mutex_unlock(&ipu_di_lock); + + return di; +} +EXPORT_SYMBOL_GPL(ipu_di_get); + +void ipu_di_put(struct ipu_di *di) +{ + mutex_lock(&ipu_di_lock); + + di->inuse = false; + + mutex_unlock(&ipu_di_lock); +} +EXPORT_SYMBOL_GPL(ipu_di_put); + +int ipu_di_init(struct ipu_soc *ipu, struct device *dev, int id, + unsigned long base, + u32 module, struct clk *clk_ipu) +{ + struct ipu_di *di; + int ret; + const char *di_parent[2]; + struct clk_init_data init = { + .ops = &clk_di_ops, + .num_parents = 2, + .flags = 0, + }; + + if (id > 1) + return -ENODEV; + + di = devm_kzalloc(dev, sizeof(*di), GFP_KERNEL); + if (!di) + return -ENOMEM; + + ipu->di_priv[id] = di; + + di->clk_di = devm_clk_get(dev, id ? "di1" : "di0"); + if (IS_ERR(di->clk_di)) + return PTR_ERR(di->clk_di); + + di->module = module; + di->id = id; + di->clk_ipu = clk_ipu; + di->base = devm_ioremap(dev, base, PAGE_SIZE); + if (!di->base) + return -ENOMEM; + + di_parent[0] = __clk_get_name(di->clk_ipu); + di_parent[1] = __clk_get_name(di->clk_di); + + ipu_di_write(di, 0x10, DI_BS_CLKGEN0); + + init.parent_names = (const char **)&di_parent; + di->clk_name = kasprintf(GFP_KERNEL, "%s_di%d_pixel", + dev_name(dev), id); + if (!di->clk_name) + return -ENOMEM; + + init.name = di->clk_name; + + di->clk_hw_out.init = &init; + di->clk_di_pixel = clk_register(dev, &di->clk_hw_out); + + if (IS_ERR(di->clk_di_pixel)) { + ret = PTR_ERR(di->clk_di_pixel); + goto failed_clk_register; + } + + dev_info(dev, "DI%d base: 0x%08lx remapped to %p\n", + id, base, di->base); + di->inuse = false; + di->ipu = ipu; + + return 0; + +failed_clk_register: + + kfree(di->clk_name); + + return ret; +} + +void ipu_di_exit(struct ipu_soc *ipu, int id) +{ + struct ipu_di *di = ipu->di_priv[id]; + + clk_unregister(di->clk_di_pixel); + kfree(di->clk_name); +} diff --git a/drivers/staging/imx-drm/ipu-v3/ipu-dmfc.c b/drivers/staging/imx-drm/ipu-v3/ipu-dmfc.c new file mode 100644 index 0000000..91821bc --- /dev/null +++ b/drivers/staging/imx-drm/ipu-v3/ipu-dmfc.c @@ -0,0 +1,408 @@ +/* + * Copyright (c) 2010 Sascha Hauer + * Copyright (C) 2005-2009 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ +#include +#include +#include +#include + +#include "imx-ipu-v3.h" +#include "ipu-prv.h" + +#define DMFC_RD_CHAN 0x0000 +#define DMFC_WR_CHAN 0x0004 +#define DMFC_WR_CHAN_DEF 0x0008 +#define DMFC_DP_CHAN 0x000c +#define DMFC_DP_CHAN_DEF 0x0010 +#define DMFC_GENERAL1 0x0014 +#define DMFC_GENERAL2 0x0018 +#define DMFC_IC_CTRL 0x001c +#define DMFC_STAT 0x0020 + +#define DMFC_WR_CHAN_1_28 0 +#define DMFC_WR_CHAN_2_41 8 +#define DMFC_WR_CHAN_1C_42 16 +#define DMFC_WR_CHAN_2C_43 24 + +#define DMFC_DP_CHAN_5B_23 0 +#define DMFC_DP_CHAN_5F_27 8 +#define DMFC_DP_CHAN_6B_24 16 +#define DMFC_DP_CHAN_6F_29 24 + +#define DMFC_FIFO_SIZE_64 (3 << 3) +#define DMFC_FIFO_SIZE_128 (2 << 3) +#define DMFC_FIFO_SIZE_256 (1 << 3) +#define DMFC_FIFO_SIZE_512 (0 << 3) + +#define DMFC_SEGMENT(x) ((x & 0x7) << 0) +#define DMFC_BURSTSIZE_128 (0 << 6) +#define DMFC_BURSTSIZE_64 (1 << 6) +#define DMFC_BURSTSIZE_32 (2 << 6) +#define DMFC_BURSTSIZE_16 (3 << 6) + +struct dmfc_channel_data { + int ipu_channel; + unsigned long channel_reg; + unsigned long shift; + unsigned eot_shift; + unsigned max_fifo_lines; +}; + +static const struct dmfc_channel_data dmfcdata[] = { + { + .ipu_channel = 23, + .channel_reg = DMFC_DP_CHAN, + .shift = DMFC_DP_CHAN_5B_23, + .eot_shift = 20, + .max_fifo_lines = 3, + }, { + .ipu_channel = 24, + .channel_reg = DMFC_DP_CHAN, + .shift = DMFC_DP_CHAN_6B_24, + .eot_shift = 22, + .max_fifo_lines = 1, + }, { + .ipu_channel = 27, + .channel_reg = DMFC_DP_CHAN, + .shift = DMFC_DP_CHAN_5F_27, + .eot_shift = 21, + .max_fifo_lines = 2, + }, { + .ipu_channel = 28, + .channel_reg = DMFC_WR_CHAN, + .shift = DMFC_WR_CHAN_1_28, + .eot_shift = 16, + .max_fifo_lines = 2, + }, { + .ipu_channel = 29, + .channel_reg = DMFC_DP_CHAN, + .shift = DMFC_DP_CHAN_6F_29, + .eot_shift = 23, + .max_fifo_lines = 1, + }, +}; + +#define DMFC_NUM_CHANNELS ARRAY_SIZE(dmfcdata) + +struct ipu_dmfc_priv; + +struct dmfc_channel { + unsigned slots; + unsigned slotmask; + unsigned segment; + int burstsize; + struct ipu_soc *ipu; + struct ipu_dmfc_priv *priv; + const struct dmfc_channel_data *data; +}; + +struct ipu_dmfc_priv { + struct ipu_soc *ipu; + struct device *dev; + struct dmfc_channel channels[DMFC_NUM_CHANNELS]; + struct mutex mutex; + unsigned long bandwidth_per_slot; + void __iomem *base; + int use_count; +}; + +int ipu_dmfc_enable_channel(struct dmfc_channel *dmfc) +{ + struct ipu_dmfc_priv *priv = dmfc->priv; + mutex_lock(&priv->mutex); + + if (!priv->use_count) + ipu_module_enable(priv->ipu, IPU_CONF_DMFC_EN); + + priv->use_count++; + + mutex_unlock(&priv->mutex); + + return 0; +} +EXPORT_SYMBOL_GPL(ipu_dmfc_enable_channel); + +void ipu_dmfc_disable_channel(struct dmfc_channel *dmfc) +{ + struct ipu_dmfc_priv *priv = dmfc->priv; + + mutex_lock(&priv->mutex); + + priv->use_count--; + + if (!priv->use_count) + ipu_module_disable(priv->ipu, IPU_CONF_DMFC_EN); + + if (priv->use_count < 0) + priv->use_count = 0; + + mutex_unlock(&priv->mutex); +} +EXPORT_SYMBOL_GPL(ipu_dmfc_disable_channel); + +static int ipu_dmfc_setup_channel(struct dmfc_channel *dmfc, int slots, + int segment, int burstsize) +{ + struct ipu_dmfc_priv *priv = dmfc->priv; + u32 val, field; + + dev_dbg(priv->dev, + "dmfc: using %d slots starting from segment %d for IPU channel %d\n", + slots, segment, dmfc->data->ipu_channel); + + if (!dmfc) + return -EINVAL; + + switch (slots) { + case 1: + field = DMFC_FIFO_SIZE_64; + break; + case 2: + field = DMFC_FIFO_SIZE_128; + break; + case 4: + field = DMFC_FIFO_SIZE_256; + break; + case 8: + field = DMFC_FIFO_SIZE_512; + break; + default: + return -EINVAL; + } + + switch (burstsize) { + case 16: + field |= DMFC_BURSTSIZE_16; + break; + case 32: + field |= DMFC_BURSTSIZE_32; + break; + case 64: + field |= DMFC_BURSTSIZE_64; + break; + case 128: + field |= DMFC_BURSTSIZE_128; + break; + } + + field |= DMFC_SEGMENT(segment); + + val = readl(priv->base + dmfc->data->channel_reg); + + val &= ~(0xff << dmfc->data->shift); + val |= field << dmfc->data->shift; + + writel(val, priv->base + dmfc->data->channel_reg); + + dmfc->slots = slots; + dmfc->segment = segment; + dmfc->burstsize = burstsize; + dmfc->slotmask = ((1 << slots) - 1) << segment; + + return 0; +} + +static int dmfc_bandwidth_to_slots(struct ipu_dmfc_priv *priv, + unsigned long bandwidth) +{ + int slots = 1; + + while (slots * priv->bandwidth_per_slot < bandwidth) + slots *= 2; + + return slots; +} + +static int dmfc_find_slots(struct ipu_dmfc_priv *priv, int slots) +{ + unsigned slotmask_need, slotmask_used = 0; + int i, segment = 0; + + slotmask_need = (1 << slots) - 1; + + for (i = 0; i < DMFC_NUM_CHANNELS; i++) + slotmask_used |= priv->channels[i].slotmask; + + while (slotmask_need <= 0xff) { + if (!(slotmask_used & slotmask_need)) + return segment; + + slotmask_need <<= 1; + segment++; + } + + return -EBUSY; +} + +void ipu_dmfc_free_bandwidth(struct dmfc_channel *dmfc) +{ + struct ipu_dmfc_priv *priv = dmfc->priv; + int i; + + dev_dbg(priv->dev, "dmfc: freeing %d slots starting from segment %d\n", + dmfc->slots, dmfc->segment); + + mutex_lock(&priv->mutex); + + if (!dmfc->slots) + goto out; + + dmfc->slotmask = 0; + dmfc->slots = 0; + dmfc->segment = 0; + + for (i = 0; i < DMFC_NUM_CHANNELS; i++) + priv->channels[i].slotmask = 0; + + for (i = 0; i < DMFC_NUM_CHANNELS; i++) { + if (priv->channels[i].slots > 0) { + priv->channels[i].segment = + dmfc_find_slots(priv, priv->channels[i].slots); + priv->channels[i].slotmask = + ((1 << priv->channels[i].slots) - 1) << + priv->channels[i].segment; + } + } + + for (i = 0; i < DMFC_NUM_CHANNELS; i++) { + if (priv->channels[i].slots > 0) + ipu_dmfc_setup_channel(&priv->channels[i], + priv->channels[i].slots, + priv->channels[i].segment, + priv->channels[i].burstsize); + } +out: + mutex_unlock(&priv->mutex); +} +EXPORT_SYMBOL_GPL(ipu_dmfc_free_bandwidth); + +int ipu_dmfc_alloc_bandwidth(struct dmfc_channel *dmfc, + unsigned long bandwidth_pixel_per_second, int burstsize) +{ + struct ipu_dmfc_priv *priv = dmfc->priv; + int slots = dmfc_bandwidth_to_slots(priv, bandwidth_pixel_per_second); + int segment = 0, ret = 0; + + dev_dbg(priv->dev, "dmfc: trying to allocate %ldMpixel/s for IPU channel %d\n", + bandwidth_pixel_per_second / 1000000, + dmfc->data->ipu_channel); + + ipu_dmfc_free_bandwidth(dmfc); + + mutex_lock(&priv->mutex); + + if (slots > 8) { + ret = -EBUSY; + goto out; + } + + segment = dmfc_find_slots(priv, slots); + if (segment < 0) { + ret = -EBUSY; + goto out; + } + + ipu_dmfc_setup_channel(dmfc, slots, segment, burstsize); + +out: + mutex_unlock(&priv->mutex); + + return ret; +} +EXPORT_SYMBOL_GPL(ipu_dmfc_alloc_bandwidth); + +int ipu_dmfc_init_channel(struct dmfc_channel *dmfc, int width) +{ + struct ipu_dmfc_priv *priv = dmfc->priv; + u32 dmfc_gen1; + + dmfc_gen1 = readl(priv->base + DMFC_GENERAL1); + + if ((dmfc->slots * 64 * 4) / width > dmfc->data->max_fifo_lines) + dmfc_gen1 |= 1 << dmfc->data->eot_shift; + else + dmfc_gen1 &= ~(1 << dmfc->data->eot_shift); + + writel(dmfc_gen1, priv->base + DMFC_GENERAL1); + + return 0; +} +EXPORT_SYMBOL_GPL(ipu_dmfc_init_channel); + +struct dmfc_channel *ipu_dmfc_get(struct ipu_soc *ipu, int ipu_channel) +{ + struct ipu_dmfc_priv *priv = ipu->dmfc_priv; + int i; + + for (i = 0; i < DMFC_NUM_CHANNELS; i++) + if (dmfcdata[i].ipu_channel == ipu_channel) + return &priv->channels[i]; + return ERR_PTR(-ENODEV); +} +EXPORT_SYMBOL_GPL(ipu_dmfc_get); + +void ipu_dmfc_put(struct dmfc_channel *dmfc) +{ + ipu_dmfc_free_bandwidth(dmfc); +} +EXPORT_SYMBOL_GPL(ipu_dmfc_put); + +int ipu_dmfc_init(struct ipu_soc *ipu, struct device *dev, unsigned long base, + struct clk *ipu_clk) +{ + struct ipu_dmfc_priv *priv; + int i; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->base = devm_ioremap(dev, base, PAGE_SIZE); + if (!priv->base) + return -ENOMEM; + + priv->dev = dev; + priv->ipu = ipu; + mutex_init(&priv->mutex); + + ipu->dmfc_priv = priv; + + for (i = 0; i < DMFC_NUM_CHANNELS; i++) { + priv->channels[i].priv = priv; + priv->channels[i].ipu = ipu; + priv->channels[i].data = &dmfcdata[i]; + } + + writel(0x0, priv->base + DMFC_WR_CHAN); + writel(0x0, priv->base + DMFC_DP_CHAN); + + /* + * We have a total bandwidth of clkrate * 4pixel divided + * into 8 slots. + */ + priv->bandwidth_per_slot = clk_get_rate(ipu_clk) / 8; + + dev_dbg(dev, "dmfc: 8 slots with %ldMpixel/s bandwidth each\n", + priv->bandwidth_per_slot / 1000000); + + writel(0x202020f6, priv->base + DMFC_WR_CHAN_DEF); + writel(0x2020f6f6, priv->base + DMFC_DP_CHAN_DEF); + writel(0x00000003, priv->base + DMFC_GENERAL1); + + return 0; +} + +void ipu_dmfc_exit(struct ipu_soc *ipu) +{ +} diff --git a/drivers/staging/imx-drm/ipu-v3/ipu-dp.c b/drivers/staging/imx-drm/ipu-v3/ipu-dp.c new file mode 100644 index 0000000..26aecaf --- /dev/null +++ b/drivers/staging/imx-drm/ipu-v3/ipu-dp.c @@ -0,0 +1,336 @@ +/* + * Copyright (c) 2010 Sascha Hauer + * Copyright (C) 2005-2009 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ +#include +#include +#include +#include +#include +#include + +#include "imx-ipu-v3.h" +#include "ipu-prv.h" + +#define DP_SYNC 0 +#define DP_ASYNC0 0x60 +#define DP_ASYNC1 0xBC + +#define DP_COM_CONF 0x0 +#define DP_GRAPH_WIND_CTRL 0x0004 +#define DP_FG_POS 0x0008 +#define DP_CSC_A_0 0x0044 +#define DP_CSC_A_1 0x0048 +#define DP_CSC_A_2 0x004C +#define DP_CSC_A_3 0x0050 +#define DP_CSC_0 0x0054 +#define DP_CSC_1 0x0058 + +#define DP_COM_CONF_FG_EN (1 << 0) +#define DP_COM_CONF_GWSEL (1 << 1) +#define DP_COM_CONF_GWAM (1 << 2) +#define DP_COM_CONF_GWCKE (1 << 3) +#define DP_COM_CONF_CSC_DEF_MASK (3 << 8) +#define DP_COM_CONF_CSC_DEF_OFFSET 8 +#define DP_COM_CONF_CSC_DEF_FG (3 << 8) +#define DP_COM_CONF_CSC_DEF_BG (2 << 8) +#define DP_COM_CONF_CSC_DEF_BOTH (1 << 8) + +struct ipu_dp_priv; + +struct ipu_dp { + u32 flow; + bool in_use; + bool foreground; + enum ipu_color_space in_cs; +}; + +struct ipu_flow { + struct ipu_dp foreground; + struct ipu_dp background; + enum ipu_color_space out_cs; + void __iomem *base; + struct ipu_dp_priv *priv; +}; + +struct ipu_dp_priv { + struct ipu_soc *ipu; + struct device *dev; + void __iomem *base; + struct ipu_flow flow[3]; + struct mutex mutex; + int use_count; +}; + +static u32 ipu_dp_flow_base[] = {DP_SYNC, DP_ASYNC0, DP_ASYNC1}; + +static inline struct ipu_flow *to_flow(struct ipu_dp *dp) +{ + if (dp->foreground) + return container_of(dp, struct ipu_flow, foreground); + else + return container_of(dp, struct ipu_flow, background); +} + +int ipu_dp_set_global_alpha(struct ipu_dp *dp, bool enable, + u8 alpha, bool bg_chan) +{ + struct ipu_flow *flow = to_flow(dp); + struct ipu_dp_priv *priv = flow->priv; + u32 reg; + + mutex_lock(&priv->mutex); + + reg = readl(flow->base + DP_COM_CONF); + if (bg_chan) + reg &= ~DP_COM_CONF_GWSEL; + else + reg |= DP_COM_CONF_GWSEL; + writel(reg, flow->base + DP_COM_CONF); + + if (enable) { + reg = readl(flow->base + DP_GRAPH_WIND_CTRL) & 0x00FFFFFFL; + writel(reg | ((u32) alpha << 24), + flow->base + DP_GRAPH_WIND_CTRL); + + reg = readl(flow->base + DP_COM_CONF); + writel(reg | DP_COM_CONF_GWAM, flow->base + DP_COM_CONF); + } else { + reg = readl(flow->base + DP_COM_CONF); + writel(reg & ~DP_COM_CONF_GWAM, flow->base + DP_COM_CONF); + } + + ipu_srm_dp_sync_update(priv->ipu); + + mutex_unlock(&priv->mutex); + + return 0; +} +EXPORT_SYMBOL_GPL(ipu_dp_set_global_alpha); + +int ipu_dp_set_window_pos(struct ipu_dp *dp, u16 x_pos, u16 y_pos) +{ + struct ipu_flow *flow = to_flow(dp); + struct ipu_dp_priv *priv = flow->priv; + + writel((x_pos << 16) | y_pos, flow->base + DP_FG_POS); + + ipu_srm_dp_sync_update(priv->ipu); + + return 0; +} +EXPORT_SYMBOL_GPL(ipu_dp_set_window_pos); + +static void ipu_dp_csc_init(struct ipu_flow *flow, + enum ipu_color_space in, + enum ipu_color_space out, + u32 place) +{ + u32 reg; + + reg = readl(flow->base + DP_COM_CONF); + reg &= ~DP_COM_CONF_CSC_DEF_MASK; + + if (in == out) { + writel(reg, flow->base + DP_COM_CONF); + return; + } + + if (in == IPUV3_COLORSPACE_RGB && out == IPUV3_COLORSPACE_YUV) { + writel(0x099 | (0x12d << 16), flow->base + DP_CSC_A_0); + writel(0x03a | (0x3a9 << 16), flow->base + DP_CSC_A_1); + writel(0x356 | (0x100 << 16), flow->base + DP_CSC_A_2); + writel(0x100 | (0x329 << 16), flow->base + DP_CSC_A_3); + writel(0x3d6 | (0x0000 << 16) | (2 << 30), + flow->base + DP_CSC_0); + writel(0x200 | (2 << 14) | (0x200 << 16) | (2 << 30), + flow->base + DP_CSC_1); + } else { + writel(0x095 | (0x000 << 16), flow->base + DP_CSC_A_0); + writel(0x0cc | (0x095 << 16), flow->base + DP_CSC_A_1); + writel(0x3ce | (0x398 << 16), flow->base + DP_CSC_A_2); + writel(0x095 | (0x0ff << 16), flow->base + DP_CSC_A_3); + writel(0x000 | (0x3e42 << 16) | (1 << 30), + flow->base + DP_CSC_0); + writel(0x10a | (1 << 14) | (0x3dd6 << 16) | (1 << 30), + flow->base + DP_CSC_1); + } + + reg |= place; + + writel(reg, flow->base + DP_COM_CONF); +} + +int ipu_dp_setup_channel(struct ipu_dp *dp, + enum ipu_color_space in, + enum ipu_color_space out) +{ + struct ipu_flow *flow = to_flow(dp); + struct ipu_dp_priv *priv = flow->priv; + + mutex_lock(&priv->mutex); + + dp->in_cs = in; + + if (!dp->foreground) + flow->out_cs = out; + + if (flow->foreground.in_cs == flow->background.in_cs) { + /* + * foreground and background are of same colorspace, put + * colorspace converter after combining unit. + */ + ipu_dp_csc_init(flow, flow->foreground.in_cs, flow->out_cs, + DP_COM_CONF_CSC_DEF_BOTH); + } else { + if (flow->foreground.in_cs == flow->out_cs) + /* + * foreground identical to output, apply color + * conversion on background + */ + ipu_dp_csc_init(flow, flow->background.in_cs, + flow->out_cs, DP_COM_CONF_CSC_DEF_BG); + else + ipu_dp_csc_init(flow, flow->foreground.in_cs, + flow->out_cs, DP_COM_CONF_CSC_DEF_FG); + } + + ipu_srm_dp_sync_update(priv->ipu); + + mutex_unlock(&priv->mutex); + + return 0; +} +EXPORT_SYMBOL_GPL(ipu_dp_setup_channel); + +int ipu_dp_enable_channel(struct ipu_dp *dp) +{ + struct ipu_flow *flow = to_flow(dp); + struct ipu_dp_priv *priv = flow->priv; + + mutex_lock(&priv->mutex); + + if (!priv->use_count) + ipu_module_enable(priv->ipu, IPU_CONF_DP_EN); + + priv->use_count++; + + if (dp->foreground) { + u32 reg; + + reg = readl(flow->base + DP_COM_CONF); + reg |= DP_COM_CONF_FG_EN; + writel(reg, flow->base + DP_COM_CONF); + + ipu_srm_dp_sync_update(priv->ipu); + } + + mutex_unlock(&priv->mutex); + + return 0; +} +EXPORT_SYMBOL_GPL(ipu_dp_enable_channel); + +void ipu_dp_disable_channel(struct ipu_dp *dp) +{ + struct ipu_flow *flow = to_flow(dp); + struct ipu_dp_priv *priv = flow->priv; + + mutex_lock(&priv->mutex); + + priv->use_count--; + + if (dp->foreground) { + u32 reg, csc; + + reg = readl(flow->base + DP_COM_CONF); + csc = reg & DP_COM_CONF_CSC_DEF_MASK; + if (csc == DP_COM_CONF_CSC_DEF_FG) + reg &= ~DP_COM_CONF_CSC_DEF_MASK; + + reg &= ~DP_COM_CONF_FG_EN; + writel(reg, flow->base + DP_COM_CONF); + + writel(0, flow->base + DP_FG_POS); + ipu_srm_dp_sync_update(priv->ipu); + } + + if (!priv->use_count) + ipu_module_disable(priv->ipu, IPU_CONF_DP_EN); + + if (priv->use_count < 0) + priv->use_count = 0; + + mutex_unlock(&priv->mutex); +} +EXPORT_SYMBOL_GPL(ipu_dp_disable_channel); + +struct ipu_dp *ipu_dp_get(struct ipu_soc *ipu, unsigned int flow) +{ + struct ipu_dp_priv *priv = ipu->dp_priv; + struct ipu_dp *dp; + + if (flow > 5) + return ERR_PTR(-EINVAL); + + if (flow & 1) + dp = &priv->flow[flow >> 1].foreground; + else + dp = &priv->flow[flow >> 1].background; + + if (dp->in_use) + return ERR_PTR(-EBUSY); + + dp->in_use = true; + + return dp; +} +EXPORT_SYMBOL_GPL(ipu_dp_get); + +void ipu_dp_put(struct ipu_dp *dp) +{ + dp->in_use = false; +} +EXPORT_SYMBOL_GPL(ipu_dp_put); + +int ipu_dp_init(struct ipu_soc *ipu, struct device *dev, unsigned long base) +{ + struct ipu_dp_priv *priv; + int i; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + priv->dev = dev; + priv->ipu = ipu; + + ipu->dp_priv = priv; + + priv->base = devm_ioremap(dev, base, PAGE_SIZE); + if (!priv->base) { + kfree(priv); + return -ENOMEM; + } + + mutex_init(&priv->mutex); + + for (i = 0; i < 3; i++) { + priv->flow[i].foreground.foreground = 1; + priv->flow[i].base = priv->base + ipu_dp_flow_base[i]; + priv->flow[i].priv = priv; + } + + return 0; +} + +void ipu_dp_exit(struct ipu_soc *ipu) +{ +} diff --git a/drivers/staging/imx-drm/ipu-v3/ipu-prv.h b/drivers/staging/imx-drm/ipu-v3/ipu-prv.h new file mode 100644 index 0000000..5518028 --- /dev/null +++ b/drivers/staging/imx-drm/ipu-v3/ipu-prv.h @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2010 Sascha Hauer + * Copyright (C) 2005-2009 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ +#ifndef __IPU_PRV_H__ +#define __IPU_PRV_H__ + +struct ipu_soc; + +#include +#include +#include +#include + +#include "imx-ipu-v3.h" + +#define IPUV3_CHANNEL_CSI0 0 +#define IPUV3_CHANNEL_CSI1 1 +#define IPUV3_CHANNEL_CSI2 2 +#define IPUV3_CHANNEL_CSI3 3 +#define IPUV3_CHANNEL_MEM_BG_SYNC 23 +#define IPUV3_CHANNEL_MEM_FG_SYNC 27 +#define IPUV3_CHANNEL_MEM_DC_SYNC 28 +#define IPUV3_CHANNEL_MEM_FG_SYNC_ALPHA 31 +#define IPUV3_CHANNEL_MEM_DC_ASYNC 41 +#define IPUV3_CHANNEL_ROT_ENC_MEM 45 +#define IPUV3_CHANNEL_ROT_VF_MEM 46 +#define IPUV3_CHANNEL_ROT_PP_MEM 47 +#define IPUV3_CHANNEL_ROT_ENC_MEM_OUT 48 +#define IPUV3_CHANNEL_ROT_VF_MEM_OUT 49 +#define IPUV3_CHANNEL_ROT_PP_MEM_OUT 50 +#define IPUV3_CHANNEL_MEM_BG_SYNC_ALPHA 51 + +#define IPU_MCU_T_DEFAULT 8 +#define IPU_CM_IDMAC_REG_OFS 0x00008000 +#define IPU_CM_IC_REG_OFS 0x00020000 +#define IPU_CM_IRT_REG_OFS 0x00028000 +#define IPU_CM_CSI0_REG_OFS 0x00030000 +#define IPU_CM_CSI1_REG_OFS 0x00038000 +#define IPU_CM_SMFC_REG_OFS 0x00050000 +#define IPU_CM_DC_REG_OFS 0x00058000 +#define IPU_CM_DMFC_REG_OFS 0x00060000 + +/* Register addresses */ +/* IPU Common registers */ +#define IPU_CM_REG(offset) (offset) + +#define IPU_CONF IPU_CM_REG(0) + +#define IPU_SRM_PRI1 IPU_CM_REG(0x00a0) +#define IPU_SRM_PRI2 IPU_CM_REG(0x00a4) +#define IPU_FS_PROC_FLOW1 IPU_CM_REG(0x00a8) +#define IPU_FS_PROC_FLOW2 IPU_CM_REG(0x00ac) +#define IPU_FS_PROC_FLOW3 IPU_CM_REG(0x00b0) +#define IPU_FS_DISP_FLOW1 IPU_CM_REG(0x00b4) +#define IPU_FS_DISP_FLOW2 IPU_CM_REG(0x00b8) +#define IPU_SKIP IPU_CM_REG(0x00bc) +#define IPU_DISP_ALT_CONF IPU_CM_REG(0x00c0) +#define IPU_DISP_GEN IPU_CM_REG(0x00c4) +#define IPU_DISP_ALT1 IPU_CM_REG(0x00c8) +#define IPU_DISP_ALT2 IPU_CM_REG(0x00cc) +#define IPU_DISP_ALT3 IPU_CM_REG(0x00d0) +#define IPU_DISP_ALT4 IPU_CM_REG(0x00d4) +#define IPU_SNOOP IPU_CM_REG(0x00d8) +#define IPU_MEM_RST IPU_CM_REG(0x00dc) +#define IPU_PM IPU_CM_REG(0x00e0) +#define IPU_GPR IPU_CM_REG(0x00e4) +#define IPU_CHA_DB_MODE_SEL(ch) IPU_CM_REG(0x0150 + 4 * ((ch) / 32)) +#define IPU_ALT_CHA_DB_MODE_SEL(ch) IPU_CM_REG(0x0168 + 4 * ((ch) / 32)) +#define IPU_CHA_CUR_BUF(ch) IPU_CM_REG(0x023C + 4 * ((ch) / 32)) +#define IPU_ALT_CUR_BUF0 IPU_CM_REG(0x0244) +#define IPU_ALT_CUR_BUF1 IPU_CM_REG(0x0248) +#define IPU_SRM_STAT IPU_CM_REG(0x024C) +#define IPU_PROC_TASK_STAT IPU_CM_REG(0x0250) +#define IPU_DISP_TASK_STAT IPU_CM_REG(0x0254) +#define IPU_CHA_BUF0_RDY(ch) IPU_CM_REG(0x0268 + 4 * ((ch) / 32)) +#define IPU_CHA_BUF1_RDY(ch) IPU_CM_REG(0x0270 + 4 * ((ch) / 32)) +#define IPU_ALT_CHA_BUF0_RDY(ch) IPU_CM_REG(0x0278 + 4 * ((ch) / 32)) +#define IPU_ALT_CHA_BUF1_RDY(ch) IPU_CM_REG(0x0280 + 4 * ((ch) / 32)) + +#define IPU_INT_CTRL(n) IPU_CM_REG(0x003C + 4 * (n)) +#define IPU_INT_STAT(n) IPU_CM_REG(0x0200 + 4 * (n)) + +#define IPU_DI0_COUNTER_RELEASE (1 << 24) +#define IPU_DI1_COUNTER_RELEASE (1 << 25) + +#define IPU_IDMAC_REG(offset) (offset) + +#define IDMAC_CONF IPU_IDMAC_REG(0x0000) +#define IDMAC_CHA_EN(ch) IPU_IDMAC_REG(0x0004 + 4 * ((ch) / 32)) +#define IDMAC_SEP_ALPHA IPU_IDMAC_REG(0x000c) +#define IDMAC_ALT_SEP_ALPHA IPU_IDMAC_REG(0x0010) +#define IDMAC_CHA_PRI(ch) IPU_IDMAC_REG(0x0014 + 4 * ((ch) / 32)) +#define IDMAC_WM_EN(ch) IPU_IDMAC_REG(0x001c + 4 * ((ch) / 32)) +#define IDMAC_CH_LOCK_EN_1 IPU_IDMAC_REG(0x0024) +#define IDMAC_CH_LOCK_EN_2 IPU_IDMAC_REG(0x0028) +#define IDMAC_SUB_ADDR_0 IPU_IDMAC_REG(0x002c) +#define IDMAC_SUB_ADDR_1 IPU_IDMAC_REG(0x0030) +#define IDMAC_SUB_ADDR_2 IPU_IDMAC_REG(0x0034) +#define IDMAC_BAND_EN(ch) IPU_IDMAC_REG(0x0040 + 4 * ((ch) / 32)) +#define IDMAC_CHA_BUSY(ch) IPU_IDMAC_REG(0x0100 + 4 * ((ch) / 32)) + +#define IPU_NUM_IRQS (32 * 5) + +enum ipu_modules { + IPU_CONF_CSI0_EN = (1 << 0), + IPU_CONF_CSI1_EN = (1 << 1), + IPU_CONF_IC_EN = (1 << 2), + IPU_CONF_ROT_EN = (1 << 3), + IPU_CONF_ISP_EN = (1 << 4), + IPU_CONF_DP_EN = (1 << 5), + IPU_CONF_DI0_EN = (1 << 6), + IPU_CONF_DI1_EN = (1 << 7), + IPU_CONF_SMFC_EN = (1 << 8), + IPU_CONF_DC_EN = (1 << 9), + IPU_CONF_DMFC_EN = (1 << 10), + + IPU_CONF_VDI_EN = (1 << 12), + + IPU_CONF_IDMAC_DIS = (1 << 22), + + IPU_CONF_IC_DMFC_SEL = (1 << 25), + IPU_CONF_IC_DMFC_SYNC = (1 << 26), + IPU_CONF_VDI_DMFC_SYNC = (1 << 27), + + IPU_CONF_CSI0_DATA_SOURCE = (1 << 28), + IPU_CONF_CSI1_DATA_SOURCE = (1 << 29), + IPU_CONF_IC_INPUT = (1 << 30), + IPU_CONF_CSI_SEL = (1 << 31), +}; + +struct ipuv3_channel { + unsigned int num; + + bool enabled; + bool busy; + + struct ipu_soc *ipu; +}; + +struct ipu_dc_priv; +struct ipu_dmfc_priv; +struct ipu_di; +struct ipu_devtype; + +struct ipu_soc { + struct device *dev; + const struct ipu_devtype *devtype; + enum ipuv3_type ipu_type; + spinlock_t lock; + struct mutex channel_lock; + + void __iomem *cm_reg; + void __iomem *idmac_reg; + struct ipu_ch_param __iomem *cpmem_base; + + int usecount; + + struct clk *clk; + + struct ipuv3_channel channel[64]; + + int irq_start; + int irq_sync; + int irq_err; + + struct ipu_dc_priv *dc_priv; + struct ipu_dp_priv *dp_priv; + struct ipu_dmfc_priv *dmfc_priv; + struct ipu_di *di_priv[2]; +}; + +void ipu_srm_dp_sync_update(struct ipu_soc *ipu); + +int ipu_module_enable(struct ipu_soc *ipu, u32 mask); +int ipu_module_disable(struct ipu_soc *ipu, u32 mask); + +int ipu_di_init(struct ipu_soc *ipu, struct device *dev, int id, + unsigned long base, u32 module, struct clk *ipu_clk); +void ipu_di_exit(struct ipu_soc *ipu, int id); + +int ipu_dmfc_init(struct ipu_soc *ipu, struct device *dev, unsigned long base, + struct clk *ipu_clk); +void ipu_dmfc_exit(struct ipu_soc *ipu); + +int ipu_dp_init(struct ipu_soc *ipu, struct device *dev, unsigned long base); +void ipu_dp_exit(struct ipu_soc *ipu); + +int ipu_dc_init(struct ipu_soc *ipu, struct device *dev, unsigned long base, + unsigned long template_base); +void ipu_dc_exit(struct ipu_soc *ipu); + +int ipu_cpmem_init(struct ipu_soc *ipu, struct device *dev, unsigned long base); +void ipu_cpmem_exit(struct ipu_soc *ipu); + +#endif /* __IPU_PRV_H__ */ -- cgit v0.10.2 From f326f7995b5e14e12b43a2c2378b93b04568c6ae Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 21 Sep 2012 10:07:50 +0200 Subject: staging: drm/imx: Add i.MX IPUv3 crtc support This adds a i.MX51/53/6 IPU (Image Processing Unit) KMS driver. The driver has been tested on the i.MX51 babbage board, the i.MX53 LOCO board and the i.MX6q sabrelite board in different clone mode and dual head setups. Signed-off-by: Sascha Hauer Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/imx-drm/Kconfig b/drivers/staging/imx-drm/Kconfig index 4849bfa..14b4449 100644 --- a/drivers/staging/imx-drm/Kconfig +++ b/drivers/staging/imx-drm/Kconfig @@ -27,3 +27,9 @@ config DRM_IMX_IPUV3_CORE Choose this if you have a i.MX5/6 system and want to use the IPU. This option only enables IPU base support. + +config DRM_IMX_IPUV3 + tristate "DRM Support for i.MX IPUv3" + depends on DRM_IMX + help + Choose this if you have a i.MX5 or i.MX6 processor. diff --git a/drivers/staging/imx-drm/Makefile b/drivers/staging/imx-drm/Makefile index e3a5b6f..83a9056 100644 --- a/drivers/staging/imx-drm/Makefile +++ b/drivers/staging/imx-drm/Makefile @@ -6,3 +6,4 @@ obj-$(CONFIG_DRM_IMX) += imxdrm.o obj-$(CONFIG_DRM_IMX_PARALLEL_DISPLAY) += parallel-display.o obj-$(CONFIG_DRM_IMX_FB_HELPER) += imx-fbdev.o obj-$(CONFIG_DRM_IMX_IPUV3_CORE) += ipu-v3/ +obj-$(CONFIG_DRM_IMX_IPUV3) += ipuv3-crtc.o diff --git a/drivers/staging/imx-drm/ipuv3-crtc.c b/drivers/staging/imx-drm/ipuv3-crtc.c new file mode 100644 index 0000000..78d3eda --- /dev/null +++ b/drivers/staging/imx-drm/ipuv3-crtc.c @@ -0,0 +1,579 @@ +/* + * i.MX IPUv3 Graphics driver + * + * Copyright (C) 2011 Sascha Hauer, Pengutronix + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ipu-v3/imx-ipu-v3.h" +#include "imx-drm.h" + +#define DRIVER_DESC "i.MX IPUv3 Graphics" + +struct ipu_framebuffer { + struct drm_framebuffer base; + void *virt; + dma_addr_t phys; + size_t len; +}; + +struct ipu_crtc { + struct drm_fb_helper fb_helper; + struct ipu_framebuffer ifb; + int num_crtcs; + struct device *dev; + struct drm_crtc base; + struct imx_drm_crtc *imx_crtc; + struct ipuv3_channel *ipu_ch; + struct ipu_dc *dc; + struct ipu_dp *dp; + struct dmfc_channel *dmfc; + struct ipu_di *di; + int enabled; + struct ipu_priv *ipu_priv; + struct drm_pending_vblank_event *page_flip_event; + struct drm_framebuffer *newfb; + int irq; + u32 interface_pix_fmt; + unsigned long di_clkflags; +}; + +#define to_ipu_crtc(x) container_of(x, struct ipu_crtc, base) + +static int calc_vref(struct drm_display_mode *mode) +{ + unsigned long htotal, vtotal; + + htotal = mode->htotal; + vtotal = mode->vtotal; + + if (!htotal || !vtotal) + return 60; + + return mode->clock * 1000 / vtotal / htotal; +} + +static int calc_bandwidth(struct drm_display_mode *mode, unsigned int vref) +{ + return mode->hdisplay * mode->vdisplay * vref; +} + +static void ipu_fb_enable(struct ipu_crtc *ipu_crtc) +{ + if (ipu_crtc->enabled) + return; + + ipu_di_enable(ipu_crtc->di); + ipu_dmfc_enable_channel(ipu_crtc->dmfc); + ipu_idmac_enable_channel(ipu_crtc->ipu_ch); + ipu_dc_enable_channel(ipu_crtc->dc); + if (ipu_crtc->dp) + ipu_dp_enable_channel(ipu_crtc->dp); + + ipu_crtc->enabled = 1; +} + +static void ipu_fb_disable(struct ipu_crtc *ipu_crtc) +{ + if (!ipu_crtc->enabled) + return; + + if (ipu_crtc->dp) + ipu_dp_disable_channel(ipu_crtc->dp); + ipu_dc_disable_channel(ipu_crtc->dc); + ipu_idmac_disable_channel(ipu_crtc->ipu_ch); + ipu_dmfc_disable_channel(ipu_crtc->dmfc); + ipu_di_disable(ipu_crtc->di); + + ipu_crtc->enabled = 0; +} + +static void ipu_crtc_dpms(struct drm_crtc *crtc, int mode) +{ + struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); + + dev_info(ipu_crtc->dev, "%s mode: %d\n", __func__, mode); + + switch (mode) { + case DRM_MODE_DPMS_ON: + ipu_fb_enable(ipu_crtc); + break; + case DRM_MODE_DPMS_STANDBY: + case DRM_MODE_DPMS_SUSPEND: + case DRM_MODE_DPMS_OFF: + ipu_fb_disable(ipu_crtc); + break; + } +} + +static int ipu_page_flip(struct drm_crtc *crtc, + struct drm_framebuffer *fb, + struct drm_pending_vblank_event *event) +{ + struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); + int ret; + + if (ipu_crtc->newfb) + return -EBUSY; + + ret = imx_drm_crtc_vblank_get(ipu_crtc->imx_crtc); + if (ret) { + dev_dbg(ipu_crtc->dev, "failed to acquire vblank counter\n"); + list_del(&event->base.link); + + return ret; + } + + ipu_crtc->newfb = fb; + ipu_crtc->page_flip_event = event; + + return 0; +} + +static const struct drm_crtc_funcs ipu_crtc_funcs = { + .set_config = drm_crtc_helper_set_config, + .destroy = drm_crtc_cleanup, + .page_flip = ipu_page_flip, +}; + +static int ipu_drm_set_base(struct drm_crtc *crtc, int x, int y) +{ + struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); + struct drm_gem_cma_object *cma_obj; + struct drm_framebuffer *fb = crtc->fb; + unsigned long phys; + + cma_obj = drm_fb_cma_get_gem_obj(fb, 0); + if (!cma_obj) { + DRM_LOG_KMS("entry is null.\n"); + return -EFAULT; + } + + phys = cma_obj->paddr; + phys += x * (fb->bits_per_pixel >> 3); + phys += y * fb->pitches[0]; + + dev_dbg(ipu_crtc->dev, "%s: phys: 0x%lx\n", __func__, phys); + dev_dbg(ipu_crtc->dev, "%s: xy: %dx%d\n", __func__, x, y); + + ipu_cpmem_set_stride(ipu_get_cpmem(ipu_crtc->ipu_ch), fb->pitches[0]); + ipu_cpmem_set_buffer(ipu_get_cpmem(ipu_crtc->ipu_ch), + 0, phys); + + return 0; +} + +static int ipu_crtc_mode_set(struct drm_crtc *crtc, + struct drm_display_mode *orig_mode, + struct drm_display_mode *mode, + int x, int y, + struct drm_framebuffer *old_fb) +{ + struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); + struct drm_framebuffer *fb = ipu_crtc->base.fb; + int ret; + struct ipu_di_signal_cfg sig_cfg = {}; + u32 out_pixel_fmt; + struct ipu_ch_param __iomem *cpmem = ipu_get_cpmem(ipu_crtc->ipu_ch); + int bpp; + u32 v4l2_fmt; + + dev_dbg(ipu_crtc->dev, "%s: mode->hdisplay: %d\n", __func__, + mode->hdisplay); + dev_dbg(ipu_crtc->dev, "%s: mode->vdisplay: %d\n", __func__, + mode->vdisplay); + + ipu_ch_param_zero(cpmem); + + switch (fb->pixel_format) { + case DRM_FORMAT_XRGB8888: + case DRM_FORMAT_ARGB8888: + v4l2_fmt = V4L2_PIX_FMT_RGB32; + bpp = 32; + break; + case DRM_FORMAT_RGB565: + v4l2_fmt = V4L2_PIX_FMT_RGB565; + bpp = 16; + break; + case DRM_FORMAT_RGB888: + v4l2_fmt = V4L2_PIX_FMT_RGB24; + bpp = 24; + break; + default: + dev_err(ipu_crtc->dev, "unsupported pixel format 0x%08x\n", + fb->pixel_format); + return -EINVAL; + } + + out_pixel_fmt = ipu_crtc->interface_pix_fmt; + + if (mode->flags & DRM_MODE_FLAG_INTERLACE) + sig_cfg.interlaced = 1; + if (mode->flags & DRM_MODE_FLAG_PHSYNC) + sig_cfg.Hsync_pol = 1; + if (mode->flags & DRM_MODE_FLAG_PVSYNC) + sig_cfg.Vsync_pol = 1; + + sig_cfg.enable_pol = 1; + sig_cfg.clk_pol = 0; + sig_cfg.width = mode->hdisplay; + sig_cfg.height = mode->vdisplay; + sig_cfg.pixel_fmt = out_pixel_fmt; + sig_cfg.h_start_width = mode->htotal - mode->hsync_end; + sig_cfg.h_sync_width = mode->hsync_end - mode->hsync_start; + sig_cfg.h_end_width = mode->hsync_start - mode->hdisplay; + + sig_cfg.v_start_width = mode->vtotal - mode->vsync_end; + sig_cfg.v_sync_width = mode->vsync_end - mode->vsync_start; + sig_cfg.v_end_width = mode->vsync_start - mode->vdisplay; + sig_cfg.pixelclock = mode->clock * 1000; + sig_cfg.clkflags = ipu_crtc->di_clkflags; + + sig_cfg.v_to_h_sync = 0; + + if (ipu_crtc->dp) { + ret = ipu_dp_setup_channel(ipu_crtc->dp, IPUV3_COLORSPACE_RGB, + IPUV3_COLORSPACE_RGB); + if (ret) { + dev_err(ipu_crtc->dev, + "initializing display processor failed with %d\n", + ret); + return ret; + } + ipu_dp_set_global_alpha(ipu_crtc->dp, 1, 0, 1); + } + + ret = ipu_dc_init_sync(ipu_crtc->dc, ipu_crtc->di, sig_cfg.interlaced, + out_pixel_fmt, mode->hdisplay); + if (ret) { + dev_err(ipu_crtc->dev, + "initializing display controller failed with %d\n", + ret); + return ret; + } + + ret = ipu_di_init_sync_panel(ipu_crtc->di, &sig_cfg); + if (ret) { + dev_err(ipu_crtc->dev, + "initializing panel failed with %d\n", ret); + return ret; + } + + ipu_cpmem_set_resolution(cpmem, mode->hdisplay, mode->vdisplay); + ipu_cpmem_set_fmt(cpmem, v4l2_fmt); + ipu_cpmem_set_high_priority(ipu_crtc->ipu_ch); + + ret = ipu_dmfc_init_channel(ipu_crtc->dmfc, mode->hdisplay); + if (ret) { + dev_err(ipu_crtc->dev, + "initializing dmfc channel failed with %d\n", + ret); + return ret; + } + + ret = ipu_dmfc_alloc_bandwidth(ipu_crtc->dmfc, + calc_bandwidth(mode, calc_vref(mode)), 64); + if (ret) { + dev_err(ipu_crtc->dev, + "allocating dmfc bandwidth failed with %d\n", + ret); + return ret; + } + + ipu_drm_set_base(crtc, x, y); + + return 0; +} + +static void ipu_crtc_handle_pageflip(struct ipu_crtc *ipu_crtc) +{ + struct drm_pending_vblank_event *e; + struct timeval now; + unsigned long flags; + struct drm_device *drm = ipu_crtc->base.dev; + + spin_lock_irqsave(&drm->event_lock, flags); + + e = ipu_crtc->page_flip_event; + if (!e) { + spin_unlock_irqrestore(&drm->event_lock, flags); + return; + } + + do_gettimeofday(&now); + e->event.sequence = 0; + e->event.tv_sec = now.tv_sec; + e->event.tv_usec = now.tv_usec; + ipu_crtc->page_flip_event = NULL; + + imx_drm_crtc_vblank_put(ipu_crtc->imx_crtc); + + list_add_tail(&e->base.link, &e->base.file_priv->event_list); + + wake_up_interruptible(&e->base.file_priv->event_wait); + + spin_unlock_irqrestore(&drm->event_lock, flags); +} + +static irqreturn_t ipu_irq_handler(int irq, void *dev_id) +{ + struct ipu_crtc *ipu_crtc = dev_id; + + imx_drm_handle_vblank(ipu_crtc->imx_crtc); + + if (ipu_crtc->newfb) { + ipu_crtc->base.fb = ipu_crtc->newfb; + ipu_crtc->newfb = NULL; + ipu_drm_set_base(&ipu_crtc->base, 0, 0); + ipu_crtc_handle_pageflip(ipu_crtc); + } + + return IRQ_HANDLED; +} + +static bool ipu_crtc_mode_fixup(struct drm_crtc *crtc, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + return true; +} + +static void ipu_crtc_prepare(struct drm_crtc *crtc) +{ + struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); + + ipu_fb_disable(ipu_crtc); +} + +static void ipu_crtc_commit(struct drm_crtc *crtc) +{ + struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); + + ipu_fb_enable(ipu_crtc); +} + +static void ipu_crtc_load_lut(struct drm_crtc *crtc) +{ +} + +static struct drm_crtc_helper_funcs ipu_helper_funcs = { + .dpms = ipu_crtc_dpms, + .mode_fixup = ipu_crtc_mode_fixup, + .mode_set = ipu_crtc_mode_set, + .prepare = ipu_crtc_prepare, + .commit = ipu_crtc_commit, + .load_lut = ipu_crtc_load_lut, +}; + +static int ipu_enable_vblank(struct drm_crtc *crtc) +{ + struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); + + enable_irq(ipu_crtc->irq); + + return 0; +} + +static void ipu_disable_vblank(struct drm_crtc *crtc) +{ + struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); + + disable_irq(ipu_crtc->irq); +} + +static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc, u32 encoder_type, + u32 pixfmt) +{ + struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); + + ipu_crtc->interface_pix_fmt = pixfmt; + + switch (encoder_type) { + case DRM_MODE_ENCODER_LVDS: + ipu_crtc->di_clkflags = IPU_DI_CLKMODE_SYNC | + IPU_DI_CLKMODE_EXT; + break; + case DRM_MODE_ENCODER_NONE: + ipu_crtc->di_clkflags = 0; + break; + } + + return 0; +} + +static const struct imx_drm_crtc_helper_funcs ipu_crtc_helper_funcs = { + .enable_vblank = ipu_enable_vblank, + .disable_vblank = ipu_disable_vblank, + .set_interface_pix_fmt = ipu_set_interface_pix_fmt, + .crtc_funcs = &ipu_crtc_funcs, + .crtc_helper_funcs = &ipu_helper_funcs, +}; + +static void ipu_put_resources(struct ipu_crtc *ipu_crtc) +{ + if (!IS_ERR_OR_NULL(ipu_crtc->ipu_ch)) + ipu_idmac_put(ipu_crtc->ipu_ch); + if (!IS_ERR_OR_NULL(ipu_crtc->dmfc)) + ipu_dmfc_put(ipu_crtc->dmfc); + if (!IS_ERR_OR_NULL(ipu_crtc->dp)) + ipu_dp_put(ipu_crtc->dp); + if (!IS_ERR_OR_NULL(ipu_crtc->di)) + ipu_di_put(ipu_crtc->di); +} + +static int ipu_get_resources(struct ipu_crtc *ipu_crtc, + struct ipu_client_platformdata *pdata) +{ + struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent); + int ret; + + ipu_crtc->ipu_ch = ipu_idmac_get(ipu, pdata->dma[0]); + if (IS_ERR_OR_NULL(ipu_crtc->ipu_ch)) { + ret = PTR_ERR(ipu_crtc->ipu_ch); + goto err_out; + } + + ipu_crtc->dc = ipu_dc_get(ipu, pdata->dc); + if (IS_ERR(ipu_crtc->dc)) { + ret = PTR_ERR(ipu_crtc->dc); + goto err_out; + } + + ipu_crtc->dmfc = ipu_dmfc_get(ipu, pdata->dma[0]); + if (IS_ERR(ipu_crtc->dmfc)) { + ret = PTR_ERR(ipu_crtc->dmfc); + goto err_out; + } + + if (pdata->dp >= 0) { + ipu_crtc->dp = ipu_dp_get(ipu, pdata->dp); + if (IS_ERR(ipu_crtc->dp)) { + ret = PTR_ERR(ipu_crtc->ipu_ch); + goto err_out; + } + } + + ipu_crtc->di = ipu_di_get(ipu, pdata->di); + if (IS_ERR(ipu_crtc->di)) { + ret = PTR_ERR(ipu_crtc->di); + goto err_out; + } + + ipu_crtc->irq = ipu_idmac_channel_irq(ipu, ipu_crtc->ipu_ch, + IPU_IRQ_EOF); + ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler, 0, + "imx_drm", ipu_crtc); + if (ret < 0) { + dev_err(ipu_crtc->dev, "irq request failed with %d.\n", ret); + goto err_out; + } + + disable_irq(ipu_crtc->irq); + + return 0; +err_out: + ipu_put_resources(ipu_crtc); + + return ret; +} + +static int ipu_crtc_init(struct ipu_crtc *ipu_crtc, + struct ipu_client_platformdata *pdata) +{ + int ret; + + ret = ipu_get_resources(ipu_crtc, pdata); + if (ret) { + dev_err(ipu_crtc->dev, "getting resources failed with %d.\n", + ret); + return ret; + } + + ret = imx_drm_add_crtc(&ipu_crtc->base, + &ipu_crtc->imx_crtc, + &ipu_crtc_helper_funcs, THIS_MODULE, + ipu_crtc->dev->parent->of_node, pdata->di); + if (ret) { + dev_err(ipu_crtc->dev, "adding crtc failed with %d.\n", ret); + goto err_put_resources; + } + + return 0; + +err_put_resources: + ipu_put_resources(ipu_crtc); + + return ret; +} + +static int __devinit ipu_drm_probe(struct platform_device *pdev) +{ + struct ipu_client_platformdata *pdata = pdev->dev.platform_data; + struct ipu_crtc *ipu_crtc; + int ret; + + if (!pdata) + return -EINVAL; + + pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); + + ipu_crtc = devm_kzalloc(&pdev->dev, sizeof(*ipu_crtc), GFP_KERNEL); + if (!ipu_crtc) + return -ENOMEM; + + ipu_crtc->dev = &pdev->dev; + + ret = ipu_crtc_init(ipu_crtc, pdata); + + platform_set_drvdata(pdev, ipu_crtc); + + return 0; +} + +static int __devexit ipu_drm_remove(struct platform_device *pdev) +{ + struct ipu_crtc *ipu_crtc = platform_get_drvdata(pdev); + + imx_drm_remove_crtc(ipu_crtc->imx_crtc); + + ipu_put_resources(ipu_crtc); + + return 0; +} + +static struct platform_driver ipu_drm_driver = { + .driver = { + .name = "imx-ipuv3-crtc", + }, + .probe = ipu_drm_probe, + .remove = __devexit_p(ipu_drm_remove), +}; +module_platform_driver(ipu_drm_driver); + +MODULE_AUTHOR("Sascha Hauer "); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 2d62da8ebd323ee65e4fb952e73dcb10d8114bda Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Fri, 21 Sep 2012 10:07:51 +0200 Subject: staging: drm/imx: Add devicetree binding documentation Signed-off-by: Philipp Zabel Signed-off-by: Sascha Hauer Signed-off-by: Greg Kroah-Hartman diff --git a/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt b/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt new file mode 100644 index 0000000..07654f0 --- /dev/null +++ b/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt @@ -0,0 +1,41 @@ +Freescale i.MX IPUv3 +==================== + +Required properties: +- compatible: Should be "fsl,-ipu" +- reg: should be register base and length as documented in the + datasheet +- interrupts: Should contain sync interrupt and error interrupt, + in this order. +- #crtc-cells: 1, See below + +example: + +ipu: ipu@18000000 { + #crtc-cells = <1>; + compatible = "fsl,imx53-ipu"; + reg = <0x18000000 0x080000000>; + interrupts = <11 10>; +}; + +Parallel display support +======================== + +Required properties: +- compatible: Should be "fsl,imx-parallel-display" +- crtc: the crtc this display is connected to, see below +Optional properties: +- interface_pix_fmt: How this display is connected to the + crtc. Currently supported types: "rgb24", "rgb565" +- edid: verbatim EDID data block describing attached display. +- ddc: phandle describing the i2c bus handling the display data + channel + +example: + +display@di0 { + compatible = "fsl,imx-parallel-display"; + edid = [edid-data]; + crtc = <&ipu 0>; + interface-pix-fmt = "rgb24"; +}; -- cgit v0.10.2 From effef787a9e7c95b58a70951ec934a4474fa73bf Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 21 Sep 2012 10:07:52 +0200 Subject: staging: drm/imx: Add TODO Signed-off-by: Sascha Hauer Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/imx-drm/TODO b/drivers/staging/imx-drm/TODO new file mode 100644 index 0000000..e52adc4 --- /dev/null +++ b/drivers/staging/imx-drm/TODO @@ -0,0 +1,22 @@ +TODO: +- get DRM Maintainer review for this code +- Factor out more code to common helper functions +- decide where to put the base driver. It is not specific to a subsystem + and would be used by DRM/KMS and media/V4L2 +- convert irq driver to irq_domain_add_linear + +Missing features (not necessarily for moving out of staging): + +- Add KMS plane support for CRTC driver +- Add LDB (LVDS Display Bridge) support +- Add i.MX6 HDMI support +- Add support for IC (Image converter) +- Add support for CSI (CMOS Sensor interface) +- Add support for VDIC (Video Deinterlacer) + +Many work-in-progress patches for the above features exist. Contact +Sascha Hauer if you are interested in working +on a specific feature. + +Please send any patches to Greg Kroah-Hartman and +Sascha Hauer -- cgit v0.10.2 From b2abd982c484ba0e46ea681b0bc6d7baf7c47730 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 19 Sep 2012 15:08:35 -0700 Subject: staging: comedi: s526: don't dereference insn->data pointer The comedi_insn 'data' pointer is a __user pointer that is passed into the kernel using an ioctl. The comedi core copies this data to kernel space in do_insnlist_ioctl() and then passes that kernel data to the drivers as a separate parameter. The drivers never need to access the data through the insn->data pointer. This fixes a number of sparse warnings about: warning: dereference of noderef expression Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c index c89bd6c..43f5c7d 100644 --- a/drivers/staging/comedi/drivers/s526.c +++ b/drivers/staging/comedi/drivers/s526.c @@ -256,14 +256,13 @@ static int s526_gpct_insn_config(struct comedi_device *dev, subdev_channel); */ for (i = 0; i < MAX_GPCT_CONFIG_DATA; i++) { - devpriv->s526_gpct_config[subdev_channel].data[i] = - insn->data[i]; -/* printk("data[%d]=%x\n", i, insn->data[i]); */ + devpriv->s526_gpct_config[subdev_channel].data[i] = data[i]; +/* printk("data[%d]=%x\n", i, data[i]); */ } /* Check what type of Counter the user requested, data[0] contains */ /* the Application type */ - switch (insn->data[0]) { + switch (data[0]) { case INSN_CONFIG_GPCT_QUADRATURE_ENCODER: /* data[0]: Application Type @@ -307,7 +306,7 @@ static int s526_gpct_insn_config(struct comedi_device *dev, #if 1 /* Set Counter Mode Register */ - cmReg.value = insn->data[1] & 0xFFFF; + cmReg.value = data[1] & 0xFFFF; /* printk("s526: Counter Mode register=%x\n", cmReg.value); */ outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel)); @@ -325,39 +324,39 @@ static int s526_gpct_insn_config(struct comedi_device *dev, cmReg.reg.countDirCtrl = 0; /* data[1] contains GPCT_X1, GPCT_X2 or GPCT_X4 */ - if (insn->data[1] == GPCT_X2) + if (data[1] == GPCT_X2) cmReg.reg.clockSource = 1; - else if (insn->data[1] == GPCT_X4) + else if (data[1] == GPCT_X4) cmReg.reg.clockSource = 2; else cmReg.reg.clockSource = 0; /* When to take into account the indexpulse: */ - /*if (insn->data[2] == GPCT_IndexPhaseLowLow) { - } else if (insn->data[2] == GPCT_IndexPhaseLowHigh) { - } else if (insn->data[2] == GPCT_IndexPhaseHighLow) { - } else if (insn->data[2] == GPCT_IndexPhaseHighHigh) { + /*if (data[2] == GPCT_IndexPhaseLowLow) { + } else if (data[2] == GPCT_IndexPhaseLowHigh) { + } else if (data[2] == GPCT_IndexPhaseHighLow) { + } else if (data[2] == GPCT_IndexPhaseHighHigh) { }*/ /* Take into account the index pulse? */ - if (insn->data[3] == GPCT_RESET_COUNTER_ON_INDEX) + if (data[3] == GPCT_RESET_COUNTER_ON_INDEX) /* Auto load with INDEX^ */ cmReg.reg.autoLoadResetRcap = 4; /* Set Counter Mode Register */ - cmReg.value = (short)(insn->data[1] & 0xFFFF); + cmReg.value = (short)(data[1] & 0xFFFF); outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel)); /* Load the pre-load register high word */ - value = (short)((insn->data[2] >> 16) & 0xFFFF); + value = (short)((data[2] >> 16) & 0xFFFF); outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel)); /* Load the pre-load register low word */ - value = (short)(insn->data[2] & 0xFFFF); + value = (short)(data[2] & 0xFFFF); outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel)); /* Write the Counter Control Register */ - if (insn->data[3] != 0) { - value = (short)(insn->data[3] & 0xFFFF); + if (data[3] != 0) { + value = (short)(data[3] & 0xFFFF); outw(value, ADDR_CHAN_REG(REG_C0C, subdev_channel)); } /* Reset the counter if it is software preload */ @@ -383,34 +382,34 @@ static int s526_gpct_insn_config(struct comedi_device *dev, SinglePulseGeneration; /* Set Counter Mode Register */ - cmReg.value = (short)(insn->data[1] & 0xFFFF); + cmReg.value = (short)(data[1] & 0xFFFF); cmReg.reg.preloadRegSel = 0; /* PR0 */ outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel)); /* Load the pre-load register 0 high word */ - value = (short)((insn->data[2] >> 16) & 0xFFFF); + value = (short)((data[2] >> 16) & 0xFFFF); outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel)); /* Load the pre-load register 0 low word */ - value = (short)(insn->data[2] & 0xFFFF); + value = (short)(data[2] & 0xFFFF); outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel)); /* Set Counter Mode Register */ - cmReg.value = (short)(insn->data[1] & 0xFFFF); + cmReg.value = (short)(data[1] & 0xFFFF); cmReg.reg.preloadRegSel = 1; /* PR1 */ outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel)); /* Load the pre-load register 1 high word */ - value = (short)((insn->data[3] >> 16) & 0xFFFF); + value = (short)((data[3] >> 16) & 0xFFFF); outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel)); /* Load the pre-load register 1 low word */ - value = (short)(insn->data[3] & 0xFFFF); + value = (short)(data[3] & 0xFFFF); outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel)); /* Write the Counter Control Register */ - if (insn->data[4] != 0) { - value = (short)(insn->data[4] & 0xFFFF); + if (data[4] != 0) { + value = (short)(data[4] & 0xFFFF); outw(value, ADDR_CHAN_REG(REG_C0C, subdev_channel)); } break; @@ -428,34 +427,34 @@ static int s526_gpct_insn_config(struct comedi_device *dev, PulseTrainGeneration; /* Set Counter Mode Register */ - cmReg.value = (short)(insn->data[1] & 0xFFFF); + cmReg.value = (short)(data[1] & 0xFFFF); cmReg.reg.preloadRegSel = 0; /* PR0 */ outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel)); /* Load the pre-load register 0 high word */ - value = (short)((insn->data[2] >> 16) & 0xFFFF); + value = (short)((data[2] >> 16) & 0xFFFF); outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel)); /* Load the pre-load register 0 low word */ - value = (short)(insn->data[2] & 0xFFFF); + value = (short)(data[2] & 0xFFFF); outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel)); /* Set Counter Mode Register */ - cmReg.value = (short)(insn->data[1] & 0xFFFF); + cmReg.value = (short)(data[1] & 0xFFFF); cmReg.reg.preloadRegSel = 1; /* PR1 */ outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel)); /* Load the pre-load register 1 high word */ - value = (short)((insn->data[3] >> 16) & 0xFFFF); + value = (short)((data[3] >> 16) & 0xFFFF); outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel)); /* Load the pre-load register 1 low word */ - value = (short)(insn->data[3] & 0xFFFF); + value = (short)(data[3] & 0xFFFF); outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel)); /* Write the Counter Control Register */ - if (insn->data[4] != 0) { - value = (short)(insn->data[4] & 0xFFFF); + if (data[4] != 0) { + value = (short)(data[4] & 0xFFFF); outw(value, ADDR_CHAN_REG(REG_C0C, subdev_channel)); } break; @@ -505,14 +504,14 @@ static int s526_gpct_winsn(struct comedi_device *dev, pulse frequency on the selected source */ printk(KERN_INFO "S526: INSN_WRITE: PTG\n"); - if ((insn->data[1] > insn->data[0]) && (insn->data[0] > 0)) { + if ((data[1] > data[0]) && (data[0] > 0)) { (devpriv->s526_gpct_config[subdev_channel]).data[0] = - insn->data[0]; + data[0]; (devpriv->s526_gpct_config[subdev_channel]).data[1] = - insn->data[1]; + data[1]; } else { printk(KERN_ERR "s526: INSN_WRITE: PTG: Problem with Pulse params -> %d %d\n", - insn->data[0], insn->data[1]); + data[0], data[1]); return -EINVAL; } -- cgit v0.10.2 From 5f2210627f8d3c5f7842b4c20d65d9f81690be49 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 19 Sep 2012 15:08:52 -0700 Subject: staging: comedi: s526: remove devpriv macro This macro relies on a local variable having a specific name. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c index 43f5c7d..c89f352 100644 --- a/drivers/staging/comedi/drivers/s526.c +++ b/drivers/staging/comedi/drivers/s526.c @@ -211,12 +211,6 @@ struct s526_private { unsigned short s526_ai_config; }; -/* - * most drivers define the following macro to make it easy to - * access the private structure. - */ -#define devpriv ((struct s526_private *)dev->private) - static int s526_gpct_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -247,6 +241,7 @@ static int s526_gpct_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct s526_private *devpriv = dev->private; int subdev_channel = CR_CHAN(insn->chanspec); /* Unpack chanspec */ int i; short value; @@ -472,6 +467,7 @@ static int s526_gpct_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct s526_private *devpriv = dev->private; int subdev_channel = CR_CHAN(insn->chanspec); /* Unpack chanspec */ short value; union cmReg cmReg; @@ -536,6 +532,7 @@ static int s526_ai_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct s526_private *devpriv = dev->private; int result = -EINVAL; if (insn->n < 1) @@ -569,6 +566,7 @@ static int s526_ai_insn_config(struct comedi_device *dev, static int s526_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct s526_private *devpriv = dev->private; int n, i; int chan = CR_CHAN(insn->chanspec); unsigned short value; @@ -619,6 +617,7 @@ static int s526_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, static int s526_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct s526_private *devpriv = dev->private; int i; int chan = CR_CHAN(insn->chanspec); unsigned short val; @@ -651,6 +650,7 @@ static int s526_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, static int s526_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct s526_private *devpriv = dev->private; int i; int chan = CR_CHAN(insn->chanspec); @@ -728,6 +728,7 @@ static int s526_dio_insn_config(struct comedi_device *dev, static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct s526_board *board = comedi_board(dev); + struct s526_private *devpriv; struct comedi_subdevice *s; int iobase; int i, n; @@ -756,12 +757,10 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = board->name; -/* - * Allocate the private structure area. alloc_private() is a - * convenient macro defined in comedidev.h. - */ - if (alloc_private(dev, sizeof(struct s526_private)) < 0) - return -ENOMEM; + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; + devpriv = dev->private; ret = comedi_alloc_subdevices(dev, 4); if (ret) -- cgit v0.10.2 From 0171e6f5bb193008361bf9668c26d8cffc41e70a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 19 Sep 2012 15:09:07 -0700 Subject: staging: comedi: s526: remove ADDR_REG macro This macro relies on a local variable having a specific name. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c index c89f352..888875e 100644 --- a/drivers/staging/comedi/drivers/s526.c +++ b/drivers/staging/comedi/drivers/s526.c @@ -197,7 +197,6 @@ static const struct s526_board s526_boards[] = { } }; -#define ADDR_REG(reg) (dev->iobase + (reg)) #define ADDR_CHAN_REG(reg, chan) (dev->iobase + (reg) + (chan) * 8) /* this structure is for data unique to this hardware driver. If @@ -548,8 +547,8 @@ static int s526_ai_insn_config(struct comedi_device *dev, * INSN_READ handler. */ /* Enable ADC interrupt */ - outw(ISR_ADC_DONE, ADDR_REG(REG_IER)); -/* printk("s526: ADC current value: 0x%04x\n", inw(ADDR_REG(REG_ADC))); */ + outw(ISR_ADC_DONE, dev->iobase + REG_IER); +/* printk("s526: ADC current value: 0x%04x\n", inw(dev->iobase + REG_ADC)); */ devpriv->s526_ai_config = (data[0] & 0x3FF) << 5; if (data[1] > 0) devpriv->s526_ai_config |= 0x8000; /* set the delay */ @@ -581,16 +580,16 @@ static int s526_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, /* convert n samples */ for (n = 0; n < insn->n; n++) { /* trigger conversion */ - outw(value, ADDR_REG(REG_ADC)); + outw(value, dev->iobase + REG_ADC); /* printk("s526: Wrote 0x%04x to ADC\n", value); */ -/* printk("s526: ADC reg=0x%04x\n", inw(ADDR_REG(REG_ADC))); */ +/* printk("s526: ADC reg=0x%04x\n", inw(dev->iobase + REG_ADC)); */ #define TIMEOUT 100 /* wait for conversion to end */ for (i = 0; i < TIMEOUT; i++) { - status = inw(ADDR_REG(REG_ISR)); + status = inw(dev->iobase + REG_ISR); if (status & ISR_ADC_DONE) { - outw(ISR_ADC_DONE, ADDR_REG(REG_ISR)); + outw(ISR_ADC_DONE, dev->iobase + REG_ISR); break; } } @@ -598,12 +597,12 @@ static int s526_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, /* printk() should be used instead of printk() * whenever the code can be called from real-time. */ printk(KERN_ERR "s526: ADC(0x%04x) timeout\n", - inw(ADDR_REG(REG_ISR))); + inw(dev->iobase + REG_ISR)); return -ETIMEDOUT; } /* read data */ - d = inw(ADDR_REG(REG_ADD)); + d = inw(dev->iobase + REG_ADD); /* printk("AI[%d]=0x%04x\n", n, (unsigned short)(d & 0xFFFF)); */ /* munge data */ @@ -625,7 +624,7 @@ static int s526_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, /* printk("s526_ao_winsn\n"); */ val = chan << 1; /* outw(val, dev->iobase + REG_DAC); */ - outw(val, ADDR_REG(REG_DAC)); + outw(val, dev->iobase + REG_DAC); /* Writing a list of values to an AO channel is probably not * very useful, but that's how the interface is defined. */ @@ -635,10 +634,11 @@ static int s526_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, * outw(data[i], dev->iobase + REG_ADD); */ /* write the data to preload register */ - outw(data[i], ADDR_REG(REG_ADD)); + outw(data[i], dev->iobase + REG_ADD); devpriv->ao_readback[chan] = data[i]; /* outw(val + 1, dev->iobase + REG_DAC); starts the D/A conversion. */ - outw(val + 1, ADDR_REG(REG_DAC)); /*starts the D/A conversion.*/ + /* starts the D/A conversion */ + outw(val + 1, dev->iobase + REG_DAC); } /* return the number of samples read/written */ @@ -675,12 +675,12 @@ static int s526_dio_insn_bits(struct comedi_device *dev, s->state &= ~data[0]; s->state |= data[0] & data[1]; /* Write out the new digital output lines */ - outw(s->state, ADDR_REG(REG_DIO)); + outw(s->state, dev->iobase + REG_DIO); } /* on return, data[1] contains the value of the digital * input and output lines. */ - data[1] = inw(ADDR_REG(REG_DIO)) & 0xFF; /* low 8 bits are the data */ + data[1] = inw(dev->iobase + REG_DIO) & 0xff; /* or we could just return the software copy of the output values if * it was a purely digital output subdevice */ /* data[1]=s->state & 0xFF; */ @@ -720,7 +720,7 @@ static int s526_dio_insn_config(struct comedi_device *dev, default: return -EINVAL; } - outw(s->state, ADDR_REG(REG_DIO)); + outw(s->state, dev->iobase + REG_DIO); return 1; } @@ -750,8 +750,8 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) /*** make it a little quieter, exw, 8/29/06 for (i = 0; i < S526_NUM_PORTS; i++) { - printk("0x%02x: 0x%04x\n", ADDR_REG(s526_ports[i]), - inw(ADDR_REG(s526_ports[i]))); + printk("0x%02x: 0x%04x\n", dev->iobase + s526_ports[i], + inw(dev->iobase + s526_ports[i])); } ***/ @@ -907,7 +907,8 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) for (i = 0; i < S526_NUM_PORTS; i++) { printk(KERN_INFO "0x%02lx: 0x%04x\n", - ADDR_REG(s526_ports[i]), inw(ADDR_REG(s526_ports[i]))); + dev->iobase + s526_ports[i], + inw(dev->iobase + s526_ports[i])); } return 1; } -- cgit v0.10.2 From 36fe5d265d394ce6889970665abcbc259d92c1cf Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 19 Sep 2012 15:09:21 -0700 Subject: staging: comedi: s526: remove ADDR_CHAN_REG macro This macro relies on a local variable having a specific name. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c index 888875e..9abbf1b 100644 --- a/drivers/staging/comedi/drivers/s526.c +++ b/drivers/staging/comedi/drivers/s526.c @@ -197,8 +197,6 @@ static const struct s526_board s526_boards[] = { } }; -#define ADDR_CHAN_REG(reg, chan) (dev->iobase + (reg) + (chan) * 8) - /* this structure is for data unique to this hardware driver. If several hardware drivers keep similar information in this structure, feel free to suggest moving the variable to the struct comedi_device @@ -226,8 +224,8 @@ static int s526_gpct_rinsn(struct comedi_device *dev, } /* Read the low word first */ for (i = 0; i < insn->n; i++) { - datalow = inw(ADDR_CHAN_REG(REG_C0L, counter_channel)); - datahigh = inw(ADDR_CHAN_REG(REG_C0H, counter_channel)); + datalow = inw(dev->iobase + REG_C0L + counter_channel * 8); + datahigh = inw(dev->iobase + REG_C0H + counter_channel * 8); data[i] = (int)(datahigh & 0x00FF); data[i] = (data[i] << 16) | (datalow & 0xFFFF); /* printk("s526 GPCT[%d]: %x(0x%04x, 0x%04x)\n", @@ -283,18 +281,18 @@ static int s526_gpct_insn_config(struct comedi_device *dev, cmReg.reg.preloadRegSel = 0; /* PR0 */ cmReg.reg.reserved = 0; - outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel)); + outw(cmReg.value, dev->iobase + REG_C0M + subdev_channel * 8); - outw(0x0001, ADDR_CHAN_REG(REG_C0H, subdev_channel)); - outw(0x3C68, ADDR_CHAN_REG(REG_C0L, subdev_channel)); + outw(0x0001, dev->iobase + REG_C0H + subdev_channel * 8); + outw(0x3C68, dev->iobase + REG_C0L + subdev_channel * 8); /* Reset the counter */ - outw(0x8000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); + outw(0x8000, dev->iobase + REG_C0C + subdev_channel * 8); /* Load the counter from PR0 */ - outw(0x4000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); + outw(0x4000, dev->iobase + REG_C0C + subdev_channel * 8); /* Reset RCAP (fires one-shot) */ - outw(0x0008, ADDR_CHAN_REG(REG_C0C, subdev_channel)); + outw(0x0008, dev->iobase + REG_C0C + subdev_channel * 8); #endif @@ -303,14 +301,14 @@ static int s526_gpct_insn_config(struct comedi_device *dev, cmReg.value = data[1] & 0xFFFF; /* printk("s526: Counter Mode register=%x\n", cmReg.value); */ - outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel)); + outw(cmReg.value, dev->iobase + REG_C0M + subdev_channel * 8); /* Reset the counter if it is software preload */ if (cmReg.reg.autoLoadResetRcap == 0) { /* Reset the counter */ - outw(0x8000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); + outw(0x8000, dev->iobase + REG_C0C + subdev_channel * 8); /* Load the counter from PR0 - * outw(0x4000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); + * outw(0x4000, dev->iobase + REG_C0C + subdev_channel * 8); */ } #else @@ -338,27 +336,27 @@ static int s526_gpct_insn_config(struct comedi_device *dev, /* Set Counter Mode Register */ cmReg.value = (short)(data[1] & 0xFFFF); - outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel)); + outw(cmReg.value, dev->iobase + REG_C0M + subdev_channel * 8); /* Load the pre-load register high word */ value = (short)((data[2] >> 16) & 0xFFFF); - outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel)); + outw(value, dev->iobase + REG_C0H + subdev_channel * 8); /* Load the pre-load register low word */ value = (short)(data[2] & 0xFFFF); - outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel)); + outw(value, dev->iobase + REG_C0L + subdev_channel * 8); /* Write the Counter Control Register */ if (data[3] != 0) { value = (short)(data[3] & 0xFFFF); - outw(value, ADDR_CHAN_REG(REG_C0C, subdev_channel)); + outw(value, dev->iobase + REG_C0C + subdev_channel * 8); } /* Reset the counter if it is software preload */ if (cmReg.reg.autoLoadResetRcap == 0) { /* Reset the counter */ - outw(0x8000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); + outw(0x8000, dev->iobase + REG_C0C + subdev_channel * 8); /* Load the counter from PR0 */ - outw(0x4000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); + outw(0x4000, dev->iobase + REG_C0C + subdev_channel * 8); } #endif break; @@ -378,33 +376,33 @@ static int s526_gpct_insn_config(struct comedi_device *dev, /* Set Counter Mode Register */ cmReg.value = (short)(data[1] & 0xFFFF); cmReg.reg.preloadRegSel = 0; /* PR0 */ - outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel)); + outw(cmReg.value, dev->iobase + REG_C0M + subdev_channel * 8); /* Load the pre-load register 0 high word */ value = (short)((data[2] >> 16) & 0xFFFF); - outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel)); + outw(value, dev->iobase + REG_C0H + subdev_channel * 8); /* Load the pre-load register 0 low word */ value = (short)(data[2] & 0xFFFF); - outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel)); + outw(value, dev->iobase + REG_C0L + subdev_channel * 8); /* Set Counter Mode Register */ cmReg.value = (short)(data[1] & 0xFFFF); cmReg.reg.preloadRegSel = 1; /* PR1 */ - outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel)); + outw(cmReg.value, dev->iobase + REG_C0M + subdev_channel * 8); /* Load the pre-load register 1 high word */ value = (short)((data[3] >> 16) & 0xFFFF); - outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel)); + outw(value, dev->iobase + REG_C0H + subdev_channel * 8); /* Load the pre-load register 1 low word */ value = (short)(data[3] & 0xFFFF); - outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel)); + outw(value, dev->iobase + REG_C0L + subdev_channel * 8); /* Write the Counter Control Register */ if (data[4] != 0) { value = (short)(data[4] & 0xFFFF); - outw(value, ADDR_CHAN_REG(REG_C0C, subdev_channel)); + outw(value, dev->iobase + REG_C0C + subdev_channel * 8); } break; @@ -423,33 +421,33 @@ static int s526_gpct_insn_config(struct comedi_device *dev, /* Set Counter Mode Register */ cmReg.value = (short)(data[1] & 0xFFFF); cmReg.reg.preloadRegSel = 0; /* PR0 */ - outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel)); + outw(cmReg.value, dev->iobase + REG_C0M + subdev_channel * 8); /* Load the pre-load register 0 high word */ value = (short)((data[2] >> 16) & 0xFFFF); - outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel)); + outw(value, dev->iobase + REG_C0H + subdev_channel * 8); /* Load the pre-load register 0 low word */ value = (short)(data[2] & 0xFFFF); - outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel)); + outw(value, dev->iobase + REG_C0L + subdev_channel * 8); /* Set Counter Mode Register */ cmReg.value = (short)(data[1] & 0xFFFF); cmReg.reg.preloadRegSel = 1; /* PR1 */ - outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel)); + outw(cmReg.value, dev->iobase + REG_C0M + subdev_channel * 8); /* Load the pre-load register 1 high word */ value = (short)((data[3] >> 16) & 0xFFFF); - outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel)); + outw(value, dev->iobase + REG_C0H + subdev_channel * 8); /* Load the pre-load register 1 low word */ value = (short)(data[3] & 0xFFFF); - outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel)); + outw(value, dev->iobase + REG_C0L + subdev_channel * 8); /* Write the Counter Control Register */ if (data[4] != 0) { value = (short)(data[4] & 0xFFFF); - outw(value, ADDR_CHAN_REG(REG_C0C, subdev_channel)); + outw(value, dev->iobase + REG_C0C + subdev_channel * 8); } break; @@ -473,22 +471,22 @@ static int s526_gpct_winsn(struct comedi_device *dev, printk(KERN_INFO "s526: GPCT_INSN_WRITE on channel %d\n", subdev_channel); - cmReg.value = inw(ADDR_CHAN_REG(REG_C0M, subdev_channel)); + cmReg.value = inw(dev->iobase + REG_C0M + subdev_channel * 8); printk(KERN_INFO "s526: Counter Mode Register: %x\n", cmReg.value); /* Check what Application of Counter this channel is configured for */ switch (devpriv->s526_gpct_config[subdev_channel].app) { case PositionMeasurement: printk(KERN_INFO "S526: INSN_WRITE: PM\n"); - outw(0xFFFF & ((*data) >> 16), ADDR_CHAN_REG(REG_C0H, - subdev_channel)); - outw(0xFFFF & (*data), ADDR_CHAN_REG(REG_C0L, subdev_channel)); + outw(0xFFFF & ((*data) >> 16), dev->iobase + REG_C0H + + subdev_channel * 8); + outw(0xFFFF & (*data), dev->iobase + REG_C0L + subdev_channel * 8); break; case SinglePulseGeneration: printk(KERN_INFO "S526: INSN_WRITE: SPG\n"); - outw(0xFFFF & ((*data) >> 16), ADDR_CHAN_REG(REG_C0H, - subdev_channel)); - outw(0xFFFF & (*data), ADDR_CHAN_REG(REG_C0L, subdev_channel)); + outw(0xFFFF & ((*data) >> 16), dev->iobase + REG_C0H + + subdev_channel * 8); + outw(0xFFFF & (*data), dev->iobase + REG_C0L + subdev_channel * 8); break; case PulseTrainGeneration: @@ -511,9 +509,9 @@ static int s526_gpct_winsn(struct comedi_device *dev, } value = (short)((*data >> 16) & 0xFFFF); - outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel)); + outw(value, dev->iobase + REG_C0H + subdev_channel * 8); value = (short)(*data & 0xFFFF); - outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel)); + outw(value, dev->iobase + REG_C0L + subdev_channel * 8); break; default: /* Impossible */ printk @@ -843,17 +841,17 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) cmReg.reg.preloadRegSel = 0; /* PR0 */ cmReg.reg.reserved = 0; - outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel)); + outw(cmReg.value, dev->iobase + REG_C0M + subdev_channel * 8); - outw(0x0001, ADDR_CHAN_REG(REG_C0H, subdev_channel)); - outw(0x3C68, ADDR_CHAN_REG(REG_C0L, subdev_channel)); + outw(0x0001, dev->iobase + REG_C0H + subdev_channel * 8); + outw(0x3C68, dev->iobase + REG_C0L + subdev_channel * 8); /* Reset the counter */ - outw(0x8000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); + outw(0x8000, dev->iobase + REG_C0C + subdev_channel * 8); /* Load the counter from PR0 */ - outw(0x4000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); + outw(0x4000, dev->iobase + REG_C0C + subdev_channel * 8); /* Reset RCAP (fires one-shot) */ - outw(0x0008, ADDR_CHAN_REG(REG_C0C, subdev_channel)); + outw(0x0008, dev->iobase + REG_C0C + subdev_channel * 8); #else @@ -872,35 +870,35 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) n = 0; printk(KERN_INFO "Mode reg=0x%04x, 0x%04lx\n", - cmReg.value, ADDR_CHAN_REG(REG_C0M, n)); - outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, n)); + cmReg.value, dev->iobase + REG_C0M + n * 8); + outw(cmReg.value, dev->iobase + REG_C0M + n * 8); udelay(1000); printk(KERN_INFO "Read back mode reg=0x%04x\n", - inw(ADDR_CHAN_REG(REG_C0M, n))); + inw(dev->iobase + REG_C0M + n * 8)); /* Load the pre-load register high word */ /* value = (short) (0x55); */ -/* outw(value, ADDR_CHAN_REG(REG_C0H, n)); */ +/* outw(value, dev->iobase + REG_C0H + n * 8); */ /* Load the pre-load register low word */ /* value = (short)(0xaa55); */ -/* outw(value, ADDR_CHAN_REG(REG_C0L, n)); */ +/* outw(value, dev->iobase + REG_C0L + n * 8); */ /* Write the Counter Control Register */ -/* outw(value, ADDR_CHAN_REG(REG_C0C, 0)); */ +/* outw(value, dev->iobase + REG_C0C + 0 * 8); */ /* Reset the counter if it is software preload */ if (cmReg.reg.autoLoadResetRcap == 0) { /* Reset the counter */ - outw(0x8000, ADDR_CHAN_REG(REG_C0C, n)); + outw(0x8000, dev->iobase + REG_C0C + n * 8); /* Load the counter from PR0 */ - outw(0x4000, ADDR_CHAN_REG(REG_C0C, n)); + outw(0x4000, dev->iobase + REG_C0C + n * 8); } - outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, n)); + outw(cmReg.value, dev->iobase + REG_C0M + n * 8); udelay(1000); printk(KERN_INFO "Read back mode reg=0x%04x\n", - inw(ADDR_CHAN_REG(REG_C0M, n))); + inw(dev->iobase + REG_C0M + n * 8)); #endif printk(KERN_INFO "Current registres:\n"); -- cgit v0.10.2 From 898143bd1ac1550f3b2b2eaf397b13fc1d1889d1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 19 Sep 2012 15:09:40 -0700 Subject: staging: comedi: s526: remove commented out debug messages These messages should be removed from the final driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c index 9abbf1b..75e3e58 100644 --- a/drivers/staging/comedi/drivers/s526.c +++ b/drivers/staging/comedi/drivers/s526.c @@ -228,8 +228,6 @@ static int s526_gpct_rinsn(struct comedi_device *dev, datahigh = inw(dev->iobase + REG_C0H + counter_channel * 8); data[i] = (int)(datahigh & 0x00FF); data[i] = (data[i] << 16) | (datalow & 0xFFFF); - /* printk("s526 GPCT[%d]: %x(0x%04x, 0x%04x)\n", - counter_channel, data[i], datahigh, datalow); */ } return i; } @@ -244,13 +242,8 @@ static int s526_gpct_insn_config(struct comedi_device *dev, short value; union cmReg cmReg; - /* printk("s526: GPCT_INSN_CONFIG: Configuring Channel %d\n", - subdev_channel); */ - - for (i = 0; i < MAX_GPCT_CONFIG_DATA; i++) { + for (i = 0; i < MAX_GPCT_CONFIG_DATA; i++) devpriv->s526_gpct_config[subdev_channel].data[i] = data[i]; -/* printk("data[%d]=%x\n", i, data[i]); */ - } /* Check what type of Counter the user requested, data[0] contains */ /* the Application type */ @@ -299,8 +292,6 @@ static int s526_gpct_insn_config(struct comedi_device *dev, #if 1 /* Set Counter Mode Register */ cmReg.value = data[1] & 0xFFFF; - -/* printk("s526: Counter Mode register=%x\n", cmReg.value); */ outw(cmReg.value, dev->iobase + REG_C0M + subdev_channel * 8); /* Reset the counter if it is software preload */ @@ -546,7 +537,6 @@ static int s526_ai_insn_config(struct comedi_device *dev, /* Enable ADC interrupt */ outw(ISR_ADC_DONE, dev->iobase + REG_IER); -/* printk("s526: ADC current value: 0x%04x\n", inw(dev->iobase + REG_ADC)); */ devpriv->s526_ai_config = (data[0] & 0x3FF) << 5; if (data[1] > 0) devpriv->s526_ai_config |= 0x8000; /* set the delay */ @@ -579,8 +569,6 @@ static int s526_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, for (n = 0; n < insn->n; n++) { /* trigger conversion */ outw(value, dev->iobase + REG_ADC); -/* printk("s526: Wrote 0x%04x to ADC\n", value); */ -/* printk("s526: ADC reg=0x%04x\n", inw(dev->iobase + REG_ADC)); */ #define TIMEOUT 100 /* wait for conversion to end */ @@ -601,7 +589,6 @@ static int s526_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, /* read data */ d = inw(dev->iobase + REG_ADD); -/* printk("AI[%d]=0x%04x\n", n, (unsigned short)(d & 0xFFFF)); */ /* munge data */ data[n] = d ^ 0x8000; @@ -619,7 +606,6 @@ static int s526_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, int chan = CR_CHAN(insn->chanspec); unsigned short val; -/* printk("s526_ao_winsn\n"); */ val = chan << 1; /* outw(val, dev->iobase + REG_DAC); */ outw(val, dev->iobase + REG_DAC); @@ -746,13 +732,6 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) printk("iobase=0x%lx\n", dev->iobase); - /*** make it a little quieter, exw, 8/29/06 - for (i = 0; i < S526_NUM_PORTS; i++) { - printk("0x%02x: 0x%04x\n", dev->iobase + s526_ports[i], - inw(dev->iobase + s526_ports[i])); - } - ***/ - dev->board_name = board->name; ret = alloc_private(dev, sizeof(*devpriv)); -- cgit v0.10.2 From d52f042ce5d64bbc56160e3653de064d380120c7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 19 Sep 2012 15:09:57 -0700 Subject: staging: comedi: s526: remove unneeded check in s526_gpct_rinsn() The comedi core validates insn->n before calling this function. Remove the unnecessary check. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c index 75e3e58..f9f0fda 100644 --- a/drivers/staging/comedi/drivers/s526.c +++ b/drivers/staging/comedi/drivers/s526.c @@ -217,11 +217,6 @@ static int s526_gpct_rinsn(struct comedi_device *dev, unsigned short datalow; unsigned short datahigh; - /* Check if (n > 0) */ - if (insn->n <= 0) { - printk(KERN_ERR "s526: INSN_READ: n should be > 0\n"); - return -EINVAL; - } /* Read the low word first */ for (i = 0; i < insn->n; i++) { datalow = inw(dev->iobase + REG_C0L + counter_channel * 8); -- cgit v0.10.2 From 28eb7e8d7649f2497c334d5e6d36e5f4fef13233 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 19 Sep 2012 15:10:15 -0700 Subject: staging: comedi: s526: remove unreachable code in s526_attach() The code after the return in this function can never execute. Just remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c index f9f0fda..f0144d9 100644 --- a/drivers/staging/comedi/drivers/s526.c +++ b/drivers/staging/comedi/drivers/s526.c @@ -710,11 +710,7 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) struct s526_private *devpriv; struct comedi_subdevice *s; int iobase; - int i, n; int ret; -/* short value; */ -/* int subdev_channel = 0; */ - union cmReg cmReg; printk(KERN_INFO "comedi%d: s526: ", dev->minor); @@ -799,90 +795,6 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) printk(KERN_INFO "attached\n"); return 1; - -#if 0 - /* Example of Counter Application */ - /* One-shot (software trigger) */ - cmReg.reg.coutSource = 0; /* out RCAP */ - cmReg.reg.coutPolarity = 1; /* Polarity inverted */ - cmReg.reg.autoLoadResetRcap = 1;/* Auto load 0:disabled, 1:enabled */ - cmReg.reg.hwCtEnableSource = 3; /* NOT RCAP */ - cmReg.reg.ctEnableCtrl = 2; /* Hardware */ - cmReg.reg.clockSource = 2; /* Internal */ - cmReg.reg.countDir = 1; /* Down */ - cmReg.reg.countDirCtrl = 1; /* Software */ - cmReg.reg.outputRegLatchCtrl = 0; /* latch on read */ - cmReg.reg.preloadRegSel = 0; /* PR0 */ - cmReg.reg.reserved = 0; - - outw(cmReg.value, dev->iobase + REG_C0M + subdev_channel * 8); - - outw(0x0001, dev->iobase + REG_C0H + subdev_channel * 8); - outw(0x3C68, dev->iobase + REG_C0L + subdev_channel * 8); - - /* Reset the counter */ - outw(0x8000, dev->iobase + REG_C0C + subdev_channel * 8); - /* Load the counter from PR0 */ - outw(0x4000, dev->iobase + REG_C0C + subdev_channel * 8); - /* Reset RCAP (fires one-shot) */ - outw(0x0008, dev->iobase + REG_C0C + subdev_channel * 8); - -#else - - /* Set Counter Mode Register */ - cmReg.reg.coutSource = 0; /* out RCAP */ - cmReg.reg.coutPolarity = 0; /* Polarity inverted */ - cmReg.reg.autoLoadResetRcap = 0; /* Auto load disabled */ - cmReg.reg.hwCtEnableSource = 2; /* NOT RCAP */ - cmReg.reg.ctEnableCtrl = 1; /* 1: Software, >1 : Hardware */ - cmReg.reg.clockSource = 3; /* x4 */ - cmReg.reg.countDir = 0; /* up */ - cmReg.reg.countDirCtrl = 0; /* quadrature */ - cmReg.reg.outputRegLatchCtrl = 0; /* latch on read */ - cmReg.reg.preloadRegSel = 0; /* PR0 */ - cmReg.reg.reserved = 0; - - n = 0; - printk(KERN_INFO "Mode reg=0x%04x, 0x%04lx\n", - cmReg.value, dev->iobase + REG_C0M + n * 8); - outw(cmReg.value, dev->iobase + REG_C0M + n * 8); - udelay(1000); - printk(KERN_INFO "Read back mode reg=0x%04x\n", - inw(dev->iobase + REG_C0M + n * 8)); - - /* Load the pre-load register high word */ -/* value = (short) (0x55); */ -/* outw(value, dev->iobase + REG_C0H + n * 8); */ - - /* Load the pre-load register low word */ -/* value = (short)(0xaa55); */ -/* outw(value, dev->iobase + REG_C0L + n * 8); */ - - /* Write the Counter Control Register */ -/* outw(value, dev->iobase + REG_C0C + 0 * 8); */ - - /* Reset the counter if it is software preload */ - if (cmReg.reg.autoLoadResetRcap == 0) { - /* Reset the counter */ - outw(0x8000, dev->iobase + REG_C0C + n * 8); - /* Load the counter from PR0 */ - outw(0x4000, dev->iobase + REG_C0C + n * 8); - } - - outw(cmReg.value, dev->iobase + REG_C0M + n * 8); - udelay(1000); - printk(KERN_INFO "Read back mode reg=0x%04x\n", - inw(dev->iobase + REG_C0M + n * 8)); - -#endif - printk(KERN_INFO "Current registres:\n"); - - for (i = 0; i < S526_NUM_PORTS; i++) { - printk(KERN_INFO "0x%02lx: 0x%04x\n", - dev->iobase + s526_ports[i], - inw(dev->iobase + s526_ports[i])); - } - return 1; } static void s526_detach(struct comedi_device *dev) -- cgit v0.10.2 From d160895fe8ef671a4e56be9fab5b2430c296dad7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 19 Sep 2012 15:10:33 -0700 Subject: staging: comedi: s526: remove printk noise Remove the function trace printk noise. Change the final attach message into a simple dev_info. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c index f0144d9..362c955 100644 --- a/drivers/staging/comedi/drivers/s526.c +++ b/drivers/staging/comedi/drivers/s526.c @@ -250,7 +250,6 @@ static int s526_gpct_insn_config(struct comedi_device *dev, data[2]: Pre-load Register Value data[3]: Conter Control Register */ - printk(KERN_INFO "s526: GPCT_INSN_CONFIG: Configuring Encoder\n"); devpriv->s526_gpct_config[subdev_channel].app = PositionMeasurement; @@ -355,7 +354,6 @@ static int s526_gpct_insn_config(struct comedi_device *dev, data[3]: Pre-load Register 1 Value data[4]: Conter Control Register */ - printk(KERN_INFO "s526: GPCT_INSN_CONFIG: Configuring SPG\n"); devpriv->s526_gpct_config[subdev_channel].app = SinglePulseGeneration; @@ -400,7 +398,6 @@ static int s526_gpct_insn_config(struct comedi_device *dev, data[3]: Pre-load Register 1 Value data[4]: Conter Control Register */ - printk(KERN_INFO "s526: GPCT_INSN_CONFIG: Configuring PTG\n"); devpriv->s526_gpct_config[subdev_channel].app = PulseTrainGeneration; @@ -438,7 +435,6 @@ static int s526_gpct_insn_config(struct comedi_device *dev, break; default: - printk(KERN_ERR "s526: unsupported GPCT_insn_config\n"); return -EINVAL; break; } @@ -455,21 +451,16 @@ static int s526_gpct_winsn(struct comedi_device *dev, short value; union cmReg cmReg; - printk(KERN_INFO "s526: GPCT_INSN_WRITE on channel %d\n", - subdev_channel); cmReg.value = inw(dev->iobase + REG_C0M + subdev_channel * 8); - printk(KERN_INFO "s526: Counter Mode Register: %x\n", cmReg.value); /* Check what Application of Counter this channel is configured for */ switch (devpriv->s526_gpct_config[subdev_channel].app) { case PositionMeasurement: - printk(KERN_INFO "S526: INSN_WRITE: PM\n"); outw(0xFFFF & ((*data) >> 16), dev->iobase + REG_C0H + subdev_channel * 8); outw(0xFFFF & (*data), dev->iobase + REG_C0L + subdev_channel * 8); break; case SinglePulseGeneration: - printk(KERN_INFO "S526: INSN_WRITE: SPG\n"); outw(0xFFFF & ((*data) >> 16), dev->iobase + REG_C0H + subdev_channel * 8); outw(0xFFFF & (*data), dev->iobase + REG_C0L + subdev_channel * 8); @@ -482,15 +473,12 @@ static int s526_gpct_winsn(struct comedi_device *dev, The above periods must be expressed as a multiple of the pulse frequency on the selected source */ - printk(KERN_INFO "S526: INSN_WRITE: PTG\n"); if ((data[1] > data[0]) && (data[0] > 0)) { (devpriv->s526_gpct_config[subdev_channel]).data[0] = data[0]; (devpriv->s526_gpct_config[subdev_channel]).data[1] = data[1]; } else { - printk(KERN_ERR "s526: INSN_WRITE: PTG: Problem with Pulse params -> %d %d\n", - data[0], data[1]); return -EINVAL; } @@ -500,9 +488,6 @@ static int s526_gpct_winsn(struct comedi_device *dev, outw(value, dev->iobase + REG_C0L + subdev_channel * 8); break; default: /* Impossible */ - printk - ("s526: INSN_WRITE: Functionality %d not implemented yet\n", - devpriv->s526_gpct_config[subdev_channel].app); return -EINVAL; break; } @@ -574,13 +559,8 @@ static int s526_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, break; } } - if (i == TIMEOUT) { - /* printk() should be used instead of printk() - * whenever the code can be called from real-time. */ - printk(KERN_ERR "s526: ADC(0x%04x) timeout\n", - inw(dev->iobase + REG_ISR)); + if (i == TIMEOUT) return -ETIMEDOUT; - } /* read data */ d = inw(dev->iobase + REG_ADD); @@ -674,8 +654,6 @@ static int s526_dio_insn_config(struct comedi_device *dev, int chan = CR_CHAN(insn->chanspec); int group, mask; - printk(KERN_INFO "S526 DIO insn_config\n"); - /* The input or output configuration of each digital line is * configured by a special insn_config instruction. chanspec * contains the channel to be changed, and data[0] contains the @@ -712,8 +690,6 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) int iobase; int ret; - printk(KERN_INFO "comedi%d: s526: ", dev->minor); - iobase = it->options[0]; if (!iobase || !request_region(iobase, S526_IOSIZE, board->name)) { comedi_error(dev, "I/O port conflict"); @@ -721,8 +697,6 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) } dev->iobase = iobase; - printk("iobase=0x%lx\n", dev->iobase); - dev->board_name = board->name; ret = alloc_private(dev, sizeof(*devpriv)); @@ -792,7 +766,7 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->type = COMEDI_SUBD_UNUSED; } - printk(KERN_INFO "attached\n"); + dev_info(dev->class_dev, "%s attached\n", dev->board_name); return 1; } -- cgit v0.10.2 From 2a117a92efc0394fd70486a9379b63004c2ebc99 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 19 Sep 2012 15:10:47 -0700 Subject: staging: comedi: s526: remove unused s526_ports array This array was used to debug dump the registers. The debug dump has been removed so this array is no longer needed. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c index 362c955..1ae250b 100644 --- a/drivers/staging/comedi/drivers/s526.c +++ b/drivers/staging/comedi/drivers/s526.c @@ -83,36 +83,6 @@ comedi_config /dev/comedi0 s526 0x2C0,0x3 #define REG_EED 0x32 #define REG_EEC 0x34 -static const int s526_ports[] = { - REG_TCR, - REG_WDC, - REG_DAC, - REG_ADC, - REG_ADD, - REG_DIO, - REG_IER, - REG_ISR, - REG_MSC, - REG_C0L, - REG_C0H, - REG_C0M, - REG_C0C, - REG_C1L, - REG_C1H, - REG_C1M, - REG_C1C, - REG_C2L, - REG_C2H, - REG_C2M, - REG_C2C, - REG_C3L, - REG_C3H, - REG_C3M, - REG_C3C, - REG_EED, - REG_EEC -}; - struct counter_mode_register_t { #if defined(__LITTLE_ENDIAN_BITFIELD) unsigned short coutSource:1; -- cgit v0.10.2 From 2c7817891dbc44612ac59a7d627716fae240b3a7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 19 Sep 2012 15:11:04 -0700 Subject: staging: comedi: s526: remove cut-and-paste comments from skel driver These comments are not necessary, they are just cut-and-paste from the skel driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c index 1ae250b..0f1ef98 100644 --- a/drivers/staging/comedi/drivers/s526.c +++ b/drivers/staging/comedi/drivers/s526.c @@ -138,11 +138,6 @@ struct s526GPCTConfig { int data[MAX_GPCT_CONFIG_DATA]; }; -/* - * Board descriptions for two imaginary boards. Describing the - * boards in this way is optional, and completely driver-dependent. - * Some drivers use arrays such as this, other do not. - */ struct s526_board { const char *name; int gpct_chans; @@ -167,11 +162,6 @@ static const struct s526_board s526_boards[] = { } }; -/* this structure is for data unique to this hardware driver. If - several hardware drivers keep similar information in this structure, - feel free to suggest moving the variable to the struct comedi_device - struct. -*/ struct s526_private { unsigned int ao_readback[2]; struct s526GPCTConfig s526_gpct_config[4]; @@ -496,10 +486,6 @@ static int s526_ai_insn_config(struct comedi_device *dev, return result; } -/* - * "instructions" read/write data in "one-shot" or "software-triggered" - * mode. - */ static int s526_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { @@ -552,30 +538,18 @@ static int s526_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, unsigned short val; val = chan << 1; -/* outw(val, dev->iobase + REG_DAC); */ outw(val, dev->iobase + REG_DAC); - /* Writing a list of values to an AO channel is probably not - * very useful, but that's how the interface is defined. */ for (i = 0; i < insn->n; i++) { - /* a typical programming sequence */ - /* write the data to preload register - * outw(data[i], dev->iobase + REG_ADD); - */ - /* write the data to preload register */ outw(data[i], dev->iobase + REG_ADD); devpriv->ao_readback[chan] = data[i]; -/* outw(val + 1, dev->iobase + REG_DAC); starts the D/A conversion. */ /* starts the D/A conversion */ outw(val + 1, dev->iobase + REG_DAC); } - /* return the number of samples read/written */ return i; } -/* AO subdevices should have a read insn as well as a write insn. - * Usually this means copying a value stored in devpriv. */ static int s526_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { @@ -589,30 +563,18 @@ static int s526_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, return i; } -/* DIO devices are slightly special. Although it is possible to - * implement the insn_read/insn_write interface, it is much more - * useful to applications if you implement the insn_bits interface. - * This allows packed reading/writing of the DIO channels. The - * comedi core can convert between insn_bits and insn_read/write */ static int s526_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - /* The insn data is a mask in data[0] and the new data - * in data[1], each channel cooresponding to a bit. */ if (data[0]) { s->state &= ~data[0]; s->state |= data[0] & data[1]; - /* Write out the new digital output lines */ + outw(s->state, dev->iobase + REG_DIO); } - /* on return, data[1] contains the value of the digital - * input and output lines. */ data[1] = inw(dev->iobase + REG_DIO) & 0xff; - /* or we could just return the software copy of the output values if - * it was a purely digital output subdevice */ - /* data[1]=s->state & 0xFF; */ return insn->n; } @@ -624,11 +586,6 @@ static int s526_dio_insn_config(struct comedi_device *dev, int chan = CR_CHAN(insn->chanspec); int group, mask; - /* The input or output configuration of each digital line is - * configured by a special insn_config instruction. chanspec - * contains the channel to be changed, and data[0] contains the - * value COMEDI_INPUT or COMEDI_OUTPUT. */ - group = chan >> 2; mask = 0xF << (group << 2); switch (data[0]) { @@ -682,33 +639,22 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* GENERAL-PURPOSE COUNTER/TIME (GPCT) */ s->type = COMEDI_SUBD_COUNTER; s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL; - /* KG: What does SDF_LSAMPL (see multiq3.c) mean? */ s->n_chan = board->gpct_chans; s->maxdata = 0x00ffffff; /* 24 bit counter */ s->insn_read = s526_gpct_rinsn; s->insn_config = s526_gpct_insn_config; s->insn_write = s526_gpct_winsn; - /* Command are not implemented yet, however they are necessary to - allocate the necessary memory for the comedi_async struct (used - to trigger the GPCT in case of pulsegenerator function */ - /* s->do_cmd = s526_gpct_cmd; */ - /* s->do_cmdtest = s526_gpct_cmdtest; */ - /* s->cancel = s526_gpct_cancel; */ - s = &dev->subdevices[1]; - /* dev->read_subdev=s; */ /* analog input subdevice */ s->type = COMEDI_SUBD_AI; - /* we support differential */ s->subdev_flags = SDF_READABLE | SDF_DIFF; /* channels 0 to 7 are the regular differential inputs */ /* channel 8 is "reference 0" (+10V), channel 9 is "reference 1" (0V) */ s->n_chan = 10; s->maxdata = 0xffff; s->range_table = &range_bipolar10; - s->len_chanlist = 16; /* This is the maximum chanlist length that - the board can handle */ + s->len_chanlist = 16; s->insn_read = s526_ai_rinsn; s->insn_config = s526_ai_insn_config; -- cgit v0.10.2 From 3d9083b27a960e10a744b8d35694b70abae9a830 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 19 Sep 2012 15:11:20 -0700 Subject: staging: comedi: s526: remove boardinfo This driver only supports one board type and only the "name", "gpct_chans", and "have_dio" information is being used anyway. Just remove the boardinfo to keep the driver simple. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c index 0f1ef98..5bd50a9 100644 --- a/drivers/staging/comedi/drivers/s526.c +++ b/drivers/staging/comedi/drivers/s526.c @@ -138,30 +138,6 @@ struct s526GPCTConfig { int data[MAX_GPCT_CONFIG_DATA]; }; -struct s526_board { - const char *name; - int gpct_chans; - int gpct_bits; - int ad_chans; - int ad_bits; - int da_chans; - int da_bits; - int have_dio; -}; - -static const struct s526_board s526_boards[] = { - { - .name = "s526", - .gpct_chans = 4, - .gpct_bits = 24, - .ad_chans = 8, - .ad_bits = 16, - .da_chans = 4, - .da_bits = 16, - .have_dio = 1, - } -}; - struct s526_private { unsigned int ao_readback[2]; struct s526GPCTConfig s526_gpct_config[4]; @@ -611,21 +587,20 @@ static int s526_dio_insn_config(struct comedi_device *dev, static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - const struct s526_board *board = comedi_board(dev); struct s526_private *devpriv; struct comedi_subdevice *s; int iobase; int ret; + dev->board_name = dev->driver->driver_name; + iobase = it->options[0]; - if (!iobase || !request_region(iobase, S526_IOSIZE, board->name)) { + if (!iobase || !request_region(iobase, S526_IOSIZE, dev->board_name)) { comedi_error(dev, "I/O port conflict"); return -EIO; } dev->iobase = iobase; - dev->board_name = board->name; - ret = alloc_private(dev, sizeof(*devpriv)); if (ret) return ret; @@ -639,7 +614,7 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* GENERAL-PURPOSE COUNTER/TIME (GPCT) */ s->type = COMEDI_SUBD_COUNTER; s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL; - s->n_chan = board->gpct_chans; + s->n_chan = 4; s->maxdata = 0x00ffffff; /* 24 bit counter */ s->insn_read = s526_gpct_rinsn; s->insn_config = s526_gpct_insn_config; @@ -670,17 +645,13 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) s = &dev->subdevices[3]; /* digital i/o subdevice */ - if (board->have_dio) { - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 8; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = s526_dio_insn_bits; - s->insn_config = s526_dio_insn_config; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 8; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = s526_dio_insn_bits; + s->insn_config = s526_dio_insn_config; dev_info(dev->class_dev, "%s attached\n", dev->board_name); @@ -698,9 +669,6 @@ static struct comedi_driver s526_driver = { .module = THIS_MODULE, .attach = s526_attach, .detach = s526_detach, - .board_name = &s526_boards[0].name, - .offset = sizeof(struct s526_board), - .num_names = ARRAY_SIZE(s526_boards), }; module_comedi_driver(s526_driver); -- cgit v0.10.2 From 43a352760e6c1c073c12f6e21d02b789525e677e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 19 Sep 2012 15:11:37 -0700 Subject: staging: comedi: s526: rename local var used for CR_CHAN() value Rename the local variable used to hold the unpacked CR_CHAN() value to help keep the lines < 80 chars. Also, since the insn->chanspec variable is an unsigned int, change the type of the local variable to match. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c index 5bd50a9..574a0b2 100644 --- a/drivers/staging/comedi/drivers/s526.c +++ b/drivers/staging/comedi/drivers/s526.c @@ -148,15 +148,15 @@ static int s526_gpct_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - int i; /* counts the Data */ - int counter_channel = CR_CHAN(insn->chanspec); + unsigned int chan = CR_CHAN(insn->chanspec); unsigned short datalow; unsigned short datahigh; + int i; /* Read the low word first */ for (i = 0; i < insn->n; i++) { - datalow = inw(dev->iobase + REG_C0L + counter_channel * 8); - datahigh = inw(dev->iobase + REG_C0H + counter_channel * 8); + datalow = inw(dev->iobase + REG_C0L + chan * 8); + datahigh = inw(dev->iobase + REG_C0H + chan * 8); data[i] = (int)(datahigh & 0x00FF); data[i] = (data[i] << 16) | (datalow & 0xFFFF); } @@ -168,13 +168,13 @@ static int s526_gpct_insn_config(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { struct s526_private *devpriv = dev->private; - int subdev_channel = CR_CHAN(insn->chanspec); /* Unpack chanspec */ + unsigned int chan = CR_CHAN(insn->chanspec); int i; short value; union cmReg cmReg; for (i = 0; i < MAX_GPCT_CONFIG_DATA; i++) - devpriv->s526_gpct_config[subdev_channel].data[i] = data[i]; + devpriv->s526_gpct_config[chan].data[i] = data[i]; /* Check what type of Counter the user requested, data[0] contains */ /* the Application type */ @@ -186,8 +186,7 @@ static int s526_gpct_insn_config(struct comedi_device *dev, data[2]: Pre-load Register Value data[3]: Conter Control Register */ - devpriv->s526_gpct_config[subdev_channel].app = - PositionMeasurement; + devpriv->s526_gpct_config[chan].app = PositionMeasurement; #if 0 /* Example of Counter Application */ @@ -204,32 +203,32 @@ static int s526_gpct_insn_config(struct comedi_device *dev, cmReg.reg.preloadRegSel = 0; /* PR0 */ cmReg.reg.reserved = 0; - outw(cmReg.value, dev->iobase + REG_C0M + subdev_channel * 8); + outw(cmReg.value, dev->iobase + REG_C0M + chan * 8); - outw(0x0001, dev->iobase + REG_C0H + subdev_channel * 8); - outw(0x3C68, dev->iobase + REG_C0L + subdev_channel * 8); + outw(0x0001, dev->iobase + REG_C0H + chan * 8); + outw(0x3C68, dev->iobase + REG_C0L + chan * 8); /* Reset the counter */ - outw(0x8000, dev->iobase + REG_C0C + subdev_channel * 8); + outw(0x8000, dev->iobase + REG_C0C + chan * 8); /* Load the counter from PR0 */ - outw(0x4000, dev->iobase + REG_C0C + subdev_channel * 8); + outw(0x4000, dev->iobase + REG_C0C + chan * 8); /* Reset RCAP (fires one-shot) */ - outw(0x0008, dev->iobase + REG_C0C + subdev_channel * 8); + outw(0x0008, dev->iobase + REG_C0C + chan * 8); #endif #if 1 /* Set Counter Mode Register */ cmReg.value = data[1] & 0xFFFF; - outw(cmReg.value, dev->iobase + REG_C0M + subdev_channel * 8); + outw(cmReg.value, dev->iobase + REG_C0M + chan * 8); /* Reset the counter if it is software preload */ if (cmReg.reg.autoLoadResetRcap == 0) { /* Reset the counter */ - outw(0x8000, dev->iobase + REG_C0C + subdev_channel * 8); + outw(0x8000, dev->iobase + REG_C0C + chan * 8); /* Load the counter from PR0 - * outw(0x4000, dev->iobase + REG_C0C + subdev_channel * 8); + * outw(0x4000, dev->iobase + REG_C0C + chan * 8); */ } #else @@ -257,27 +256,27 @@ static int s526_gpct_insn_config(struct comedi_device *dev, /* Set Counter Mode Register */ cmReg.value = (short)(data[1] & 0xFFFF); - outw(cmReg.value, dev->iobase + REG_C0M + subdev_channel * 8); + outw(cmReg.value, dev->iobase + REG_C0M + chan * 8); /* Load the pre-load register high word */ value = (short)((data[2] >> 16) & 0xFFFF); - outw(value, dev->iobase + REG_C0H + subdev_channel * 8); + outw(value, dev->iobase + REG_C0H + chan * 8); /* Load the pre-load register low word */ value = (short)(data[2] & 0xFFFF); - outw(value, dev->iobase + REG_C0L + subdev_channel * 8); + outw(value, dev->iobase + REG_C0L + chan * 8); /* Write the Counter Control Register */ if (data[3] != 0) { value = (short)(data[3] & 0xFFFF); - outw(value, dev->iobase + REG_C0C + subdev_channel * 8); + outw(value, dev->iobase + REG_C0C + chan * 8); } /* Reset the counter if it is software preload */ if (cmReg.reg.autoLoadResetRcap == 0) { /* Reset the counter */ - outw(0x8000, dev->iobase + REG_C0C + subdev_channel * 8); + outw(0x8000, dev->iobase + REG_C0C + chan * 8); /* Load the counter from PR0 */ - outw(0x4000, dev->iobase + REG_C0C + subdev_channel * 8); + outw(0x4000, dev->iobase + REG_C0C + chan * 8); } #endif break; @@ -290,39 +289,38 @@ static int s526_gpct_insn_config(struct comedi_device *dev, data[3]: Pre-load Register 1 Value data[4]: Conter Control Register */ - devpriv->s526_gpct_config[subdev_channel].app = - SinglePulseGeneration; + devpriv->s526_gpct_config[chan].app = SinglePulseGeneration; /* Set Counter Mode Register */ cmReg.value = (short)(data[1] & 0xFFFF); cmReg.reg.preloadRegSel = 0; /* PR0 */ - outw(cmReg.value, dev->iobase + REG_C0M + subdev_channel * 8); + outw(cmReg.value, dev->iobase + REG_C0M + chan * 8); /* Load the pre-load register 0 high word */ value = (short)((data[2] >> 16) & 0xFFFF); - outw(value, dev->iobase + REG_C0H + subdev_channel * 8); + outw(value, dev->iobase + REG_C0H + chan * 8); /* Load the pre-load register 0 low word */ value = (short)(data[2] & 0xFFFF); - outw(value, dev->iobase + REG_C0L + subdev_channel * 8); + outw(value, dev->iobase + REG_C0L + chan * 8); /* Set Counter Mode Register */ cmReg.value = (short)(data[1] & 0xFFFF); cmReg.reg.preloadRegSel = 1; /* PR1 */ - outw(cmReg.value, dev->iobase + REG_C0M + subdev_channel * 8); + outw(cmReg.value, dev->iobase + REG_C0M + chan * 8); /* Load the pre-load register 1 high word */ value = (short)((data[3] >> 16) & 0xFFFF); - outw(value, dev->iobase + REG_C0H + subdev_channel * 8); + outw(value, dev->iobase + REG_C0H + chan * 8); /* Load the pre-load register 1 low word */ value = (short)(data[3] & 0xFFFF); - outw(value, dev->iobase + REG_C0L + subdev_channel * 8); + outw(value, dev->iobase + REG_C0L + chan * 8); /* Write the Counter Control Register */ if (data[4] != 0) { value = (short)(data[4] & 0xFFFF); - outw(value, dev->iobase + REG_C0C + subdev_channel * 8); + outw(value, dev->iobase + REG_C0C + chan * 8); } break; @@ -334,39 +332,38 @@ static int s526_gpct_insn_config(struct comedi_device *dev, data[3]: Pre-load Register 1 Value data[4]: Conter Control Register */ - devpriv->s526_gpct_config[subdev_channel].app = - PulseTrainGeneration; + devpriv->s526_gpct_config[chan].app = PulseTrainGeneration; /* Set Counter Mode Register */ cmReg.value = (short)(data[1] & 0xFFFF); cmReg.reg.preloadRegSel = 0; /* PR0 */ - outw(cmReg.value, dev->iobase + REG_C0M + subdev_channel * 8); + outw(cmReg.value, dev->iobase + REG_C0M + chan * 8); /* Load the pre-load register 0 high word */ value = (short)((data[2] >> 16) & 0xFFFF); - outw(value, dev->iobase + REG_C0H + subdev_channel * 8); + outw(value, dev->iobase + REG_C0H + chan * 8); /* Load the pre-load register 0 low word */ value = (short)(data[2] & 0xFFFF); - outw(value, dev->iobase + REG_C0L + subdev_channel * 8); + outw(value, dev->iobase + REG_C0L + chan * 8); /* Set Counter Mode Register */ cmReg.value = (short)(data[1] & 0xFFFF); cmReg.reg.preloadRegSel = 1; /* PR1 */ - outw(cmReg.value, dev->iobase + REG_C0M + subdev_channel * 8); + outw(cmReg.value, dev->iobase + REG_C0M + chan * 8); /* Load the pre-load register 1 high word */ value = (short)((data[3] >> 16) & 0xFFFF); - outw(value, dev->iobase + REG_C0H + subdev_channel * 8); + outw(value, dev->iobase + REG_C0H + chan * 8); /* Load the pre-load register 1 low word */ value = (short)(data[3] & 0xFFFF); - outw(value, dev->iobase + REG_C0L + subdev_channel * 8); + outw(value, dev->iobase + REG_C0L + chan * 8); /* Write the Counter Control Register */ if (data[4] != 0) { value = (short)(data[4] & 0xFFFF); - outw(value, dev->iobase + REG_C0C + subdev_channel * 8); + outw(value, dev->iobase + REG_C0C + chan * 8); } break; @@ -383,23 +380,21 @@ static int s526_gpct_winsn(struct comedi_device *dev, unsigned int *data) { struct s526_private *devpriv = dev->private; - int subdev_channel = CR_CHAN(insn->chanspec); /* Unpack chanspec */ + unsigned int chan = CR_CHAN(insn->chanspec); short value; union cmReg cmReg; - cmReg.value = inw(dev->iobase + REG_C0M + subdev_channel * 8); + cmReg.value = inw(dev->iobase + REG_C0M + chan * 8); /* Check what Application of Counter this channel is configured for */ - switch (devpriv->s526_gpct_config[subdev_channel].app) { + switch (devpriv->s526_gpct_config[chan].app) { case PositionMeasurement: - outw(0xFFFF & ((*data) >> 16), dev->iobase + REG_C0H + - subdev_channel * 8); - outw(0xFFFF & (*data), dev->iobase + REG_C0L + subdev_channel * 8); + outw(0xFFFF & ((*data) >> 16), dev->iobase + REG_C0H + chan * 8); + outw(0xFFFF & (*data), dev->iobase + REG_C0L + chan * 8); break; case SinglePulseGeneration: - outw(0xFFFF & ((*data) >> 16), dev->iobase + REG_C0H + - subdev_channel * 8); - outw(0xFFFF & (*data), dev->iobase + REG_C0L + subdev_channel * 8); + outw(0xFFFF & ((*data) >> 16), dev->iobase + REG_C0H + chan * 8); + outw(0xFFFF & (*data), dev->iobase + REG_C0L + chan * 8); break; case PulseTrainGeneration: @@ -410,18 +405,16 @@ static int s526_gpct_winsn(struct comedi_device *dev, pulse frequency on the selected source */ if ((data[1] > data[0]) && (data[0] > 0)) { - (devpriv->s526_gpct_config[subdev_channel]).data[0] = - data[0]; - (devpriv->s526_gpct_config[subdev_channel]).data[1] = - data[1]; + (devpriv->s526_gpct_config[chan]).data[0] = data[0]; + (devpriv->s526_gpct_config[chan]).data[1] = data[1]; } else { return -EINVAL; } value = (short)((*data >> 16) & 0xFFFF); - outw(value, dev->iobase + REG_C0H + subdev_channel * 8); + outw(value, dev->iobase + REG_C0H + chan * 8); value = (short)(*data & 0xFFFF); - outw(value, dev->iobase + REG_C0L + subdev_channel * 8); + outw(value, dev->iobase + REG_C0L + chan * 8); break; default: /* Impossible */ return -EINVAL; @@ -466,8 +459,8 @@ static int s526_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { struct s526_private *devpriv = dev->private; + unsigned int chan = CR_CHAN(insn->chanspec); int n, i; - int chan = CR_CHAN(insn->chanspec); unsigned short value; unsigned int d; unsigned int status; @@ -509,9 +502,9 @@ static int s526_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { struct s526_private *devpriv = dev->private; - int i; - int chan = CR_CHAN(insn->chanspec); + unsigned int chan = CR_CHAN(insn->chanspec); unsigned short val; + int i; val = chan << 1; outw(val, dev->iobase + REG_DAC); @@ -530,8 +523,8 @@ static int s526_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { struct s526_private *devpriv = dev->private; + unsigned int chan = CR_CHAN(insn->chanspec); int i; - int chan = CR_CHAN(insn->chanspec); for (i = 0; i < insn->n; i++) data[i] = devpriv->ao_readback[chan]; @@ -559,7 +552,7 @@ static int s526_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - int chan = CR_CHAN(insn->chanspec); + unsigned int chan = CR_CHAN(insn->chanspec); int group, mask; group = chan >> 2; -- cgit v0.10.2 From 2a29edf69807a43ad7594554cea4def755443103 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 19 Sep 2012 15:12:01 -0700 Subject: staging: comedi: s526: cleanup s526_gpct_rinsn() Use a local variable for the iobase of the channel being read. This makes the inw() calls a bit cleaner. Move the masking of the read data to make the value stored in the data array a bit clearer. The comedi core expects insn_read functions to return the number of insn data values read. For this function, the final value of 'i' is correct but change the return to 'insn->n' just to make it clear. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c index 574a0b2..86b5c7b 100644 --- a/drivers/staging/comedi/drivers/s526.c +++ b/drivers/staging/comedi/drivers/s526.c @@ -145,22 +145,25 @@ struct s526_private { }; static int s526_gpct_rinsn(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) { unsigned int chan = CR_CHAN(insn->chanspec); - unsigned short datalow; - unsigned short datahigh; + unsigned long chan_iobase = dev->iobase + chan * 8; + unsigned int lo; + unsigned int hi; int i; - /* Read the low word first */ for (i = 0; i < insn->n; i++) { - datalow = inw(dev->iobase + REG_C0L + chan * 8); - datahigh = inw(dev->iobase + REG_C0H + chan * 8); - data[i] = (int)(datahigh & 0x00FF); - data[i] = (data[i] << 16) | (datalow & 0xFFFF); + /* Read the low word first */ + lo = inw(chan_iobase + REG_C0L) & 0xffff; + hi = inw(chan_iobase + REG_C0H) & 0xff; + + data[i] = (hi << 16) | lo; } - return i; + + return insn->n; } static int s526_gpct_insn_config(struct comedi_device *dev, -- cgit v0.10.2 From 5a5614cb669f9f99bb3e983b3c4987a1eaef852b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 19 Sep 2012 15:12:17 -0700 Subject: staging: comedi: s526: cleanup s526_gpct_insn_config() Use a local variable for the iobase of the channel being configured. This makes the outw() calls a bit cleaner. Remove the unnecessary casting of the values being written to the channel registers. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c index 86b5c7b..66741b6 100644 --- a/drivers/staging/comedi/drivers/s526.c +++ b/drivers/staging/comedi/drivers/s526.c @@ -168,12 +168,14 @@ static int s526_gpct_rinsn(struct comedi_device *dev, static int s526_gpct_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_insn *insn, + unsigned int *data) { struct s526_private *devpriv = dev->private; unsigned int chan = CR_CHAN(insn->chanspec); + unsigned long chan_iobase = dev->iobase + chan * 8; + unsigned int val; int i; - short value; union cmReg cmReg; for (i = 0; i < MAX_GPCT_CONFIG_DATA; i++) @@ -206,32 +208,32 @@ static int s526_gpct_insn_config(struct comedi_device *dev, cmReg.reg.preloadRegSel = 0; /* PR0 */ cmReg.reg.reserved = 0; - outw(cmReg.value, dev->iobase + REG_C0M + chan * 8); + outw(cmReg.value, chan_iobase + REG_C0M); - outw(0x0001, dev->iobase + REG_C0H + chan * 8); - outw(0x3C68, dev->iobase + REG_C0L + chan * 8); + outw(0x0001, chan_iobase + REG_C0H); + outw(0x3C68, chan_iobase + REG_C0L); /* Reset the counter */ - outw(0x8000, dev->iobase + REG_C0C + chan * 8); + outw(0x8000, chan_iobase + REG_C0C); /* Load the counter from PR0 */ - outw(0x4000, dev->iobase + REG_C0C + chan * 8); + outw(0x4000, chan_iobase + REG_C0C); /* Reset RCAP (fires one-shot) */ - outw(0x0008, dev->iobase + REG_C0C + chan * 8); + outw(0x0008, chan_iobase + REG_C0C); #endif #if 1 /* Set Counter Mode Register */ - cmReg.value = data[1] & 0xFFFF; - outw(cmReg.value, dev->iobase + REG_C0M + chan * 8); + cmReg.value = data[1] & 0xffff; + outw(cmReg.value, chan_iobase + REG_C0M); /* Reset the counter if it is software preload */ if (cmReg.reg.autoLoadResetRcap == 0) { /* Reset the counter */ - outw(0x8000, dev->iobase + REG_C0C + chan * 8); + outw(0x8000, chan_iobase + REG_C0C); /* Load the counter from PR0 - * outw(0x4000, dev->iobase + REG_C0C + chan * 8); + * outw(0x4000, chan_iobase + REG_C0C); */ } #else @@ -258,28 +260,28 @@ static int s526_gpct_insn_config(struct comedi_device *dev, cmReg.reg.autoLoadResetRcap = 4; /* Set Counter Mode Register */ - cmReg.value = (short)(data[1] & 0xFFFF); - outw(cmReg.value, dev->iobase + REG_C0M + chan * 8); + cmReg.value = data[1] & 0xffff; + outw(cmReg.value, chan_iobase + REG_C0M); /* Load the pre-load register high word */ - value = (short)((data[2] >> 16) & 0xFFFF); - outw(value, dev->iobase + REG_C0H + chan * 8); + val = (data[2] >> 16) & 0xffff; + outw(val, chan_iobase + REG_C0H); /* Load the pre-load register low word */ - value = (short)(data[2] & 0xFFFF); - outw(value, dev->iobase + REG_C0L + chan * 8); + val = data[2] & 0xffff; + outw(val, chan_iobase + REG_C0L); /* Write the Counter Control Register */ - if (data[3] != 0) { - value = (short)(data[3] & 0xFFFF); - outw(value, dev->iobase + REG_C0C + chan * 8); + if (data[3]) { + val = data[3] & 0xffff; + outw(val, chan_iobase + REG_C0C); } /* Reset the counter if it is software preload */ if (cmReg.reg.autoLoadResetRcap == 0) { /* Reset the counter */ - outw(0x8000, dev->iobase + REG_C0C + chan * 8); + outw(0x8000, chan_iobase + REG_C0C); /* Load the counter from PR0 */ - outw(0x4000, dev->iobase + REG_C0C + chan * 8); + outw(0x4000, chan_iobase + REG_C0C); } #endif break; @@ -295,35 +297,35 @@ static int s526_gpct_insn_config(struct comedi_device *dev, devpriv->s526_gpct_config[chan].app = SinglePulseGeneration; /* Set Counter Mode Register */ - cmReg.value = (short)(data[1] & 0xFFFF); + cmReg.value = data[1] & 0xffff; cmReg.reg.preloadRegSel = 0; /* PR0 */ - outw(cmReg.value, dev->iobase + REG_C0M + chan * 8); + outw(cmReg.value, chan_iobase + REG_C0M); /* Load the pre-load register 0 high word */ - value = (short)((data[2] >> 16) & 0xFFFF); - outw(value, dev->iobase + REG_C0H + chan * 8); + val = (data[2] >> 16) & 0xffff; + outw(val, chan_iobase + REG_C0H); /* Load the pre-load register 0 low word */ - value = (short)(data[2] & 0xFFFF); - outw(value, dev->iobase + REG_C0L + chan * 8); + val = data[2] & 0xffff; + outw(val, chan_iobase + REG_C0L); /* Set Counter Mode Register */ - cmReg.value = (short)(data[1] & 0xFFFF); + cmReg.value = data[1] & 0xffff; cmReg.reg.preloadRegSel = 1; /* PR1 */ - outw(cmReg.value, dev->iobase + REG_C0M + chan * 8); + outw(cmReg.value, chan_iobase + REG_C0M); /* Load the pre-load register 1 high word */ - value = (short)((data[3] >> 16) & 0xFFFF); - outw(value, dev->iobase + REG_C0H + chan * 8); + val = (data[3] >> 16) & 0xffff; + outw(val, chan_iobase + REG_C0H); /* Load the pre-load register 1 low word */ - value = (short)(data[3] & 0xFFFF); - outw(value, dev->iobase + REG_C0L + chan * 8); + val = data[3] & 0xffff; + outw(val, chan_iobase + REG_C0L); /* Write the Counter Control Register */ - if (data[4] != 0) { - value = (short)(data[4] & 0xFFFF); - outw(value, dev->iobase + REG_C0C + chan * 8); + if (data[4]) { + val = data[4] & 0xffff; + outw(val, chan_iobase + REG_C0C); } break; @@ -338,35 +340,35 @@ static int s526_gpct_insn_config(struct comedi_device *dev, devpriv->s526_gpct_config[chan].app = PulseTrainGeneration; /* Set Counter Mode Register */ - cmReg.value = (short)(data[1] & 0xFFFF); + cmReg.value = data[1] & 0xffff; cmReg.reg.preloadRegSel = 0; /* PR0 */ - outw(cmReg.value, dev->iobase + REG_C0M + chan * 8); + outw(cmReg.value, chan_iobase + REG_C0M); /* Load the pre-load register 0 high word */ - value = (short)((data[2] >> 16) & 0xFFFF); - outw(value, dev->iobase + REG_C0H + chan * 8); + val = (data[2] >> 16) & 0xffff; + outw(val, chan_iobase + REG_C0H); /* Load the pre-load register 0 low word */ - value = (short)(data[2] & 0xFFFF); - outw(value, dev->iobase + REG_C0L + chan * 8); + val = data[2] & 0xffff; + outw(val, chan_iobase + REG_C0L); /* Set Counter Mode Register */ - cmReg.value = (short)(data[1] & 0xFFFF); + cmReg.value = data[1] & 0xffff; cmReg.reg.preloadRegSel = 1; /* PR1 */ - outw(cmReg.value, dev->iobase + REG_C0M + chan * 8); + outw(cmReg.value, chan_iobase + REG_C0M); /* Load the pre-load register 1 high word */ - value = (short)((data[3] >> 16) & 0xFFFF); - outw(value, dev->iobase + REG_C0H + chan * 8); + val = (data[3] >> 16) & 0xffff; + outw(val, chan_iobase + REG_C0H); /* Load the pre-load register 1 low word */ - value = (short)(data[3] & 0xFFFF); - outw(value, dev->iobase + REG_C0L + chan * 8); + val = data[3] & 0xffff; + outw(val, chan_iobase + REG_C0L); /* Write the Counter Control Register */ - if (data[4] != 0) { - value = (short)(data[4] & 0xFFFF); - outw(value, dev->iobase + REG_C0C + chan * 8); + if (data[4]) { + val = data[4] & 0xffff; + outw(val, chan_iobase + REG_C0C); } break; -- cgit v0.10.2 From 5c813bb100431eff1f78d75682ae1fe2d30744b4 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 19 Sep 2012 15:12:33 -0700 Subject: staging: comedi: s526: cleanup s526_gpct_winsn() Use a local variable for the iobase of the channel being written. This makes the outw() calls a bit cleaner. Rearrange the switch () so that the actual write to the device can be common regardless of the gpct configuration. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c index 66741b6..7782061 100644 --- a/drivers/staging/comedi/drivers/s526.c +++ b/drivers/staging/comedi/drivers/s526.c @@ -381,27 +381,18 @@ static int s526_gpct_insn_config(struct comedi_device *dev, } static int s526_gpct_winsn(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) { struct s526_private *devpriv = dev->private; unsigned int chan = CR_CHAN(insn->chanspec); - short value; - union cmReg cmReg; + unsigned long chan_iobase = dev->iobase + chan * 8; + + inw(chan_iobase + REG_C0M); /* Is this read required? */ - cmReg.value = inw(dev->iobase + REG_C0M + chan * 8); /* Check what Application of Counter this channel is configured for */ switch (devpriv->s526_gpct_config[chan].app) { - case PositionMeasurement: - outw(0xFFFF & ((*data) >> 16), dev->iobase + REG_C0H + chan * 8); - outw(0xFFFF & (*data), dev->iobase + REG_C0L + chan * 8); - break; - - case SinglePulseGeneration: - outw(0xFFFF & ((*data) >> 16), dev->iobase + REG_C0H + chan * 8); - outw(0xFFFF & (*data), dev->iobase + REG_C0L + chan * 8); - break; - case PulseTrainGeneration: /* data[0] contains the PULSE_WIDTH data[1] contains the PULSE_PERIOD @@ -410,22 +401,24 @@ static int s526_gpct_winsn(struct comedi_device *dev, pulse frequency on the selected source */ if ((data[1] > data[0]) && (data[0] > 0)) { - (devpriv->s526_gpct_config[chan]).data[0] = data[0]; - (devpriv->s526_gpct_config[chan]).data[1] = data[1]; + devpriv->s526_gpct_config[chan].data[0] = data[0]; + devpriv->s526_gpct_config[chan].data[1] = data[1]; } else { return -EINVAL; } - value = (short)((*data >> 16) & 0xFFFF); - outw(value, dev->iobase + REG_C0H + chan * 8); - value = (short)(*data & 0xFFFF); - outw(value, dev->iobase + REG_C0L + chan * 8); + /* Fall thru to write the PULSE_WIDTH */ + + case PositionMeasurement: + case SinglePulseGeneration: + outw((data[0] >> 16) & 0xffff, chan_iobase + REG_C0H); + outw(data[0] & 0xffff, chan_iobase + REG_C0L); break; - default: /* Impossible */ + + default: return -EINVAL; - break; } - /* return the number of samples written */ + return insn->n; } -- cgit v0.10.2 From 675f98f101fb6d1a694a03961b36997cb407dfae Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 19 Sep 2012 15:12:54 -0700 Subject: staging: comedi: s526: remove struct s526GPCTConfig The enum in this struct is used by the driver to know how the gpct channels have been configured. Instead of using the private enum S526_GPCT_APP_CLASS, we can just use the INSN_CONFIG_* value that was passed in data[0] to the s526_gpct_insn_config(). The data array in this struct in never used. It actually could cause a BUG since it assumes that the data pointer passed to s526_gpct_insn_config() always has 6 values but the comments indicate that there are really only 4 or 5. Remove the s526GPCTConfig struct and associated S526_GPCT_APP_CLASS enum and just use and unsigned int array in the private data to hold the gpct configuration. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c index 7782061..e1927cf 100644 --- a/drivers/staging/comedi/drivers/s526.c +++ b/drivers/staging/comedi/drivers/s526.c @@ -118,29 +118,9 @@ union cmReg { unsigned short value; }; -#define MAX_GPCT_CONFIG_DATA 6 - -/* Different Application Classes for GPCT Subdevices */ -/* The list is not exhaustive and needs discussion! */ -enum S526_GPCT_APP_CLASS { - CountingAndTimeMeasurement, - SinglePulseGeneration, - PulseTrainGeneration, - PositionMeasurement, - Miscellaneous -}; - -/* Config struct for different GPCT subdevice Application Classes and - their options -*/ -struct s526GPCTConfig { - enum S526_GPCT_APP_CLASS app; - int data[MAX_GPCT_CONFIG_DATA]; -}; - struct s526_private { unsigned int ao_readback[2]; - struct s526GPCTConfig s526_gpct_config[4]; + unsigned int gpct_config[4]; unsigned short s526_ai_config; }; @@ -175,12 +155,8 @@ static int s526_gpct_insn_config(struct comedi_device *dev, unsigned int chan = CR_CHAN(insn->chanspec); unsigned long chan_iobase = dev->iobase + chan * 8; unsigned int val; - int i; union cmReg cmReg; - for (i = 0; i < MAX_GPCT_CONFIG_DATA; i++) - devpriv->s526_gpct_config[chan].data[i] = data[i]; - /* Check what type of Counter the user requested, data[0] contains */ /* the Application type */ switch (data[0]) { @@ -191,7 +167,7 @@ static int s526_gpct_insn_config(struct comedi_device *dev, data[2]: Pre-load Register Value data[3]: Conter Control Register */ - devpriv->s526_gpct_config[chan].app = PositionMeasurement; + devpriv->gpct_config[chan] = data[0]; #if 0 /* Example of Counter Application */ @@ -294,7 +270,7 @@ static int s526_gpct_insn_config(struct comedi_device *dev, data[3]: Pre-load Register 1 Value data[4]: Conter Control Register */ - devpriv->s526_gpct_config[chan].app = SinglePulseGeneration; + devpriv->gpct_config[chan] = data[0]; /* Set Counter Mode Register */ cmReg.value = data[1] & 0xffff; @@ -337,7 +313,7 @@ static int s526_gpct_insn_config(struct comedi_device *dev, data[3]: Pre-load Register 1 Value data[4]: Conter Control Register */ - devpriv->s526_gpct_config[chan].app = PulseTrainGeneration; + devpriv->gpct_config[chan] = data[0]; /* Set Counter Mode Register */ cmReg.value = data[1] & 0xffff; @@ -392,25 +368,21 @@ static int s526_gpct_winsn(struct comedi_device *dev, inw(chan_iobase + REG_C0M); /* Is this read required? */ /* Check what Application of Counter this channel is configured for */ - switch (devpriv->s526_gpct_config[chan].app) { - case PulseTrainGeneration: + switch (devpriv->gpct_config[chan]) { + case INSN_CONFIG_GPCT_PULSE_TRAIN_GENERATOR: /* data[0] contains the PULSE_WIDTH data[1] contains the PULSE_PERIOD @pre PULSE_PERIOD > PULSE_WIDTH > 0 The above periods must be expressed as a multiple of the pulse frequency on the selected source */ - if ((data[1] > data[0]) && (data[0] > 0)) { - devpriv->s526_gpct_config[chan].data[0] = data[0]; - devpriv->s526_gpct_config[chan].data[1] = data[1]; - } else { + if ((data[1] < data[0]) || !data[0]) return -EINVAL; - } /* Fall thru to write the PULSE_WIDTH */ - case PositionMeasurement: - case SinglePulseGeneration: + case INSN_CONFIG_GPCT_QUADRATURE_ENCODER: + case INSN_CONFIG_GPCT_SINGLE_PULSE_GENERATOR: outw((data[0] >> 16) & 0xffff, chan_iobase + REG_C0H); outw(data[0] & 0xffff, chan_iobase + REG_C0L); break; -- cgit v0.10.2 From bda60cbfe252ad5ba7d4df4cc17c0f55e8b54599 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 19 Sep 2012 15:13:10 -0700 Subject: staging: comedi: s526: rename s526_ai_config For aesthetic reasons, rename the private data variable 's526_ai_config' to simply 'ai_config'. Its private data and does not need the 's526_' namespace. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c index e1927cf..4ad6adf 100644 --- a/drivers/staging/comedi/drivers/s526.c +++ b/drivers/staging/comedi/drivers/s526.c @@ -121,7 +121,7 @@ union cmReg { struct s526_private { unsigned int ao_readback[2]; unsigned int gpct_config[4]; - unsigned short s526_ai_config; + unsigned short ai_config; }; static int s526_gpct_rinsn(struct comedi_device *dev, @@ -416,11 +416,11 @@ static int s526_ai_insn_config(struct comedi_device *dev, /* Enable ADC interrupt */ outw(ISR_ADC_DONE, dev->iobase + REG_IER); - devpriv->s526_ai_config = (data[0] & 0x3FF) << 5; + devpriv->ai_config = (data[0] & 0x3ff) << 5; if (data[1] > 0) - devpriv->s526_ai_config |= 0x8000; /* set the delay */ + devpriv->ai_config |= 0x8000; /* set the delay */ - devpriv->s526_ai_config |= 0x0001; /* ADC start bit. */ + devpriv->ai_config |= 0x0001; /* ADC start bit */ return result; } @@ -437,8 +437,8 @@ static int s526_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, /* Set configured delay, enable channel for this channel only, * select "ADC read" channel, set "ADC start" bit. */ - value = (devpriv->s526_ai_config & 0x8000) | - ((1 << 5) << chan) | (chan << 1) | 0x0001; + value = (devpriv->ai_config & 0x8000) | + ((1 << 5) << chan) | (chan << 1) | 0x0001; /* convert n samples */ for (n = 0; n < insn->n; n++) { -- cgit v0.10.2 From 453443f32fd8d5fb3da702aa02901297dd4ad51f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 19 Sep 2012 16:20:38 -0700 Subject: staging: comedi: usbduxsigma: remove usbduxsigma_attach This driver originally used the 'attach' method in order to get the firmware for the device from the comedi_config utility. It now uses request_firmware_nowait() in the usb_driver probe to get this firmware. Since this driver has an 'attach_usb' method in the comedi_driver, the 'attach' method can be removed because it is now optional. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index 034f5df..b4ab83f 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -2301,10 +2301,8 @@ static void tidy_up(struct usbduxsub *usbduxsub_tmp) usbduxsub_tmp->pwm_cmd_running = 0; } -/* common part of attach and attach_usb */ static int usbduxsigma_attach_common(struct comedi_device *dev, - struct usbduxsub *uds, - void *aux_data, int aux_len) + struct usbduxsub *uds) { int ret; struct comedi_subdevice *s; @@ -2314,9 +2312,6 @@ static int usbduxsigma_attach_common(struct comedi_device *dev, down(&uds->sem); /* pointer back to the corresponding comedi device */ uds->comedidev = dev; - /* trying to upload the firmware into the FX2 */ - if (aux_data) - firmwareUpload(uds, aux_data, aux_len); dev->board_name = "usbduxsigma"; /* set number of subdevices */ if (uds->high_speed) @@ -2419,47 +2414,6 @@ static int usbduxsigma_attach_common(struct comedi_device *dev, return 0; } -/* is called for COMEDI_DEVCONFIG ioctl (when comedi_config is run) */ -static int usbduxsigma_attach(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - int ret; - int index; - int i; - void *aux_data; - int aux_len; - - dev->private = NULL; - - aux_data = comedi_aux_data(it->options, 0); - aux_len = it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]; - if (aux_data == NULL) - aux_len = 0; - else if (aux_len == 0) - aux_data = NULL; - - down(&start_stop_sem); - /* find a valid device which has been detected by the probe function of - * the usb */ - index = -1; - for (i = 0; i < NUMUSBDUX; i++) { - if ((usbduxsub[i].probed) && (!usbduxsub[i].attached)) { - index = i; - break; - } - } - if (index < 0) { - dev_err(dev->class_dev, - "usbduxsigma: error: attach failed, dev not connected to the usb bus.\n"); - ret = -ENODEV; - } else - ret = usbduxsigma_attach_common(dev, &usbduxsub[index], - aux_data, aux_len); - up(&start_stop_sem); - return ret; -} - -/* is called from comedi_usb_auto_config() */ static int usbduxsigma_attach_usb(struct comedi_device *dev, struct usb_interface *uinterf) { @@ -2478,7 +2432,7 @@ static int usbduxsigma_attach_usb(struct comedi_device *dev, "usbduxsigma: error: attach_usb failed, already attached\n"); ret = -ENODEV; } else - ret = usbduxsigma_attach_common(dev, uds, NULL, 0); + ret = usbduxsigma_attach_common(dev, uds); up(&start_stop_sem); return ret; } @@ -2499,9 +2453,8 @@ static void usbduxsigma_detach(struct comedi_device *dev) static struct comedi_driver usbduxsigma_driver = { .driver_name = "usbduxsigma", .module = THIS_MODULE, - .attach = usbduxsigma_attach, - .detach = usbduxsigma_detach, .attach_usb = usbduxsigma_attach_usb, + .detach = usbduxsigma_detach, }; static void usbdux_firmware_request_complete_handler(const struct firmware *fw, -- cgit v0.10.2 From 4e5ba2f6bd1c480ce6b362a17a6a3456a2354cf0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 19 Sep 2012 16:20:57 -0700 Subject: staging: comedi: usbduxfast: remove usbduxfast_attach This driver originally used the 'attach' method in order to get the firmware for the device from the comedi_config utility. It now uses request_firmware_nowait() in the usb_driver probe to get this firmware. Since this driver has an 'attach_usb' method in the comedi_driver, the 'attach' method can be removed because it is now optional. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index 3f68fc3..0f6c139 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -1430,10 +1430,8 @@ static void tidy_up(struct usbduxfastsub_s *udfs) udfs->ai_cmd_running = 0; } -/* common part of attach and attach_usb */ static int usbduxfast_attach_common(struct comedi_device *dev, - struct usbduxfastsub_s *udfs, - void *aux_data, int aux_len) + struct usbduxfastsub_s *udfs) { int ret; struct comedi_subdevice *s; @@ -1441,9 +1439,6 @@ static int usbduxfast_attach_common(struct comedi_device *dev, down(&udfs->sem); /* pointer back to the corresponding comedi device */ udfs->comedidev = dev; - /* trying to upload the firmware into the chip */ - if (aux_data) - firmwareUpload(udfs, aux_data, aux_len); dev->board_name = "usbduxfast"; ret = comedi_alloc_subdevices(dev, 1); if (ret) { @@ -1485,48 +1480,6 @@ static int usbduxfast_attach_common(struct comedi_device *dev, return 0; } -/* is called for COMEDI_DEVCONFIG ioctl (when comedi_config is run) */ -static int usbduxfast_attach(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - int ret; - int index; - int i; - void *aux_data; - int aux_len; - - dev->private = NULL; - - aux_data = comedi_aux_data(it->options, 0); - aux_len = it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]; - if (aux_data == NULL) - aux_len = 0; - else if (aux_len == 0) - aux_data = NULL; - down(&start_stop_sem); - /* - * find a valid device which has been detected by the - * probe function of the usb - */ - index = -1; - for (i = 0; i < NUMUSBDUXFAST; i++) { - if (usbduxfastsub[i].probed && !usbduxfastsub[i].attached) { - index = i; - break; - } - } - if (index < 0) { - dev_err(dev->class_dev, - "usbduxfast: error: attach failed, no usbduxfast devs connected to the usb bus.\n"); - ret = -ENODEV; - } else - ret = usbduxfast_attach_common(dev, &usbduxfastsub[index], - aux_data, aux_len); - up(&start_stop_sem); - return ret; -} - -/* is called from comedi_usb_auto_config() */ static int usbduxfast_attach_usb(struct comedi_device *dev, struct usb_interface *uinterf) { @@ -1545,7 +1498,7 @@ static int usbduxfast_attach_usb(struct comedi_device *dev, "usbduxfast: error: attach_usb failed, already attached\n"); ret = -ENODEV; } else - ret = usbduxfast_attach_common(dev, udfs, NULL, 0); + ret = usbduxfast_attach_common(dev, udfs); up(&start_stop_sem); return ret; } @@ -1568,9 +1521,8 @@ static void usbduxfast_detach(struct comedi_device *dev) static struct comedi_driver usbduxfast_driver = { .driver_name = "usbduxfast", .module = THIS_MODULE, - .attach = usbduxfast_attach, - .detach = usbduxfast_detach, .attach_usb = usbduxfast_attach_usb, + .detach = usbduxfast_detach, }; static void usbduxfast_firmware_request_complete_handler(const struct firmware -- cgit v0.10.2 From 5a0f2260897621cc0118cd16801b171acd06c31c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 19 Sep 2012 16:21:13 -0700 Subject: staging: comedi: usbdux: remove usbdux_attach This driver originally used the 'attach' method in order to get the firmware for the device from the comedi_config utility. It now uses request_firmware_nowait() in the usb_driver probe to get this firmware. Since this driver has an 'attach_usb' method in the comedi_driver, the 'attach' method can be removed because it is now optional. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 7aac213..bc5fc5c 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -2293,10 +2293,8 @@ static void tidy_up(struct usbduxsub *usbduxsub_tmp) usbduxsub_tmp->pwm_cmd_running = 0; } -/* common part of attach and attach_usb */ static int usbdux_attach_common(struct comedi_device *dev, - struct usbduxsub *udev, - void *aux_data, int aux_len) + struct usbduxsub *udev) { int ret; struct comedi_subdevice *s = NULL; @@ -2306,10 +2304,6 @@ static int usbdux_attach_common(struct comedi_device *dev, /* pointer back to the corresponding comedi device */ udev->comedidev = dev; - /* trying to upload the firmware into the chip */ - if (aux_data) - firmwareUpload(udev, aux_data, aux_len); - dev->board_name = "usbdux"; /* set number of subdevices */ @@ -2429,48 +2423,6 @@ static int usbdux_attach_common(struct comedi_device *dev, return 0; } -/* is called when comedi-config is called */ -static int usbdux_attach(struct comedi_device *dev, struct comedi_devconfig *it) -{ - int ret; - int index; - int i; - void *aux_data; - int aux_len; - - dev->private = NULL; - - aux_data = comedi_aux_data(it->options, 0); - aux_len = it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]; - if (aux_data == NULL) - aux_len = 0; - else if (aux_len == 0) - aux_data = NULL; - - down(&start_stop_sem); - /* find a valid device which has been detected by the probe function of - * the usb */ - index = -1; - for (i = 0; i < NUMUSBDUX; i++) { - if ((usbduxsub[i].probed) && (!usbduxsub[i].attached)) { - index = i; - break; - } - } - - if (index < 0) { - printk(KERN_ERR - "comedi%d: usbdux: error: attach failed, no usbdux devs connected to the usb bus.\n", - dev->minor); - ret = -ENODEV; - } else - ret = usbdux_attach_common(dev, &usbduxsub[index], - aux_data, aux_len); - up(&start_stop_sem); - return ret; -} - -/* is called from comedi_usb_auto_config() */ static int usbdux_attach_usb(struct comedi_device *dev, struct usb_interface *uinterf) { @@ -2492,7 +2444,7 @@ static int usbdux_attach_usb(struct comedi_device *dev, dev->minor); ret = -ENODEV; } else - ret = usbdux_attach_common(dev, this_usbduxsub, NULL, 0); + ret = usbdux_attach_common(dev, this_usbduxsub); up(&start_stop_sem); return ret; } @@ -2513,9 +2465,8 @@ static void usbdux_detach(struct comedi_device *dev) static struct comedi_driver usbdux_driver = { .driver_name = "usbdux", .module = THIS_MODULE, - .attach = usbdux_attach, - .detach = usbdux_detach, .attach_usb = usbdux_attach_usb, + .detach = usbdux_detach, }; static void usbdux_firmware_request_complete_handler(const struct firmware *fw, -- cgit v0.10.2 From 1e12ca3407850641fc72adb620eee8a8e6dd8c90 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 19 Sep 2012 16:21:29 -0700 Subject: staging: comedi: me_daq: use request_firmware() This driver requires loading a firmware file for the fpga. This is currently being done by passing the firmware data using the COMEDI_DEVCONFIG ioctl through the attach() hook in the driver. This does not work for auto-configured PCI devices due to the firmware loading options not being set in the comedi_devconfig parameter passed to the driver. Change the driver so it gets the firmware using request_firmware() and ignore any firmware options passed in the comedi_devconfig. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index c68c407..eeb493d 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -41,20 +41,14 @@ Configuration options: If bus/slot is not specified, the first available PCI device will be used. - -The 2600 requires a firmware upload, which can be accomplished -using the -i or --init-data option of comedi_config. -The firmware can be -found in the comedi_nonfree_firmware tarball available -from http://www.comedi.org - */ #include #include +#include #include "../comedidev.h" -/*#include "me2600_fw.h" */ +#define ME2600_FIRMWARE "me2600_firmware.bin" #define ME_DRIVER_NAME "me_daq" @@ -524,8 +518,7 @@ static int me_ao_insn_read(struct comedi_device *dev, /* Xilinx firmware download for card: ME-2600i */ static int me2600_xilinx_download(struct comedi_device *dev, - unsigned char *me2600_firmware, - unsigned int length) + const u8 *data, size_t size) { unsigned int value; unsigned int file_length; @@ -552,19 +545,20 @@ static int me2600_xilinx_download(struct comedi_device *dev, * Byte 8-11: date * Byte 12-15: reserved */ - if (length < 16) + if (size < 16) return -EINVAL; - file_length = (((unsigned int)me2600_firmware[0] & 0xff) << 24) + - (((unsigned int)me2600_firmware[1] & 0xff) << 16) + - (((unsigned int)me2600_firmware[2] & 0xff) << 8) + - ((unsigned int)me2600_firmware[3] & 0xff); + + file_length = (((unsigned int)data[0] & 0xff) << 24) + + (((unsigned int)data[1] & 0xff) << 16) + + (((unsigned int)data[2] & 0xff) << 8) + + ((unsigned int)data[3] & 0xff); /* * Loop for writing firmware byte by byte to xilinx * Firmware data start at offfset 16 */ for (i = 0; i < file_length; i++) - writeb((me2600_firmware[16 + i] & 0xff), + writeb((data[16 + i] & 0xff), dev_private->me_regbase + 0x0); /* Write 5 dummy values to xilinx */ @@ -590,6 +584,22 @@ static int me2600_xilinx_download(struct comedi_device *dev, return 0; } +static int me2600_upload_firmware(struct comedi_device *dev) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + const struct firmware *fw; + int ret; + + ret = request_firmware(&fw, ME2600_FIRMWARE, &pcidev->dev); + if (ret) + return ret; + + ret = me2600_xilinx_download(dev, fw->data, fw->size); + release_firmware(fw); + + return ret; +} + /* Reset device */ static int me_reset(struct comedi_device *dev) { @@ -735,23 +745,13 @@ static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->minor); return -ENOMEM; } + /* Download firmware and reset card */ if (board->device_id == ME2600_DEVICE_ID) { - unsigned char *aux_data; - int aux_len; - - aux_data = comedi_aux_data(it->options, 0); - aux_len = it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]; - - if (!aux_data || aux_len < 1) { - comedi_error(dev, "You must provide me2600 firmware " - "using the --init-data option of " - "comedi_config"); - return -EINVAL; - } - me2600_xilinx_download(dev, aux_data, aux_len); + result = me2600_upload_firmware(dev); + if (result < 0) + return result; } - me_reset(dev); error = comedi_alloc_subdevices(dev, 3); @@ -851,3 +851,4 @@ module_comedi_pci_driver(me_daq_driver, me_daq_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); +MODULE_FIRMWARE(ME2600_FIRMWARE); -- cgit v0.10.2 From 94174847ea41b1c2a44d997f2850530fb33f41cd Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 19 Sep 2012 16:21:49 -0700 Subject: staging: comedi: me_daq: use attach_pci callback Convert this PCI driver to use the comedi PCI auto config attach mechanism by adding an 'attach_pci' callback function. Since the driver does not require any external configuration options. and the legacy 'attach' callback is now optional, remove it. Also, make the boardinfo 'name' unique for the different board types. Use this name when requesting the PCI resources. Change the printk at the end of the attach into a dev_info. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index eeb493d..2ce0b14 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -50,8 +50,6 @@ Configuration options: #define ME2600_FIRMWARE "me2600_firmware.bin" -#define ME_DRIVER_NAME "me_daq" - #define PCI_VENDOR_ID_MEILHAUS 0x1402 #define ME2000_DEVICE_ID 0x2000 #define ME2600_DEVICE_ID 0x2600 @@ -192,8 +190,7 @@ struct me_board { static const struct me_board me_boards[] = { { - /* -- ME-2600i -- */ - .name = ME_DRIVER_NAME, + .name = "me-2600i", .device_id = ME2600_DEVICE_ID, /* Analog Output */ .ao_channel_nbr = 4, @@ -208,8 +205,7 @@ static const struct me_board me_boards[] = { .dio_channel_nbr = 32, }, { - /* -- ME-2000i -- */ - .name = ME_DRIVER_NAME, + .name = "me-2000i", .device_id = ME2000_DEVICE_ID, /* Analog Output */ .ao_channel_nbr = 0, @@ -617,44 +613,24 @@ static int me_reset(struct comedi_device *dev) return 0; } -static struct pci_dev *me_find_pci_dev(struct comedi_device *dev, - struct comedi_devconfig *it) +static const void *me_find_boardinfo(struct comedi_device *dev, + struct pci_dev *pcidev) { const struct me_board *board; - struct pci_dev *pcidev = NULL; - int bus = it->options[0]; - int slot = it->options[1]; int i; - for_each_pci_dev(pcidev) { - if (bus || slot) { - if (pcidev->bus->number != bus || - PCI_SLOT(pcidev->devfn) != slot) - continue; - } - if (pcidev->vendor != PCI_VENDOR_ID_MEILHAUS) - continue; - - for (i = 0; i < ARRAY_SIZE(me_boards); i++) { - board = &me_boards[i]; - if (board->device_id != pcidev->device) - continue; - - dev->board_ptr = board; - return pcidev; - } + for (i = 0; i < ARRAY_SIZE(me_boards); i++) { + board = &me_boards[i]; + if (board->device_id == pcidev->device) + return board; } - dev_err(dev->class_dev, - "No supported board found! (req. bus %d, slot %d)\n", - bus, slot); return NULL; } -static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it) +static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) { - struct pci_dev *pci_device; + const struct me_board *board; struct comedi_subdevice *s; - struct me_board *board; resource_size_t plx_regbase_tmp; unsigned long plx_regbase_size_tmp; resource_size_t me_regbase_tmp; @@ -664,29 +640,28 @@ static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it) resource_size_t regbase_tmp; int result, error; + comedi_set_hw_dev(dev, &pcidev->dev); + + board = me_find_boardinfo(dev, pcidev); + if (!board) + return -ENODEV; + dev->board_ptr = board; + dev->board_name = board->name; + /* Allocate private memory */ if (alloc_private(dev, sizeof(struct me_private_data)) < 0) return -ENOMEM; - pci_device = me_find_pci_dev(dev, it); - if (!pci_device) - return -EIO; - comedi_set_hw_dev(dev, &pci_device->dev); - board = (struct me_board *)dev->board_ptr; - /* Enable PCI device and request PCI regions */ - if (comedi_pci_enable(pci_device, ME_DRIVER_NAME) < 0) { + if (comedi_pci_enable(pcidev, dev->board_name) < 0) { printk(KERN_ERR "comedi%d: Failed to enable PCI device and " "request regions\n", dev->minor); return -EIO; } - /* Set data in device structure */ - dev->board_name = board->name; - /* Read PLX register base address [PCI_BASE_ADDRESS #0]. */ - plx_regbase_tmp = pci_resource_start(pci_device, 0); - plx_regbase_size_tmp = pci_resource_len(pci_device, 0); + plx_regbase_tmp = pci_resource_start(pcidev, 0); + plx_regbase_size_tmp = pci_resource_len(pcidev, 0); dev_private->plx_regbase = ioremap(plx_regbase_tmp, plx_regbase_size_tmp); dev_private->plx_regbase_size = plx_regbase_size_tmp; @@ -697,8 +672,8 @@ static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* Read Swap base address [PCI_BASE_ADDRESS #5]. */ - swap_regbase_tmp = pci_resource_start(pci_device, 5); - swap_regbase_size_tmp = pci_resource_len(pci_device, 5); + swap_regbase_tmp = pci_resource_start(pcidev, 5); + swap_regbase_size_tmp = pci_resource_len(pcidev, 5); if (!swap_regbase_tmp) printk(KERN_ERR "comedi%d: Swap not present\n", dev->minor); @@ -712,20 +687,20 @@ static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it) plx_regbase_tmp = swap_regbase_tmp; swap_regbase_tmp = regbase_tmp; - result = pci_write_config_dword(pci_device, + result = pci_write_config_dword(pcidev, PCI_BASE_ADDRESS_0, plx_regbase_tmp); if (result != PCIBIOS_SUCCESSFUL) return -EIO; - result = pci_write_config_dword(pci_device, + result = pci_write_config_dword(pcidev, PCI_BASE_ADDRESS_5, swap_regbase_tmp); if (result != PCIBIOS_SUCCESSFUL) return -EIO; } else { plx_regbase_tmp -= 0x80; - result = pci_write_config_dword(pci_device, + result = pci_write_config_dword(pcidev, PCI_BASE_ADDRESS_0, plx_regbase_tmp); if (result != PCIBIOS_SUCCESSFUL) @@ -736,8 +711,8 @@ static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* Read Meilhaus register base address [PCI_BASE_ADDRESS #2]. */ - me_regbase_tmp = pci_resource_start(pci_device, 2); - me_regbase_size_tmp = pci_resource_len(pci_device, 2); + me_regbase_tmp = pci_resource_start(pcidev, 2); + me_regbase_size_tmp = pci_resource_len(pcidev, 2); dev_private->me_regbase_size = me_regbase_size_tmp; dev_private->me_regbase = ioremap(me_regbase_tmp, me_regbase_size_tmp); if (!dev_private->me_regbase) { @@ -791,8 +766,9 @@ static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->insn_config = me_dio_insn_config; s->io_bits = 0; - printk(KERN_INFO "comedi%d: " ME_DRIVER_NAME " attached.\n", - dev->minor); + dev_info(dev->class_dev, "%s: %s attached\n", + dev->driver->driver_name, dev->board_name); + return 0; } @@ -818,7 +794,7 @@ static void me_detach(struct comedi_device *dev) static struct comedi_driver me_daq_driver = { .driver_name = "me_daq", .module = THIS_MODULE, - .attach = me_attach, + .attach_pci = me_attach_pci, .detach = me_detach, }; -- cgit v0.10.2 From 1f5cc359158772304a92ee9c5682ca83416d2ba8 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 19 Sep 2012 17:26:53 -0700 Subject: staging: comedi: kcomedilib: fix a __user space access issue The 'data' field in struct comedi_insn is an unsigned int __user *. The comedi core copies this data to kernel space before passing it on to a drivers insn_bits/insn_config method. kcomedilib provides an interface for external kernel modules to use the comedi drivers. This interface creates a comedi_insn that is then passed to the comedi drivers insn_bits/insn_config method. Unfortunately, kcomedilib is using the comedi_insn 'data' field directly which results in some sparse warnings: warning: incorrect type in argument 4 (different address spaces) expected unsigned int * got unsigned int [noderef] *data warning: incorrect type in assignment (different address spaces) expected unsigned int [noderef] *[addressable] [assigned] data got unsigned int * Fix this by passing the kernel data directly, as a separate parameter, instead of trying to put in into the comedi_insn 'data' field. This is how the comedi core handles the data from user space. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c index f96416d..3f20ea5 100644 --- a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c +++ b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c @@ -80,7 +80,9 @@ int comedi_close(struct comedi_device *d) } EXPORT_SYMBOL(comedi_close); -static int comedi_do_insn(struct comedi_device *dev, struct comedi_insn *insn) +static int comedi_do_insn(struct comedi_device *dev, + struct comedi_insn *insn, + unsigned int *data) { struct comedi_subdevice *s; int ret = 0; @@ -115,11 +117,11 @@ static int comedi_do_insn(struct comedi_device *dev, struct comedi_insn *insn) switch (insn->insn) { case INSN_BITS: - ret = s->insn_bits(dev, s, insn, insn->data); + ret = s->insn_bits(dev, s, insn, data); break; case INSN_CONFIG: /* XXX should check instruction length */ - ret = s->insn_config(dev, s, insn, insn->data); + ret = s->insn_config(dev, s, insn, data); break; default: ret = -EINVAL; @@ -140,11 +142,10 @@ int comedi_dio_config(struct comedi_device *dev, unsigned int subdev, memset(&insn, 0, sizeof(insn)); insn.insn = INSN_CONFIG; insn.n = 1; - insn.data = &io; insn.subdev = subdev; insn.chanspec = CR_PACK(chan, 0, 0); - return comedi_do_insn(dev, &insn); + return comedi_do_insn(dev, &insn, &io); } EXPORT_SYMBOL(comedi_dio_config); @@ -158,13 +159,12 @@ int comedi_dio_bitfield(struct comedi_device *dev, unsigned int subdev, memset(&insn, 0, sizeof(insn)); insn.insn = INSN_BITS; insn.n = 2; - insn.data = data; insn.subdev = subdev; data[0] = mask; data[1] = *bits; - ret = comedi_do_insn(dev, &insn); + ret = comedi_do_insn(dev, &insn, data); *bits = data[1]; -- cgit v0.10.2 From 5743aaac2938eb841e14879b0f73afb7fca6f0ad Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 19 Sep 2012 17:06:47 -0700 Subject: staging: comedi: 8253: mmio address is a void __iomem * The inline functions for accessing a memory mapped 8254 device are using a void * for the 'base_address' of the device. Memory mapped io using the read/write functions should be using a void __iomem * for the address. Fixing these exposed a couple other void * / void __iomem * issues in the ni_labpc driver. This fixes a number of sparse warnings like: warning: incorrect type in argument 2 (different address spaces) expected void volatile [noderef] *addr got void * warning: incorrect type in argument 1 (different address spaces) expected void const volatile [noderef] *addr got void * Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/8253.h b/drivers/staging/comedi/drivers/8253.h index 3eb45d4..429e0d6 100644 --- a/drivers/staging/comedi/drivers/8253.h +++ b/drivers/staging/comedi/drivers/8253.h @@ -262,8 +262,10 @@ static inline int i8254_load(unsigned long base_address, unsigned int regshift, return 0; } -static inline int i8254_mm_load(void *base_address, unsigned int regshift, - unsigned int counter_number, unsigned int count, +static inline int i8254_mm_load(void __iomem *base_address, + unsigned int regshift, + unsigned int counter_number, + unsigned int count, unsigned int mode) { unsigned int byte; @@ -311,7 +313,8 @@ static inline int i8254_read(unsigned long base_address, unsigned int regshift, return ret; } -static inline int i8254_mm_read(void *base_address, unsigned int regshift, +static inline int i8254_mm_read(void __iomem *base_address, + unsigned int regshift, unsigned int counter_number) { unsigned int byte; @@ -348,7 +351,7 @@ static inline void i8254_write(unsigned long base_address, outb(byte, base_address + (counter_number << regshift)); } -static inline void i8254_mm_write(void *base_address, +static inline void i8254_mm_write(void __iomem *base_address, unsigned int regshift, unsigned int counter_number, unsigned int count) @@ -390,7 +393,7 @@ static inline int i8254_set_mode(unsigned long base_address, return 0; } -static inline int i8254_mm_set_mode(void *base_address, +static inline int i8254_mm_set_mode(void __iomem *base_address, unsigned int regshift, unsigned int counter_number, unsigned int mode) @@ -419,7 +422,7 @@ static inline int i8254_status(unsigned long base_address, return inb(base_address + (counter_number << regshift)); } -static inline int i8254_mm_status(void *base_address, +static inline int i8254_mm_status(void __iomem *base_address, unsigned int regshift, unsigned int counter_number) { diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index 295ddbb..2d060b5 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -409,12 +409,12 @@ static inline void labpc_outb(unsigned int byte, unsigned long address) static inline unsigned int labpc_readb(unsigned long address) { - return readb((void *)address); + return readb((void __iomem *)address); } static inline void labpc_writeb(unsigned int byte, unsigned long address) { - writeb(byte, (void *)address); + writeb(byte, (void __iomem *)address); } static const struct labpc_board_struct labpc_boards[] = { @@ -494,8 +494,8 @@ static inline int labpc_counter_load(struct comedi_device *dev, unsigned int count, unsigned int mode) { if (thisboard->memory_mapped_io) - return i8254_mm_load((void *)base_address, 0, counter_number, - count, mode); + return i8254_mm_load((void __iomem *)base_address, 0, + counter_number, count, mode); else return i8254_load(base_address, 0, counter_number, count, mode); } @@ -1896,10 +1896,10 @@ static int labpc_dio_mem_callback(int dir, int port, int data, unsigned long iobase) { if (dir) { - writeb(data, (void *)(iobase + port)); + writeb(data, (void __iomem *)(iobase + port)); return 0; } else { - return readb((void *)(iobase + port)); + return readb((void __iomem *)(iobase + port)); } } -- cgit v0.10.2 From 6f73fbcec27be8b074555e18d9f50c3013e4d802 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 19 Sep 2012 19:37:37 +0100 Subject: staging: comedi: ni_labpc: pass ai scan mode through various functions Pass the `enum scan_mode` value calculated by `labpc_ai_scan_mode()` as a parameter to various other functions so they don't have to call it themselves. Amongst others, the affected functions include `labpc_adc_timing()`, `labpc_ai_convert_period()` and `labpc_ai_scan_period()`. `labpc_adc_timing()` calls `labpc_ai_convert_period()` and `labpc_ai_scan_period()` in several places, but the returned values are the same each time, so change it to just call those functions once and re-use the return values. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index 2d060b5..200099e 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -206,6 +206,13 @@ NI manuals: #define INIT_A1_BITS 0x70 #define COUNTER_B_BASE_REG 0x18 +enum scan_mode { + MODE_SINGLE_CHAN, + MODE_SINGLE_CHAN_INTERVAL, + MODE_MULT_CHAN_UP, + MODE_MULT_CHAN_DOWN, +}; + static int labpc_cancel(struct comedi_device *dev, struct comedi_subdevice *s); static irqreturn_t labpc_interrupt(int irq, void *d); static int labpc_drain_fifo(struct comedi_device *dev); @@ -236,7 +243,8 @@ static int labpc_eeprom_write_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); -static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd); +static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd, + enum scan_mode scan_mode); #ifdef CONFIG_ISA_DMA_API static unsigned int labpc_suggest_transfer_size(struct comedi_cmd cmd); #endif @@ -254,13 +262,6 @@ static int labpc_eeprom_write(struct comedi_device *dev, static void write_caldac(struct comedi_device *dev, unsigned int channel, unsigned int value); -enum scan_mode { - MODE_SINGLE_CHAN, - MODE_SINGLE_CHAN_INTERVAL, - MODE_MULT_CHAN_UP, - MODE_MULT_CHAN_DOWN, -}; - /* analog input ranges */ #define NUM_LABPC_PLUS_AI_RANGES 16 /* indicates unipolar ranges */ @@ -839,15 +840,14 @@ static enum scan_mode labpc_ai_scan_mode(const struct comedi_cmd *cmd) } static int labpc_ai_chanlist_invalid(const struct comedi_device *dev, - const struct comedi_cmd *cmd) + const struct comedi_cmd *cmd, + enum scan_mode mode) { - int mode, channel, range, aref, i; + int channel, range, aref, i; if (cmd->chanlist == NULL) return 0; - mode = labpc_ai_scan_mode(cmd); - if (mode == MODE_SINGLE_CHAN) return 0; @@ -911,9 +911,10 @@ static int labpc_ai_chanlist_invalid(const struct comedi_device *dev, return 0; } -static int labpc_use_continuous_mode(const struct comedi_cmd *cmd) +static int labpc_use_continuous_mode(const struct comedi_cmd *cmd, + enum scan_mode mode) { - if (labpc_ai_scan_mode(cmd) == MODE_SINGLE_CHAN) + if (mode == MODE_SINGLE_CHAN) return 1; if (cmd->scan_begin_src == TRIG_FOLLOW) @@ -922,24 +923,25 @@ static int labpc_use_continuous_mode(const struct comedi_cmd *cmd) return 0; } -static unsigned int labpc_ai_convert_period(const struct comedi_cmd *cmd) +static unsigned int labpc_ai_convert_period(const struct comedi_cmd *cmd, + enum scan_mode mode) { if (cmd->convert_src != TRIG_TIMER) return 0; - if (labpc_ai_scan_mode(cmd) == MODE_SINGLE_CHAN && - cmd->scan_begin_src == TRIG_TIMER) + if (mode == MODE_SINGLE_CHAN && cmd->scan_begin_src == TRIG_TIMER) return cmd->scan_begin_arg; return cmd->convert_arg; } -static void labpc_set_ai_convert_period(struct comedi_cmd *cmd, unsigned int ns) +static void labpc_set_ai_convert_period(struct comedi_cmd *cmd, + enum scan_mode mode, unsigned int ns) { if (cmd->convert_src != TRIG_TIMER) return; - if (labpc_ai_scan_mode(cmd) == MODE_SINGLE_CHAN && + if (mode == MODE_SINGLE_CHAN && cmd->scan_begin_src == TRIG_TIMER) { cmd->scan_begin_arg = ns; if (cmd->convert_arg > cmd->scan_begin_arg) @@ -948,25 +950,25 @@ static void labpc_set_ai_convert_period(struct comedi_cmd *cmd, unsigned int ns) cmd->convert_arg = ns; } -static unsigned int labpc_ai_scan_period(const struct comedi_cmd *cmd) +static unsigned int labpc_ai_scan_period(const struct comedi_cmd *cmd, + enum scan_mode mode) { if (cmd->scan_begin_src != TRIG_TIMER) return 0; - if (labpc_ai_scan_mode(cmd) == MODE_SINGLE_CHAN && - cmd->convert_src == TRIG_TIMER) + if (mode == MODE_SINGLE_CHAN && cmd->convert_src == TRIG_TIMER) return 0; return cmd->scan_begin_arg; } -static void labpc_set_ai_scan_period(struct comedi_cmd *cmd, unsigned int ns) +static void labpc_set_ai_scan_period(struct comedi_cmd *cmd, + enum scan_mode mode, unsigned int ns) { if (cmd->scan_begin_src != TRIG_TIMER) return; - if (labpc_ai_scan_mode(cmd) == MODE_SINGLE_CHAN && - cmd->convert_src == TRIG_TIMER) + if (mode == MODE_SINGLE_CHAN && cmd->convert_src == TRIG_TIMER) return; cmd->scan_begin_arg = ns; @@ -978,6 +980,7 @@ static int labpc_ai_cmdtest(struct comedi_device *dev, int err = 0; int tmp, tmp2; int stop_mask; + enum scan_mode mode; /* step 1: make sure trigger sources are trivially valid */ @@ -1099,14 +1102,15 @@ static int labpc_ai_cmdtest(struct comedi_device *dev, tmp = cmd->convert_arg; tmp2 = cmd->scan_begin_arg; - labpc_adc_timing(dev, cmd); + mode = labpc_ai_scan_mode(cmd); + labpc_adc_timing(dev, cmd, mode); if (tmp != cmd->convert_arg || tmp2 != cmd->scan_begin_arg) err++; if (err) return 4; - if (labpc_ai_chanlist_invalid(dev, cmd)) + if (labpc_ai_chanlist_invalid(dev, cmd, mode)) return 5; return 0; @@ -1122,6 +1126,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; enum transfer_type xfer; + enum scan_mode mode; unsigned long flags; if (!dev->irq) { @@ -1187,6 +1192,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) } else xfer = fifo_not_empty_transfer; devpriv->current_transfer = xfer; + mode = labpc_ai_scan_mode(cmd); /* setup command6 register for 1200 boards */ if (thisboard->register_layout == labpc_1200_layout) { @@ -1211,7 +1217,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) else devpriv->command6_bits &= ~A1_INTR_EN_BIT; /* are we scanning up or down through channels? */ - if (labpc_ai_scan_mode(cmd) == MODE_MULT_CHAN_UP) + if (mode == MODE_MULT_CHAN_UP) devpriv->command6_bits |= ADC_SCAN_UP_BIT; else devpriv->command6_bits &= ~ADC_SCAN_UP_BIT; @@ -1222,19 +1228,18 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* setup channel list, etc (command1 register) */ devpriv->command1_bits = 0; - if (labpc_ai_scan_mode(cmd) == MODE_MULT_CHAN_UP) + if (mode == MODE_MULT_CHAN_UP) channel = CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]); else channel = CR_CHAN(cmd->chanlist[0]); /* munge channel bits for differential / scan disabled mode */ - if (labpc_ai_scan_mode(cmd) != MODE_SINGLE_CHAN && aref == AREF_DIFF) + if (mode != MODE_SINGLE_CHAN && aref == AREF_DIFF) channel *= 2; devpriv->command1_bits |= ADC_CHAN_BITS(channel); devpriv->command1_bits |= thisboard->ai_range_code[range]; devpriv->write_byte(devpriv->command1_bits, dev->iobase + COMMAND1_REG); /* manual says to set scan enable bit on second pass */ - if (labpc_ai_scan_mode(cmd) == MODE_MULT_CHAN_UP || - labpc_ai_scan_mode(cmd) == MODE_MULT_CHAN_DOWN) { + if (mode == MODE_MULT_CHAN_UP || mode == MODE_MULT_CHAN_DOWN) { devpriv->command1_bits |= ADC_SCAN_EN_BIT; /* need a brief delay before enabling scan, or scan * list will get screwed when you switch @@ -1249,7 +1254,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->command4_bits |= EXT_CONVERT_DISABLE_BIT; /* XXX should discard first scan when using interval scanning * since manual says it is not synced with scan clock */ - if (labpc_use_continuous_mode(cmd) == 0) { + if (labpc_use_continuous_mode(cmd, mode) == 0) { devpriv->command4_bits |= INTERVAL_SCAN_EN_BIT; if (cmd->scan_begin_src == TRIG_EXT) devpriv->command4_bits |= EXT_SCAN_EN_BIT; @@ -1267,7 +1272,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) if (cmd->convert_src == TRIG_TIMER || cmd->scan_begin_src == TRIG_TIMER) { /* set up pacing */ - labpc_adc_timing(dev, cmd); + labpc_adc_timing(dev, cmd, mode); /* load counter b0 in mode 3 */ ret = labpc_counter_load(dev, dev->iobase + COUNTER_B_BASE_REG, 0, devpriv->divisor_b0, 3); @@ -1277,7 +1282,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) } } /* set up conversion pacing */ - if (labpc_ai_convert_period(cmd)) { + if (labpc_ai_convert_period(cmd, mode)) { /* load counter a0 in mode 2 */ ret = labpc_counter_load(dev, dev->iobase + COUNTER_A_BASE_REG, 0, devpriv->divisor_a0, 2); @@ -1290,7 +1295,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) dev->iobase + COUNTER_A_CONTROL_REG); /* set up scan pacing */ - if (labpc_ai_scan_period(cmd)) { + if (labpc_ai_scan_period(cmd, mode)) { /* load counter b1 in mode 2 */ ret = labpc_counter_load(dev, dev->iobase + COUNTER_B_BASE_REG, 1, devpriv->divisor_b1, 2); @@ -1791,24 +1796,29 @@ static unsigned int labpc_suggest_transfer_size(struct comedi_cmd cmd) #endif /* figures out what counter values to use based on command */ -static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd) +static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd, + enum scan_mode mode) { /* max value for 16 bit counter in mode 2 */ const int max_counter_value = 0x10000; /* min value for 16 bit counter in mode 2 */ const int min_counter_value = 2; unsigned int base_period; + unsigned int scan_period; + unsigned int convert_period; /* * if both convert and scan triggers are TRIG_TIMER, then they * both rely on counter b0 */ - if (labpc_ai_convert_period(cmd) && labpc_ai_scan_period(cmd)) { + convert_period = labpc_ai_convert_period(cmd, mode); + scan_period = labpc_ai_scan_period(cmd, mode); + if (convert_period && scan_period) { /* * pick the lowest b0 divisor value we can (for maximum input * clock speed on convert and scan counters) */ - devpriv->divisor_b0 = (labpc_ai_scan_period(cmd) - 1) / + devpriv->divisor_b0 = (scan_period - 1) / (LABPC_TIMER_BASE * max_counter_value) + 1; if (devpriv->divisor_b0 < min_counter_value) devpriv->divisor_b0 = min_counter_value; @@ -1822,25 +1832,19 @@ static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd) default: case TRIG_ROUND_NEAREST: devpriv->divisor_a0 = - (labpc_ai_convert_period(cmd) + - (base_period / 2)) / base_period; + (convert_period + (base_period / 2)) / base_period; devpriv->divisor_b1 = - (labpc_ai_scan_period(cmd) + - (base_period / 2)) / base_period; + (scan_period + (base_period / 2)) / base_period; break; case TRIG_ROUND_UP: devpriv->divisor_a0 = - (labpc_ai_convert_period(cmd) + (base_period - - 1)) / base_period; + (convert_period + (base_period - 1)) / base_period; devpriv->divisor_b1 = - (labpc_ai_scan_period(cmd) + (base_period - - 1)) / base_period; + (scan_period + (base_period - 1)) / base_period; break; case TRIG_ROUND_DOWN: - devpriv->divisor_a0 = - labpc_ai_convert_period(cmd) / base_period; - devpriv->divisor_b1 = - labpc_ai_scan_period(cmd) / base_period; + devpriv->divisor_a0 = convert_period / base_period; + devpriv->divisor_b1 = scan_period / base_period; break; } /* make sure a0 and b1 values are acceptable */ @@ -1853,18 +1857,15 @@ static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd) if (devpriv->divisor_b1 > max_counter_value) devpriv->divisor_b1 = max_counter_value; /* write corrected timings to command */ - labpc_set_ai_convert_period(cmd, + labpc_set_ai_convert_period(cmd, mode, base_period * devpriv->divisor_a0); - labpc_set_ai_scan_period(cmd, + labpc_set_ai_scan_period(cmd, mode, base_period * devpriv->divisor_b1); /* * if only one TRIG_TIMER is used, we can employ the generic * cascaded timing functions */ - } else if (labpc_ai_scan_period(cmd)) { - unsigned int scan_period; - - scan_period = labpc_ai_scan_period(cmd); + } else if (scan_period) { /* * calculate cascaded counter values * that give desired scan timing @@ -1874,11 +1875,8 @@ static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd) &(devpriv->divisor_b0), &scan_period, cmd->flags & TRIG_ROUND_MASK); - labpc_set_ai_scan_period(cmd, scan_period); - } else if (labpc_ai_convert_period(cmd)) { - unsigned int convert_period; - - convert_period = labpc_ai_convert_period(cmd); + labpc_set_ai_scan_period(cmd, mode, scan_period); + } else if (convert_period) { /* * calculate cascaded counter values * that give desired conversion timing @@ -1888,7 +1886,7 @@ static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd) &(devpriv->divisor_b0), &convert_period, cmd->flags & TRIG_ROUND_MASK); - labpc_set_ai_convert_period(cmd, convert_period); + labpc_set_ai_convert_period(cmd, mode, convert_period); } } -- cgit v0.10.2 From c8cad4c89ee3b15935c532210ae6ebb5c0a2734d Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 19 Sep 2012 19:37:39 +0100 Subject: staging: comedi: fix memory leak for saved channel list When `do_cmd_ioctl()` allocates memory for the kernel copy of a channel list, it frees any previously allocated channel list in `async->cmd.chanlist` and replaces it with the new one. However, if the device is ever removed (or "detached") the cleanup code in `cleanup_device()` in "drivers.c" does not free this memory so it is lost. A sensible place to free the kernel copy of the channel list is in `do_become_nonbusy()` as at that point the comedi asynchronous command associated with the channel list is no longer valid. Free the channel list in `do_become_nonbusy()` instead of `do_cmd_ioctl()` and clear the pointer to prevent it being freed more than once. Note that `cleanup_device()` could be called at an inappropriate time while the comedi device is open, but that's a separate bug not related to this this patch. Cc: stable@vger.kernel.org Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index f496f4d..c2a32cf 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -1195,7 +1195,6 @@ static int do_cmd_ioctl(struct comedi_device *dev, goto cleanup; } - kfree(async->cmd.chanlist); async->cmd = cmd; async->cmd.data = NULL; /* load channel/gain list */ @@ -2033,6 +2032,8 @@ static void do_become_nonbusy(struct comedi_device *dev, if (async) { comedi_reset_async_buf(async); async->inttrig = NULL; + kfree(async->cmd.chanlist); + async->cmd.chanlist = NULL; } else { dev_err(dev->class_dev, "BUG: (?) do_become_nonbusy called with async=NULL\n"); -- cgit v0.10.2 From 44b255f7b13bacb076e2789352e4a8afe19b922e Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 19 Sep 2012 19:37:40 +0100 Subject: staging: comedi: das16: pass struct comedi_cmd by reference Change `das16_suggest_transfer_size()` to take a pointer to the `struct comedi_cmd` instead of passing it by value. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c index 2a38915..744376a 100644 --- a/drivers/staging/comedi/drivers/das16.c +++ b/drivers/staging/comedi/drivers/das16.c @@ -558,7 +558,7 @@ static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, /* utility function that suggests a dma transfer size in bytes */ static unsigned int das16_suggest_transfer_size(struct comedi_device *dev, - struct comedi_cmd cmd) + const struct comedi_cmd *cmd) { unsigned int size; unsigned int freq; @@ -571,16 +571,16 @@ static unsigned int das16_suggest_transfer_size(struct comedi_device *dev, /* otherwise, we are relying on dma terminal count interrupt, * so pick a reasonable size */ - if (cmd.convert_src == TRIG_TIMER) - freq = 1000000000 / cmd.convert_arg; - else if (cmd.scan_begin_src == TRIG_TIMER) - freq = (1000000000 / cmd.scan_begin_arg) * cmd.chanlist_len; + if (cmd->convert_src == TRIG_TIMER) + freq = 1000000000 / cmd->convert_arg; + else if (cmd->scan_begin_src == TRIG_TIMER) + freq = (1000000000 / cmd->scan_begin_arg) * cmd->chanlist_len; /* return some default value */ else freq = 0xffffffff; - if (cmd.flags & TRIG_WAKE_EOS) { - size = sample_size * cmd.chanlist_len; + if (cmd->flags & TRIG_WAKE_EOS) { + size = sample_size * cmd->chanlist_len; } else { /* make buffer fill in no more than 1/3 second */ size = (freq / 3) * sample_size; @@ -592,7 +592,7 @@ static unsigned int das16_suggest_transfer_size(struct comedi_device *dev, else if (size < sample_size) size = sample_size; - if (cmd.stop_src == TRIG_COUNT && size > devpriv->adc_byte_count) + if (cmd->stop_src == TRIG_COUNT && size > devpriv->adc_byte_count) size = devpriv->adc_byte_count; return size; @@ -685,7 +685,7 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s) set_dma_addr(devpriv->dma_chan, devpriv->dma_buffer_addr[devpriv->current_buffer]); /* set appropriate size of transfer */ - devpriv->dma_transfer_size = das16_suggest_transfer_size(dev, *cmd); + devpriv->dma_transfer_size = das16_suggest_transfer_size(dev, cmd); set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size); enable_dma(devpriv->dma_chan); release_dma_lock(flags); -- cgit v0.10.2 From eb4332eff5aa071b19f89f45ae7f6393af59ba62 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 19 Sep 2012 19:37:41 +0100 Subject: staging: comedi: das1800: don't pass struct comedi_cmd by value Various functions in das1800.c take a `struct comedi_cmd` parameter by value. Change them to pass the parameter by reference instead. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index 5aca8fb..711d4e2 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -958,14 +958,14 @@ static int das1800_ai_do_cmdtest(struct comedi_device *dev, } /* returns appropriate bits for control register a, depending on command */ -static int control_a_bits(struct comedi_cmd cmd) +static int control_a_bits(const struct comedi_cmd *cmd) { int control_a; control_a = FFEN; /* enable fifo */ - if (cmd.stop_src == TRIG_EXT) + if (cmd->stop_src == TRIG_EXT) control_a |= ATEN; - switch (cmd.start_src) { + switch (cmd->start_src) { case TRIG_EXT: control_a |= TGEN | CGSL; break; @@ -980,7 +980,7 @@ static int control_a_bits(struct comedi_cmd cmd) } /* returns appropriate bits for control register c, depending on command */ -static int control_c_bits(struct comedi_cmd cmd) +static int control_c_bits(const struct comedi_cmd *cmd) { int control_c; int aref; @@ -988,18 +988,18 @@ static int control_c_bits(struct comedi_cmd cmd) /* set clock source to internal or external, select analog reference, * select unipolar / bipolar */ - aref = CR_AREF(cmd.chanlist[0]); + aref = CR_AREF(cmd->chanlist[0]); control_c = UQEN; /* enable upper qram addresses */ if (aref != AREF_DIFF) control_c |= SD; if (aref == AREF_COMMON) control_c |= CMEN; /* if a unipolar range was selected */ - if (CR_RANGE(cmd.chanlist[0]) & UNIPOLAR) + if (CR_RANGE(cmd->chanlist[0]) & UNIPOLAR) control_c |= UB; - switch (cmd.scan_begin_src) { + switch (cmd->scan_begin_src) { case TRIG_FOLLOW: /* not in burst mode */ - switch (cmd.convert_src) { + switch (cmd->convert_src) { case TRIG_TIMER: /* trig on cascaded counters */ control_c |= IPCLK; @@ -1047,29 +1047,33 @@ static int das1800_set_frequency(struct comedi_device *dev) } /* sets up counters */ -static int setup_counters(struct comedi_device *dev, struct comedi_cmd cmd) +static int setup_counters(struct comedi_device *dev, + const struct comedi_cmd *cmd) { + unsigned int period; + /* setup cascaded counters for conversion/scan frequency */ - switch (cmd.scan_begin_src) { + switch (cmd->scan_begin_src) { case TRIG_FOLLOW: /* not in burst mode */ - if (cmd.convert_src == TRIG_TIMER) { + if (cmd->convert_src == TRIG_TIMER) { /* set conversion frequency */ + period = cmd->convert_arg; i8253_cascade_ns_to_timer_2div(TIMER_BASE, - &(devpriv->divisor1), - &(devpriv->divisor2), - &(cmd.convert_arg), - cmd. - flags & TRIG_ROUND_MASK); + &devpriv->divisor1, + &devpriv->divisor2, + &period, + cmd->flags & + TRIG_ROUND_MASK); if (das1800_set_frequency(dev) < 0) return -1; } break; case TRIG_TIMER: /* in burst mode */ /* set scan frequency */ - i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1), - &(devpriv->divisor2), - &(cmd.scan_begin_arg), - cmd.flags & TRIG_ROUND_MASK); + period = cmd->scan_begin_arg; + i8253_cascade_ns_to_timer_2div(TIMER_BASE, &devpriv->divisor1, + &devpriv->divisor2, &period, + cmd->flags & TRIG_ROUND_MASK); if (das1800_set_frequency(dev) < 0) return -1; break; @@ -1078,7 +1082,7 @@ static int setup_counters(struct comedi_device *dev, struct comedi_cmd cmd) } /* setup counter 0 for 'about triggering' */ - if (cmd.stop_src == TRIG_EXT) { + if (cmd->stop_src == TRIG_EXT) { /* load counter 0 in mode 0 */ i8254_load(dev->iobase + DAS1800_COUNTER, 0, 0, 1, 0); } @@ -1087,7 +1091,7 @@ static int setup_counters(struct comedi_device *dev, struct comedi_cmd cmd) } /* utility function that suggests a dma transfer size based on the conversion period 'ns' */ -static unsigned int suggest_transfer_size(struct comedi_cmd *cmd) +static unsigned int suggest_transfer_size(const struct comedi_cmd *cmd) { unsigned int size = DMA_BUF_SIZE; static const int sample_size = 2; /* size in bytes of one sample from board */ @@ -1125,7 +1129,7 @@ static unsigned int suggest_transfer_size(struct comedi_cmd *cmd) } /* sets up dma */ -static void setup_dma(struct comedi_device *dev, struct comedi_cmd cmd) +static void setup_dma(struct comedi_device *dev, const struct comedi_cmd *cmd) { unsigned long lock_flags; const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; @@ -1134,7 +1138,7 @@ static void setup_dma(struct comedi_device *dev, struct comedi_cmd cmd) return; /* determine a reasonable dma transfer size */ - devpriv->dma_transfer_size = suggest_transfer_size(&cmd); + devpriv->dma_transfer_size = suggest_transfer_size(cmd); lock_flags = claim_dma_lock(); disable_dma(devpriv->dma0); /* clear flip-flop to make sure 2-byte registers for @@ -1163,14 +1167,15 @@ static void setup_dma(struct comedi_device *dev, struct comedi_cmd cmd) } /* programs channel/gain list into card */ -static void program_chanlist(struct comedi_device *dev, struct comedi_cmd cmd) +static void program_chanlist(struct comedi_device *dev, + const struct comedi_cmd *cmd) { int i, n, chan_range; unsigned long irq_flags; const int range_mask = 0x3; /* masks unipolar/bipolar bit off range */ const int range_bitshift = 8; - n = cmd.chanlist_len; + n = cmd->chanlist_len; /* spinlock protects indirect addressing */ spin_lock_irqsave(&dev->spinlock, irq_flags); outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */ @@ -1178,9 +1183,9 @@ static void program_chanlist(struct comedi_device *dev, struct comedi_cmd cmd) /* make channel / gain list */ for (i = 0; i < n; i++) { chan_range = - CR_CHAN(cmd. - chanlist[i]) | ((CR_RANGE(cmd.chanlist[i]) & - range_mask) << range_bitshift); + CR_CHAN(cmd->chanlist[i]) | + ((CR_RANGE(cmd->chanlist[i]) & range_mask) << + range_bitshift); outw(chan_range, dev->iobase + DAS1800_QRAM); } outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */ @@ -1196,7 +1201,7 @@ static int das1800_ai_do_cmd(struct comedi_device *dev, int ret; int control_a, control_c; struct comedi_async *async = s->async; - struct comedi_cmd cmd = async->cmd; + const struct comedi_cmd *cmd = &async->cmd; if (!dev->irq) { comedi_error(dev, @@ -1206,12 +1211,12 @@ static int das1800_ai_do_cmd(struct comedi_device *dev, /* disable dma on TRIG_WAKE_EOS, or TRIG_RT * (because dma in handler is unsafe at hard real-time priority) */ - if (cmd.flags & (TRIG_WAKE_EOS | TRIG_RT)) + if (cmd->flags & (TRIG_WAKE_EOS | TRIG_RT)) devpriv->irq_dma_bits &= ~DMA_ENABLED; else devpriv->irq_dma_bits |= devpriv->dma_bits; /* interrupt on end of conversion for TRIG_WAKE_EOS */ - if (cmd.flags & TRIG_WAKE_EOS) { + if (cmd->flags & TRIG_WAKE_EOS) { /* interrupt fifo not empty */ devpriv->irq_dma_bits &= ~FIMD; } else { @@ -1219,8 +1224,8 @@ static int das1800_ai_do_cmd(struct comedi_device *dev, devpriv->irq_dma_bits |= FIMD; } /* determine how many conversions we need */ - if (cmd.stop_src == TRIG_COUNT) - devpriv->count = cmd.stop_arg * cmd.chanlist_len; + if (cmd->stop_src == TRIG_COUNT) + devpriv->count = cmd->stop_arg * cmd->chanlist_len; das1800_cancel(dev, s); @@ -1240,9 +1245,9 @@ static int das1800_ai_do_cmd(struct comedi_device *dev, /* set conversion rate and length for burst mode */ if (control_c & BMDE) { /* program conversion period with number of microseconds minus 1 */ - outb(cmd.convert_arg / 1000 - 1, + outb(cmd->convert_arg / 1000 - 1, dev->iobase + DAS1800_BURST_RATE); - outb(cmd.chanlist_len - 1, dev->iobase + DAS1800_BURST_LENGTH); + outb(cmd->chanlist_len - 1, dev->iobase + DAS1800_BURST_LENGTH); } outb(devpriv->irq_dma_bits, dev->iobase + DAS1800_CONTROL_B); /* enable irq/dma */ outb(control_a, dev->iobase + DAS1800_CONTROL_A); /* enable fifo and triggering */ -- cgit v0.10.2 From 62fea8c8f1bf5ca33ba55b3f421d9598a68297ee Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 19 Sep 2012 19:37:42 +0100 Subject: staging: comedi: ni_labpc: don't pass struct comedi_cmd by value `labpc_suggest_transfer_size()` has a parameter of type `struct comedi_cmd` passed by value. Change it to pass by pointer reference. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index 200099e..d534e63 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -246,7 +246,7 @@ static int labpc_eeprom_write_insn(struct comedi_device *dev, static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd, enum scan_mode scan_mode); #ifdef CONFIG_ISA_DMA_API -static unsigned int labpc_suggest_transfer_size(struct comedi_cmd cmd); +static unsigned int labpc_suggest_transfer_size(const struct comedi_cmd *cmd); #endif static int labpc_dio_mem_callback(int dir, int port, int data, unsigned long arg); @@ -1318,7 +1318,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) set_dma_addr(devpriv->dma_chan, virt_to_bus(devpriv->dma_buffer)); /* set appropriate size of transfer */ - devpriv->dma_transfer_size = labpc_suggest_transfer_size(*cmd); + devpriv->dma_transfer_size = labpc_suggest_transfer_size(cmd); if (cmd->stop_src == TRIG_COUNT && devpriv->count * sample_size < devpriv->dma_transfer_size) { devpriv->dma_transfer_size = @@ -1771,13 +1771,13 @@ static int labpc_eeprom_write_insn(struct comedi_device *dev, #ifdef CONFIG_ISA_DMA_API /* utility function that suggests a dma transfer size in bytes */ -static unsigned int labpc_suggest_transfer_size(struct comedi_cmd cmd) +static unsigned int labpc_suggest_transfer_size(const struct comedi_cmd *cmd) { unsigned int size; unsigned int freq; - if (cmd.convert_src == TRIG_TIMER) - freq = 1000000000 / cmd.convert_arg; + if (cmd->convert_src == TRIG_TIMER) + freq = 1000000000 / cmd->convert_arg; /* return some default value */ else freq = 0xffffffff; -- cgit v0.10.2 From f07b60b7c34b771431f1d00e783f29a3667ff5ee Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Thu, 20 Sep 2012 01:15:00 +0100 Subject: iio: hid-sensors: Prevent crash during hot-unplug When hid sensor hub is unplugged, there is a crash in iio_device_unregister_trigger_consumer. In a typical IIO driver when remove is called, it will unregister and free trigger and then it will call iio_device_free. The function iio_trigger_free() will free the allocated memory for trigger. If this trigger was assigned to iio_dev->trig, then it should be set to NULL. Othewise when iio_device_free() is called later, it finally calls iio_device_unregsister_trigger(), which checks for if (indio_dev->trig) iio_trigger_put(indio_dev->trig); If indio_dev->trig is not set to NULL, it calls iio_trigger_put on a bad pointer causing crash. This scenerio can happen in any driver, which is storing trigger pointer in iio_dev structure and following current procedure during remove. Signed-off-by: Srinivas Pandruvada Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c index 12277e8..d4b790d 100644 --- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c +++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c @@ -56,6 +56,7 @@ void hid_sensor_remove_trigger(struct iio_dev *indio_dev) { iio_trigger_unregister(indio_dev->trig); iio_trigger_free(indio_dev->trig); + indio_dev->trig = NULL; } EXPORT_SYMBOL(hid_sensor_remove_trigger); -- cgit v0.10.2 From 369d0e20138c774e4c0c07ca1572e412207bc3fc Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 19 Sep 2012 07:27:00 +0100 Subject: iio: dac/ad5755: signedness bug in ad5755_setup_pdata() We need "ret" to be signed for the error handling to work correctly. Signed-off-by: Dan Carpenter Acked-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/dac/ad5755.c b/drivers/iio/dac/ad5755.c index e6dbe5f..5db3506 100644 --- a/drivers/iio/dac/ad5755.c +++ b/drivers/iio/dac/ad5755.c @@ -451,9 +451,9 @@ static int __devinit ad5755_setup_pdata(struct iio_dev *indio_dev, const struct ad5755_platform_data *pdata) { struct ad5755_state *st = iio_priv(indio_dev); - unsigned int ret; unsigned int val; unsigned int i; + int ret; if (pdata->dc_dc_phase > AD5755_DC_DC_PHASE_90_DEGREE || pdata->dc_dc_freq > AD5755_DC_DC_FREQ_650kHZ || -- cgit v0.10.2 From 801c4b5ca373c4cfe78912616d68e1f7fd84110c Mon Sep 17 00:00:00 2001 From: "Kim, Milo" Date: Tue, 18 Sep 2012 05:55:00 +0100 Subject: iio: inkern: put the IIO device when it fails to allocate memory The reference count of the IIO device is increased if the IIO map has matched consumer name. After then, it tries to allocate the iio_channel which is used by the consumer. If it fails to allocate memory, the reference count should be decreased. This patch enables restoring the reference count of the IIO device. Signed-off-by: Milo(Woogyom) Kim Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index 25b0076..e38f414 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -132,7 +132,7 @@ struct iio_channel *iio_channel_get(const char *name, const char *channel_name) channel = kzalloc(sizeof(*channel), GFP_KERNEL); if (channel == NULL) - return ERR_PTR(-ENOMEM); + goto error_no_mem; channel->indio_dev = c->indio_dev; @@ -151,6 +151,9 @@ error_no_chan: iio_device_put(c->indio_dev); kfree(channel); return ERR_PTR(-EINVAL); +error_no_mem: + iio_device_put(c->indio_dev); + return ERR_PTR(-ENOMEM); } EXPORT_SYMBOL_GPL(iio_channel_get); -- cgit v0.10.2 From 3183bac16f537503eb3177773781d6d3059ad7b1 Mon Sep 17 00:00:00 2001 From: "Kim, Milo" Date: Tue, 18 Sep 2012 05:56:00 +0100 Subject: iio: inkern: clean up error return code When the IIO consumer tries to get specific IIO channel, few error cases can be happened. (a) Memory allocation failure (b) No matched ADC channel error (c) Invalid input arguments This patch enables cleaning up error handling in case of (a) and (b). In error handling code, (a): the reference count of the IIO device should be decreased. (b): the allocated memory should be freed with restoring the reference count. Therefore iio_deivce_put() is called in both cases. This can be handled in the last error statement. Additionally, integer variable is used for stating each error case explicitly. Then, the error returns as ERR_PTR() with this value. Signed-off-by: Milo(Woogyom) Kim Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index e38f414..f2b78d4 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -111,6 +111,7 @@ struct iio_channel *iio_channel_get(const char *name, const char *channel_name) { struct iio_map_internal *c_i = NULL, *c = NULL; struct iio_channel *channel; + int err; if (name == NULL && channel_name == NULL) return ERR_PTR(-ENODEV); @@ -131,8 +132,10 @@ struct iio_channel *iio_channel_get(const char *name, const char *channel_name) return ERR_PTR(-ENODEV); channel = kzalloc(sizeof(*channel), GFP_KERNEL); - if (channel == NULL) + if (channel == NULL) { + err = -ENOMEM; goto error_no_mem; + } channel->indio_dev = c->indio_dev; @@ -141,19 +144,19 @@ struct iio_channel *iio_channel_get(const char *name, const char *channel_name) iio_chan_spec_from_name(channel->indio_dev, c->map->adc_channel_label); - if (channel->channel == NULL) + if (channel->channel == NULL) { + err = -EINVAL; goto error_no_chan; + } } return channel; error_no_chan: - iio_device_put(c->indio_dev); kfree(channel); - return ERR_PTR(-EINVAL); error_no_mem: iio_device_put(c->indio_dev); - return ERR_PTR(-ENOMEM); + return ERR_PTR(err); } EXPORT_SYMBOL_GPL(iio_channel_get); -- cgit v0.10.2 From bea3e8a31f42269318378461ee2663b17957b165 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 22 Sep 2012 09:56:00 +0100 Subject: staging:iio:adis16200: Do not return a error in remove function In the Linux device driver model the remove callback is not allowed to fail and the device will be removed regardless of the return value of the remove callback. So if we abort in the remove function and do not free all resources we will create a resource leak. Also all kinds of undefined behaviour are expected to happen since the IIO device is still there while its parent is already gone. The error which the driver tries to handle in the remove function is non-critical, so we can just ignore it and continue to free all resources and remove the IIO device. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c index 1d58d0e..9571c03 100644 --- a/drivers/staging/iio/gyro/adis16260_core.c +++ b/drivers/staging/iio/gyro/adis16260_core.c @@ -702,22 +702,16 @@ error_ret: static int __devexit adis16260_remove(struct spi_device *spi) { - int ret; struct iio_dev *indio_dev = spi_get_drvdata(spi); iio_device_unregister(indio_dev); - - ret = adis16260_stop_device(indio_dev); - if (ret) - goto err_ret; - + adis16260_stop_device(indio_dev); adis16260_remove_trigger(indio_dev); iio_buffer_unregister(indio_dev); adis16260_unconfigure_ring(indio_dev); iio_device_free(indio_dev); -err_ret: - return ret; + return 0; } /* -- cgit v0.10.2 From 0b4ac3dce4093f426322be0eec0e38127a62bb7f Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 22 Sep 2012 09:56:00 +0100 Subject: staging:iio:adis16400: Do not return a error in remove function In the Linux device driver model the remove callback is not allowed to fail and the device will be removed regardless of the return value of the remove callback. So if we abort in the remove function and do not free all resources we will create a resource leak. Also all kinds of undefined behaviour are expected to happen since the IIO device is still there while its parent is already gone. The error which the driver tries to handle in the remove function is non-critical, so we can just ignore it and continue to free all resources and remove the IIO device. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c index b8c280c..b302c9b 100644 --- a/drivers/staging/iio/imu/adis16400_core.c +++ b/drivers/staging/iio/imu/adis16400_core.c @@ -1208,13 +1208,10 @@ error_ret: /* fixme, confirm ordering in this function */ static int __devexit adis16400_remove(struct spi_device *spi) { - int ret; struct iio_dev *indio_dev = spi_get_drvdata(spi); iio_device_unregister(indio_dev); - ret = adis16400_stop_device(indio_dev); - if (ret) - goto err_ret; + adis16400_stop_device(indio_dev); adis16400_remove_trigger(indio_dev); iio_buffer_unregister(indio_dev); @@ -1222,9 +1219,6 @@ static int __devexit adis16400_remove(struct spi_device *spi) iio_device_free(indio_dev); return 0; - -err_ret: - return ret; } static const struct spi_device_id adis16400_id[] = { -- cgit v0.10.2 From d576c7558616e3c096fca1f21531e1e50d2f27ca Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 22 Sep 2012 09:56:00 +0100 Subject: staging:iio:ade7753: Do not return a error in remove function In the Linux device driver model the remove callback is not allowed to fail and the device will be removed regardless of the return value of the remove callback. So if we abort in the remove function and do not free all resources we will create a resource leak. Also all kinds of undefined behaviour are expected to happen since the IIO device is still there while its parent is already gone. The error which the driver tries to handle in the remove function is non-critical, so we can just ignore it and continue to free all resources and remove the IIO device. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/meter/ade7753.c b/drivers/staging/iio/meter/ade7753.c index 380c05e..8b9eceb 100644 --- a/drivers/staging/iio/meter/ade7753.c +++ b/drivers/staging/iio/meter/ade7753.c @@ -557,18 +557,13 @@ error_ret: /* fixme, confirm ordering in this function */ static int __devexit ade7753_remove(struct spi_device *spi) { - int ret; struct iio_dev *indio_dev = spi_get_drvdata(spi); iio_device_unregister(indio_dev); - - ret = ade7753_stop_device(&(indio_dev->dev)); - if (ret) - goto err_ret; - + ade7753_stop_device(&indio_dev->dev); iio_device_free(indio_dev); -err_ret: - return ret; + + return 0; } static struct spi_driver ade7753_driver = { -- cgit v0.10.2 From db314a1aaa2c0aa262f24e14c81b91b09e72e470 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 22 Sep 2012 09:56:00 +0100 Subject: staging:iio:ade7754: Do not return a error in remove function In the Linux device driver model the remove callback is not allowed to fail and the device will be removed regardless of the return value of the remove callback. So if we abort in the remove function and do not free all resources we will create a resource leak. Also all kinds of undefined behaviour are expected to happen since the IIO device is still there while its parent is already gone. The error which the driver tries to handle in the remove function is non-critical, so we can just ignore it and continue to free all resources and remove the IIO device. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c index 7dea7fd..76e0ade 100644 --- a/drivers/staging/iio/meter/ade7754.c +++ b/drivers/staging/iio/meter/ade7754.c @@ -579,19 +579,13 @@ error_ret: /* fixme, confirm ordering in this function */ static int __devexit ade7754_remove(struct spi_device *spi) { - int ret; struct iio_dev *indio_dev = spi_get_drvdata(spi); iio_device_unregister(indio_dev); - ret = ade7754_stop_device(&(indio_dev->dev)); - if (ret) - goto err_ret; - + ade7754_stop_device(&indio_dev->dev); iio_device_free(indio_dev); -err_ret: - return ret; - + return 0; } static struct spi_driver ade7754_driver = { -- cgit v0.10.2 From 4922fd697a573cfc519668b3013a7f8de97c4ae7 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 22 Sep 2012 09:56:00 +0100 Subject: staging:iio:ade7758: Do not return a error in remove function In the Linux device driver model the remove callback is not allowed to fail and the device will be removed regardless of the return value of the remove callback. So if we abort in the remove function and do not free all resources we will create a resource leak. Also all kinds of undefined behaviour are expected to happen since the IIO device is still there while its parent is already gone. The error which the driver tries to handle in the remove function is non-critical, so we can just ignore it and continue to free all resources and remove the IIO device. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c index 958f8f2..a0fef77 100644 --- a/drivers/staging/iio/meter/ade7758_core.c +++ b/drivers/staging/iio/meter/ade7758_core.c @@ -966,13 +966,9 @@ static int __devexit ade7758_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); struct ade7758_state *st = iio_priv(indio_dev); - int ret; iio_device_unregister(indio_dev); - ret = ade7758_stop_device(&indio_dev->dev); - if (ret) - goto err_ret; - + ade7758_stop_device(&indio_dev->dev); ade7758_remove_trigger(indio_dev); ade7758_uninitialize_ring(indio_dev); ade7758_unconfigure_ring(indio_dev); @@ -981,8 +977,7 @@ static int __devexit ade7758_remove(struct spi_device *spi) iio_device_free(indio_dev); -err_ret: - return ret; + return 0; } static const struct spi_device_id ade7758_id[] = { -- cgit v0.10.2 From e854bcc938e734e2f556bc7ada9552669b8f58b0 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 22 Sep 2012 09:56:00 +0100 Subject: staging:iio:ade7759: Do not return a error in remove function In the Linux device driver model the remove callback is not allowed to fail and the device will be removed regardless of the return value of the remove callback. So if we abort in the remove function and do not free all resources we will create a resource leak. Also all kinds of undefined behaviour are expected to happen since the IIO device is still there while its parent is already gone. The error which the driver tries to handle in the remove function is non-critical, so we can just ignore it and continue to free all resources and remove the IIO device. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c index 435e35b..cb0707c 100644 --- a/drivers/staging/iio/meter/ade7759.c +++ b/drivers/staging/iio/meter/ade7759.c @@ -501,18 +501,13 @@ error_ret: /* fixme, confirm ordering in this function */ static int __devexit ade7759_remove(struct spi_device *spi) { - int ret; struct iio_dev *indio_dev = spi_get_drvdata(spi); iio_device_unregister(indio_dev); - ret = ade7759_stop_device(&(indio_dev->dev)); - if (ret) - goto err_ret; - + ade7759_stop_device(&indio_dev->dev); iio_device_free(indio_dev); -err_ret: - return ret; + return 0; } static struct spi_driver ade7759_driver = { -- cgit v0.10.2 From e71a837c810587e12620c957f1464c0674220d51 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 22 Sep 2012 09:56:00 +0100 Subject: staging:iio:lis3l02dq: Do not return a error in remove function In the Linux device driver model the remove callback is not allowed to fail and the device will be removed regardless of the return value of the remove callback. So if we abort in the remove function and do not free all resources we will create a resource leak. Also all kinds of undefined behaviour are expected to happen since the IIO device is still there while its parent is already gone. The errors which the driver tries to handle in the remove function are non-critical, so we can just ignore them and continue to free all resources and remove the IIO device. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c index d900d63..21b0469 100644 --- a/drivers/staging/iio/accel/lis3l02dq_core.c +++ b/drivers/staging/iio/accel/lis3l02dq_core.c @@ -782,19 +782,13 @@ err_ret: /* fixme, confirm ordering in this function */ static int __devexit lis3l02dq_remove(struct spi_device *spi) { - int ret; struct iio_dev *indio_dev = spi_get_drvdata(spi); struct lis3l02dq_state *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); - ret = lis3l02dq_disable_all_events(indio_dev); - if (ret) - goto err_ret; - - ret = lis3l02dq_stop_device(indio_dev); - if (ret) - goto err_ret; + lis3l02dq_disable_all_events(indio_dev); + lis3l02dq_stop_device(indio_dev); if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) free_irq(st->us->irq, indio_dev); @@ -804,8 +798,8 @@ static int __devexit lis3l02dq_remove(struct spi_device *spi) lis3l02dq_unconfigure_buffer(indio_dev); iio_device_free(indio_dev); -err_ret: - return ret; + + return 0; } static struct spi_driver lis3l02dq_driver = { -- cgit v0.10.2 From 67ad4e08dcc772153fda90cc747cfc9e03ab44f6 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 22 Sep 2012 09:56:00 +0100 Subject: staging:iio:sca3000: Do not return a error in remove function In the Linux device driver model the remove callback is not allowed to fail and the device will be removed regardless of the return value of the remove callback. So if we abort in the remove function and do not free all resources we will create a resource leak. Also all kinds of undefined behaviour are expected to happen since the IIO device is still there while its parent is already gone. The errors which the driver tries to handle in the remove function are non-critical, so we can just ignore them and continue to free all resources and remove the IIO device. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c index 6d72d97..ffd1697 100644 --- a/drivers/staging/iio/accel/sca3000_core.c +++ b/drivers/staging/iio/accel/sca3000_core.c @@ -1237,11 +1237,9 @@ static int __devexit sca3000_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); struct sca3000_state *st = iio_priv(indio_dev); - int ret; + /* Must ensure no interrupts can be generated after this!*/ - ret = sca3000_stop_all_interrupts(st); - if (ret) - return ret; + sca3000_stop_all_interrupts(st); if (spi->irq) free_irq(spi->irq, indio_dev); iio_device_unregister(indio_dev); -- cgit v0.10.2 From 332ed63ee9ec0b899cf6d03eecd85bebe1b8e943 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 21 Sep 2012 14:29:00 +0100 Subject: staging:iio:ad7780: Make powerdown GPIO optional Some designs hardwire the PDRST pin to always on. In this case there is no GPIO to control the mode of the device, so make the GPIO optional. Since now all of the the platform data fields are optional now, make the platform data as a whole optional as well. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/adc/ad7780.c b/drivers/staging/iio/adc/ad7780.c index 5f807ce..1dd7cdb 100644 --- a/drivers/staging/iio/adc/ad7780.c +++ b/drivers/staging/iio/adc/ad7780.c @@ -73,7 +73,8 @@ static int ad7780_set_mode(struct ad_sigma_delta *sigma_delta, break; } - gpio_set_value(st->powerdown_gpio, val); + if (gpio_is_valid(st->powerdown_gpio)) + gpio_set_value(st->powerdown_gpio, val); return 0; } @@ -148,11 +149,6 @@ static int __devinit ad7780_probe(struct spi_device *spi) struct iio_dev *indio_dev; int ret, voltage_uv = 0; - if (!pdata) { - dev_dbg(&spi->dev, "no platform data?\n"); - return -ENODEV; - } - indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) return -ENOMEM; @@ -174,8 +170,6 @@ static int __devinit ad7780_probe(struct spi_device *spi) st->chip_info = &ad7780_chip_info_tbl[spi_get_device_id(spi)->driver_data]; - st->powerdown_gpio = pdata->gpio_pdrst; - if (pdata && pdata->vref_mv) st->int_vref_mv = pdata->vref_mv; else if (voltage_uv) @@ -192,11 +186,17 @@ static int __devinit ad7780_probe(struct spi_device *spi) indio_dev->num_channels = 1; indio_dev->info = &ad7780_info; - ret = gpio_request_one(pdata->gpio_pdrst, GPIOF_OUT_INIT_LOW, + if (pdata && gpio_is_valid(pdata->gpio_pdrst)) { + + ret = gpio_request_one(pdata->gpio_pdrst, GPIOF_OUT_INIT_LOW, "AD7780 /PDRST"); - if (ret) { - dev_err(&spi->dev, "failed to request GPIO PDRST\n"); - goto error_disable_reg; + if (ret) { + dev_err(&spi->dev, "failed to request GPIO PDRST\n"); + goto error_disable_reg; + } + st->powerdown_gpio = pdata->gpio_pdrst; + } else { + st->powerdown_gpio = -1; } ret = ad_sd_setup_buffer_and_trigger(indio_dev); @@ -212,7 +212,8 @@ static int __devinit ad7780_probe(struct spi_device *spi) error_cleanup_buffer_and_trigger: ad_sd_cleanup_buffer_and_trigger(indio_dev); error_free_gpio: - gpio_free(pdata->gpio_pdrst); + if (pdata && gpio_is_valid(pdata->gpio_pdrst)) + gpio_free(pdata->gpio_pdrst); error_disable_reg: if (!IS_ERR(st->reg)) regulator_disable(st->reg); @@ -233,7 +234,9 @@ static int __devexit ad7780_remove(struct spi_device *spi) iio_device_unregister(indio_dev); ad_sd_cleanup_buffer_and_trigger(indio_dev); - gpio_free(st->powerdown_gpio); + if (gpio_is_valid(st->powerdown_gpio)) + gpio_free(st->powerdown_gpio); + if (!IS_ERR(st->reg)) { regulator_disable(st->reg); regulator_put(st->reg); -- cgit v0.10.2 From 7aecec986e043f02738705328d85f97375ca6f41 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 21 Sep 2012 14:29:00 +0100 Subject: staging:iio:ad7780: Add support for the ad7170/ad7171 The ad7170/ad7171 have a software interface similar to the ad7780. They do not have an external pin which allows to change the internal gain and the what is used for the gain bit in the ad7780/ad7781 becomes part of the check pattern. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index 1b4a356..a525143 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -82,12 +82,12 @@ config AD7887 module will be called ad7887. config AD7780 - tristate "Analog Devices AD7780 AD7781 ADC driver" + tristate "Analog Devices AD7780 and similar ADCs driver" depends on SPI depends on GPIOLIB select AD_SIGMA_DELTA help - Say yes here to build support for Analog Devices + Say yes here to build support for Analog Devices AD7170, AD7171, AD7780 and AD7781 SPI analog to digital converters (ADC). If unsure, say N (but it's safe to say "Y"). diff --git a/drivers/staging/iio/adc/ad7780.c b/drivers/staging/iio/adc/ad7780.c index 1dd7cdb..0a1328b 100644 --- a/drivers/staging/iio/adc/ad7780.c +++ b/drivers/staging/iio/adc/ad7780.c @@ -1,5 +1,5 @@ /* - * AD7780/AD7781 SPI ADC driver + * AD7170/AD7171 and AD7780/AD7781 SPI ADC driver * * Copyright 2011 Analog Devices Inc. * @@ -34,7 +34,9 @@ #define AD7780_PAT0 (1 << 0) struct ad7780_chip_info { - struct iio_chan_spec channel; + struct iio_chan_spec channel; + unsigned int pattern_mask; + unsigned int pattern; }; struct ad7780_state { @@ -48,6 +50,8 @@ struct ad7780_state { }; enum ad7780_supported_device_ids { + ID_AD7170, + ID_AD7171, ID_AD7780, ID_AD7781, }; @@ -109,9 +113,10 @@ static int ad7780_postprocess_sample(struct ad_sigma_delta *sigma_delta, unsigned int raw_sample) { struct ad7780_state *st = ad_sigma_delta_to_ad7780(sigma_delta); + const struct ad7780_chip_info *chip_info = st->chip_info; if ((raw_sample & AD7780_ERR) || - !((raw_sample & AD7780_PAT0) && !(raw_sample & AD7780_PAT1))) + ((raw_sample & chip_info->pattern_mask) != chip_info->pattern)) return -EIO; if (raw_sample & AD7780_GAIN) @@ -128,12 +133,29 @@ static const struct ad_sigma_delta_info ad7780_sigma_delta_info = { .has_registers = false, }; +#define AD7780_CHANNEL(bits, wordsize) \ + AD_SD_CHANNEL(1, 0, 0, bits, 32, wordsize - bits) + static const struct ad7780_chip_info ad7780_chip_info_tbl[] = { + [ID_AD7170] = { + .channel = AD7780_CHANNEL(12, 24), + .pattern = 0x5, + .pattern_mask = 0x7, + }, + [ID_AD7171] = { + .channel = AD7780_CHANNEL(16, 24), + .pattern = 0x5, + .pattern_mask = 0x7, + }, [ID_AD7780] = { - .channel = AD_SD_CHANNEL(1, 0, 0, 24, 32, 8), + .channel = AD7780_CHANNEL(24, 32), + .pattern = 0x1, + .pattern_mask = 0x3, }, [ID_AD7781] = { - .channel = AD_SD_CHANNEL(1, 0, 0, 20, 32, 12), + .channel = AD7780_CHANNEL(20, 32), + .pattern = 0x1, + .pattern_mask = 0x3, }, }; @@ -247,6 +269,8 @@ static int __devexit ad7780_remove(struct spi_device *spi) } static const struct spi_device_id ad7780_id[] = { + {"ad7170", ID_AD7170}, + {"ad7171", ID_AD7171}, {"ad7780", ID_AD7780}, {"ad7781", ID_AD7781}, {} @@ -265,5 +289,5 @@ static struct spi_driver ad7780_driver = { module_spi_driver(ad7780_driver); MODULE_AUTHOR("Michael Hennerich "); -MODULE_DESCRIPTION("Analog Devices AD7780/1 ADC"); +MODULE_DESCRIPTION("Analog Devices AD7780 and similar ADCs"); MODULE_LICENSE("GPL v2"); -- cgit v0.10.2 From f0347c36ccd7cfd31c8af10509d4110f0a769a85 Mon Sep 17 00:00:00 2001 From: "Kim, Milo" Date: Mon, 17 Sep 2012 10:35:00 +0100 Subject: iio: adc: add new lp8788 adc driver TI LP8788 PMU provides regulators, battery charger, ADC, RTC, backlight driver and current sinks. This patch enables the LP8788 ADC functions. The LP8788 ADC has several ADC input selection and supports 12bit resolution. Internal operation of getting ADC is access to registers of LP8788. The LP8788 ADC uses exported functions for accessing these registers. (exported by LP8788 MFD device driver) This driver supports IIO_CHAN_INFO_RAW and SCALE. So the IIO consumer can calculate the value with raw and scale. The unit of scale is micro. (ADC Input Selection) Voltage: battery voltage (MAX 5.0, 5.5 and 6.0V) charger input voltage four general ADC inputs coin cell voltage Current: battery charging current Temperature: IC temperature (The IIO map for the IIO consumer) The ADC input is configurable in the platform side. Even though this platform data is not defined, the default IIO map is created for supporting the power supply driver. The battery voltage and temperature are used inside this driver. (History) Patch v6. (a) Fix scale value for each ADC input selection Voltage and current type are mili unit and temperature is degree. To calculate the IC temperature, temp = raw * scaleint + (raw * scalepart)/ 1000000, scaleint is always 0. = raw * 0.061050, raw: 0 ~ 4095 Then range of IC temperature(ADC result) is 0 ~ 250'C (b) Reorganization of the IIO channel Spec Remove address, scan_type and scan_index and rollback the datasheet name. The reason why 'address' field is unnecessary is no relation with each channel. Moreover, to get the raw ADC value, the address info is not only one register but also several registers. Therefore specific function(lp8788_get_adc_result) is called rather than using one 'address' field. (c) Fix coding style Remove duplicated checking routine while unregistering the IIO map. Fix code for space and parenthesis. Patch v5. Fix default consumer name as 'lp8788-charger'. Add mutex for ADC read operation. Reorganization on lp8788_adc_read_raw(). Patch v4. Fix adc_raw function: support RAW and SCALE channel info. Change LP8788 ADC platform data - iio map. Enables the default IIO map. Patch v3. Fix wrong size of allocating iio private data. Fix coding styles. Patch v2. Support RAW and SCALE interface for IIO consumer. Clean up the iio channel spec macro. Signed-off-by: Milo(Woogyom) Kim Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 03791a6..4927581 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -54,4 +54,10 @@ config AT91_ADC help Say yes here to build support for Atmel AT91 ADC. +config LP8788_ADC + bool "LP8788 ADC driver" + depends on MFD_LP8788 + help + Say yes here to build support for TI LP8788 ADC. + endmenu diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index 9824a70..900995d 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -7,3 +7,4 @@ obj-$(CONFIG_AD7266) += ad7266.o obj-$(CONFIG_AD7476) += ad7476.o obj-$(CONFIG_AD7791) += ad7791.o obj-$(CONFIG_AT91_ADC) += at91_adc.o +obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o diff --git a/drivers/iio/adc/lp8788_adc.c b/drivers/iio/adc/lp8788_adc.c new file mode 100644 index 0000000..a93aaf0 --- /dev/null +++ b/drivers/iio/adc/lp8788_adc.c @@ -0,0 +1,264 @@ +/* + * TI LP8788 MFD - ADC driver + * + * Copyright 2012 Texas Instruments + * + * Author: Milo(Woogyom) Kim + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* register address */ +#define LP8788_ADC_CONF 0x60 +#define LP8788_ADC_RAW 0x61 +#define LP8788_ADC_DONE 0x63 + +#define ADC_CONV_START 1 + +struct lp8788_adc { + struct lp8788 *lp; + struct iio_map *map; + struct mutex lock; +}; + +static const int lp8788_scale[LPADC_MAX] = { + [LPADC_VBATT_5P5] = 1343101, + [LPADC_VIN_CHG] = 3052503, + [LPADC_IBATT] = 610500, + [LPADC_IC_TEMP] = 61050, + [LPADC_VBATT_6P0] = 1465201, + [LPADC_VBATT_5P0] = 1221001, + [LPADC_ADC1] = 610500, + [LPADC_ADC2] = 610500, + [LPADC_VDD] = 1025641, + [LPADC_VCOIN] = 757020, + [LPADC_ADC3] = 610500, + [LPADC_ADC4] = 610500, +}; + +static int lp8788_get_adc_result(struct lp8788_adc *adc, enum lp8788_adc_id id, + int *val) +{ + unsigned int msb; + unsigned int lsb; + unsigned int result; + u8 data; + u8 rawdata[2]; + int size = ARRAY_SIZE(rawdata); + int retry = 5; + int ret; + + data = (id << 1) | ADC_CONV_START; + ret = lp8788_write_byte(adc->lp, LP8788_ADC_CONF, data); + if (ret) + goto err_io; + + /* retry until adc conversion is done */ + data = 0; + while (retry--) { + usleep_range(100, 200); + + ret = lp8788_read_byte(adc->lp, LP8788_ADC_DONE, &data); + if (ret) + goto err_io; + + /* conversion done */ + if (data) + break; + } + + ret = lp8788_read_multi_bytes(adc->lp, LP8788_ADC_RAW, rawdata, size); + if (ret) + goto err_io; + + msb = (rawdata[0] << 4) & 0x00000ff0; + lsb = (rawdata[1] >> 4) & 0x0000000f; + result = msb | lsb; + *val = result; + + return 0; + +err_io: + return ret; +} + +static int lp8788_adc_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct lp8788_adc *adc = iio_priv(indio_dev); + enum lp8788_adc_id id = chan->channel; + int ret; + + mutex_lock(&adc->lock); + + switch (mask) { + case IIO_CHAN_INFO_RAW: + ret = lp8788_get_adc_result(adc, id, val) ? -EIO : IIO_VAL_INT; + break; + case IIO_CHAN_INFO_SCALE: + *val = lp8788_scale[id] / 1000000; + *val2 = lp8788_scale[id] % 1000000; + ret = IIO_VAL_INT_PLUS_MICRO; + break; + default: + ret = -EINVAL; + break; + } + + mutex_unlock(&adc->lock); + + return ret; +} + +static const struct iio_info lp8788_adc_info = { + .read_raw = &lp8788_adc_read_raw, + .driver_module = THIS_MODULE, +}; + +#define LP8788_CHAN(_id, _type) { \ + .type = _type, \ + .indexed = 1, \ + .channel = LPADC_##_id, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ + .datasheet_name = #_id, \ +} + +static const struct iio_chan_spec lp8788_adc_channels[] = { + [LPADC_VBATT_5P5] = LP8788_CHAN(VBATT_5P5, IIO_VOLTAGE), + [LPADC_VIN_CHG] = LP8788_CHAN(VIN_CHG, IIO_VOLTAGE), + [LPADC_IBATT] = LP8788_CHAN(IBATT, IIO_CURRENT), + [LPADC_IC_TEMP] = LP8788_CHAN(IC_TEMP, IIO_TEMP), + [LPADC_VBATT_6P0] = LP8788_CHAN(VBATT_6P0, IIO_VOLTAGE), + [LPADC_VBATT_5P0] = LP8788_CHAN(VBATT_5P0, IIO_VOLTAGE), + [LPADC_ADC1] = LP8788_CHAN(ADC1, IIO_VOLTAGE), + [LPADC_ADC2] = LP8788_CHAN(ADC2, IIO_VOLTAGE), + [LPADC_VDD] = LP8788_CHAN(VDD, IIO_VOLTAGE), + [LPADC_VCOIN] = LP8788_CHAN(VCOIN, IIO_VOLTAGE), + [LPADC_ADC3] = LP8788_CHAN(ADC3, IIO_VOLTAGE), + [LPADC_ADC4] = LP8788_CHAN(ADC4, IIO_VOLTAGE), +}; + +/* default maps used by iio consumer (lp8788-charger driver) */ +static struct iio_map lp8788_default_iio_maps[] = { + { + .consumer_dev_name = "lp8788-charger", + .consumer_channel = "lp8788_vbatt_5p0", + .adc_channel_label = "VBATT_5P0", + }, + { + .consumer_dev_name = "lp8788-charger", + .consumer_channel = "lp8788_adc1", + .adc_channel_label = "ADC1", + }, + { } +}; + +static int lp8788_iio_map_register(struct iio_dev *indio_dev, + struct lp8788_platform_data *pdata, + struct lp8788_adc *adc) +{ + struct iio_map *map; + int ret; + + map = (!pdata || !pdata->adc_pdata) ? + lp8788_default_iio_maps : pdata->adc_pdata; + + ret = iio_map_array_register(indio_dev, map); + if (ret) { + dev_err(adc->lp->dev, "iio map err: %d\n", ret); + return ret; + } + + adc->map = map; + return 0; +} + +static inline void lp8788_iio_map_unregister(struct iio_dev *indio_dev, + struct lp8788_adc *adc) +{ + iio_map_array_unregister(indio_dev, adc->map); +} + +static int __devinit lp8788_adc_probe(struct platform_device *pdev) +{ + struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent); + struct iio_dev *indio_dev; + struct lp8788_adc *adc; + int ret; + + indio_dev = iio_device_alloc(sizeof(*adc)); + if (!indio_dev) + return -ENOMEM; + + adc = iio_priv(indio_dev); + adc->lp = lp; + platform_set_drvdata(pdev, indio_dev); + + ret = lp8788_iio_map_register(indio_dev, lp->pdata, adc); + if (ret) + goto err_iio_map; + + mutex_init(&adc->lock); + + indio_dev->dev.parent = lp->dev; + indio_dev->name = pdev->name; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &lp8788_adc_info; + indio_dev->channels = lp8788_adc_channels; + indio_dev->num_channels = ARRAY_SIZE(lp8788_adc_channels); + + ret = iio_device_register(indio_dev); + if (ret) { + dev_err(lp->dev, "iio dev register err: %d\n", ret); + goto err_iio_device; + } + + return 0; + +err_iio_device: + lp8788_iio_map_unregister(indio_dev, adc); +err_iio_map: + iio_device_free(indio_dev); + return ret; +} + +static int __devexit lp8788_adc_remove(struct platform_device *pdev) +{ + struct iio_dev *indio_dev = platform_get_drvdata(pdev); + struct lp8788_adc *adc = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + lp8788_iio_map_unregister(indio_dev, adc); + iio_device_free(indio_dev); + + return 0; +} + +static struct platform_driver lp8788_adc_driver = { + .probe = lp8788_adc_probe, + .remove = __devexit_p(lp8788_adc_remove), + .driver = { + .name = LP8788_DEV_ADC, + .owner = THIS_MODULE, + }, +}; +module_platform_driver(lp8788_adc_driver); + +MODULE_DESCRIPTION("Texas Instruments LP8788 ADC Driver"); +MODULE_AUTHOR("Milo Kim"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:lp8788-adc"); -- cgit v0.10.2 From 3f257caf2d18fb45ab8d0fbaf71812d2b403cd0d Mon Sep 17 00:00:00 2001 From: Axel Lin <[mailto:axel.lin@gmail.com]> Date: Wed, 19 Sep 2012 16:30:00 +0100 Subject: HID: hid-sensor-hub: Remove hdev->claimed setting Current implementation of hid_hw_start() allows connect_mask to be 0. Setting hdev->claimed = HID_CLAIMED_INPUT before calling hid_hw_start() is not necessary. Remove it. Signed-off-by: Axel Lin Acked-by: Jiri Kosina Acked-by: Srinivas Pandruvada Signed-off-by: Jonathan Cameron diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index 22ec3c6..0e0fad0 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c @@ -530,7 +530,6 @@ static int sensor_hub_probe(struct hid_device *hdev, } INIT_LIST_HEAD(&hdev->inputs); - hdev->claimed = HID_CLAIMED_INPUT; ret = hid_hw_start(hdev, 0); if (ret) { hid_err(hdev, "hw start failed\n"); @@ -618,7 +617,6 @@ static void sensor_hub_remove(struct hid_device *hdev) int i; hid_dbg(hdev, " hardware removed\n"); - hdev->claimed &= ~HID_CLAIMED_INPUT; hid_hw_stop(hdev); hid_hw_close(hdev); spin_lock_irqsave(&data->lock, flags); -- cgit v0.10.2 From f2f13a68c37c13a7147b279b77b8fb2a36846059 Mon Sep 17 00:00:00 2001 From: Axel Lin <[mailto:axel.lin@gmail.com]> Date: Wed, 19 Sep 2012 16:30:00 +0100 Subject: HID: hid-sensor-hub: Fix sensor_hub_probe error handling Fix below issues: 1. In the case of goto err_close, hid_hw_stop(hdev) is called twice. Fix it. 2. If fails to allocate MFD device name, we also need to free all successfully allocated names in previous iterations. 3. In sensor_hub_remove(), Call hid_hw_close() before hid_hw_stop(). 4. Adjust unnecessary change lines for hid_err. Signed-off-by: Axel Lin Acked-by: Jiri Kosina Acked-by: Srinivas Pandruvada Signed-off-by: Jonathan Cameron diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index 0e0fad0..d9d73e9 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c @@ -555,8 +555,7 @@ static int sensor_hub_probe(struct hid_device *hdev, sizeof(struct mfd_cell), GFP_KERNEL); if (sd->hid_sensor_hub_client_devs == NULL) { - hid_err(hdev, - "Failed to allocate memory for mfd cells\n"); + hid_err(hdev, "Failed to allocate memory for mfd cells\n"); ret = -ENOMEM; goto err_close; } @@ -568,10 +567,9 @@ static int sensor_hub_probe(struct hid_device *hdev, name = kasprintf(GFP_KERNEL, "HID-SENSOR-%x", field->physical); if (name == NULL) { - hid_err(hdev, - "Failed MFD device name\n"); + hid_err(hdev, "Failed MFD device name\n"); ret = -ENOMEM; - goto err_free_cells; + goto err_free_names; } sd->hid_sensor_hub_client_devs[ sd->hid_sensor_client_cnt].name = name; @@ -595,10 +593,8 @@ static int sensor_hub_probe(struct hid_device *hdev, err_free_names: for (i = 0; i < sd->hid_sensor_client_cnt ; ++i) kfree(sd->hid_sensor_hub_client_devs[i].name); -err_free_cells: kfree(sd->hid_sensor_hub_client_devs); err_close: - hid_hw_stop(hdev); hid_hw_close(hdev); err_stop_hw: hid_hw_stop(hdev); @@ -617,8 +613,8 @@ static void sensor_hub_remove(struct hid_device *hdev) int i; hid_dbg(hdev, " hardware removed\n"); - hid_hw_stop(hdev); hid_hw_close(hdev); + hid_hw_stop(hdev); spin_lock_irqsave(&data->lock, flags); if (data->pending.status) complete(&data->pending.ready); -- cgit v0.10.2 From e60fea794e6ecb9ea4df2623c9498412afe31d4d Mon Sep 17 00:00:00 2001 From: anish kumar Date: Fri, 21 Sep 2012 17:10:00 +0100 Subject: power: battery: Generic battery driver using IIO Driver to allow use of the ADC drivers supported by the IIO subsystem for battery status monitoring. Connecting this driver to the relevant IIO device requires registration of the appropriate iio_map structure array by the IIO device driver (usually from platform data). If specified the driver will also make use of a gpio to provide interrupt driven notification that the battery is fully charged. In last version: Addressed concerns raised by lars: a. made the adc_bat per device. b. get the IIO channel using hardcoded channel names. c. Minor issues related to gpio_is_valid and some code refactoring. In V1: Addressed concerns raised by Anton: a. changed the struct name to gab(generic adc battery). b. Added some functions to neaten the code. c. Some minor coding guidelines changes. d. Used the latest function introduce by lars: iio_read_channel_processed to streamline the code. In V2: Addressed concerns by lars: a. No need of allocating memory for channels.Make it array. b. Code restructring, coding style and following kernel guidelines changes suggested by him. In V3: Addressed conerns by Anton: a. Added the copyright. b. Coding guidelines changes suggested by him. c. Added Makefile and Kconfig Signed-off-by: anish kumar Acked-by: Anton Vorontsov Signed-off-by: Jonathan Cameron diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index c1892f3..8097819 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -29,6 +29,13 @@ config APM_POWER Say Y here to enable support APM status emulation using battery class devices. +config GENERIC_ADC_BATTERY + tristate "Generic battery support using IIO" + depends on IIO + help + Say Y here to enable support for the generic battery driver + which uses IIO framework to read adc. + config MAX8925_POWER tristate "MAX8925 battery charger support" depends on MFD_MAX8925 diff --git a/drivers/power/Makefile b/drivers/power/Makefile index ee58afb..e0b4d42 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -5,6 +5,7 @@ power_supply-$(CONFIG_SYSFS) += power_supply_sysfs.o power_supply-$(CONFIG_LEDS_TRIGGERS) += power_supply_leds.o obj-$(CONFIG_POWER_SUPPLY) += power_supply.o +obj-$(CONFIG_GENERIC_ADC_BATTERY) += generic-adc-battery.o obj-$(CONFIG_PDA_POWER) += pda_power.o obj-$(CONFIG_APM_POWER) += apm_power.o diff --git a/drivers/power/generic-adc-battery.c b/drivers/power/generic-adc-battery.c new file mode 100644 index 0000000..9bdf444 --- /dev/null +++ b/drivers/power/generic-adc-battery.c @@ -0,0 +1,422 @@ +/* + * Generic battery driver code using IIO + * Copyright (C) 2012, Anish Kumar + * based on jz4740-battery.c + * based on s3c_adc_battery.c + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define JITTER_DEFAULT 10 /* hope 10ms is enough */ + +enum gab_chan_type { + GAB_VOLTAGE = 0, + GAB_CURRENT, + GAB_POWER, + GAB_MAX_CHAN_TYPE +}; + +/* + * gab_chan_name suggests the standard channel names for commonly used + * channel types. + */ +static const char *const gab_chan_name[] = { + [GAB_VOLTAGE] = "voltage", + [GAB_CURRENT] = "current", + [GAB_POWER] = "power", +}; + +struct gab { + struct power_supply psy; + struct iio_channel *channel[GAB_MAX_CHAN_TYPE]; + struct gab_platform_data *pdata; + struct delayed_work bat_work; + int level; + int status; + bool cable_plugged; +}; + +static struct gab *to_generic_bat(struct power_supply *psy) +{ + return container_of(psy, struct gab, psy); +} + +static void gab_ext_power_changed(struct power_supply *psy) +{ + struct gab *adc_bat = to_generic_bat(psy); + + schedule_delayed_work(&adc_bat->bat_work, msecs_to_jiffies(0)); +} + +static const enum power_supply_property gab_props[] = { + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, + POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN, + POWER_SUPPLY_PROP_CHARGE_NOW, + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_CURRENT_NOW, + POWER_SUPPLY_PROP_TECHNOLOGY, + POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, + POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, + POWER_SUPPLY_PROP_MODEL_NAME, +}; + +/* + * This properties are set based on the received platform data and this + * should correspond one-to-one with enum chan_type. + */ +static const enum power_supply_property gab_dyn_props[] = { + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_CURRENT_NOW, + POWER_SUPPLY_PROP_POWER_NOW, +}; + +static bool gab_charge_finished(struct gab *adc_bat) +{ + struct gab_platform_data *pdata = adc_bat->pdata; + bool ret = gpio_get_value(pdata->gpio_charge_finished); + bool inv = pdata->gpio_inverted; + + if (!gpio_is_valid(pdata->gpio_charge_finished)) + return false; + return ret ^ inv; +} + +static int gab_get_status(struct gab *adc_bat) +{ + struct gab_platform_data *pdata = adc_bat->pdata; + struct power_supply_info *bat_info; + + bat_info = &pdata->battery_info; + if (adc_bat->level == bat_info->charge_full_design) + return POWER_SUPPLY_STATUS_FULL; + return adc_bat->status; +} + +static enum gab_chan_type gab_prop_to_chan(enum power_supply_property psp) +{ + switch (psp) { + case POWER_SUPPLY_PROP_POWER_NOW: + return GAB_POWER; + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + return GAB_VOLTAGE; + case POWER_SUPPLY_PROP_CURRENT_NOW: + return GAB_CURRENT; + default: + WARN_ON(1); + break; + } + return GAB_POWER; +} + +static int read_channel(struct gab *adc_bat, enum power_supply_property psp, + int *result) +{ + int ret; + int chan_index; + + chan_index = gab_prop_to_chan(psp); + ret = iio_read_channel_processed(adc_bat->channel[chan_index], + result); + if (ret < 0) + pr_err("read channel error\n"); + return ret; +} + +static int gab_get_property(struct power_supply *psy, + enum power_supply_property psp, union power_supply_propval *val) +{ + struct gab *adc_bat; + struct gab_platform_data *pdata; + struct power_supply_info *bat_info; + int result = 0; + int ret = 0; + + adc_bat = to_generic_bat(psy); + if (!adc_bat) { + dev_err(psy->dev, "no battery infos ?!\n"); + return -EINVAL; + } + pdata = adc_bat->pdata; + bat_info = &pdata->battery_info; + + switch (psp) { + case POWER_SUPPLY_PROP_STATUS: + gab_get_status(adc_bat); + break; + case POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN: + val->intval = 0; + break; + case POWER_SUPPLY_PROP_CHARGE_NOW: + val->intval = pdata->cal_charge(result); + break; + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + case POWER_SUPPLY_PROP_CURRENT_NOW: + case POWER_SUPPLY_PROP_POWER_NOW: + ret = read_channel(adc_bat, psp, &result); + if (ret < 0) + goto err; + val->intval = result; + break; + case POWER_SUPPLY_PROP_TECHNOLOGY: + val->intval = bat_info->technology; + break; + case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: + val->intval = bat_info->voltage_min_design; + break; + case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: + val->intval = bat_info->voltage_max_design; + break; + case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: + val->intval = bat_info->charge_full_design; + break; + case POWER_SUPPLY_PROP_MODEL_NAME: + val->strval = bat_info->name; + break; + default: + return -EINVAL; + } +err: + return ret; +} + +static void gab_work(struct work_struct *work) +{ + struct gab *adc_bat; + struct gab_platform_data *pdata; + struct delayed_work *delayed_work; + bool is_plugged; + int status; + + delayed_work = container_of(work, struct delayed_work, work); + adc_bat = container_of(delayed_work, struct gab, bat_work); + pdata = adc_bat->pdata; + status = adc_bat->status; + + is_plugged = power_supply_am_i_supplied(&adc_bat->psy); + adc_bat->cable_plugged = is_plugged; + + if (!is_plugged) + adc_bat->status = POWER_SUPPLY_STATUS_DISCHARGING; + else if (gab_charge_finished(adc_bat)) + adc_bat->status = POWER_SUPPLY_STATUS_NOT_CHARGING; + else + adc_bat->status = POWER_SUPPLY_STATUS_CHARGING; + + if (status != adc_bat->status) + power_supply_changed(&adc_bat->psy); +} + +static irqreturn_t gab_charged(int irq, void *dev_id) +{ + struct gab *adc_bat = dev_id; + struct gab_platform_data *pdata = adc_bat->pdata; + int delay; + + delay = pdata->jitter_delay ? pdata->jitter_delay : JITTER_DEFAULT; + schedule_delayed_work(&adc_bat->bat_work, + msecs_to_jiffies(delay)); + return IRQ_HANDLED; +} + +static int __devinit gab_probe(struct platform_device *pdev) +{ + struct gab *adc_bat; + struct power_supply *psy; + struct gab_platform_data *pdata = pdev->dev.platform_data; + enum power_supply_property *properties; + int ret = 0; + int chan; + int index = 0; + + adc_bat = devm_kzalloc(&pdev->dev, sizeof(*adc_bat), GFP_KERNEL); + if (!adc_bat) { + dev_err(&pdev->dev, "failed to allocate memory\n"); + return -ENOMEM; + } + + psy = &adc_bat->psy; + psy->name = pdata->battery_info.name; + + /* bootup default values for the battery */ + adc_bat->cable_plugged = false; + adc_bat->status = POWER_SUPPLY_STATUS_DISCHARGING; + psy->type = POWER_SUPPLY_TYPE_BATTERY; + psy->get_property = gab_get_property; + psy->external_power_changed = gab_ext_power_changed; + adc_bat->pdata = pdata; + + /* calculate the total number of channels */ + chan = ARRAY_SIZE(gab_chan_name); + + /* + * copying the static properties and allocating extra memory for holding + * the extra configurable properties received from platform data. + */ + psy->properties = kcalloc(ARRAY_SIZE(gab_props) + + ARRAY_SIZE(gab_chan_name), + sizeof(*psy->properties), GFP_KERNEL); + if (!psy->properties) { + ret = -ENOMEM; + goto first_mem_fail; + } + + memcpy(psy->properties, gab_props, sizeof(gab_props)); + properties = psy->properties + sizeof(gab_props); + + /* + * getting channel from iio and copying the battery properties + * based on the channel supported by consumer device. + */ + for (chan = 0; chan < ARRAY_SIZE(gab_chan_name); chan++) { + adc_bat->channel[chan] = iio_channel_get(dev_name(&pdev->dev), + gab_chan_name[chan]); + if (IS_ERR(adc_bat->channel[chan])) { + ret = PTR_ERR(adc_bat->channel[chan]); + } else { + /* copying properties for supported channels only */ + memcpy(properties + sizeof(*(psy->properties)) * index, + &gab_dyn_props[chan], + sizeof(gab_dyn_props[chan])); + index++; + } + } + + /* none of the channels are supported so let's bail out */ + if (index == ARRAY_SIZE(gab_chan_name)) + goto second_mem_fail; + + /* + * Total number of properties is equal to static properties + * plus the dynamic properties.Some properties may not be set + * as come channels may be not be supported by the device.So + * we need to take care of that. + */ + psy->num_properties = ARRAY_SIZE(gab_props) + index; + + ret = power_supply_register(&pdev->dev, psy); + if (ret) + goto err_reg_fail; + + INIT_DELAYED_WORK(&adc_bat->bat_work, gab_work); + + if (gpio_is_valid(pdata->gpio_charge_finished)) { + int irq; + ret = gpio_request(pdata->gpio_charge_finished, "charged"); + if (ret) + goto gpio_req_fail; + + irq = gpio_to_irq(pdata->gpio_charge_finished); + ret = request_any_context_irq(irq, gab_charged, + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, + "battery charged", adc_bat); + if (ret) + goto err_gpio; + } + + platform_set_drvdata(pdev, adc_bat); + + /* Schedule timer to check current status */ + schedule_delayed_work(&adc_bat->bat_work, + msecs_to_jiffies(0)); + return 0; + +err_gpio: + gpio_free(pdata->gpio_charge_finished); +gpio_req_fail: + power_supply_unregister(psy); +err_reg_fail: + for (chan = 0; ARRAY_SIZE(gab_chan_name); chan++) + iio_channel_release(adc_bat->channel[chan]); +second_mem_fail: + kfree(psy->properties); +first_mem_fail: + return ret; +} + +static int __devexit gab_remove(struct platform_device *pdev) +{ + int chan; + struct gab *adc_bat = platform_get_drvdata(pdev); + struct gab_platform_data *pdata = adc_bat->pdata; + + power_supply_unregister(&adc_bat->psy); + + if (gpio_is_valid(pdata->gpio_charge_finished)) { + free_irq(gpio_to_irq(pdata->gpio_charge_finished), adc_bat); + gpio_free(pdata->gpio_charge_finished); + } + + for (chan = 0; ARRAY_SIZE(gab_chan_name); chan++) + iio_channel_release(adc_bat->channel[chan]); + + kfree(adc_bat->psy.properties); + cancel_delayed_work(&adc_bat->bat_work); + return 0; +} + +#ifdef CONFIG_PM +static int gab_suspend(struct device *dev) +{ + struct gab *adc_bat = dev_get_drvdata(dev); + + cancel_delayed_work_sync(&adc_bat->bat_work); + adc_bat->status = POWER_SUPPLY_STATUS_UNKNOWN; + return 0; +} + +static int gab_resume(struct device *dev) +{ + struct gab *adc_bat = dev_get_drvdata(dev); + struct gab_platform_data *pdata = adc_bat->pdata; + int delay; + + delay = pdata->jitter_delay ? pdata->jitter_delay : JITTER_DEFAULT; + + /* Schedule timer to check current status */ + schedule_delayed_work(&adc_bat->bat_work, + msecs_to_jiffies(delay)); + return 0; +} + +static const struct dev_pm_ops gab_pm_ops = { + .suspend = gab_suspend, + .resume = gab_resume, +}; + +#define GAB_PM_OPS (&gab_pm_ops) +#else +#define GAB_PM_OPS (NULL) +#endif + +static struct platform_driver gab_driver = { + .driver = { + .name = "generic-adc-battery", + .owner = THIS_MODULE, + .pm = GAB_PM_OPS + }, + .probe = gab_probe, + .remove = __devexit_p(gab_remove), +}; +module_platform_driver(gab_driver); + +MODULE_AUTHOR("anish kumar "); +MODULE_DESCRIPTION("generic battery driver using IIO"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/power/generic-adc-battery.h b/include/linux/power/generic-adc-battery.h new file mode 100644 index 0000000..b1ebe08 --- /dev/null +++ b/include/linux/power/generic-adc-battery.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2012, Anish Kumar + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef GENERIC_ADC_BATTERY_H +#define GENERIC_ADC_BATTERY_H + +/** + * struct gab_platform_data - platform_data for generic adc iio battery driver. + * @battery_info: recommended structure to specify static power supply + * parameters + * @cal_charge: calculate charge level. + * @gpio_charge_finished: gpio for the charger. + * @gpio_inverted: Should be 1 if the GPIO is active low otherwise 0 + * @jitter_delay: delay required after the interrupt to check battery + * status.Default set is 10ms. + */ +struct gab_platform_data { + struct power_supply_info battery_info; + int (*cal_charge)(long value); + int gpio_charge_finished; + bool gpio_inverted; + int jitter_delay; +}; + +#endif /* GENERIC_ADC_BATTERY_H */ -- cgit v0.10.2 From 3fff22743640637c2b61473d3cc8d7dc2215984f Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 12 Sep 2012 12:06:00 +0100 Subject: staging:iio:dummy: Fix potential NULL pointer dereference If the config contains CONFIG_IIO_BUFFER=y and CONFIG_IIO_SIMPLE_DUMMY_BUFFER=n iio_simple_dummy_configure_buffer() is stubbed out and iio_buffer_register() is not. As a result we try to register a buffer which has not been configured. This will causes a NULL pointer deref in iio_buffer_register. To solve this issue move the iio_buffer_register() call to iio_simple_dummy_configure_buffer(), so it will only be called if iio_simple_dummy_configure_buffer() has been called. Reported-by: Fengguang Wu Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/iio_simple_dummy.c b/drivers/staging/iio/iio_simple_dummy.c index 029bcc6..dc6c728 100644 --- a/drivers/staging/iio/iio_simple_dummy.c +++ b/drivers/staging/iio/iio_simple_dummy.c @@ -445,26 +445,20 @@ static int __devinit iio_dummy_probe(int index) if (ret < 0) goto error_free_device; - /* Configure buffered capture support. */ - ret = iio_simple_dummy_configure_buffer(indio_dev); - if (ret < 0) - goto error_unregister_events; - /* - * Register the channels with the buffer, but avoid the output - * channel being registered by reducing the number of channels by 1. + * Configure buffered capture support and register the channels with the + * buffer, but avoid the output channel being registered by reducing the + * number of channels by 1. */ - ret = iio_buffer_register(indio_dev, iio_dummy_channels, 5); + ret = iio_simple_dummy_configure_buffer(indio_dev, iio_dummy_channels, 5); if (ret < 0) - goto error_unconfigure_buffer; + goto error_unregister_events; ret = iio_device_register(indio_dev); if (ret < 0) - goto error_unregister_buffer; + goto error_unconfigure_buffer; return 0; -error_unregister_buffer: - iio_buffer_unregister(indio_dev); error_unconfigure_buffer: iio_simple_dummy_unconfigure_buffer(indio_dev); error_unregister_events: @@ -499,7 +493,6 @@ static int iio_dummy_remove(int index) /* Device specific code to power down etc */ /* Buffered capture related cleanup */ - iio_buffer_unregister(indio_dev); iio_simple_dummy_unconfigure_buffer(indio_dev); ret = iio_simple_dummy_events_unregister(indio_dev); @@ -530,6 +523,7 @@ static __init int iio_dummy_init(void) instances = 1; return -EINVAL; } + /* Fake a bus */ iio_dummy_devs = kcalloc(instances, sizeof(*iio_dummy_devs), GFP_KERNEL); diff --git a/drivers/staging/iio/iio_simple_dummy.h b/drivers/staging/iio/iio_simple_dummy.h index 53975d9..c9e8702 100644 --- a/drivers/staging/iio/iio_simple_dummy.h +++ b/drivers/staging/iio/iio_simple_dummy.h @@ -95,10 +95,12 @@ enum iio_simple_dummy_scan_elements { }; #ifdef CONFIG_IIO_SIMPLE_DUMMY_BUFFER -int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev); +int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev, + const struct iio_chan_spec *channels, unsigned int num_channels); void iio_simple_dummy_unconfigure_buffer(struct iio_dev *indio_dev); #else -static inline int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev) +static inline int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev, + const struct iio_chan_spec *channels, unsigned int num_channels) { return 0; }; diff --git a/drivers/staging/iio/iio_simple_dummy_buffer.c b/drivers/staging/iio/iio_simple_dummy_buffer.c index 1fd3809..697d970 100644 --- a/drivers/staging/iio/iio_simple_dummy_buffer.c +++ b/drivers/staging/iio/iio_simple_dummy_buffer.c @@ -126,7 +126,8 @@ static const struct iio_buffer_setup_ops iio_simple_dummy_buffer_setup_ops = { .predisable = &iio_triggered_buffer_predisable, }; -int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev) +int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev, + const struct iio_chan_spec *channels, unsigned int num_channels) { int ret; struct iio_buffer *buffer; @@ -182,8 +183,15 @@ int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev) * driven by a trigger. */ indio_dev->modes |= INDIO_BUFFER_TRIGGERED; + + ret = iio_buffer_register(indio_dev, channels, num_channels); + if (ret) + goto error_dealloc_pollfunc; + return 0; +error_dealloc_pollfunc: + iio_dealloc_pollfunc(indio_dev->pollfunc); error_free_buffer: iio_kfifo_free(indio_dev->buffer); error_ret: @@ -197,6 +205,7 @@ error_ret: */ void iio_simple_dummy_unconfigure_buffer(struct iio_dev *indio_dev) { + iio_buffer_unregister(indio_dev); iio_dealloc_pollfunc(indio_dev->pollfunc); iio_kfifo_free(indio_dev->buffer); } -- cgit v0.10.2 From 4c229df0b19cda41a8ea93f26497374004299fda Mon Sep 17 00:00:00 2001 From: Alexey Khoroshilov Date: Tue, 25 Sep 2012 16:56:02 +0400 Subject: staging: sbe-2t3e3: fix error handling in t3e3_init_channel() t3e3_init_channel() incorrectly handles errors in several places: it returns zero and does not deallocate all required resources. The patch fixes that places. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov Reviewed-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/sbe-2t3e3/module.c b/drivers/staging/sbe-2t3e3/module.c index cd778b3..8adb178 100644 --- a/drivers/staging/sbe-2t3e3/module.c +++ b/drivers/staging/sbe-2t3e3/module.c @@ -67,6 +67,7 @@ static int __devinit t3e3_init_channel(struct channel *channel, struct pci_dev * dev = alloc_hdlcdev(channel); if (!dev) { printk(KERN_ERR "SBE 2T3E3" ": Out of memory\n"); + err = -ENOMEM; goto free_regions; } @@ -82,8 +83,9 @@ static int __devinit t3e3_init_channel(struct channel *channel, struct pci_dev * else channel->h.slot = 0; - if (setup_device(dev, channel)) - goto free_regions; + err = setup_device(dev, channel); + if (err) + goto free_dev; pci_read_config_dword(channel->pdev, 0x40, &val); /* mask sleep mode */ pci_write_config_dword(channel->pdev, 0x40, val & 0x3FFFFFFF); @@ -92,14 +94,19 @@ static int __devinit t3e3_init_channel(struct channel *channel, struct pci_dev * pci_read_config_dword(channel->pdev, PCI_COMMAND, &channel->h.command); t3e3_init(channel); - if (request_irq(dev->irq, &t3e3_intr, IRQF_SHARED, dev->name, dev)) { + err = request_irq(dev->irq, &t3e3_intr, IRQF_SHARED, dev->name, dev); + if (err) { printk(KERN_WARNING "%s: could not get irq: %d\n", dev->name, dev->irq); - goto free_regions; + goto unregister_dev; } pci_set_drvdata(pdev, channel); return 0; +unregister_dev: + unregister_hdlc_device(dev); +free_dev: + free_netdev(dev); free_regions: pci_release_regions(pdev); disable: -- cgit v0.10.2 From 9970eeae4854e0eee03e5e467ace4ec7cbf36d1f Mon Sep 17 00:00:00 2001 From: Harsh Kumar Date: Mon, 24 Sep 2012 20:27:04 +0530 Subject: staging: winbond: Coding Style correction and removal of unused macro Removed an unused macro. Plus, couple of grammatical and coding style fixes. 1) The macro _INLINE is not used anywhere. Anyways __inline is not portable. 2) Changed comment from "Not use" to "Unused" make it grammatically correct and to fit in 80 word limit. 3.) Removed space after * Signed-off-by: Harsh Kumar Acked-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/winbond/sme_api.h b/drivers/staging/winbond/sme_api.h index 712331b..652ae70 100644 --- a/drivers/staging/winbond/sme_api.h +++ b/drivers/staging/winbond/sme_api.h @@ -12,7 +12,6 @@ #include "localpara.h" /****************** CONSTANT AND MACRO SECTION ******************************/ -#define _INLINE __inline #define MEDIA_STATE_DISCONNECTED 0 #define MEDIA_STATE_CONNECTED 1 @@ -26,17 +25,17 @@ /* OID_802_11_BSSID */ s8 sme_get_bssid(void *pcore_data, u8 *pbssid); -s8 sme_get_desired_bssid(void *pcore_data, u8 *pbssid); /* Not use */ +s8 sme_get_desired_bssid(void *pcore_data, u8 *pbssid); /* Unused */ s8 sme_set_desired_bssid(void *pcore_data, u8 *pbssid); /* OID_802_11_SSID */ s8 sme_get_ssid(void *pcore_data, u8 *pssid, u8 *pssid_len); -s8 sme_get_desired_ssid(void *pcore_data, u8 *pssid, u8 *pssid_len);/* Not use */ +s8 sme_get_desired_ssid(void *pcore_data, u8 *pssid, u8 *pssid_len);/* Unused */ s8 sme_set_desired_ssid(void *pcore_data, u8 *pssid, u8 ssid_len); /* OID_802_11_INFRASTRUCTURE_MODE */ s8 sme_get_bss_type(void *pcore_data, u8 *pbss_type); -s8 sme_get_desired_bss_type(void *pcore_data, u8 *pbss_type); /* Not use */ +s8 sme_get_desired_bss_type(void *pcore_data, u8 *pbss_type); /* Unused */ s8 sme_set_desired_bss_type(void *pcore_data, u8 bss_type); /* OID_802_11_FRAGMENTATION_THRESHOLD */ @@ -138,7 +137,7 @@ s8 sme_set_txrate_policy(void *pcore_data, u8 policy); s8 sme_get_txrate_policy(void *pcore_data, u8 *policy); s8 sme_get_cwmin_value(void *pcore_data, u8 *cwmin); s8 sme_get_cwmax_value(void *pcore_data, u16 *cwmax); -s8 sme_get_ms_radio_mode(void *pcore_data, u8 * pMsRadioOff); +s8 sme_get_ms_radio_mode(void *pcore_data, u8 *pMsRadioOff); s8 sme_set_ms_radio_mode(void *pcore_data, u8 boMsRadioOff); void sme_get_tx_power_level(void *pcore_data, u32 *TxPower); -- cgit v0.10.2 From 37594bb99fa50653ceba20dcd95604567cc57bf3 Mon Sep 17 00:00:00 2001 From: Harsh Kumar Date: Wed, 26 Sep 2012 11:02:47 +0530 Subject: Staging: winbond: Changed c99 comments to c89 comments checkpatch cleanup: Changed c99 comments to c89 comments Signed-off-by: Harsh Kumar Acked-by: Pavel Machek Reviewed-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/winbond/wb35tx_s.h b/drivers/staging/winbond/wb35tx_s.h index 9186526..412cb25 100644 --- a/drivers/staging/winbond/wb35tx_s.h +++ b/drivers/staging/winbond/wb35tx_s.h @@ -3,36 +3,32 @@ #include "mds_s.h" -//==================================== -// IS89C35 Tx related definition -//==================================== -#define TX_INTERFACE 0 // Interface 1 -#define TX_PIPE 3 // endpoint 4 -#define TX_INTERRUPT 1 // endpoint 2 -#define MAX_INTERRUPT_LENGTH 64 // It must be 64 for EP2 hardware +/* IS89C35 Tx related definition */ +#define TX_INTERFACE 0 /* Interface 1 */ +#define TX_PIPE 3 /* Endpoint 4 */ +#define TX_INTERRUPT 1 /* Endpoint 2 */ +#define MAX_INTERRUPT_LENGTH 64 /* It must be 64 for EP2 hardware */ -//==================================== -// Internal variable for module -//==================================== +/* Internal variable for module */ struct wb35_tx { - // For Tx buffer + /* For Tx buffer */ u8 TxBuffer[ MAX_USB_TX_BUFFER_NUMBER ][ MAX_USB_TX_BUFFER ]; - // For Interrupt pipe + /* For Interrupt pipe */ u8 EP2_buf[MAX_INTERRUPT_LENGTH]; - atomic_t TxResultCount;// For thread control of EP2 931130.4.m - atomic_t TxFireCounter;// For thread control of EP4 931130.4.n + atomic_t TxResultCount; /* For thread control of EP2 931130.4.m */ + atomic_t TxFireCounter; /* For thread control of EP4 931130.4.n */ u32 ByteTransfer; - u32 TxSendIndex;// The next index of Mds array to be sent - u32 EP2vm_state; // for EP2vm state - u32 EP4vm_state; // for EP4vm state - u32 tx_halt; // Stopping VM + u32 TxSendIndex; /* The next index of Mds array to be sent */ + u32 EP2vm_state; /* for EP2vm state */ + u32 EP4vm_state; /* for EP4vm state */ + u32 tx_halt; /* Stopping VM */ struct urb * Tx4Urb; struct urb * Tx2Urb; @@ -40,8 +36,8 @@ struct wb35_tx { int EP2VM_status; int EP4VM_status; - u32 TxFillCount; // 20060928 - u32 TxTimer; // 20060928 Add if sending packet is greater than 13 + u32 TxFillCount; /* 20060928 */ + u32 TxTimer; /* 20060928 Add if sending packet is greater than 13 */ }; #endif -- cgit v0.10.2 From bd084bac93a440388a70f0d9dbddcb5cbad08aca Mon Sep 17 00:00:00 2001 From: Harsh Kumar Date: Wed, 26 Sep 2012 11:03:15 +0530 Subject: Staging: winbond: Removed undesired spaces, lines and tabs checkpatch cleanup: Removed some undesired spaces, lines and tabs to comply with coding style. Signed-off-by: Harsh Kumar Acked-by: Pavel Machek Reviewed-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/winbond/wb35tx_s.h b/drivers/staging/winbond/wb35tx_s.h index 412cb25..715f87d 100644 --- a/drivers/staging/winbond/wb35tx_s.h +++ b/drivers/staging/winbond/wb35tx_s.h @@ -4,16 +4,12 @@ #include "mds_s.h" /* IS89C35 Tx related definition */ -#define TX_INTERFACE 0 /* Interface 1 */ -#define TX_PIPE 3 /* Endpoint 4 */ -#define TX_INTERRUPT 1 /* Endpoint 2 */ +#define TX_INTERFACE 0 /* Interface 1 */ +#define TX_PIPE 3 /* Endpoint 4 */ +#define TX_INTERRUPT 1 /* Endpoint 2 */ #define MAX_INTERRUPT_LENGTH 64 /* It must be 64 for EP2 hardware */ - - /* Internal variable for module */ - - struct wb35_tx { /* For Tx buffer */ u8 TxBuffer[ MAX_USB_TX_BUFFER_NUMBER ][ MAX_USB_TX_BUFFER ]; @@ -23,15 +19,15 @@ struct wb35_tx { atomic_t TxResultCount; /* For thread control of EP2 931130.4.m */ atomic_t TxFireCounter; /* For thread control of EP4 931130.4.n */ - u32 ByteTransfer; + u32 ByteTransfer; - u32 TxSendIndex; /* The next index of Mds array to be sent */ - u32 EP2vm_state; /* for EP2vm state */ - u32 EP4vm_state; /* for EP4vm state */ - u32 tx_halt; /* Stopping VM */ + u32 TxSendIndex; /* The next index of Mds array to be sent */ + u32 EP2vm_state; /* for EP2vm state */ + u32 EP4vm_state; /* for EP4vm state */ + u32 tx_halt; /* Stopping VM */ - struct urb * Tx4Urb; - struct urb * Tx2Urb; + struct urb *Tx4Urb; + struct urb *Tx2Urb; int EP2VM_status; int EP4VM_status; -- cgit v0.10.2 From d34602de3ba29b3ceafe4e15e27a25c6a5bccc38 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 24 Sep 2012 09:16:57 -0700 Subject: staging "wlan-ng" Fix typos. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlan-ng/cfg80211.c b/drivers/staging/wlan-ng/cfg80211.c index 57a2b05..18c06a5 100644 --- a/drivers/staging/wlan-ng/cfg80211.c +++ b/drivers/staging/wlan-ng/cfg80211.c @@ -1,7 +1,7 @@ /* cfg80211 Interface for prism2_usb module */ -/* Prism2 channell/frequency/bitrate declarations */ +/* Prism2 channel/frequency/bitrate declarations */ static const struct ieee80211_channel prism2_channels[] = { { .center_freq = 2412 }, { .center_freq = 2417 }, @@ -502,7 +502,7 @@ int prism2_connect(struct wiphy *wiphy, struct net_device *dev, goto exit; } - /* Set the authorisation */ + /* Set the authorization */ if ((sme->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) || ((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && !is_wep)) msg_join.authtype.data = P80211ENUM_authalg_opensystem; diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c index 6ca07e7..750330f 100644 --- a/drivers/staging/wlan-ng/p80211netdev.c +++ b/drivers/staging/wlan-ng/p80211netdev.c @@ -461,7 +461,7 @@ failed: /*---------------------------------------------------------------- * p80211knetdev_set_multicast_list * -* Called from higher lavers whenever there's a need to set/clear +* Called from higher layers whenever there's a need to set/clear * promiscuous mode or rewrite the multicast list. * * Arguments: diff --git a/drivers/staging/wlan-ng/p80211types.h b/drivers/staging/wlan-ng/p80211types.h index f043090..8cb4fc6 100644 --- a/drivers/staging/wlan-ng/p80211types.h +++ b/drivers/staging/wlan-ng/p80211types.h @@ -197,7 +197,7 @@ P80211DID_LSB_ACCESS) /*----------------------------------------------------------------*/ -/* The following structure types are used for the represenation */ +/* The following structure types are used for the representation */ /* of ENUMint type metadata. */ typedef struct p80211enumpair { diff --git a/drivers/staging/wlan-ng/prism2fw.c b/drivers/staging/wlan-ng/prism2fw.c index e22784e..0dfd2a4 100644 --- a/drivers/staging/wlan-ng/prism2fw.c +++ b/drivers/staging/wlan-ng/prism2fw.c @@ -806,7 +806,7 @@ static int read_cardpda(struct pda *pda, wlandevice_t *wlandev) * * Note also that the start address record, originally an S7 record in * the srec file, is expected in the fw file to be like a data record but -* with a certain address to make it identiable. +* with a certain address to make it identifiable. * * Here's the SREC format that the fw should have come from: * S[37]nnaaaaaaaaddd...dddcc -- cgit v0.10.2 From 55e7b4fbd47a510b6c8ca53eaf7d9dff816cd26c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sun, 23 Sep 2012 19:31:30 +0300 Subject: staging: rts5139: use kzalloc() to close an info leak If we don't fill the whole buffer then there is information leaked to the user. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/rts51x_fop.c b/drivers/staging/rts5139/rts51x_fop.c index e1200fe..bf1a9e6 100644 --- a/drivers/staging/rts5139/rts51x_fop.c +++ b/drivers/staging/rts5139/rts51x_fop.c @@ -79,7 +79,7 @@ static int rts51x_sd_direct_cmnd(struct rts51x_chip *chip, case 1: /* Read from card */ - buf = kmalloc(cmnd->buf_len, GFP_KERNEL); + buf = kzalloc(cmnd->buf_len, GFP_KERNEL); if (!buf) TRACE_RET(chip, STATUS_NOMEM); -- cgit v0.10.2 From e1656648c920984005019cf39b00b43d2d47b49f Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sun, 23 Sep 2012 12:57:21 -0400 Subject: staging: rtl8712: remove assignment of 0 to a static global variable fixes the following checkpatch warning: drivers/staging/rtl8712/os_intfs.c:99: ERROR: do not initialise statics to 0 or NULL as statics are always initialised to 0. Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8712/os_intfs.c b/drivers/staging/rtl8712/os_intfs.c index 448f00d..e00f791 100644 --- a/drivers/staging/rtl8712/os_intfs.c +++ b/drivers/staging/rtl8712/os_intfs.c @@ -96,7 +96,7 @@ static char *initmac; /* if wifi_test = 1, driver will disable the turbo mode and pass it to * firmware private. */ -static int wifi_test = 0; +static int wifi_test; module_param_string(ifname, ifname, sizeof(ifname), S_IRUGO|S_IWUSR); module_param(wifi_test, int, 0644); -- cgit v0.10.2 From c06df2334ce9a0072c94ffffcd8977fe726015f1 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sun, 23 Sep 2012 12:57:22 -0400 Subject: staging: rtl8712: fix a foo * bar errors reported by checkpatch fixes the following error: drivers/staging/rtl8712/rtl8712_xmit.c:379: ERROR: "foo * bar" should be "foo *bar" Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8712/rtl8712_xmit.c b/drivers/staging/rtl8712/rtl8712_xmit.c index 3d23514..4e3f094 100644 --- a/drivers/staging/rtl8712/rtl8712_xmit.c +++ b/drivers/staging/rtl8712/rtl8712_xmit.c @@ -376,7 +376,7 @@ u8 r8712_dump_aggr_xframe(struct xmit_buf *pxmitbuf, { struct _adapter *padapter = pxmitframe->padapter; struct dvobj_priv *pdvobj = (struct dvobj_priv *) &padapter->dvobjpriv; - struct tx_desc * ptxdesc = (struct tx_desc *)pxmitbuf->pbuf; + struct tx_desc *ptxdesc = (struct tx_desc *)pxmitbuf->pbuf; struct cmd_hdr *pcmd_hdr = (struct cmd_hdr *) (pxmitbuf->pbuf + TXDESC_SIZE); u16 total_length = (u16) (ptxdesc->txdw0 & 0xffff); -- cgit v0.10.2 From 53176607a470092ad62a2268860308f441e493cd Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sun, 23 Sep 2012 12:57:23 -0400 Subject: staging: rtl8712: fix foo* bar (foo*) errors reported by checkpatch fixes the following errors: drivers/staging/rtl8712/rtl871x_security.c:61: ERROR: "foo * bar" should be "foo *bar" drivers/staging/rtl8712/rtl871x_security.c:291: ERROR: "foo * bar" should be "foo *bar" drivers/staging/rtl8712/rtl871x_security.c:323: ERROR: "foo * bar" should be "foo *bar" drivers/staging/rtl8712/rtl871x_security.c:1371: ERROR: "(foo*)" should be "(foo *)" Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8712/rtl871x_security.c b/drivers/staging/rtl8712/rtl871x_security.c index 7b92927..e33fd6d 100644 --- a/drivers/staging/rtl8712/rtl871x_security.c +++ b/drivers/staging/rtl8712/rtl871x_security.c @@ -58,7 +58,7 @@ struct arc4context { u8 state[256]; }; -static void arcfour_init(struct arc4context *parc4ctx, u8 * key, u32 key_len) +static void arcfour_init(struct arc4context *parc4ctx, u8 *key, u32 key_len) { u32 t, u; u32 keyindex; @@ -288,7 +288,7 @@ static void secmicclear(struct mic_data *pmicdata) pmicdata->M = 0; } -void r8712_secmicsetkey(struct mic_data *pmicdata, u8 * key) +void r8712_secmicsetkey(struct mic_data *pmicdata, u8 *key) { /* Set the key */ pmicdata->K0 = secmicgetuint32(key); @@ -320,7 +320,7 @@ static void secmicappendbyte(struct mic_data *pmicdata, u8 b) } } -void r8712_secmicappend(struct mic_data *pmicdata, u8 * src, u32 nbytes) +void r8712_secmicappend(struct mic_data *pmicdata, u8 *src, u32 nbytes) { /* This is simple */ while (nbytes > 0) { @@ -1368,7 +1368,7 @@ u32 r8712_aes_decrypt(struct _adapter *padapter, u8 *precvframe) precvframe)->u.hdr.attrib; struct security_priv *psecuritypriv = &padapter->securitypriv; - pframe = (unsigned char *)((union recv_frame*)precvframe)-> + pframe = (unsigned char *)((union recv_frame *)precvframe)-> u.hdr.rx_data; /* 4 start to encrypt each fragment */ if ((prxattrib->encrypt == _AES_)) { -- cgit v0.10.2 From de473db168ad279fbae5419f03ce0797637ca6df Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Sun, 23 Sep 2012 23:07:10 -0400 Subject: Staging: bcm: Remove typedef for stLocalSFDeleteIndication and call directly. This patch removes typedef for stLocalSFDeleteIndication, and changes the name of the struct to bcm_del_indication. In addition, any calls to the following typedef "stLocalSFDeleteIndication" are changed to call the struct directly. Signed-off-by: Kevin McKinney Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c index 25aa20a..1d1f550 100644 --- a/drivers/staging/bcm/CmHost.c +++ b/drivers/staging/bcm/CmHost.c @@ -1856,10 +1856,10 @@ BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter, /* PLength = sizeof(stLocalSFDeleteIndication); - *((stLocalSFDeleteIndication *)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *((stLocalSFDeleteIndication *)pstAddIndication); + pLeader->PLength = sizeof(struct bcm_del_indication); + *((struct bcm_del_indication *)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *((struct bcm_del_indication *)pstAddIndication); - ulSFID = ntohl(((stLocalSFDeleteIndication *)pstAddIndication)->u32SFID); + ulSFID = ntohl(((struct bcm_del_indication *)pstAddIndication)->u32SFID); uiSearchRuleIndex = SearchSfid(Adapter, ulSFID); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "DSD - Removing connection %x", uiSearchRuleIndex); @@ -1870,7 +1870,7 @@ BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter, /* caDsxReqResp[LEADER_SIZE]))->u8Type = DSD_RSP; + ((struct bcm_del_indication *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSD_RSP; CopyBufferToControlPacket(Adapter, (PVOID)Adapter->caDsxReqResp); } case DSD_RSP: diff --git a/drivers/staging/bcm/cntrl_SignalingInterface.h b/drivers/staging/bcm/cntrl_SignalingInterface.h index 11b3181..a2e1bf5 100644 --- a/drivers/staging/bcm/cntrl_SignalingInterface.h +++ b/drivers/staging/bcm/cntrl_SignalingInterface.h @@ -323,10 +323,7 @@ typedef struct _stLocalSFDeleteRequest { B_UINT32 u32SFID; /* < SFID */ } stLocalSFDeleteRequest, *pstLocalSFDeleteRequest; -/* - * structure stLocalSFDeleteIndication - */ -typedef struct stLocalSFDeleteIndication { +struct bcm_del_indication { B_UINT8 u8Type; /* < Type */ B_UINT8 u8Padding; /* < Padding */ B_UINT16 u16TID; /* < TID */ @@ -339,7 +336,7 @@ typedef struct stLocalSFDeleteIndication { /* brief 8bit Confirmation code */ B_UINT8 u8ConfirmationCode; /* < Confirmation code */ B_UINT8 u8Padding1[3]; /* < 3 byte Padding */ -} stLocalSFDeleteIndication; +}; struct bcm_stim_sfhostnotify { B_UINT32 SFID; /* SFID of the service flow */ -- cgit v0.10.2 From ec5bb992648881f1721a555f9a4652e60e17880f Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Sun, 23 Sep 2012 23:07:11 -0400 Subject: Staging: bcm: Remove typedef for _stLocalSFDeleteRequest and call directly. This patch removes typedef for _stLocalSFDeleteRequest, and changes the name of the struct to bcm_del_request. In addition, any calls to typedefs "stLocalSFDeleteRequest or *pstLocalSFDeleteRequest" are changed to call the struct directly. Signed-off-by: Kevin McKinney Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c index 1d1f550..fd2780d 100644 --- a/drivers/staging/bcm/CmHost.c +++ b/drivers/staging/bcm/CmHost.c @@ -1335,7 +1335,7 @@ ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBu { stLocalSFAddIndicationAlt *pstAddIndicationAlt = NULL; stLocalSFAddIndication *pstAddIndication = NULL; - stLocalSFDeleteRequest *pstDeletionRequest; + struct bcm_del_request *pstDeletionRequest; UINT uiSearchRuleIndex; ULONG ulSFID; @@ -1346,7 +1346,7 @@ ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBu * we can stop the further classifying the pkt for this SF. */ if (pstAddIndicationAlt->u8Type == DSD_REQ) { - pstDeletionRequest = (stLocalSFDeleteRequest *)pvBuffer; + pstDeletionRequest = (struct bcm_del_request *)pvBuffer; ulSFID = ntohl(pstDeletionRequest->u32SFID); uiSearchRuleIndex = SearchSfid(Adapter, ulSFID); diff --git a/drivers/staging/bcm/cntrl_SignalingInterface.h b/drivers/staging/bcm/cntrl_SignalingInterface.h index a2e1bf5..0f9ecc0 100644 --- a/drivers/staging/bcm/cntrl_SignalingInterface.h +++ b/drivers/staging/bcm/cntrl_SignalingInterface.h @@ -312,16 +312,13 @@ typedef struct _stLocalSFAddIndication stLocalSFChangeRequest, *pstLocalSFChange */ typedef struct _stLocalSFAddIndication stLocalSFChangeIndication, *pstLocalSFChangeIndication; -/* - * structure stLocalSFDeleteRequest - */ -typedef struct _stLocalSFDeleteRequest { +struct bcm_del_request { B_UINT8 u8Type; /* < Type */ B_UINT8 u8Padding; /* < Padding byte */ B_UINT16 u16TID; /* < TID */ /* brief 32bitSFID */ B_UINT32 u32SFID; /* < SFID */ -} stLocalSFDeleteRequest, *pstLocalSFDeleteRequest; +}; struct bcm_del_indication { B_UINT8 u8Type; /* < Type */ -- cgit v0.10.2 From da529f0ffb03b90f8d6a462f2681e72f4da7032a Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Sun, 23 Sep 2012 23:07:12 -0400 Subject: Staging: bcm: Remove typedef for _stLocalSFAddIndication and call directly. This patch removes typedef for _stLocalSFAddIndication, and changes the name of the struct to bcm_add_indication. In addition, any calls to typedefs "stLocalSFAddIndication, *pstLocalSFAddIndication, stLocalSFChangeRequest, *pstLocalSFChangeRequest, stLocalSFChangeIndication, or *pstLocalSFChangeIndication " are changed to call the struct directly. Signed-off-by: Kevin McKinney Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c index fd2780d..e1a93481 100644 --- a/drivers/staging/bcm/CmHost.c +++ b/drivers/staging/bcm/CmHost.c @@ -1334,7 +1334,7 @@ static ULONG StoreSFParam(struct bcm_mini_adapter *Adapter, PUCHAR pucSrcBuffer, ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBuffer, UINT *puBufferLength) { stLocalSFAddIndicationAlt *pstAddIndicationAlt = NULL; - stLocalSFAddIndication *pstAddIndication = NULL; + struct bcm_add_indication *pstAddIndication = NULL; struct bcm_del_request *pstDeletionRequest; UINT uiSearchRuleIndex; ULONG ulSFID; @@ -1365,7 +1365,7 @@ ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBu } /* For DSA_REQ, only up to "psfAuthorizedSet" parameter should be accessed by driver! */ - pstAddIndication = kmalloc(sizeof(*pstAddIndication), GFP_KERNEL); + pstAddIndication = kmalloc(sizeof(struct bcm_add_indication), GFP_KERNEL); if (pstAddIndication == NULL) return 0; @@ -1439,8 +1439,8 @@ ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBu pstAddIndication->psfActiveSet = (stServiceFlowParamSI *)ntohl((ULONG)pstAddIndication->psfActiveSet); - (*puBufferLength) = sizeof(stLocalSFAddIndication); - *(stLocalSFAddIndication *)pvBuffer = *pstAddIndication; + (*puBufferLength) = sizeof(struct bcm_add_indication); + *(struct bcm_add_indication *)pvBuffer = *pstAddIndication; kfree(pstAddIndication); return 1; } @@ -1449,10 +1449,10 @@ static inline stLocalSFAddIndicationAlt *RestoreCmControlResponseMessage(register struct bcm_mini_adapter *Adapter, register PVOID pvBuffer) { ULONG ulStatus = 0; - stLocalSFAddIndication *pstAddIndication = NULL; + struct bcm_add_indication *pstAddIndication = NULL; stLocalSFAddIndicationAlt *pstAddIndicationDest = NULL; - pstAddIndication = (stLocalSFAddIndication *)(pvBuffer); + pstAddIndication = (struct bcm_add_indication *)(pvBuffer); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "=====>"); if ((pstAddIndication->u8Type == DSD_REQ) || (pstAddIndication->u8Type == DSD_RSP) || @@ -1644,7 +1644,7 @@ BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter, /* u16TID, FALSE); + ClearTargetDSXBuffer(Adapter, ((struct bcm_add_indication *)pvBuffer)->u16TID, FALSE); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Error in restoring Service Flow param structure from DSx message"); return FALSE; } diff --git a/drivers/staging/bcm/cntrl_SignalingInterface.h b/drivers/staging/bcm/cntrl_SignalingInterface.h index 0f9ecc0..fbdc231 100644 --- a/drivers/staging/bcm/cntrl_SignalingInterface.h +++ b/drivers/staging/bcm/cntrl_SignalingInterface.h @@ -277,10 +277,7 @@ typedef struct _stLocalSFAddRequest { } stLocalSFAddRequest, *pstLocalSFAddRequest; -/* - * structure stLocalSFAddIndication - */ -typedef struct _stLocalSFAddIndication { +struct bcm_add_indication { B_UINT8 u8Type; /* < Type */ B_UINT8 eConnectionDir; /* < Connection Direction */ /* brief 16 bit TID */ @@ -299,18 +296,7 @@ typedef struct _stLocalSFAddIndication { B_UINT8 u8CC; /* Date: Sun, 23 Sep 2012 23:07:13 -0400 Subject: Staging: bcm: Remove typedef for _stLocalSFAddRequest and call directly. This patch removes typedef for _stLocalSFAddRequest, and changes the name of the struct to bcm_add_request. In addition, any calls to typedefs "stLocalSFAddRequest or *pstLocalSFAddRequest" are changed to call the struct directly. Signed-off-by: Kevin McKinney Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c index e1a93481..96fd158 100644 --- a/drivers/staging/bcm/CmHost.c +++ b/drivers/staging/bcm/CmHost.c @@ -1387,7 +1387,7 @@ ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBu pstAddIndication->psfAuthorizedSet = (stServiceFlowParamSI *)ntohl((ULONG)pstAddIndication->psfAuthorizedSet); if (pstAddIndicationAlt->u8Type == DSA_REQ) { - stLocalSFAddRequest AddRequest; + struct bcm_add_request AddRequest; AddRequest.u8Type = pstAddIndicationAlt->u8Type; AddRequest.eConnectionDir = pstAddIndicationAlt->u8Direction; @@ -1395,8 +1395,8 @@ ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBu AddRequest.u16CID = pstAddIndicationAlt->u16CID; AddRequest.u16VCID = pstAddIndicationAlt->u16VCID; AddRequest.psfParameterSet = pstAddIndication->psfAuthorizedSet; - (*puBufferLength) = sizeof(stLocalSFAddRequest); - memcpy(pvBuffer, &AddRequest, sizeof(stLocalSFAddRequest)); + (*puBufferLength) = sizeof(struct bcm_add_request); + memcpy(pvBuffer, &AddRequest, sizeof(struct bcm_add_request)); kfree(pstAddIndication); return 1; } diff --git a/drivers/staging/bcm/cntrl_SignalingInterface.h b/drivers/staging/bcm/cntrl_SignalingInterface.h index fbdc231..43d462e 100644 --- a/drivers/staging/bcm/cntrl_SignalingInterface.h +++ b/drivers/staging/bcm/cntrl_SignalingInterface.h @@ -260,10 +260,7 @@ typedef struct _stServiceFlowParamSI { } stServiceFlowParamSI, *pstServiceFlowParamSI; typedef stServiceFlowParamSI CServiceFlowParamSI; -/* - * structure stLocalSFAddRequest - */ -typedef struct _stLocalSFAddRequest { +struct bcm_add_request { B_UINT8 u8Type; /* < Type */ B_UINT8 eConnectionDir; /* < Connection direction */ /* brief 16 bit TID */ @@ -274,8 +271,7 @@ typedef struct _stLocalSFAddRequest { B_UINT16 u16VCID; /* < 16bit VCID */ /* brief structure ParameterSet */ stServiceFlowParamSI *psfParameterSet; /* < structure ParameterSet */ - -} stLocalSFAddRequest, *pstLocalSFAddRequest; +}; struct bcm_add_indication { B_UINT8 u8Type; /* < Type */ -- cgit v0.10.2 From b766fb15e1c489d1e5b5a80501593f61fae3a7eb Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Sun, 23 Sep 2012 23:07:14 -0400 Subject: Staging: bcm: Remove typedef for _stServiceFlowParamSI and call directly. This patch removes typedef for _stServiceFlowParamSI, changes the name of the struct to bcm_connect_mgr_params, and updates the comments appropriately. In addition, any calls to typedefs "stServiceFlowParamSI, *pstServiceFlowParamSI, and CServiceFlowParamSI" are changed to call the struct directly. Signed-off-by: Kevin McKinney Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c index 96fd158..af7f7c6 100644 --- a/drivers/staging/bcm/CmHost.c +++ b/drivers/staging/bcm/CmHost.c @@ -428,7 +428,7 @@ VOID DeleteAllClassifiersForSF(struct bcm_mini_adapter *Adapter, UINT uiSearchRu * @ingroup ctrl_pkt_functions */ static VOID CopyToAdapter(register struct bcm_mini_adapter *Adapter, /* psfAuthorizedSet = (stServiceFlowParamSI *) + pstAddIndication->psfAuthorizedSet = (struct bcm_connect_mgr_params *) GetNextTargetBufferLocation(Adapter, pstAddIndicationAlt->u16TID); if (!pstAddIndication->psfAuthorizedSet) { kfree(pstAddIndication); @@ -1384,7 +1384,7 @@ ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBu } /* this can't possibly be right */ - pstAddIndication->psfAuthorizedSet = (stServiceFlowParamSI *)ntohl((ULONG)pstAddIndication->psfAuthorizedSet); + pstAddIndication->psfAuthorizedSet = (struct bcm_connect_mgr_params *)ntohl((ULONG)pstAddIndication->psfAuthorizedSet); if (pstAddIndicationAlt->u8Type == DSA_REQ) { struct bcm_add_request AddRequest; @@ -1412,7 +1412,7 @@ ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBu pstAddIndication->u8CC = pstAddIndicationAlt->u8CC; /* ADMITTED SET */ - pstAddIndication->psfAdmittedSet = (stServiceFlowParamSI *) + pstAddIndication->psfAdmittedSet = (struct bcm_connect_mgr_params *) GetNextTargetBufferLocation(Adapter, pstAddIndicationAlt->u16TID); if (!pstAddIndication->psfAdmittedSet) { kfree(pstAddIndication); @@ -1423,10 +1423,10 @@ ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBu return 0; } - pstAddIndication->psfAdmittedSet = (stServiceFlowParamSI *)ntohl((ULONG)pstAddIndication->psfAdmittedSet); + pstAddIndication->psfAdmittedSet = (struct bcm_connect_mgr_params *)ntohl((ULONG)pstAddIndication->psfAdmittedSet); /* ACTIVE SET */ - pstAddIndication->psfActiveSet = (stServiceFlowParamSI *) + pstAddIndication->psfActiveSet = (struct bcm_connect_mgr_params *) GetNextTargetBufferLocation(Adapter, pstAddIndicationAlt->u16TID); if (!pstAddIndication->psfActiveSet) { kfree(pstAddIndication); @@ -1437,7 +1437,7 @@ ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBu return 0; } - pstAddIndication->psfActiveSet = (stServiceFlowParamSI *)ntohl((ULONG)pstAddIndication->psfActiveSet); + pstAddIndication->psfActiveSet = (struct bcm_connect_mgr_params *)ntohl((ULONG)pstAddIndication->psfActiveSet); (*puBufferLength) = sizeof(struct bcm_add_indication); *(struct bcm_add_indication *)pvBuffer = *pstAddIndication; @@ -1539,7 +1539,7 @@ ULONG SetUpTargetDsxBuffers(struct bcm_mini_adapter *Adapter) if (Adapter->astTargetDsxBuffer[0].ulTargetDsxBuffer) return 1; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Size of Each DSX Buffer(Also size of ServiceFlowParamSI): %zx ", sizeof(stServiceFlowParamSI)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Size of Each DSX Buffer(Also size of connection manager parameters): %zx ", sizeof(struct bcm_connect_mgr_params)); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Reading DSX buffer From Target location %x ", DSX_MESSAGE_EXCHANGE_BUFFER); Status = rdmalt(Adapter, DSX_MESSAGE_EXCHANGE_BUFFER, (PUINT)&ulTargetDsxBuffersBase, sizeof(UINT)); @@ -1550,7 +1550,7 @@ ULONG SetUpTargetDsxBuffers(struct bcm_mini_adapter *Adapter) BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Base Address Of DSX Target Buffer : 0x%lx", ulTargetDsxBuffersBase); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Tgt Buffer is Now %lx :", ulTargetDsxBuffersBase); - ulCntTargetBuffers = DSX_MESSAGE_EXCHANGE_BUFFER_SIZE / sizeof(stServiceFlowParamSI); + ulCntTargetBuffers = DSX_MESSAGE_EXCHANGE_BUFFER_SIZE / sizeof(struct bcm_connect_mgr_params); Adapter->ulTotalTargetBuffersAvailable = ulCntTargetBuffers > MAX_TARGET_DSX_BUFFERS ? @@ -1562,7 +1562,7 @@ ULONG SetUpTargetDsxBuffers(struct bcm_mini_adapter *Adapter) Adapter->astTargetDsxBuffer[i].ulTargetDsxBuffer = ulTargetDsxBuffersBase; Adapter->astTargetDsxBuffer[i].valid = 1; Adapter->astTargetDsxBuffer[i].tid = 0; - ulTargetDsxBuffersBase += sizeof(stServiceFlowParamSI); + ulTargetDsxBuffersBase += sizeof(struct bcm_connect_mgr_params); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " Target DSX Buffer %lx setup at 0x%lx", i, Adapter->astTargetDsxBuffer[i].ulTargetDsxBuffer); } @@ -1633,7 +1633,7 @@ int FreeAdapterDsxBuffer(struct bcm_mini_adapter *Adapter) BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter, /* PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable; -- cgit v0.10.2 From c07b53131ef87e11d14402a588a44440892f946c Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Sun, 23 Sep 2012 23:07:15 -0400 Subject: Staging: bcm: Remove typedef for _stConvergenceSLTypes and call directly. This patch removes typedef for _stConvergenceSLTypes, changes the name of the struct to bcm_convergence_types, and updates the comments appropriately. In addition, any calls to typedefs "stConvergenceSLTypes, CConvergenceSLTypes, and *pstConvergenceSLTypes" are changed to call the struct directly. Signed-off-by: Kevin McKinney Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c index af7f7c6..325b592 100644 --- a/drivers/staging/bcm/CmHost.c +++ b/drivers/staging/bcm/CmHost.c @@ -235,7 +235,7 @@ void ClearTargetDSXBuffer(struct bcm_mini_adapter *Adapter, B_UINT16 TID, BOOLEA * @ingroup ctrl_pkt_functions * copy classifier rule into the specified SF index */ -static inline VOID CopyClassifierRuleToSF(struct bcm_mini_adapter *Adapter, stConvergenceSLTypes *psfCSType, UINT uiSearchRuleIndex, UINT nClassifierIndex) +static inline VOID CopyClassifierRuleToSF(struct bcm_mini_adapter *Adapter, struct bcm_convergence_types *psfCSType, UINT uiSearchRuleIndex, UINT nClassifierIndex) { struct bcm_classifier_rule *pstClassifierEntry = NULL; /* VOID *pvPhsContext = NULL; */ @@ -439,7 +439,7 @@ static VOID CopyToAdapter(register struct bcm_mini_adapter *Adapter, /* PackInfo[uiSearchRuleIndex].usVCID_Value; UINT UGIValue = 0; @@ -915,7 +915,7 @@ static VOID DumpCmControlPacket(PVOID pvBuffer) if (!pstAddIndication->sfAuthorizedSet.bValid) pstAddIndication->sfAuthorizedSet.bValid = 1; for (nIndex = 0; nIndex < nCurClassifierCnt; nIndex++) { - stConvergenceSLTypes *psfCSType = NULL; + struct bcm_convergence_types *psfCSType = NULL; psfCSType = &pstAddIndication->sfAuthorizedSet.cConvergenceSLTypes[nIndex]; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "psfCSType = %p", psfCSType); @@ -1059,7 +1059,7 @@ static VOID DumpCmControlPacket(PVOID pvBuffer) nCurClassifierCnt = MAX_CLASSIFIERS_IN_SF; for (nIndex = 0; nIndex < nCurClassifierCnt; nIndex++) { - stConvergenceSLTypes *psfCSType = NULL; + struct bcm_convergence_types *psfCSType = NULL; psfCSType = &pstAddIndication->sfAdmittedSet.cConvergenceSLTypes[nIndex]; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " CCPacketClassificationRuleSI====>"); @@ -1198,7 +1198,7 @@ static VOID DumpCmControlPacket(PVOID pvBuffer) nCurClassifierCnt = MAX_CLASSIFIERS_IN_SF; for (nIndex = 0; nIndex < nCurClassifierCnt; nIndex++) { - stConvergenceSLTypes *psfCSType = NULL; + struct bcm_convergence_types *psfCSType = NULL; psfCSType = &pstAddIndication->sfActiveSet.cConvergenceSLTypes[nIndex]; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " CCPacketClassificationRuleSI====>"); diff --git a/drivers/staging/bcm/cntrl_SignalingInterface.h b/drivers/staging/bcm/cntrl_SignalingInterface.h index 3694255..1bf4780 100644 --- a/drivers/staging/bcm/cntrl_SignalingInterface.h +++ b/drivers/staging/bcm/cntrl_SignalingInterface.h @@ -122,8 +122,7 @@ typedef struct _stPhsRuleSI { } stPhsRuleSI, *pstPhsRuleSI; typedef stPhsRuleSI CPhsRuleSI; -/* brief structure cConvergenceSLTypes */ -struct _stConvergenceSLTypes { +struct bcm_convergence_types { /* 8bit Phs Classfier Action Of The Service Flow */ B_UINT8 u8ClassfierDSCAction; /* 8bit Phs DSC Action Of The Service Flow */ @@ -135,7 +134,6 @@ struct _stConvergenceSLTypes { /* brief class CPhsRuleSI */ struct _stPhsRuleSI cPhsRule; }; -typedef struct _stConvergenceSLTypes stConvergenceSLTypes, CConvergenceSLTypes, *pstConvergenceSLTypes; struct bcm_connect_mgr_params { /* 32bitSFID Of The Service Flow */ @@ -251,10 +249,10 @@ struct bcm_connect_mgr_params { B_UINT8 u8TotalClassifiers; /* < Total number of valid classifiers */ B_UINT8 bValid; /* < Validity flag */ B_UINT8 u8Padding; /* < Padding byte */ -/* - * Structure for Convergence SubLayer Types with a maximum of 4 classifiers - */ - stConvergenceSLTypes cConvergenceSLTypes[MAX_CLASSIFIERS_IN_SF]; + /* + * Structure for Convergence SubLayer Types with a maximum of 4 classifiers + */ + struct bcm_convergence_types cConvergenceSLTypes[MAX_CLASSIFIERS_IN_SF]; }; struct bcm_add_request { -- cgit v0.10.2 From d2a392c2bd1dde3e5b8391a23ca1df7ea3d5cec5 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Sun, 23 Sep 2012 23:07:16 -0400 Subject: Staging: bcm: Remove typedef for _stPhsRuleSI and call directly. This patch removes typedef for _stPhsRuleSI, changes the name of the struct to bcm_phs_rules, and updates the comments appropriately. In addition, any calls to typedefs "stPhsRuleSI, *pstPhsRuleSI, or CPhsRuleSI" are changed to call the struct directly. Signed-off-by: Kevin McKinney Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/cntrl_SignalingInterface.h b/drivers/staging/bcm/cntrl_SignalingInterface.h index 1bf4780..f67cb6e 100644 --- a/drivers/staging/bcm/cntrl_SignalingInterface.h +++ b/drivers/staging/bcm/cntrl_SignalingInterface.h @@ -98,8 +98,7 @@ struct _stCPacketClassificationRuleSI { }; typedef struct _stCPacketClassificationRuleSI CCPacketClassificationRuleSI, stCPacketClassificationRuleSI, *pstCPacketClassificationRuleSI; -/* brief class CPhsRuleSI */ -typedef struct _stPhsRuleSI { +struct bcm_phs_rules { /* 8bit PHS Index Of The Service Flow */ B_UINT8 u8PHSI; /* PHSF Length Of The Service Flow */ @@ -119,8 +118,7 @@ typedef struct _stPhsRuleSI { /* Vendor Specific PHS param Of The Service Flow */ B_UINT8 u8VendorSpecificPHSParams[VENDOR_PHS_PARAM_LENGTH]; B_UINT8 u8Padding[2]; -} stPhsRuleSI, *pstPhsRuleSI; -typedef stPhsRuleSI CPhsRuleSI; +}; struct bcm_convergence_types { /* 8bit Phs Classfier Action Of The Service Flow */ @@ -131,8 +129,8 @@ struct bcm_convergence_types { B_UINT8 u8Padding[2]; /* brief class cCPacketClassificationRule */ stCPacketClassificationRuleSI cCPacketClassificationRule; - /* brief class CPhsRuleSI */ - struct _stPhsRuleSI cPhsRule; + /* Payload header suppression rules structure */ + struct bcm_phs_rules cPhsRule; }; struct bcm_connect_mgr_params { -- cgit v0.10.2 From 4b0cb3cb3bf96fd22bc9c5b0de5a3751f18e8fb6 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Sun, 23 Sep 2012 23:07:17 -0400 Subject: Staging: bcm: Remove typedef for _stCPacketClassificationRuleSI and call directly. This patch removes typedef for _stCPacketClassificationRuleSI, changes the name of the struct to bcm_packet_class_rules, and updates the comments appropriately . In addition, any calls to typedefs "CCPacketClassificationRuleSI, stCPacketClassificationRuleSI, or *pstCPacketClassificationRuleSI" are changed to call the struct directly. Signed-off-by: Kevin McKinney Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/cntrl_SignalingInterface.h b/drivers/staging/bcm/cntrl_SignalingInterface.h index f67cb6e..990e809 100644 --- a/drivers/staging/bcm/cntrl_SignalingInterface.h +++ b/drivers/staging/bcm/cntrl_SignalingInterface.h @@ -34,12 +34,7 @@ #define NUM_ETHERTYPE_BYTES 3 #define NUM_IPV6_FLOWLABLE_BYTES 3 -/* - * structure Definitions - * - * brief class cCPacketClassificationRule - */ -struct _stCPacketClassificationRuleSI { +struct bcm_packet_class_rules { /* 16bit UserPriority Of The Service Flow */ B_UINT16 u16UserPriority; /* 16bit VLANID Of The Service Flow */ @@ -96,7 +91,6 @@ struct _stCPacketClassificationRuleSI { B_UINT8 u8ClassifierActionRule; B_UINT16 u16ValidityBitMap; }; -typedef struct _stCPacketClassificationRuleSI CCPacketClassificationRuleSI, stCPacketClassificationRuleSI, *pstCPacketClassificationRuleSI; struct bcm_phs_rules { /* 8bit PHS Index Of The Service Flow */ @@ -127,8 +121,8 @@ struct bcm_convergence_types { B_UINT8 u8PhsDSCAction; /* 16bit Padding */ B_UINT8 u8Padding[2]; - /* brief class cCPacketClassificationRule */ - stCPacketClassificationRuleSI cCPacketClassificationRule; + /* Packet classification rules structure */ + struct bcm_packet_class_rules cCPacketClassificationRule; /* Payload header suppression rules structure */ struct bcm_phs_rules cPhsRule; }; -- cgit v0.10.2 From 9d54814f31ea4f577db2b2d49c00b2f9bcb0c124 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 21 Sep 2012 12:05:45 +0100 Subject: staging: comedi: ni_daq_700: use prefix daq700 Rename a few functions and variables to use the prefix `daq700` instead of the prefix or suffix `dio700`. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 7355860..53bce6c 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -51,7 +51,7 @@ emu as port A output, port B input, port C N/A). static struct pcmcia_device *pcmcia_cur_dev; -struct dio700_board { +struct daq700_board { const char *name; }; @@ -97,9 +97,9 @@ static int subdev_700_insn_config(struct comedi_device *dev, return insn->n; } -static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it) +static int daq700_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - const struct dio700_board *thisboard = comedi_board(dev); + const struct daq700_board *thisboard = comedi_board(dev); struct comedi_subdevice *s; struct pcmcia_device *link; int ret; @@ -141,12 +141,12 @@ static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it) return 0; } -static void dio700_detach(struct comedi_device *dev) +static void daq700_detach(struct comedi_device *dev) { /* nothing to cleanup */ } -static const struct dio700_board dio700_boards[] = { +static const struct daq700_board daq700_boards[] = { { .name = "daqcard-700", }, { @@ -154,17 +154,17 @@ static const struct dio700_board dio700_boards[] = { }, }; -static struct comedi_driver driver_dio700 = { +static struct comedi_driver daq700_driver = { .driver_name = "ni_daq_700", .module = THIS_MODULE, - .attach = dio700_attach, - .detach = dio700_detach, - .board_name = &dio700_boards[0].name, - .num_names = ARRAY_SIZE(dio700_boards), - .offset = sizeof(struct dio700_board), + .attach = daq700_attach, + .detach = daq700_detach, + .board_name = &daq700_boards[0].name, + .num_names = ARRAY_SIZE(daq700_boards), + .offset = sizeof(struct daq700_board), }; -static int dio700_pcmcia_config_loop(struct pcmcia_device *p_dev, +static int daq700_pcmcia_config_loop(struct pcmcia_device *p_dev, void *priv_data) { if (p_dev->config_index == 0) @@ -173,14 +173,14 @@ static int dio700_pcmcia_config_loop(struct pcmcia_device *p_dev, return pcmcia_request_io(p_dev); } -static int dio700_cs_attach(struct pcmcia_device *link) +static int daq700_cs_attach(struct pcmcia_device *link) { int ret; link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_AUDIO | CONF_AUTO_SET_IO; - ret = pcmcia_loop_config(link, dio700_pcmcia_config_loop, NULL); + ret = pcmcia_loop_config(link, daq700_pcmcia_config_loop, NULL); if (ret) goto failed; @@ -199,50 +199,50 @@ failed: return ret; } -static void dio700_cs_detach(struct pcmcia_device *link) +static void daq700_cs_detach(struct pcmcia_device *link) { pcmcia_disable_device(link); pcmcia_cur_dev = NULL; } -static const struct pcmcia_device_id dio700_cs_ids[] = { +static const struct pcmcia_device_id daq700_cs_ids[] = { PCMCIA_DEVICE_MANF_CARD(0x010b, 0x4743), PCMCIA_DEVICE_NULL }; -MODULE_DEVICE_TABLE(pcmcia, dio700_cs_ids); +MODULE_DEVICE_TABLE(pcmcia, daq700_cs_ids); -static struct pcmcia_driver dio700_cs_driver = { +static struct pcmcia_driver daq700_cs_driver = { .name = "ni_daq_700", .owner = THIS_MODULE, - .probe = dio700_cs_attach, - .remove = dio700_cs_detach, - .id_table = dio700_cs_ids, + .probe = daq700_cs_attach, + .remove = daq700_cs_detach, + .id_table = daq700_cs_ids, }; -static int __init dio700_cs_init(void) +static int __init daq700_cs_init(void) { int ret; - ret = comedi_driver_register(&driver_dio700); + ret = comedi_driver_register(&daq700_driver); if (ret < 0) return ret; - ret = pcmcia_register_driver(&dio700_cs_driver); + ret = pcmcia_register_driver(&daq700_cs_driver); if (ret < 0) { - comedi_driver_unregister(&driver_dio700); + comedi_driver_unregister(&daq700_driver); return ret; } return 0; } -module_init(dio700_cs_init); +module_init(daq700_cs_init); -static void __exit dio700_cs_exit(void) +static void __exit daq700_cs_exit(void) { - pcmcia_unregister_driver(&dio700_cs_driver); - comedi_driver_unregister(&driver_dio700); + pcmcia_unregister_driver(&daq700_cs_driver); + comedi_driver_unregister(&daq700_driver); } -module_exit(dio700_cs_exit); +module_exit(daq700_cs_exit); MODULE_AUTHOR("Fred Brooks "); MODULE_DESCRIPTION( -- cgit v0.10.2 From 08351926d23577711c48ef63168b1255702c6c77 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 21 Sep 2012 12:05:46 +0100 Subject: staging: comedi: ni_daq_700: rename functions for DIO subdevice Rename `subdev_700_insn()` to `daq700_dio_insn_bits()` and `subdev_700_insn_config()` to `daq700_dio_insn_config()`. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 53bce6c..2318463 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -58,9 +58,9 @@ struct daq700_board { #define DIO_W 0x04 #define DIO_R 0x05 -static int subdev_700_insn(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data) +static int daq700_dio_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) { if (data[0]) { s->state &= ~data[0]; @@ -76,7 +76,7 @@ static int subdev_700_insn(struct comedi_device *dev, return insn->n; } -static int subdev_700_insn_config(struct comedi_device *dev, +static int daq700_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { @@ -127,8 +127,8 @@ static int daq700_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->n_chan = 16; s->range_table = &range_digital; s->maxdata = 1; - s->insn_bits = subdev_700_insn; - s->insn_config = subdev_700_insn_config; + s->insn_bits = daq700_dio_insn_bits; + s->insn_config = daq700_dio_insn_config; s->state = 0; s->io_bits = 0x00ff; -- cgit v0.10.2 From 198b0fa48b25b60e4857132a7c55c9e6e18748d9 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 21 Sep 2012 12:05:47 +0100 Subject: staging: comedi: ni_daq_700: add AI subdevice Add subdevice 1 as an analog input (AI) subdevice. It currently only supports basic, software-triggered acquisitions. This is mostly the work of Fred Brooks (MODULE_AUTHOR), but he based his update on an older version of the driver. I applied the relevant changes with a few tweaks: adding an explicit `udelay(1)` in a timeout loop, replacing binary constants with hex, renaming functions, replacing `printk()` calls, removing exported symbols, removing (very) incomplete comedi "command" support, and making some coding-style changes. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 2318463..2ba0ade 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -1,6 +1,6 @@ /* * comedi/drivers/ni_daq_700.c - * Driver for DAQCard-700 DIO only + * Driver for DAQCard-700 DIO/AI * copied from 8255 * * COMEDI - Linux Control and Measurement Device Interface @@ -29,14 +29,25 @@ Author: Fred Brooks , based on ni_daq_dio24 by Daniel Vecino Castel Devices: [National Instruments] PCMCIA DAQ-Card-700 (ni_daq_700) Status: works -Updated: Thu, 21 Feb 2008 12:07:20 +0000 +Updated: Wed, 19 Sep 2012 12:07:20 +0000 -The daqcard-700 appears in Comedi as a single digital I/O subdevice with -16 channels. The channel 0 corresponds to the daqcard-700's output +The daqcard-700 appears in Comedi as a digital I/O subdevice (0) with +16 channels and a analog input subdevice (1) with 16 single-ended channels. + +Digital: The channel 0 corresponds to the daqcard-700's output port, bit 0; channel 8 corresponds to the input port, bit 0. -Direction configuration: channels 0-7 output, 8-15 input (8225 device +Digital direction configuration: channels 0-7 output, 8-15 input (8225 device emu as port A output, port B input, port C N/A). + +Analog: The input range is 0 to 4095 for -10 to +10 volts +IRQ is assigned but not used. + +Version 0.1 Original DIO only driver +Version 0.2 DIO and basic AI analog input support on 16 se channels + +Manuals: Register level: http://www.ni.com/pdf/manuals/340698.pdf + User Manual: http://www.ni.com/pdf/manuals/320676d.pdf */ #include @@ -55,8 +66,21 @@ struct daq700_board { const char *name; }; -#define DIO_W 0x04 -#define DIO_R 0x05 +/* daqcard700 registers */ +#define DIO_W 0x04 /* WO 8bit */ +#define DIO_R 0x05 /* RO 8bit */ +#define CMD_R1 0x00 /* WO 8bit */ +#define CMD_R2 0x07 /* RW 8bit */ +#define CMD_R3 0x05 /* W0 8bit */ +#define STA_R1 0x00 /* RO 8bit */ +#define STA_R2 0x01 /* RO 8bit */ +#define ADFIFO_R 0x02 /* RO 16bit */ +#define ADCLEAR_R 0x01 /* WO 8bit */ +#define CDA_R0 0x08 /* RW 8bit */ +#define CDA_R1 0x09 /* RW 8bit */ +#define CDA_R2 0x0A /* RW 8bit */ +#define CMO_R 0x0B /* RO 8bit */ +#define TIC_R 0x06 /* WO 8bit */ static int daq700_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, @@ -97,6 +121,87 @@ static int daq700_dio_insn_config(struct comedi_device *dev, return insn->n; } +static int daq700_ai_rinsn(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + int n, i, chan; + int d; + unsigned int status; + enum { TIMEOUT = 100 }; + + chan = CR_CHAN(insn->chanspec); + /* write channel to multiplexer */ + /* set mask scan bit high to disable scanning */ + outb(chan | 0x80, dev->iobase + CMD_R1); + + /* convert n samples */ + for (n = 0; n < insn->n; n++) { + /* trigger conversion with out0 L to H */ + outb(0x00, dev->iobase + CMD_R2); /* enable ADC conversions */ + outb(0x30, dev->iobase + CMO_R); /* mode 0 out0 L, from H */ + /* mode 1 out0 H, L to H, start conversion */ + outb(0x32, dev->iobase + CMO_R); + /* wait for conversion to end */ + for (i = 0; i < TIMEOUT; i++) { + status = inb(dev->iobase + STA_R2); + if ((status & 0x03) != 0) { + dev_info(dev->class_dev, + "Overflow/run Error\n"); + return -EOVERFLOW; + } + status = inb(dev->iobase + STA_R1); + if ((status & 0x02) != 0) { + dev_info(dev->class_dev, "Data Error\n"); + return -ENODATA; + } + if ((status & 0x11) == 0x01) { + /* ADC conversion complete */ + break; + } + udelay(1); + } + if (i == TIMEOUT) { + dev_info(dev->class_dev, + "timeout during ADC conversion\n"); + return -ETIMEDOUT; + } + /* read data */ + d = inw(dev->iobase + ADFIFO_R); + /* mangle the data as necessary */ + /* Bipolar Offset Binary: 0 to 4095 for -10 to +10 */ + d &= 0x0fff; + d ^= 0x0800; + data[n] = d; + } + return n; +} + +/* + * Data acquisition is enabled. + * The counter 0 output is high. + * The I/O connector pin CLK1 drives counter 1 source. + * Multiple-channel scanning is disabled. + * All interrupts are disabled. + * The analog input range is set to +-10 V + * The analog input mode is single-ended. + * The analog input circuitry is initialized to channel 0. + * The A/D FIFO is cleared. + */ +static void daq700_ai_config(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + unsigned long iobase = dev->iobase; + + outb(0x80, iobase + CMD_R1); /* disable scanning, ADC to chan 0 */ + outb(0x00, iobase + CMD_R2); /* clear all bits */ + outb(0x00, iobase + CMD_R3); /* set +-10 range */ + outb(0x32, iobase + CMO_R); /* config counter mode1, out0 to H */ + outb(0x00, iobase + TIC_R); /* clear counter interrupt */ + outb(0x00, iobase + ADCLEAR_R); /* clear the ADC FIFO */ + inw(iobase + ADFIFO_R); /* read 16bit junk from FIFO to clear */ +} + static int daq700_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct daq700_board *thisboard = comedi_board(dev); @@ -116,7 +221,7 @@ static int daq700_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = thisboard->name; - ret = comedi_alloc_subdevices(dev, 1); + ret = comedi_alloc_subdevices(dev, 2); if (ret) return ret; @@ -129,10 +234,20 @@ static int daq700_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->maxdata = 1; s->insn_bits = daq700_dio_insn_bits; s->insn_config = daq700_dio_insn_config; - s->state = 0; s->io_bits = 0x00ff; + /* DAQCard-700 ai */ + s = &dev->subdevices[1]; + s->type = COMEDI_SUBD_AI; + /* we support single-ended (ground) */ + s->subdev_flags = SDF_READABLE | SDF_GROUND; + s->n_chan = 16; + s->maxdata = (1 << 12) - 1; + s->range_table = &range_bipolar10; + s->insn_read = daq700_ai_rinsn; + daq700_ai_config(dev, s); + dev_info(dev->class_dev, "%s: %s, io 0x%lx\n", dev->driver->driver_name, dev->board_name, @@ -246,5 +361,6 @@ module_exit(daq700_cs_exit); MODULE_AUTHOR("Fred Brooks "); MODULE_DESCRIPTION( - "Comedi driver for National Instruments PCMCIA DAQCard-700 DIO"); + "Comedi driver for National Instruments PCMCIA DAQCard-700 DIO/AI"); +MODULE_VERSION("0.2.00"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 832defbb58061fedb7a5c43aab7d762afaac2cc9 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 24 Sep 2012 13:21:30 -0700 Subject: staging: comedi: s626: remove boardinfo This driver only supports one board type. Move the used board info out of the boardinfo struct and remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index f90578e..bac1445 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -82,40 +82,6 @@ INSN_CONFIG instructions: #define PCI_SUBVENDOR_ID_S626 0x6000 #define PCI_SUBDEVICE_ID_S626 0x0272 -struct s626_board { - const char *name; - int vendor_id; - int device_id; - int subvendor_id; - int subdevice_id; - int ai_chans; - int ai_bits; - int ao_chans; - int ao_bits; - int dio_chans; - int dio_banks; - int enc_chans; -}; - -static const struct s626_board s626_boards[] = { - { - .name = "s626", - .vendor_id = PCI_VENDOR_ID_S626, - .device_id = PCI_DEVICE_ID_S626, - .subvendor_id = PCI_SUBVENDOR_ID_S626, - .subdevice_id = PCI_SUBDEVICE_ID_S626, - .ai_chans = S626_ADC_CHANNELS, - .ai_bits = 14, - .ao_chans = S626_DAC_CHANNELS, - .ao_bits = 13, - .dio_chans = S626_DIO_CHANNELS, - .dio_banks = S626_DIO_BANKS, - .enc_chans = S626_ENCODER_CHANNELS, - } -}; - -#define thisboard ((const struct s626_board *)dev->board_ptr) - struct s626_private { struct pci_dev *pdev; void __iomem *base_addr; @@ -2484,24 +2450,23 @@ static struct pci_dev *s626_find_pci(struct comedi_device *dev, int slot = it->options[1]; int i; - for (i = 0; i < ARRAY_SIZE(s626_boards) && !pcidev; i++) { - do { - pcidev = pci_get_subsys(s626_boards[i].vendor_id, - s626_boards[i].device_id, - s626_boards[i].subvendor_id, - s626_boards[i].subdevice_id, - pcidev); - - if ((bus || slot) && pcidev) { - /* matches requested bus/slot */ - if (pcidev->bus->number == bus && - PCI_SLOT(pcidev->devfn) == slot) - break; - } else { + do { + pcidev = pci_get_subsys(PCI_VENDOR_ID_S626, + PCI_DEVICE_ID_S626, + PCI_SUBVENDOR_ID_S626, + PCI_SUBDEVICE_ID_S626, + pcidev); + + if ((bus || slot) && pcidev) { + /* matches requested bus/slot */ + if (pcidev->bus->number == bus && + PCI_SLOT(pcidev->devfn) == slot) break; - } - } while (1); - } + } else { + break; + } + } while (1); + return pcidev; } @@ -2581,8 +2546,7 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it) } - dev->board_ptr = s626_boards; - dev->board_name = thisboard->name; + dev->board_name = dev->driver->driver_name; ret = comedi_alloc_subdevices(dev, 6); if (ret) @@ -2610,12 +2574,10 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* we support single-ended (ground) and differential */ s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_CMD_READ; - s->n_chan = thisboard->ai_chans; + s->n_chan = S626_ADC_CHANNELS; s->maxdata = (0xffff >> 2); s->range_table = &s626_range_table; - s->len_chanlist = thisboard->ai_chans; /* This is the maximum chanlist - length that the board can - handle */ + s->len_chanlist = S626_ADC_CHANNELS; s->insn_config = s626_ai_insn_config; s->insn_read = s626_ai_insn_read; s->do_cmd = s626_ai_cmd; @@ -2626,7 +2588,7 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* analog output subdevice */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE | SDF_READABLE; - s->n_chan = thisboard->ao_chans; + s->n_chan = S626_DAC_CHANNELS; s->maxdata = (0x3fff); s->range_table = &range_bipolar10; s->insn_write = s626_ao_winsn; @@ -2672,7 +2634,7 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* encoder (counter) subdevice */ s->type = COMEDI_SUBD_COUNTER; s->subdev_flags = SDF_WRITABLE | SDF_READABLE | SDF_LSAMPL; - s->n_chan = thisboard->enc_chans; + s->n_chan = S626_ENCODER_CHANNELS; s->private = enc_private_data; s->insn_config = s626_enc_insn_config; s->insn_read = s626_enc_insn_read; -- cgit v0.10.2 From 91e674e83c530d5902e482ede1af0115989c4fe6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 24 Sep 2012 13:21:53 -0700 Subject: staging: comedi: s626: use attach_pci callback Convert this PCI driver to use the comedi PCI auto config attach mechanism by adding an 'attach_pci' callback function. Since the driver does not require any external configuration options, and the legacy 'attach' callback is not optional, remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index bac1445..eff7e96 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -32,11 +32,7 @@ Authors: Gianluca Palli , Updated: Fri, 15 Feb 2008 10:28:42 +0000 Status: experimental -Configuration options: - [0] - PCI bus of device (optional) - [1] - PCI slot of device (optional) - If bus/slot is not specified, the first supported - PCI device found will be used. +Configuration options: not applicable, uses PCI auto config INSN_CONFIG instructions: analog input: @@ -2442,35 +2438,7 @@ static void CountersInit(struct comedi_device *dev) } } -static struct pci_dev *s626_find_pci(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - struct pci_dev *pcidev = NULL; - int bus = it->options[0]; - int slot = it->options[1]; - int i; - - do { - pcidev = pci_get_subsys(PCI_VENDOR_ID_S626, - PCI_DEVICE_ID_S626, - PCI_SUBVENDOR_ID_S626, - PCI_SUBDEVICE_ID_S626, - pcidev); - - if ((bus || slot) && pcidev) { - /* matches requested bus/slot */ - if (pcidev->bus->number == bus && - PCI_SLOT(pcidev->devfn) == slot) - break; - } else { - break; - } - } while (1); - - return pcidev; -} - -static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it) +static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) { /* uint8_t PollList; */ /* uint16_t AdcData; */ @@ -2487,11 +2455,7 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (alloc_private(dev, sizeof(struct s626_private)) < 0) return -ENOMEM; - devpriv->pdev = s626_find_pci(dev, it); - if (!devpriv->pdev) { - printk(KERN_ERR "s626_attach: Board not present!!!\n"); - return -ENODEV; - } + devpriv->pdev = pcidev; result = comedi_pci_enable(devpriv->pdev, "s626"); if (result < 0) { @@ -2932,7 +2896,6 @@ static void s626_detach(struct comedi_device *dev) if (devpriv->pdev) { if (devpriv->got_regions) comedi_pci_disable(devpriv->pdev); - pci_dev_put(devpriv->pdev); } } } @@ -2940,7 +2903,7 @@ static void s626_detach(struct comedi_device *dev) static struct comedi_driver s626_driver = { .driver_name = "s626", .module = THIS_MODULE, - .attach = s626_attach, + .attach_pci = s626_attach_pci, .detach = s626_detach, }; -- cgit v0.10.2 From f574af6d268240a68f99fac9f2f42ce38b26eae9 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 24 Sep 2012 13:22:10 -0700 Subject: staging: comedi: s626: store the pci_dev in the comedi_device Use the hw_dev pointer in the comedi_device struct to hold the pci_dev instead of carrying it in the private data. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index eff7e96..e30833f 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -79,7 +79,6 @@ INSN_CONFIG instructions: #define PCI_SUBDEVICE_ID_S626 0x0272 struct s626_private { - struct pci_dev *pdev; void __iomem *base_addr; int got_regions; short allocatedBuf; @@ -1882,6 +1881,7 @@ static void WriteMISC2(struct comedi_device *dev, uint16_t NewImage) static void CloseDMAB(struct comedi_device *dev, struct bufferDMA *pdma, size_t bsize) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); void *vbptr; dma_addr_t vpptr; @@ -1892,7 +1892,7 @@ static void CloseDMAB(struct comedi_device *dev, struct bufferDMA *pdma, vbptr = pdma->LogicalBase; vpptr = pdma->PhysicalBase; if (vbptr) { - pci_free_consistent(devpriv->pdev, bsize, vbptr, vpptr); + pci_free_consistent(pcidev, bsize, vbptr, vpptr); pdma->LogicalBase = NULL; pdma->PhysicalBase = 0; } @@ -2452,19 +2452,19 @@ static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) dma_addr_t appdma; struct comedi_subdevice *s; + comedi_set_hw_dev(dev, &pcidev->dev); + if (alloc_private(dev, sizeof(struct s626_private)) < 0) return -ENOMEM; - devpriv->pdev = pcidev; - - result = comedi_pci_enable(devpriv->pdev, "s626"); + result = comedi_pci_enable(pcidev, "s626"); if (result < 0) { printk(KERN_ERR "s626_attach: comedi_pci_enable fails\n"); return -ENODEV; } devpriv->got_regions = 1; - resourceStart = pci_resource_start(devpriv->pdev, 0); + resourceStart = pci_resource_start(pcidev, 0); devpriv->base_addr = ioremap(resourceStart, SIZEOF_ADDRESS_SPACE); if (devpriv->base_addr == NULL) { @@ -2485,7 +2485,7 @@ static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) devpriv->allocatedBuf = 0; devpriv->ANABuf.LogicalBase = - pci_alloc_consistent(devpriv->pdev, DMABUF_SIZE, &appdma); + pci_alloc_consistent(pcidev, DMABUF_SIZE, &appdma); if (devpriv->ANABuf.LogicalBase == NULL) { printk(KERN_ERR "s626_attach: DMA Memory mapping error\n"); @@ -2497,7 +2497,7 @@ static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) devpriv->allocatedBuf++; devpriv->RPSBuf.LogicalBase = - pci_alloc_consistent(devpriv->pdev, DMABUF_SIZE, &appdma); + pci_alloc_consistent(pcidev, DMABUF_SIZE, &appdma); if (devpriv->RPSBuf.LogicalBase == NULL) { printk(KERN_ERR "s626_attach: DMA Memory mapping error\n"); @@ -2517,7 +2517,7 @@ static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) return ret; dev->iobase = (unsigned long)devpriv->base_addr; - dev->irq = devpriv->pdev->irq; + dev->irq = pcidev->irq; /* set up interrupt handler */ if (dev->irq == 0) { @@ -2869,6 +2869,8 @@ static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) static void s626_detach(struct comedi_device *dev) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + if (devpriv) { /* stop ai_command */ devpriv->ai_cmd_running = 0; @@ -2893,10 +2895,10 @@ static void s626_detach(struct comedi_device *dev) free_irq(dev->irq, dev); if (devpriv->base_addr) iounmap(devpriv->base_addr); - if (devpriv->pdev) { - if (devpriv->got_regions) - comedi_pci_disable(devpriv->pdev); - } + } + if (pcidev) { + if (devpriv->got_regions) + comedi_pci_disable(pcidev); } } -- cgit v0.10.2 From 7c843aa7731c774a78a31b6dab371024c4756d38 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 24 Sep 2012 13:22:31 -0700 Subject: staging: comedi: s626: use dev->board_name for resource name Instead of the literal string "s626", use the dev->board_name for the resource name when enabling the PCI device and requesting the irq. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index e30833f..fb215b2 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -2453,11 +2453,12 @@ static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) struct comedi_subdevice *s; comedi_set_hw_dev(dev, &pcidev->dev); + dev->board_name = dev->driver->driver_name; if (alloc_private(dev, sizeof(struct s626_private)) < 0) return -ENOMEM; - result = comedi_pci_enable(pcidev, "s626"); + result = comedi_pci_enable(pcidev, dev->board_name); if (result < 0) { printk(KERN_ERR "s626_attach: comedi_pci_enable fails\n"); return -ENODEV; @@ -2510,8 +2511,6 @@ static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) } - dev->board_name = dev->driver->driver_name; - ret = comedi_alloc_subdevices(dev, 6); if (ret) return ret; @@ -2524,7 +2523,7 @@ static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) printk(KERN_ERR " unknown irq (bad)\n"); } else { ret = request_irq(dev->irq, s626_irq_handler, IRQF_SHARED, - "s626", dev); + dev->board_name, dev); if (ret < 0) { printk(KERN_ERR " irq not available\n"); -- cgit v0.10.2 From 41f821d07729d1c3d59d1ebebf4c57e2ffe0a37c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 24 Sep 2012 13:22:50 -0700 Subject: staging: comedi: s626: remove unneeded local variable in attach_pci() The 'result' variable is only used to check the return from comedi_pci_enable(). Just reuse the 'ret' variable. Also, remove the kernel noise and use the error code from comedi_pci_enable() instead of returning -ENODEV. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index fb215b2..93e55c3 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -2445,7 +2445,6 @@ static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) /* uint16_t StartVal; */ /* uint16_t index; */ /* unsigned int data[16]; */ - int result; int i; int ret; resource_size_t resourceStart; @@ -2458,11 +2457,9 @@ static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) if (alloc_private(dev, sizeof(struct s626_private)) < 0) return -ENOMEM; - result = comedi_pci_enable(pcidev, dev->board_name); - if (result < 0) { - printk(KERN_ERR "s626_attach: comedi_pci_enable fails\n"); - return -ENODEV; - } + ret = comedi_pci_enable(pcidev, dev->board_name); + if (ret) + return ret; devpriv->got_regions = 1; resourceStart = pci_resource_start(pcidev, 0); -- cgit v0.10.2 From 58f4a8fce1d6f1e42543376c85839576992e6100 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 24 Sep 2012 13:23:07 -0700 Subject: staging: comedi: s626: remove 'got_regions' from private data This variable is only used as a flag to indicate that the pci device has been enabled and needs to be disabled in the detach. Use the comedi_device 'iobase' for this and remove the private data variable. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 93e55c3..12709b0 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -80,7 +80,6 @@ INSN_CONFIG instructions: struct s626_private { void __iomem *base_addr; - int got_regions; short allocatedBuf; uint8_t ai_cmd_running; /* ai_cmd is running */ uint8_t ai_continous; /* continous acquisition */ @@ -2460,7 +2459,7 @@ static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) return ret; - devpriv->got_regions = 1; + dev->iobase = 1; /* detach needs this */ resourceStart = pci_resource_start(pcidev, 0); @@ -2512,7 +2511,6 @@ static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) if (ret) return ret; - dev->iobase = (unsigned long)devpriv->base_addr; dev->irq = pcidev->irq; /* set up interrupt handler */ @@ -2893,7 +2891,7 @@ static void s626_detach(struct comedi_device *dev) iounmap(devpriv->base_addr); } if (pcidev) { - if (devpriv->got_regions) + if (dev->iobase) comedi_pci_disable(pcidev); } } -- cgit v0.10.2 From 4f6c7bf992bc6f1bbf38b08e9b3c8a21865888f2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 24 Sep 2012 13:23:22 -0700 Subject: staging: comedi: s626: cleanup ioremap() The local variable 'resourceStart' is only used in the ioremap() to hold the PCI bar 0 base address. Just use the pci_resource_start() directly in the ioremap(). Also, instead of assuming the resource size for the ioremap, use pci_resource_len() to get the actual size. Remove the kernel noise when the ioremap fails and change the error code from -ENODEV to -ENOMEM. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 12709b0..6f6c808 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -2446,7 +2446,6 @@ static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) /* unsigned int data[16]; */ int i; int ret; - resource_size_t resourceStart; dma_addr_t appdma; struct comedi_subdevice *s; @@ -2461,13 +2460,10 @@ static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) return ret; dev->iobase = 1; /* detach needs this */ - resourceStart = pci_resource_start(pcidev, 0); - - devpriv->base_addr = ioremap(resourceStart, SIZEOF_ADDRESS_SPACE); - if (devpriv->base_addr == NULL) { - printk(KERN_ERR "s626_attach: IOREMAP failed\n"); - return -ENODEV; - } + devpriv->base_addr = ioremap(pci_resource_start(pcidev, 0), + pci_resource_len(pcidev, 0)); + if (!devpriv->base_addr) + return -ENOMEM; if (devpriv->base_addr) { /* disable master interrupt */ diff --git a/drivers/staging/comedi/drivers/s626.h b/drivers/staging/comedi/drivers/s626.h index 8a8f196..ff4b3a5 100644 --- a/drivers/staging/comedi/drivers/s626.h +++ b/drivers/staging/comedi/drivers/s626.h @@ -73,7 +73,6 @@ #include #define S626_SIZE 0x0200 -#define SIZEOF_ADDRESS_SPACE 0x0200 #define DMABUF_SIZE 4096 /* 4k pages */ #define S626_ADC_CHANNELS 16 -- cgit v0.10.2 From 97d87e00e3d6bdc8f3de606dd7cc5aa149709435 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 24 Sep 2012 13:23:40 -0700 Subject: staging: comedi: s626: remove unnecessary checks of 'devpriv->base_addr' 'devpriv->base_addr' is valid from this point on in the attach_pci() function. Remove the unnecessary checks. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 6f6c808..a9d78c7 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -2465,43 +2465,40 @@ static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) if (!devpriv->base_addr) return -ENOMEM; - if (devpriv->base_addr) { - /* disable master interrupt */ - writel(0, devpriv->base_addr + P_IER); + /* disable master interrupt */ + writel(0, devpriv->base_addr + P_IER); - /* soft reset */ - writel(MC1_SOFT_RESET, devpriv->base_addr + P_MC1); + /* soft reset */ + writel(MC1_SOFT_RESET, devpriv->base_addr + P_MC1); - /* DMA FIXME DMA// */ + /* DMA FIXME DMA// */ - /* adc buffer allocation */ - devpriv->allocatedBuf = 0; + /* adc buffer allocation */ + devpriv->allocatedBuf = 0; - devpriv->ANABuf.LogicalBase = - pci_alloc_consistent(pcidev, DMABUF_SIZE, &appdma); + devpriv->ANABuf.LogicalBase = + pci_alloc_consistent(pcidev, DMABUF_SIZE, &appdma); - if (devpriv->ANABuf.LogicalBase == NULL) { - printk(KERN_ERR "s626_attach: DMA Memory mapping error\n"); - return -ENOMEM; - } - - devpriv->ANABuf.PhysicalBase = appdma; + if (devpriv->ANABuf.LogicalBase == NULL) { + printk(KERN_ERR "s626_attach: DMA Memory mapping error\n"); + return -ENOMEM; + } - devpriv->allocatedBuf++; + devpriv->ANABuf.PhysicalBase = appdma; - devpriv->RPSBuf.LogicalBase = - pci_alloc_consistent(pcidev, DMABUF_SIZE, &appdma); + devpriv->allocatedBuf++; - if (devpriv->RPSBuf.LogicalBase == NULL) { - printk(KERN_ERR "s626_attach: DMA Memory mapping error\n"); - return -ENOMEM; - } + devpriv->RPSBuf.LogicalBase = + pci_alloc_consistent(pcidev, DMABUF_SIZE, &appdma); - devpriv->RPSBuf.PhysicalBase = appdma; + if (devpriv->RPSBuf.LogicalBase == NULL) { + printk(KERN_ERR "s626_attach: DMA Memory mapping error\n"); + return -ENOMEM; + } - devpriv->allocatedBuf++; + devpriv->RPSBuf.PhysicalBase = appdma; - } + devpriv->allocatedBuf++; ret = comedi_alloc_subdevices(dev, 6); if (ret) @@ -2599,7 +2596,7 @@ static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) /* stop ai_command */ devpriv->ai_cmd_running = 0; - if (devpriv->base_addr && (devpriv->allocatedBuf == 2)) { + if (devpriv->allocatedBuf == 2) { dma_addr_t pPhysBuf; uint16_t chan; -- cgit v0.10.2 From b7047895b9c9deee0b0f4cb2a0a788c189f985f2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 24 Sep 2012 13:23:57 -0700 Subject: staging: comedi: s626: factor out the dma buffer allocation To make the attach a bit cleaner, factor the dma buffer allocation out of attach_pci() into a new function. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index a9d78c7..61bb8ab 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -2437,6 +2437,33 @@ static void CountersInit(struct comedi_device *dev) } } +static int s626_allocate_dma_buffers(struct comedi_device *dev) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + void *addr; + dma_addr_t appdma; + + devpriv->allocatedBuf = 0; + + addr = pci_alloc_consistent(pcidev, DMABUF_SIZE, &appdma); + if (!addr) + return -ENOMEM; + devpriv->ANABuf.LogicalBase = addr; + devpriv->ANABuf.PhysicalBase = appdma; + + devpriv->allocatedBuf++; + + addr = pci_alloc_consistent(pcidev, DMABUF_SIZE, &appdma); + if (!addr) + return -ENOMEM; + devpriv->RPSBuf.LogicalBase = addr; + devpriv->RPSBuf.PhysicalBase = appdma; + + devpriv->allocatedBuf++; + + return 0; +} + static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) { /* uint8_t PollList; */ @@ -2446,7 +2473,6 @@ static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) /* unsigned int data[16]; */ int i; int ret; - dma_addr_t appdma; struct comedi_subdevice *s; comedi_set_hw_dev(dev, &pcidev->dev); @@ -2473,32 +2499,9 @@ static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) /* DMA FIXME DMA// */ - /* adc buffer allocation */ - devpriv->allocatedBuf = 0; - - devpriv->ANABuf.LogicalBase = - pci_alloc_consistent(pcidev, DMABUF_SIZE, &appdma); - - if (devpriv->ANABuf.LogicalBase == NULL) { - printk(KERN_ERR "s626_attach: DMA Memory mapping error\n"); - return -ENOMEM; - } - - devpriv->ANABuf.PhysicalBase = appdma; - - devpriv->allocatedBuf++; - - devpriv->RPSBuf.LogicalBase = - pci_alloc_consistent(pcidev, DMABUF_SIZE, &appdma); - - if (devpriv->RPSBuf.LogicalBase == NULL) { - printk(KERN_ERR "s626_attach: DMA Memory mapping error\n"); - return -ENOMEM; - } - - devpriv->RPSBuf.PhysicalBase = appdma; - - devpriv->allocatedBuf++; + ret = s626_allocate_dma_buffers(dev); + if (ret) + return ret; ret = comedi_alloc_subdevices(dev, 6); if (ret) -- cgit v0.10.2 From 8c7e4277c1197d31c0b34dbaf23e6edddb5978f7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 24 Sep 2012 13:24:12 -0700 Subject: staging: comedi: s626: cleanup request_irq in s626_attach_pci() Only set dev->irq if request_irq is successfull. Remove the kernel message noise. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 61bb8ab..4ad3f27 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -2503,25 +2503,18 @@ static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) if (ret) return ret; - ret = comedi_alloc_subdevices(dev, 6); - if (ret) - return ret; - - dev->irq = pcidev->irq; - - /* set up interrupt handler */ - if (dev->irq == 0) { - printk(KERN_ERR " unknown irq (bad)\n"); - } else { - ret = request_irq(dev->irq, s626_irq_handler, IRQF_SHARED, + if (pcidev->irq) { + ret = request_irq(pcidev->irq, s626_irq_handler, IRQF_SHARED, dev->board_name, dev); - if (ret < 0) { - printk(KERN_ERR " irq not available\n"); - dev->irq = 0; - } + if (ret == 0) + dev->irq = pcidev->irq; } + ret = comedi_alloc_subdevices(dev, 6); + if (ret) + return ret; + s = dev->subdevices + 0; /* analog input subdevice */ dev->read_subdev = s; -- cgit v0.10.2 From 80ec9510296224048021793b644eb9057c59df5a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 24 Sep 2012 13:24:27 -0700 Subject: staging: comedi: s626: factor out the board init code To make the attach a bit cleaner, factor the board init code out of attach_pci() into a new function. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 4ad3f27..cbae8e4 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -2464,7 +2464,7 @@ static int s626_allocate_dma_buffers(struct comedi_device *dev) return 0; } -static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) +static void s626_initialize(struct comedi_device *dev) { /* uint8_t PollList; */ /* uint16_t AdcData; */ @@ -2472,125 +2472,6 @@ static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) /* uint16_t index; */ /* unsigned int data[16]; */ int i; - int ret; - struct comedi_subdevice *s; - - comedi_set_hw_dev(dev, &pcidev->dev); - dev->board_name = dev->driver->driver_name; - - if (alloc_private(dev, sizeof(struct s626_private)) < 0) - return -ENOMEM; - - ret = comedi_pci_enable(pcidev, dev->board_name); - if (ret) - return ret; - dev->iobase = 1; /* detach needs this */ - - devpriv->base_addr = ioremap(pci_resource_start(pcidev, 0), - pci_resource_len(pcidev, 0)); - if (!devpriv->base_addr) - return -ENOMEM; - - /* disable master interrupt */ - writel(0, devpriv->base_addr + P_IER); - - /* soft reset */ - writel(MC1_SOFT_RESET, devpriv->base_addr + P_MC1); - - /* DMA FIXME DMA// */ - - ret = s626_allocate_dma_buffers(dev); - if (ret) - return ret; - - if (pcidev->irq) { - ret = request_irq(pcidev->irq, s626_irq_handler, IRQF_SHARED, - dev->board_name, dev); - - if (ret == 0) - dev->irq = pcidev->irq; - } - - ret = comedi_alloc_subdevices(dev, 6); - if (ret) - return ret; - - s = dev->subdevices + 0; - /* analog input subdevice */ - dev->read_subdev = s; - /* we support single-ended (ground) and differential */ - s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_CMD_READ; - s->n_chan = S626_ADC_CHANNELS; - s->maxdata = (0xffff >> 2); - s->range_table = &s626_range_table; - s->len_chanlist = S626_ADC_CHANNELS; - s->insn_config = s626_ai_insn_config; - s->insn_read = s626_ai_insn_read; - s->do_cmd = s626_ai_cmd; - s->do_cmdtest = s626_ai_cmdtest; - s->cancel = s626_ai_cancel; - - s = dev->subdevices + 1; - /* analog output subdevice */ - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE; - s->n_chan = S626_DAC_CHANNELS; - s->maxdata = (0x3fff); - s->range_table = &range_bipolar10; - s->insn_write = s626_ao_winsn; - s->insn_read = s626_ao_rinsn; - - s = dev->subdevices + 2; - /* digital I/O subdevice */ - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE; - s->n_chan = 16; - s->maxdata = 1; - s->io_bits = 0xffff; - s->private = &dio_private_A; - s->range_table = &range_digital; - s->insn_config = s626_dio_insn_config; - s->insn_bits = s626_dio_insn_bits; - - s = dev->subdevices + 3; - /* digital I/O subdevice */ - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE; - s->n_chan = 16; - s->maxdata = 1; - s->io_bits = 0xffff; - s->private = &dio_private_B; - s->range_table = &range_digital; - s->insn_config = s626_dio_insn_config; - s->insn_bits = s626_dio_insn_bits; - - s = dev->subdevices + 4; - /* digital I/O subdevice */ - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE; - s->n_chan = 16; - s->maxdata = 1; - s->io_bits = 0xffff; - s->private = &dio_private_C; - s->range_table = &range_digital; - s->insn_config = s626_dio_insn_config; - s->insn_bits = s626_dio_insn_bits; - - s = dev->subdevices + 5; - /* encoder (counter) subdevice */ - s->type = COMEDI_SUBD_COUNTER; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE | SDF_LSAMPL; - s->n_chan = S626_ENCODER_CHANNELS; - s->private = enc_private_data; - s->insn_config = s626_enc_insn_config; - s->insn_read = s626_enc_insn_read; - s->insn_write = s626_enc_insn_write; - s->maxdata = 0xffffff; - s->range_table = &range_unknown; - - /* stop ai_command */ - devpriv->ai_cmd_running = 0; if (devpriv->allocatedBuf == 2) { dma_addr_t pPhysBuf; @@ -2846,6 +2727,131 @@ static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) /* enable interrupt test */ /* writel(IRQ_GPIO3 | IRQ_RPS1,devpriv->base_addr+P_IER); */ } +} + +static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) +{ + struct comedi_subdevice *s; + int ret; + + comedi_set_hw_dev(dev, &pcidev->dev); + dev->board_name = dev->driver->driver_name; + + if (alloc_private(dev, sizeof(struct s626_private)) < 0) + return -ENOMEM; + + ret = comedi_pci_enable(pcidev, dev->board_name); + if (ret) + return ret; + dev->iobase = 1; /* detach needs this */ + + devpriv->base_addr = ioremap(pci_resource_start(pcidev, 0), + pci_resource_len(pcidev, 0)); + if (!devpriv->base_addr) + return -ENOMEM; + + /* disable master interrupt */ + writel(0, devpriv->base_addr + P_IER); + + /* soft reset */ + writel(MC1_SOFT_RESET, devpriv->base_addr + P_MC1); + + /* DMA FIXME DMA// */ + + ret = s626_allocate_dma_buffers(dev); + if (ret) + return ret; + + if (pcidev->irq) { + ret = request_irq(pcidev->irq, s626_irq_handler, IRQF_SHARED, + dev->board_name, dev); + + if (ret == 0) + dev->irq = pcidev->irq; + } + + ret = comedi_alloc_subdevices(dev, 6); + if (ret) + return ret; + + s = dev->subdevices + 0; + /* analog input subdevice */ + dev->read_subdev = s; + /* we support single-ended (ground) and differential */ + s->type = COMEDI_SUBD_AI; + s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_CMD_READ; + s->n_chan = S626_ADC_CHANNELS; + s->maxdata = (0xffff >> 2); + s->range_table = &s626_range_table; + s->len_chanlist = S626_ADC_CHANNELS; + s->insn_config = s626_ai_insn_config; + s->insn_read = s626_ai_insn_read; + s->do_cmd = s626_ai_cmd; + s->do_cmdtest = s626_ai_cmdtest; + s->cancel = s626_ai_cancel; + + s = dev->subdevices + 1; + /* analog output subdevice */ + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITABLE | SDF_READABLE; + s->n_chan = S626_DAC_CHANNELS; + s->maxdata = (0x3fff); + s->range_table = &range_bipolar10; + s->insn_write = s626_ao_winsn; + s->insn_read = s626_ao_rinsn; + + s = dev->subdevices + 2; + /* digital I/O subdevice */ + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_WRITABLE | SDF_READABLE; + s->n_chan = 16; + s->maxdata = 1; + s->io_bits = 0xffff; + s->private = &dio_private_A; + s->range_table = &range_digital; + s->insn_config = s626_dio_insn_config; + s->insn_bits = s626_dio_insn_bits; + + s = dev->subdevices + 3; + /* digital I/O subdevice */ + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_WRITABLE | SDF_READABLE; + s->n_chan = 16; + s->maxdata = 1; + s->io_bits = 0xffff; + s->private = &dio_private_B; + s->range_table = &range_digital; + s->insn_config = s626_dio_insn_config; + s->insn_bits = s626_dio_insn_bits; + + s = dev->subdevices + 4; + /* digital I/O subdevice */ + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_WRITABLE | SDF_READABLE; + s->n_chan = 16; + s->maxdata = 1; + s->io_bits = 0xffff; + s->private = &dio_private_C; + s->range_table = &range_digital; + s->insn_config = s626_dio_insn_config; + s->insn_bits = s626_dio_insn_bits; + + s = dev->subdevices + 5; + /* encoder (counter) subdevice */ + s->type = COMEDI_SUBD_COUNTER; + s->subdev_flags = SDF_WRITABLE | SDF_READABLE | SDF_LSAMPL; + s->n_chan = S626_ENCODER_CHANNELS; + s->private = enc_private_data; + s->insn_config = s626_enc_insn_config; + s->insn_read = s626_enc_insn_read; + s->insn_write = s626_enc_insn_write; + s->maxdata = 0xffffff; + s->range_table = &range_unknown; + + /* stop ai_command */ + devpriv->ai_cmd_running = 0; + + s626_initialize(dev); return 1; } -- cgit v0.10.2 From b7eaf21a6709fb1dd1659dd0e56ce665375ba538 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 24 Sep 2012 13:24:42 -0700 Subject: staging: comedi: s626: remove unneeded clear of private data The private data is kzalloc'ed. All the variables in it are initially '0'. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index cbae8e4..f4251ac 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -2848,9 +2848,6 @@ static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) s->maxdata = 0xffffff; s->range_table = &range_unknown; - /* stop ai_command */ - devpriv->ai_cmd_running = 0; - s626_initialize(dev); return 1; -- cgit v0.10.2 From f996ab29e9dd1ed607ea9ba708dff6fa4d253859 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 24 Sep 2012 13:37:19 -0700 Subject: staging: comedi: s626: add final attach message Add a simple dev_info() message after a successfull attach. Change the final return to '0' to indicate success. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index f4251ac..07ff93b 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -2850,7 +2850,9 @@ static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) s626_initialize(dev); - return 1; + dev_info(dev->class_dev, "%s attached\n", dev->board_name); + + return 0; } static void s626_detach(struct comedi_device *dev) -- cgit v0.10.2 From 68ad0ae0eac07911e6749e28da75d77d25524864 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 24 Sep 2012 13:37:36 -0700 Subject: staging: comedi: s626: remove 'allocatedBuf' from private data This variable is only used to count the number of dma buffers allocated during the attach. If an allocation fails, the attach function exits with -ENOMEM. When this variable is checked later it will always be == 2. Just remove the variable and the check. This allows bringing the code back an indent level in s626_initialize(). Note, coding style issues in this function are not addressed yet. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 07ff93b..cd09c37 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -80,7 +80,6 @@ INSN_CONFIG instructions: struct s626_private { void __iomem *base_addr; - short allocatedBuf; uint8_t ai_cmd_running; /* ai_cmd is running */ uint8_t ai_continous; /* continous acquisition */ int ai_sample_count; /* number of samples to acquire */ @@ -2443,24 +2442,18 @@ static int s626_allocate_dma_buffers(struct comedi_device *dev) void *addr; dma_addr_t appdma; - devpriv->allocatedBuf = 0; - addr = pci_alloc_consistent(pcidev, DMABUF_SIZE, &appdma); if (!addr) return -ENOMEM; devpriv->ANABuf.LogicalBase = addr; devpriv->ANABuf.PhysicalBase = appdma; - devpriv->allocatedBuf++; - addr = pci_alloc_consistent(pcidev, DMABUF_SIZE, &appdma); if (!addr) return -ENOMEM; devpriv->RPSBuf.LogicalBase = addr; devpriv->RPSBuf.PhysicalBase = appdma; - devpriv->allocatedBuf++; - return 0; } @@ -2471,117 +2464,116 @@ static void s626_initialize(struct comedi_device *dev) /* uint16_t StartVal; */ /* uint16_t index; */ /* unsigned int data[16]; */ + dma_addr_t pPhysBuf; + uint16_t chan; int i; - if (devpriv->allocatedBuf == 2) { - dma_addr_t pPhysBuf; - uint16_t chan; - - /* enab DEBI and audio pins, enable I2C interface. */ - MC_ENABLE(P_MC1, MC1_DEBI | MC1_AUDIO | MC1_I2C); - /* Configure DEBI operating mode. */ - WR7146(P_DEBICFG, DEBI_CFG_SLAVE16 /* Local bus is 16 */ - /* bits wide. */ - | (DEBI_TOUT << DEBI_CFG_TOUT_BIT) - - /* Declare DEBI */ - /* transfer timeout */ - /* interval. */ - |DEBI_SWAP /* Set up byte lane */ - /* steering. */ - | DEBI_CFG_INTEL); /* Intel-compatible */ - /* local bus (DEBI */ - /* never times out). */ - - /* DEBI INIT S626 WR7146( P_DEBICFG, DEBI_CFG_INTEL | DEBI_CFG_TOQ */ - /* | DEBI_CFG_INCQ| DEBI_CFG_16Q); //end */ - - /* Paging is disabled. */ - WR7146(P_DEBIPAGE, DEBI_PAGE_DISABLE); /* Disable MMU paging. */ - - /* Init GPIO so that ADC Start* is negated. */ - WR7146(P_GPIO, GPIO_BASE | GPIO1_HI); - - /* IsBoardRevA is a boolean that indicates whether the board is RevA. - * - * VERSION 2.01 CHANGE: REV A & B BOARDS NOW SUPPORTED BY DYNAMIC - * EEPROM ADDRESS SELECTION. Initialize the I2C interface, which - * is used to access the onboard serial EEPROM. The EEPROM's I2C - * DeviceAddress is hardwired to a value that is dependent on the - * 626 board revision. On all board revisions, the EEPROM stores - * TrimDAC calibration constants for analog I/O. On RevB and - * higher boards, the DeviceAddress is hardwired to 0 to enable - * the EEPROM to also store the PCI SubVendorID and SubDeviceID; - * this is the address at which the SAA7146 expects a - * configuration EEPROM to reside. On RevA boards, the EEPROM - * device address, which is hardwired to 4, prevents the SAA7146 - * from retrieving PCI sub-IDs, so the SAA7146 uses its built-in - * default values, instead. - */ - /* devpriv->I2Cards= IsBoardRevA ? 0xA8 : 0xA0; // Set I2C EEPROM */ - /* DeviceType (0xA0) */ - /* and DeviceAddress<<1. */ + /* enab DEBI and audio pins, enable I2C interface. */ + MC_ENABLE(P_MC1, MC1_DEBI | MC1_AUDIO | MC1_I2C); + /* Configure DEBI operating mode. */ + WR7146(P_DEBICFG, DEBI_CFG_SLAVE16 /* Local bus is 16 */ + /* bits wide. */ + | (DEBI_TOUT << DEBI_CFG_TOUT_BIT) + + /* Declare DEBI */ + /* transfer timeout */ + /* interval. */ + |DEBI_SWAP /* Set up byte lane */ + /* steering. */ + | DEBI_CFG_INTEL); /* Intel-compatible */ + /* local bus (DEBI */ + /* never times out). */ + + /* DEBI INIT S626 WR7146( P_DEBICFG, DEBI_CFG_INTEL | DEBI_CFG_TOQ */ + /* | DEBI_CFG_INCQ| DEBI_CFG_16Q); //end */ + + /* Paging is disabled. */ + WR7146(P_DEBIPAGE, DEBI_PAGE_DISABLE); /* Disable MMU paging. */ + + /* Init GPIO so that ADC Start* is negated. */ + WR7146(P_GPIO, GPIO_BASE | GPIO1_HI); + + /* IsBoardRevA is a boolean that indicates whether the board is RevA. + * + * VERSION 2.01 CHANGE: REV A & B BOARDS NOW SUPPORTED BY DYNAMIC + * EEPROM ADDRESS SELECTION. Initialize the I2C interface, which + * is used to access the onboard serial EEPROM. The EEPROM's I2C + * DeviceAddress is hardwired to a value that is dependent on the + * 626 board revision. On all board revisions, the EEPROM stores + * TrimDAC calibration constants for analog I/O. On RevB and + * higher boards, the DeviceAddress is hardwired to 0 to enable + * the EEPROM to also store the PCI SubVendorID and SubDeviceID; + * this is the address at which the SAA7146 expects a + * configuration EEPROM to reside. On RevA boards, the EEPROM + * device address, which is hardwired to 4, prevents the SAA7146 + * from retrieving PCI sub-IDs, so the SAA7146 uses its built-in + * default values, instead. + */ + + /* devpriv->I2Cards= IsBoardRevA ? 0xA8 : 0xA0; // Set I2C EEPROM */ + /* DeviceType (0xA0) */ + /* and DeviceAddress<<1. */ - devpriv->I2CAdrs = 0xA0; /* I2C device address for onboard */ - /* eeprom(revb) */ + devpriv->I2CAdrs = 0xA0; /* I2C device address for onboard */ + /* eeprom(revb) */ - /* Issue an I2C ABORT command to halt any I2C operation in */ - /* progress and reset BUSY flag. */ - WR7146(P_I2CSTAT, I2C_CLKSEL | I2C_ABORT); - /* Write I2C control: abort any I2C activity. */ - MC_ENABLE(P_MC2, MC2_UPLD_IIC); - /* Invoke command upload */ - while ((RR7146(P_MC2) & MC2_UPLD_IIC) == 0) + /* Issue an I2C ABORT command to halt any I2C operation in */ + /* progress and reset BUSY flag. */ + WR7146(P_I2CSTAT, I2C_CLKSEL | I2C_ABORT); + /* Write I2C control: abort any I2C activity. */ + MC_ENABLE(P_MC2, MC2_UPLD_IIC); + /* Invoke command upload */ + while ((RR7146(P_MC2) & MC2_UPLD_IIC) == 0) + ; + /* and wait for upload to complete. */ + + /* Per SAA7146 data sheet, write to STATUS reg twice to + * reset all I2C error flags. */ + for (i = 0; i < 2; i++) { + WR7146(P_I2CSTAT, I2C_CLKSEL); + /* Write I2C control: reset error flags. */ + MC_ENABLE(P_MC2, MC2_UPLD_IIC); /* Invoke command upload */ + while (!MC_TEST(P_MC2, MC2_UPLD_IIC)) ; - /* and wait for upload to complete. */ - - /* Per SAA7146 data sheet, write to STATUS reg twice to - * reset all I2C error flags. */ - for (i = 0; i < 2; i++) { - WR7146(P_I2CSTAT, I2C_CLKSEL); - /* Write I2C control: reset error flags. */ - MC_ENABLE(P_MC2, MC2_UPLD_IIC); /* Invoke command upload */ - while (!MC_TEST(P_MC2, MC2_UPLD_IIC)) - ; - /* and wait for upload to complete. */ - } + /* and wait for upload to complete. */ + } - /* Init audio interface functional attributes: set DAC/ADC - * serial clock rates, invert DAC serial clock so that - * DAC data setup times are satisfied, enable DAC serial - * clock out. - */ + /* Init audio interface functional attributes: set DAC/ADC + * serial clock rates, invert DAC serial clock so that + * DAC data setup times are satisfied, enable DAC serial + * clock out. + */ - WR7146(P_ACON2, ACON2_INIT); + WR7146(P_ACON2, ACON2_INIT); - /* Set up TSL1 slot list, which is used to control the - * accumulation of ADC data: RSD1 = shift data in on SD1. - * SIB_A1 = store data uint8_t at next available location in - * FB BUFFER1 register. */ - WR7146(P_TSL1, RSD1 | SIB_A1); - /* Fetch ADC high data uint8_t. */ - WR7146(P_TSL1 + 4, RSD1 | SIB_A1 | EOS); - /* Fetch ADC low data uint8_t; end of TSL1. */ + /* Set up TSL1 slot list, which is used to control the + * accumulation of ADC data: RSD1 = shift data in on SD1. + * SIB_A1 = store data uint8_t at next available location in + * FB BUFFER1 register. */ + WR7146(P_TSL1, RSD1 | SIB_A1); + /* Fetch ADC high data uint8_t. */ + WR7146(P_TSL1 + 4, RSD1 | SIB_A1 | EOS); + /* Fetch ADC low data uint8_t; end of TSL1. */ - /* enab TSL1 slot list so that it executes all the time. */ - WR7146(P_ACON1, ACON1_ADCSTART); + /* enab TSL1 slot list so that it executes all the time. */ + WR7146(P_ACON1, ACON1_ADCSTART); - /* Initialize RPS registers used for ADC. */ + /* Initialize RPS registers used for ADC. */ - /* Physical start of RPS program. */ - WR7146(P_RPSADDR1, (uint32_t) devpriv->RPSBuf.PhysicalBase); + /* Physical start of RPS program. */ + WR7146(P_RPSADDR1, (uint32_t) devpriv->RPSBuf.PhysicalBase); - WR7146(P_RPSPAGE1, 0); - /* RPS program performs no explicit mem writes. */ - WR7146(P_RPS1_TOUT, 0); /* Disable RPS timeouts. */ + WR7146(P_RPSPAGE1, 0); + /* RPS program performs no explicit mem writes. */ + WR7146(P_RPS1_TOUT, 0); /* Disable RPS timeouts. */ - /* SAA7146 BUG WORKAROUND. Initialize SAA7146 ADC interface - * to a known state by invoking ADCs until FB BUFFER 1 - * register shows that it is correctly receiving ADC data. - * This is necessary because the SAA7146 ADC interface does - * not start up in a defined state after a PCI reset. - */ + /* SAA7146 BUG WORKAROUND. Initialize SAA7146 ADC interface + * to a known state by invoking ADCs until FB BUFFER 1 + * register shows that it is correctly receiving ADC data. + * This is necessary because the SAA7146 ADC interface does + * not start up in a defined state after a PCI reset. + */ /* PollList = EOPL; // Create a simple polling */ /* // list for analog input */ @@ -2609,124 +2601,121 @@ static void s626_initialize(struct comedi_device *dev) /* break; */ /* } */ - /* end initADC */ + /* end initADC */ - /* init the DAC interface */ + /* init the DAC interface */ - /* Init Audio2's output DMAC attributes: burst length = 1 - * DWORD, threshold = 1 DWORD. - */ - WR7146(P_PCI_BT_A, 0); - - /* Init Audio2's output DMA physical addresses. The protection - * address is set to 1 DWORD past the base address so that a - * single DWORD will be transferred each time a DMA transfer is - * enabled. */ - - pPhysBuf = - devpriv->ANABuf.PhysicalBase + - (DAC_WDMABUF_OS * sizeof(uint32_t)); - - WR7146(P_BASEA2_OUT, (uint32_t) pPhysBuf); /* Buffer base adrs. */ - WR7146(P_PROTA2_OUT, (uint32_t) (pPhysBuf + sizeof(uint32_t))); /* Protection address. */ - - /* Cache Audio2's output DMA buffer logical address. This is - * where DAC data is buffered for A2 output DMA transfers. */ - devpriv->pDacWBuf = - (uint32_t *) devpriv->ANABuf.LogicalBase + DAC_WDMABUF_OS; - - /* Audio2's output channels does not use paging. The protection - * violation handling bit is set so that the DMAC will - * automatically halt and its PCI address pointer will be reset - * when the protection address is reached. */ - - WR7146(P_PAGEA2_OUT, 8); - - /* Initialize time slot list 2 (TSL2), which is used to control - * the clock generation for and serialization of data to be sent - * to the DAC devices. Slot 0 is a NOP that is used to trap TSL - * execution; this permits other slots to be safely modified - * without first turning off the TSL sequencer (which is - * apparently impossible to do). Also, SD3 (which is driven by a - * pull-up resistor) is shifted in and stored to the MSB of - * FB_BUFFER2 to be used as evidence that the slot sequence has - * not yet finished executing. - */ + /* Init Audio2's output DMAC attributes: burst length = 1 + * DWORD, threshold = 1 DWORD. + */ + WR7146(P_PCI_BT_A, 0); + + /* Init Audio2's output DMA physical addresses. The protection + * address is set to 1 DWORD past the base address so that a + * single DWORD will be transferred each time a DMA transfer is + * enabled. */ + + pPhysBuf = devpriv->ANABuf.PhysicalBase + + (DAC_WDMABUF_OS * sizeof(uint32_t)); + + WR7146(P_BASEA2_OUT, (uint32_t) pPhysBuf); /* Buffer base adrs. */ + WR7146(P_PROTA2_OUT, (uint32_t) (pPhysBuf + sizeof(uint32_t))); /* Protection address. */ + + /* Cache Audio2's output DMA buffer logical address. This is + * where DAC data is buffered for A2 output DMA transfers. */ + devpriv->pDacWBuf = (uint32_t *)devpriv->ANABuf.LogicalBase + + DAC_WDMABUF_OS; + + /* Audio2's output channels does not use paging. The protection + * violation handling bit is set so that the DMAC will + * automatically halt and its PCI address pointer will be reset + * when the protection address is reached. */ + + WR7146(P_PAGEA2_OUT, 8); + + /* Initialize time slot list 2 (TSL2), which is used to control + * the clock generation for and serialization of data to be sent + * to the DAC devices. Slot 0 is a NOP that is used to trap TSL + * execution; this permits other slots to be safely modified + * without first turning off the TSL sequencer (which is + * apparently impossible to do). Also, SD3 (which is driven by a + * pull-up resistor) is shifted in and stored to the MSB of + * FB_BUFFER2 to be used as evidence that the slot sequence has + * not yet finished executing. + */ - SETVECT(0, XSD2 | RSD3 | SIB_A2 | EOS); - /* Slot 0: Trap TSL execution, shift 0xFF into FB_BUFFER2. */ + SETVECT(0, XSD2 | RSD3 | SIB_A2 | EOS); + /* Slot 0: Trap TSL execution, shift 0xFF into FB_BUFFER2. */ - /* Initialize slot 1, which is constant. Slot 1 causes a - * DWORD to be transferred from audio channel 2's output FIFO - * to the FIFO's output buffer so that it can be serialized - * and sent to the DAC during subsequent slots. All remaining - * slots are dynamically populated as required by the target - * DAC device. - */ - SETVECT(1, LF_A2); - /* Slot 1: Fetch DWORD from Audio2's output FIFO. */ + /* Initialize slot 1, which is constant. Slot 1 causes a + * DWORD to be transferred from audio channel 2's output FIFO + * to the FIFO's output buffer so that it can be serialized + * and sent to the DAC during subsequent slots. All remaining + * slots are dynamically populated as required by the target + * DAC device. + */ + SETVECT(1, LF_A2); + /* Slot 1: Fetch DWORD from Audio2's output FIFO. */ - /* Start DAC's audio interface (TSL2) running. */ - WR7146(P_ACON1, ACON1_DACSTART); + /* Start DAC's audio interface (TSL2) running. */ + WR7146(P_ACON1, ACON1_DACSTART); - /* end init DAC interface */ + /* end init DAC interface */ - /* Init Trim DACs to calibrated values. Do it twice because the - * SAA7146 audio channel does not always reset properly and - * sometimes causes the first few TrimDAC writes to malfunction. - */ + /* Init Trim DACs to calibrated values. Do it twice because the + * SAA7146 audio channel does not always reset properly and + * sometimes causes the first few TrimDAC writes to malfunction. + */ - LoadTrimDACs(dev); - LoadTrimDACs(dev); /* Insurance. */ + LoadTrimDACs(dev); + LoadTrimDACs(dev); /* Insurance. */ - /* Manually init all gate array hardware in case this is a soft - * reset (we have no way of determining whether this is a warm - * or cold start). This is necessary because the gate array will - * reset only in response to a PCI hard reset; there is no soft - * reset function. */ + /* Manually init all gate array hardware in case this is a soft + * reset (we have no way of determining whether this is a warm + * or cold start). This is necessary because the gate array will + * reset only in response to a PCI hard reset; there is no soft + * reset function. */ - /* Init all DAC outputs to 0V and init all DAC setpoint and - * polarity images. - */ - for (chan = 0; chan < S626_DAC_CHANNELS; chan++) - SetDAC(dev, chan, 0); + /* Init all DAC outputs to 0V and init all DAC setpoint and + * polarity images. + */ + for (chan = 0; chan < S626_DAC_CHANNELS; chan++) + SetDAC(dev, chan, 0); - /* Init image of WRMISC2 Battery Charger Enabled control bit. - * This image is used when the state of the charger control bit, - * which has no direct hardware readback mechanism, is queried. - */ - devpriv->ChargeEnabled = 0; + /* Init image of WRMISC2 Battery Charger Enabled control bit. + * This image is used when the state of the charger control bit, + * which has no direct hardware readback mechanism, is queried. + */ + devpriv->ChargeEnabled = 0; - /* Init image of watchdog timer interval in WRMISC2. This image - * maintains the value of the control bits of MISC2 are - * continuously reset to zero as long as the WD timer is disabled. - */ - devpriv->WDInterval = 0; + /* Init image of watchdog timer interval in WRMISC2. This image + * maintains the value of the control bits of MISC2 are + * continuously reset to zero as long as the WD timer is disabled. + */ + devpriv->WDInterval = 0; - /* Init Counter Interrupt enab mask for RDMISC2. This mask is - * applied against MISC2 when testing to determine which timer - * events are requesting interrupt service. - */ - devpriv->CounterIntEnabs = 0; + /* Init Counter Interrupt enab mask for RDMISC2. This mask is + * applied against MISC2 when testing to determine which timer + * events are requesting interrupt service. + */ + devpriv->CounterIntEnabs = 0; - /* Init counters. */ - CountersInit(dev); + /* Init counters. */ + CountersInit(dev); - /* Without modifying the state of the Battery Backup enab, disable - * the watchdog timer, set DIO channels 0-5 to operate in the - * standard DIO (vs. counter overflow) mode, disable the battery - * charger, and reset the watchdog interval selector to zero. - */ - WriteMISC2(dev, (uint16_t) (DEBIread(dev, - LP_RDMISC2) & - MISC2_BATT_ENABLE)); + /* Without modifying the state of the Battery Backup enab, disable + * the watchdog timer, set DIO channels 0-5 to operate in the + * standard DIO (vs. counter overflow) mode, disable the battery + * charger, and reset the watchdog interval selector to zero. + */ + WriteMISC2(dev, (uint16_t)(DEBIread(dev, LP_RDMISC2) & + MISC2_BATT_ENABLE)); - /* Initialize the digital I/O subsystem. */ - s626_dio_init(dev); + /* Initialize the digital I/O subsystem. */ + s626_dio_init(dev); - /* enable interrupt test */ - /* writel(IRQ_GPIO3 | IRQ_RPS1,devpriv->base_addr+P_IER); */ - } + /* enable interrupt test */ + /* writel(IRQ_GPIO3 | IRQ_RPS1,devpriv->base_addr+P_IER); */ } static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) -- cgit v0.10.2 From 597478473a172213ce396a799f65089bf4e75517 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 24 Sep 2012 13:37:52 -0700 Subject: staging: comedi: s626: #if 0 out the "SAA7146 BUG WORKAROUND" Until it's determined if this workaround can be removed, block out the code with an #if 0/#endif and remove the individual comments on each line. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index cd09c37..4315892 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -2459,16 +2459,10 @@ static int s626_allocate_dma_buffers(struct comedi_device *dev) static void s626_initialize(struct comedi_device *dev) { -/* uint8_t PollList; */ -/* uint16_t AdcData; */ -/* uint16_t StartVal; */ -/* uint16_t index; */ -/* unsigned int data[16]; */ dma_addr_t pPhysBuf; uint16_t chan; int i; - /* enab DEBI and audio pins, enable I2C interface. */ MC_ENABLE(P_MC1, MC1_DEBI | MC1_AUDIO | MC1_I2C); /* Configure DEBI operating mode. */ @@ -2568,38 +2562,50 @@ static void s626_initialize(struct comedi_device *dev) /* RPS program performs no explicit mem writes. */ WR7146(P_RPS1_TOUT, 0); /* Disable RPS timeouts. */ - /* SAA7146 BUG WORKAROUND. Initialize SAA7146 ADC interface - * to a known state by invoking ADCs until FB BUFFER 1 - * register shows that it is correctly receiving ADC data. - * This is necessary because the SAA7146 ADC interface does - * not start up in a defined state after a PCI reset. +#if 0 + /* + * SAA7146 BUG WORKAROUND + * + * Initialize SAA7146 ADC interface to a known state by + * invoking ADCs until FB BUFFER 1 register shows that it + * is correctly receiving ADC data. This is necessary + * because the SAA7146 ADC interface does not start up in + * a defined state after a PCI reset. */ -/* PollList = EOPL; // Create a simple polling */ -/* // list for analog input */ -/* // channel 0. */ -/* ResetADC( dev, &PollList ); */ - -/* s626_ai_rinsn(dev,dev->subdevices,NULL,data); //( &AdcData ); // */ -/* //Get initial ADC */ -/* //value. */ - -/* StartVal = data[0]; */ - -/* // VERSION 2.01 CHANGE: TIMEOUT ADDED TO PREVENT HANGED EXECUTION. */ -/* // Invoke ADCs until the new ADC value differs from the initial */ -/* // value or a timeout occurs. The timeout protects against the */ -/* // possibility that the driver is restarting and the ADC data is a */ -/* // fixed value resulting from the applied ADC analog input being */ -/* // unusually quiet or at the rail. */ - -/* for ( index = 0; index < 500; index++ ) */ -/* { */ -/* s626_ai_rinsn(dev,dev->subdevices,NULL,data); */ -/* AdcData = data[0]; //ReadADC( &AdcData ); */ -/* if ( AdcData != StartVal ) */ -/* break; */ -/* } */ + { + uint8_t PollList; + uint16_t AdcData; + uint16_t StartVal; + uint16_t index; + unsigned int data[16]; + + /* Create a simple polling list for analog input channel 0 */ + PollList = EOPL; + ResetADC(dev, &PollList); + + /* Get initial ADC value */ + s626_ai_rinsn(dev, dev->subdevices, NULL, data); + StartVal = data[0]; + + /* + * VERSION 2.01 CHANGE: TIMEOUT ADDED TO PREVENT HANGED EXECUTION. + * + * Invoke ADCs until the new ADC value differs from the initial + * value or a timeout occurs. The timeout protects against the + * possibility that the driver is restarting and the ADC data is a + * fixed value resulting from the applied ADC analog input being + * unusually quiet or at the rail. + */ + for (index = 0; index < 500; index++) { + s626_ai_rinsn(dev, dev->subdevices, NULL, data); + AdcData = data[0]; + if (AdcData != StartVal) + break; + } + + } +#endif /* SAA7146 BUG WORKAROUND */ /* end initADC */ -- cgit v0.10.2 From 17553c88a21866333f4dfe15fe75591d80f02f76 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 24 Sep 2012 13:38:07 -0700 Subject: staging: comedi: s626: remove 'IsBoardRevA' comment IsBoardRevA is not defined in the driver. Remove the comment about it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 4315892..e67e129 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -2488,29 +2488,8 @@ static void s626_initialize(struct comedi_device *dev) /* Init GPIO so that ADC Start* is negated. */ WR7146(P_GPIO, GPIO_BASE | GPIO1_HI); - /* IsBoardRevA is a boolean that indicates whether the board is RevA. - * - * VERSION 2.01 CHANGE: REV A & B BOARDS NOW SUPPORTED BY DYNAMIC - * EEPROM ADDRESS SELECTION. Initialize the I2C interface, which - * is used to access the onboard serial EEPROM. The EEPROM's I2C - * DeviceAddress is hardwired to a value that is dependent on the - * 626 board revision. On all board revisions, the EEPROM stores - * TrimDAC calibration constants for analog I/O. On RevB and - * higher boards, the DeviceAddress is hardwired to 0 to enable - * the EEPROM to also store the PCI SubVendorID and SubDeviceID; - * this is the address at which the SAA7146 expects a - * configuration EEPROM to reside. On RevA boards, the EEPROM - * device address, which is hardwired to 4, prevents the SAA7146 - * from retrieving PCI sub-IDs, so the SAA7146 uses its built-in - * default values, instead. - */ - - /* devpriv->I2Cards= IsBoardRevA ? 0xA8 : 0xA0; // Set I2C EEPROM */ - /* DeviceType (0xA0) */ - /* and DeviceAddress<<1. */ - - devpriv->I2CAdrs = 0xA0; /* I2C device address for onboard */ - /* eeprom(revb) */ + /* I2C device address for onboard eeprom (revb) */ + devpriv->I2CAdrs = 0xA0; /* Issue an I2C ABORT command to halt any I2C operation in */ /* progress and reset BUSY flag. */ -- cgit v0.10.2 From 7f98961c0d4bdebc4508c59cead7f349e47feb7f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 24 Sep 2012 13:38:22 -0700 Subject: staging: comedi: s626: remove 'ChargeEnabled' from private data This variable is never used in the driver. Just remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index e67e129..4eb1a67 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -98,7 +98,6 @@ struct s626_private { /* Pointer to logical adrs of DMA buffer used to hold DAC data. */ uint16_t Dacpol; /* Image of DAC polarity register. */ uint8_t TrimSetpoint[12]; /* Images of TrimDAC setpoints */ - uint16_t ChargeEnabled; /* Image of MISC2 Battery */ /* Charge Enabled (0 or WRMISC2_CHARGE_ENABLE). */ uint16_t WDInterval; /* Image of MISC2 watchdog interval control bits. */ uint32_t I2CAdrs; @@ -2667,12 +2666,6 @@ static void s626_initialize(struct comedi_device *dev) for (chan = 0; chan < S626_DAC_CHANNELS; chan++) SetDAC(dev, chan, 0); - /* Init image of WRMISC2 Battery Charger Enabled control bit. - * This image is used when the state of the charger control bit, - * which has no direct hardware readback mechanism, is queried. - */ - devpriv->ChargeEnabled = 0; - /* Init image of watchdog timer interval in WRMISC2. This image * maintains the value of the control bits of MISC2 are * continuously reset to zero as long as the WD timer is disabled. -- cgit v0.10.2 From dc598176bbd7dfbcfcd6177d14b10768c59effae Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 24 Sep 2012 13:38:39 -0700 Subject: staging: comedi: s626: remove 'WDInterval' from private data This variable is never used in the driver. Just remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 4eb1a67..0b89737 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -99,7 +99,6 @@ struct s626_private { uint16_t Dacpol; /* Image of DAC polarity register. */ uint8_t TrimSetpoint[12]; /* Images of TrimDAC setpoints */ /* Charge Enabled (0 or WRMISC2_CHARGE_ENABLE). */ - uint16_t WDInterval; /* Image of MISC2 watchdog interval control bits. */ uint32_t I2CAdrs; /* I2C device address for onboard EEPROM (board rev dependent). */ /* short I2Cards; */ @@ -2666,12 +2665,6 @@ static void s626_initialize(struct comedi_device *dev) for (chan = 0; chan < S626_DAC_CHANNELS; chan++) SetDAC(dev, chan, 0); - /* Init image of watchdog timer interval in WRMISC2. This image - * maintains the value of the control bits of MISC2 are - * continuously reset to zero as long as the WD timer is disabled. - */ - devpriv->WDInterval = 0; - /* Init Counter Interrupt enab mask for RDMISC2. This mask is * applied against MISC2 when testing to determine which timer * events are requesting interrupt service. -- cgit v0.10.2 From 98667bf7cc930c56f9257a8296d27a78eebac43f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 24 Sep 2012 13:38:53 -0700 Subject: staging: comedi: s626: remove clear of kzalloc'ed data The private data is kzalloc'ed. There is no need to set any of the initial data to '0'. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 0b89737..6f1705b 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -2665,12 +2665,6 @@ static void s626_initialize(struct comedi_device *dev) for (chan = 0; chan < S626_DAC_CHANNELS; chan++) SetDAC(dev, chan, 0); - /* Init Counter Interrupt enab mask for RDMISC2. This mask is - * applied against MISC2 when testing to determine which timer - * events are requesting interrupt service. - */ - devpriv->CounterIntEnabs = 0; - /* Init counters. */ CountersInit(dev); -- cgit v0.10.2 From 54a2a02ea51f606ba37f800c5e5eebb049ca6fb8 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 24 Sep 2012 13:39:14 -0700 Subject: staging: comedi: s626: cleanup comments in s626_initialize() Cleanup the comments to follow the coding style of the kernel. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 6f1705b..e1d10f3 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -2461,83 +2461,80 @@ static void s626_initialize(struct comedi_device *dev) uint16_t chan; int i; - /* enab DEBI and audio pins, enable I2C interface. */ + /* Enable DEBI and audio pins, enable I2C interface */ MC_ENABLE(P_MC1, MC1_DEBI | MC1_AUDIO | MC1_I2C); - /* Configure DEBI operating mode. */ - WR7146(P_DEBICFG, DEBI_CFG_SLAVE16 /* Local bus is 16 */ - /* bits wide. */ - | (DEBI_TOUT << DEBI_CFG_TOUT_BIT) - - /* Declare DEBI */ - /* transfer timeout */ - /* interval. */ - |DEBI_SWAP /* Set up byte lane */ - /* steering. */ - | DEBI_CFG_INTEL); /* Intel-compatible */ - /* local bus (DEBI */ - /* never times out). */ - - /* DEBI INIT S626 WR7146( P_DEBICFG, DEBI_CFG_INTEL | DEBI_CFG_TOQ */ - /* | DEBI_CFG_INCQ| DEBI_CFG_16Q); //end */ - - /* Paging is disabled. */ - WR7146(P_DEBIPAGE, DEBI_PAGE_DISABLE); /* Disable MMU paging. */ - - /* Init GPIO so that ADC Start* is negated. */ + + /* + * Configure DEBI operating mode + * + * Local bus is 16 bits wide + * Declare DEBI transfer timeout interval + * Set up byte lane steering + * Intel-compatible local bus (DEBI never times out) + */ + WR7146(P_DEBICFG, DEBI_CFG_SLAVE16 | + (DEBI_TOUT << DEBI_CFG_TOUT_BIT) | + DEBI_SWAP | DEBI_CFG_INTEL); + + /* Disable MMU paging */ + WR7146(P_DEBIPAGE, DEBI_PAGE_DISABLE); + + /* Init GPIO so that ADC Start* is negated */ WR7146(P_GPIO, GPIO_BASE | GPIO1_HI); /* I2C device address for onboard eeprom (revb) */ devpriv->I2CAdrs = 0xA0; - /* Issue an I2C ABORT command to halt any I2C operation in */ - /* progress and reset BUSY flag. */ + /* + * Issue an I2C ABORT command to halt any I2C + * operation in progress and reset BUSY flag. + */ WR7146(P_I2CSTAT, I2C_CLKSEL | I2C_ABORT); - /* Write I2C control: abort any I2C activity. */ MC_ENABLE(P_MC2, MC2_UPLD_IIC); - /* Invoke command upload */ while ((RR7146(P_MC2) & MC2_UPLD_IIC) == 0) ; - /* and wait for upload to complete. */ - /* Per SAA7146 data sheet, write to STATUS reg twice to - * reset all I2C error flags. */ + /* + * Per SAA7146 data sheet, write to STATUS + * reg twice to reset all I2C error flags. + */ for (i = 0; i < 2; i++) { WR7146(P_I2CSTAT, I2C_CLKSEL); - /* Write I2C control: reset error flags. */ - MC_ENABLE(P_MC2, MC2_UPLD_IIC); /* Invoke command upload */ + MC_ENABLE(P_MC2, MC2_UPLD_IIC); while (!MC_TEST(P_MC2, MC2_UPLD_IIC)) ; - /* and wait for upload to complete. */ } - /* Init audio interface functional attributes: set DAC/ADC + /* + * Init audio interface functional attributes: set DAC/ADC * serial clock rates, invert DAC serial clock so that * DAC data setup times are satisfied, enable DAC serial * clock out. */ - WR7146(P_ACON2, ACON2_INIT); - /* Set up TSL1 slot list, which is used to control the + /* + * Set up TSL1 slot list, which is used to control the * accumulation of ADC data: RSD1 = shift data in on SD1. - * SIB_A1 = store data uint8_t at next available location in - * FB BUFFER1 register. */ + * SIB_A1 = store data uint8_t at next available location + * in FB BUFFER1 register. + */ WR7146(P_TSL1, RSD1 | SIB_A1); - /* Fetch ADC high data uint8_t. */ WR7146(P_TSL1 + 4, RSD1 | SIB_A1 | EOS); - /* Fetch ADC low data uint8_t; end of TSL1. */ - /* enab TSL1 slot list so that it executes all the time. */ + /* Enable TSL1 slot list so that it executes all the time */ WR7146(P_ACON1, ACON1_ADCSTART); - /* Initialize RPS registers used for ADC. */ - - /* Physical start of RPS program. */ - WR7146(P_RPSADDR1, (uint32_t) devpriv->RPSBuf.PhysicalBase); + /* + * Initialize RPS registers used for ADC + */ + /* Physical start of RPS program */ + WR7146(P_RPSADDR1, (uint32_t)devpriv->RPSBuf.PhysicalBase); + /* RPS program performs no explicit mem writes */ WR7146(P_RPSPAGE1, 0); - /* RPS program performs no explicit mem writes. */ - WR7146(P_RPS1_TOUT, 0); /* Disable RPS timeouts. */ + /* Disable RPS timeouts */ + WR7146(P_RPS1_TOUT, 0); #if 0 /* @@ -2584,39 +2581,45 @@ static void s626_initialize(struct comedi_device *dev) } #endif /* SAA7146 BUG WORKAROUND */ - /* end initADC */ - - /* init the DAC interface */ + /* + * Initialize the DAC interface + */ - /* Init Audio2's output DMAC attributes: burst length = 1 - * DWORD, threshold = 1 DWORD. + /* + * Init Audio2's output DMAC attributes: + * burst length = 1 DWORD + * threshold = 1 DWORD. */ WR7146(P_PCI_BT_A, 0); - /* Init Audio2's output DMA physical addresses. The protection + /* + * Init Audio2's output DMA physical addresses. The protection * address is set to 1 DWORD past the base address so that a * single DWORD will be transferred each time a DMA transfer is - * enabled. */ - + * enabled. + */ pPhysBuf = devpriv->ANABuf.PhysicalBase + (DAC_WDMABUF_OS * sizeof(uint32_t)); + WR7146(P_BASEA2_OUT, (uint32_t) pPhysBuf); + WR7146(P_PROTA2_OUT, (uint32_t) (pPhysBuf + sizeof(uint32_t))); - WR7146(P_BASEA2_OUT, (uint32_t) pPhysBuf); /* Buffer base adrs. */ - WR7146(P_PROTA2_OUT, (uint32_t) (pPhysBuf + sizeof(uint32_t))); /* Protection address. */ - - /* Cache Audio2's output DMA buffer logical address. This is - * where DAC data is buffered for A2 output DMA transfers. */ + /* + * Cache Audio2's output DMA buffer logical address. This is + * where DAC data is buffered for A2 output DMA transfers. + */ devpriv->pDacWBuf = (uint32_t *)devpriv->ANABuf.LogicalBase + DAC_WDMABUF_OS; - /* Audio2's output channels does not use paging. The protection - * violation handling bit is set so that the DMAC will - * automatically halt and its PCI address pointer will be reset - * when the protection address is reached. */ - + /* + * Audio2's output channels does not use paging. The + * protection violation handling bit is set so that the + * DMAC will automatically halt and its PCI address pointer + * will be reset when the protection address is reached. + */ WR7146(P_PAGEA2_OUT, 8); - /* Initialize time slot list 2 (TSL2), which is used to control + /* + * Initialize time slot list 2 (TSL2), which is used to control * the clock generation for and serialization of data to be sent * to the DAC devices. Slot 0 is a NOP that is used to trap TSL * execution; this permits other slots to be safely modified @@ -2627,48 +2630,52 @@ static void s626_initialize(struct comedi_device *dev) * not yet finished executing. */ + /* Slot 0: Trap TSL execution, shift 0xFF into FB_BUFFER2 */ SETVECT(0, XSD2 | RSD3 | SIB_A2 | EOS); - /* Slot 0: Trap TSL execution, shift 0xFF into FB_BUFFER2. */ - /* Initialize slot 1, which is constant. Slot 1 causes a + /* + * Initialize slot 1, which is constant. Slot 1 causes a * DWORD to be transferred from audio channel 2's output FIFO * to the FIFO's output buffer so that it can be serialized * and sent to the DAC during subsequent slots. All remaining * slots are dynamically populated as required by the target * DAC device. */ + + /* Slot 1: Fetch DWORD from Audio2's output FIFO */ SETVECT(1, LF_A2); - /* Slot 1: Fetch DWORD from Audio2's output FIFO. */ - /* Start DAC's audio interface (TSL2) running. */ + /* Start DAC's audio interface (TSL2) running */ WR7146(P_ACON1, ACON1_DACSTART); - /* end init DAC interface */ - - /* Init Trim DACs to calibrated values. Do it twice because the + /* + * Init Trim DACs to calibrated values. Do it twice because the * SAA7146 audio channel does not always reset properly and * sometimes causes the first few TrimDAC writes to malfunction. */ - LoadTrimDACs(dev); - LoadTrimDACs(dev); /* Insurance. */ + LoadTrimDACs(dev); - /* Manually init all gate array hardware in case this is a soft + /* + * Manually init all gate array hardware in case this is a soft * reset (we have no way of determining whether this is a warm * or cold start). This is necessary because the gate array will * reset only in response to a PCI hard reset; there is no soft - * reset function. */ + * reset function. + */ - /* Init all DAC outputs to 0V and init all DAC setpoint and + /* + * Init all DAC outputs to 0V and init all DAC setpoint and * polarity images. */ for (chan = 0; chan < S626_DAC_CHANNELS; chan++) SetDAC(dev, chan, 0); - /* Init counters. */ + /* Init counters */ CountersInit(dev); - /* Without modifying the state of the Battery Backup enab, disable + /* + * Without modifying the state of the Battery Backup enab, disable * the watchdog timer, set DIO channels 0-5 to operate in the * standard DIO (vs. counter overflow) mode, disable the battery * charger, and reset the watchdog interval selector to zero. @@ -2676,11 +2683,11 @@ static void s626_initialize(struct comedi_device *dev) WriteMISC2(dev, (uint16_t)(DEBIread(dev, LP_RDMISC2) & MISC2_BATT_ENABLE)); - /* Initialize the digital I/O subsystem. */ + /* Initialize the digital I/O subsystem */ s626_dio_init(dev); /* enable interrupt test */ - /* writel(IRQ_GPIO3 | IRQ_RPS1,devpriv->base_addr+P_IER); */ + /* writel(IRQ_GPIO3 | IRQ_RPS1, devpriv->base_addr + P_IER); */ } static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) -- cgit v0.10.2 From 67f2021fb1519057b0643d871b2afcd583bcc40d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 24 Sep 2012 13:50:48 -0700 Subject: staging: comedi: s526: fix if() check in s526_gpct_winsn() This if() check was flipped from a test for valid data params to a test for invalid params. As pointed out by Dan Carpenter, the orignal test was: if ((data[1] > data[0]) && (data[0] > 0)) { the flipped test should be: if (data[1] <= data[0]) ... Add the missing '='. Signed-off-by: H Hartley Sweeten Reported-by: Dan Carpenter Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c index 4ad6adf..a1e2562 100644 --- a/drivers/staging/comedi/drivers/s526.c +++ b/drivers/staging/comedi/drivers/s526.c @@ -376,7 +376,7 @@ static int s526_gpct_winsn(struct comedi_device *dev, The above periods must be expressed as a multiple of the pulse frequency on the selected source */ - if ((data[1] < data[0]) || !data[0]) + if ((data[1] <= data[0]) || !data[0]) return -EINVAL; /* Fall thru to write the PULSE_WIDTH */ -- cgit v0.10.2 From b655c2c4782ed3e2e71d2608154e295a3e860311 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 24 Sep 2012 17:20:52 +0100 Subject: staging: comedi: s626: don't dereference insn->data `s626_enc_insn_config()` is incorrectly dereferencing `insn->data` which is a pointer to user memory. It should be dereferencing the separate `data` parameter that points to a copy of the data in kernel memory. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Cc: stable Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index e1d10f3..430e26b 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -1825,7 +1825,7 @@ static int s626_enc_insn_config(struct comedi_device *dev, /* (data==NULL) ? (Preloadvalue=0) : (Preloadvalue=data[0]); */ k->SetMode(dev, k, Setup, TRUE); - Preload(dev, k, *(insn->data)); + Preload(dev, k, data[0]); k->PulseIndex(dev, k); SetLatchSource(dev, k, valueSrclatch); k->SetEnable(dev, k, (uint16_t) (enab != 0)); -- cgit v0.10.2 From affdc230d7d328d2b602113e459a57d9de5ded08 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 24 Sep 2012 17:20:53 +0100 Subject: staging: comedi: s626: add FIXME comment `s626_enc_insn_config()` is the `insn_config()` handler for a counter subdevice. The `data[0]` value is supposed to be one of the `INSN_CONFIG_...` constants defined in "comedi.h" indicating the type of configuration instruction, but this function seems to be using it as a variable value to preload the counter with. Various values of `data[0]` are going to cause `check_insn_config_length()` in the comedi core ("comedi_fops.c") to return an error, and this function won't be called in those cases. Most other values will log a warning to the kernel log. It's not entirely clear what constant should be checked for in `data[0]`, so add a "FIXME" comment for now. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 430e26b..24878c8 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -1804,6 +1804,9 @@ static int s626_dio_insn_config(struct comedi_device *dev, /* Now this function initializes the value of the counter (data[0]) and set the subdevice. To complete with trigger and interrupt configuration */ +/* FIXME: data[0] is supposed to be an INSN_CONFIG_xxx constant indicating + * what is being configured, but this function appears to be using data[0] + * as a variable. */ static int s626_enc_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) -- cgit v0.10.2 From 3cd73bc1cf59b2c9232d9889ba2b148e262054b6 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 24 Sep 2012 16:27:59 +0100 Subject: staging: comedi: ni_mio_common: always lock in ni_ai_poll() `ni_ai_poll()` currently acquires (and later releases) the comedi device's spin-lock iff `in_interrupt()` returns 0. However, it is only called during processing of a `COMEDI_POLL` ioctl so `in_interrupt()` will always return 0 in this case. Remove this test and acquire/release the spin-lock unconditionally. This eliminates a sparse warning about different lock contexts for basic block. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index 87995da..4bbb979 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -1766,20 +1766,18 @@ static int ni_ai_reset(struct comedi_device *dev, struct comedi_subdevice *s) static int ni_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s) { - unsigned long flags = 0; + unsigned long flags; int count; /* lock to avoid race with interrupt handler */ - if (in_interrupt() == 0) - spin_lock_irqsave(&dev->spinlock, flags); + spin_lock_irqsave(&dev->spinlock, flags); #ifndef PCIDMA ni_handle_fifo_dregs(dev); #else ni_sync_ai_dma(dev); #endif count = s->async->buf_write_count - s->async->buf_read_count; - if (in_interrupt() == 0) - spin_unlock_irqrestore(&dev->spinlock, flags); + spin_unlock_irqrestore(&dev->spinlock, flags); return count; } -- cgit v0.10.2 From fa16e5ea25d7dd83f663f333e70713aa2fa5dffe Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Wed, 26 Sep 2012 14:01:31 -0500 Subject: staging: r8712u: Do not queue cloned skb Some post-3.4 kernels have a problem when a cloned skb is used in the RX path. This patch handles one such case for r8712u. The patch was suggested by Eric Dumazet. Signed-off-by: Larry Finger Cc: Stable [v3.4+] Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8712/rtl8712_recv.c b/drivers/staging/rtl8712/rtl8712_recv.c index 4cd297a..c76732c 100644 --- a/drivers/staging/rtl8712/rtl8712_recv.c +++ b/drivers/staging/rtl8712/rtl8712_recv.c @@ -1131,6 +1131,9 @@ static void recv_tasklet(void *priv) recvbuf2recvframe(padapter, pskb); skb_reset_tail_pointer(pskb); pskb->len = 0; - skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb); + if (!skb_cloned(pskb)) + skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb); + else + consume_skb(pskb); } } -- cgit v0.10.2 From 8c6c4460e96e159df5dffaefc2d4b57500a56e95 Mon Sep 17 00:00:00 2001 From: Harsh Kumar Date: Wed, 26 Sep 2012 23:24:45 +0530 Subject: Staging: winbond: Changed c99 comments to c89 comments checkpatch cleanup: Changed c99 comments to c89 comments Signed-off-by: Harsh Kumar Reviewed-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/winbond/wb35tx.c b/drivers/staging/winbond/wb35tx.c index 0f870da..a4074fd 100644 --- a/drivers/staging/winbond/wb35tx.c +++ b/drivers/staging/winbond/wb35tx.c @@ -1,13 +1,13 @@ -//============================================================================ -// Copyright (c) 1996-2002 Winbond Electronic Corporation -// -// Module Name: -// Wb35Tx.c -// -// Abstract: -// Processing the Tx message and put into down layer -// -//============================================================================ +/* + * Copyright (c) 1996-2002 Winbond Electronic Corporation + * + * Module Name: + * Wb35Tx.c + * + * Abstract: + * Processing the Tx message and put into down layer + * + */ #include #include @@ -33,20 +33,21 @@ static void Wb35Tx_complete(struct urb * pUrb) struct wb35_mds *pMds = &adapter->Mds; printk("wb35: tx complete\n"); - // Variable setting + /* Variable setting */ pWb35Tx->EP4vm_state = VM_COMPLETED; - pWb35Tx->EP4VM_status = pUrb->status; //Store the last result of Irp - pMds->TxOwner[ pWb35Tx->TxSendIndex ] = 0;// Set the owner. Free the owner bit always. + pWb35Tx->EP4VM_status = pUrb->status; /* Store the last result of Irp */ + /* Set the owner. Free the owner bit always. */ + pMds->TxOwner[ pWb35Tx->TxSendIndex ] = 0; pWb35Tx->TxSendIndex++; pWb35Tx->TxSendIndex %= MAX_USB_TX_BUFFER_NUMBER; - if (pHwData->SurpriseRemove) // Let WbWlanHalt to handle surprise remove + if (pHwData->SurpriseRemove) /* Let WbWlanHalt to handle surprise remove */ goto error; if (pWb35Tx->tx_halt) goto error; - // The URB is completed, check the result + /* The URB is completed, check the result */ if (pWb35Tx->EP4VM_status != 0) { printk("URB submission failed\n"); pWb35Tx->EP4vm_state = VM_STOP; @@ -79,15 +80,15 @@ static void Wb35Tx(struct wbsoft_priv *adapter) if (pWb35Tx->tx_halt) goto cleanup; - // Ownership checking + /* Ownership checking */ SendIndex = pWb35Tx->TxSendIndex; - if (!pMds->TxOwner[SendIndex]) //No more data need to be sent, return immediately + /* No more data need to be sent, return immediately */ + if (!pMds->TxOwner[SendIndex]) goto cleanup; pTxBufferAddress = pWb35Tx->TxBuffer[SendIndex]; - // - // Issuing URB - // + + /* Issuing URB */ usb_fill_bulk_urb(pUrb, pHwData->udev, usb_sndbulkpipe(pHwData->udev, 4), pTxBufferAddress, pMds->TxBufferSize[ SendIndex ], @@ -100,7 +101,7 @@ static void Wb35Tx(struct wbsoft_priv *adapter) goto cleanup; } - // Check if driver needs issue Irp for EP2 + /* Check if driver needs issue Irp for EP2 */ pWb35Tx->TxFillCount += pMds->TxCountInBuffer[SendIndex]; if (pWb35Tx->TxFillCount > 12) Wb35Tx_EP2VM_start(adapter); @@ -118,7 +119,7 @@ void Wb35Tx_start(struct wbsoft_priv *adapter) struct hw_data * pHwData = &adapter->sHwData; struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx; - // Allow only one thread to run into function + /* Allow only one thread to run into function */ if (atomic_inc_return(&pWb35Tx->TxFireCounter) == 1) { pWb35Tx->EP4vm_state = VM_RUNNING; Wb35Tx(adapter); @@ -144,32 +145,32 @@ unsigned char Wb35Tx_initial(struct hw_data * pHwData) return true; } -//====================================================== void Wb35Tx_stop(struct hw_data * pHwData) { struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx; - // Try to cancel the Trp of EP2 + /* Try to cancel the Trp of EP2 */ if (pWb35Tx->EP2vm_state == VM_RUNNING) - usb_unlink_urb( pWb35Tx->Tx2Urb ); // Only use unlink, let Wb35Tx_destroy to free them + /* Only use unlink, let Wb35Tx_destroy to free them */ + usb_unlink_urb( pWb35Tx->Tx2Urb ); pr_debug("EP2 Tx stop\n"); - // Try to cancel the Irp of EP4 + /* Try to cancel the Irp of EP4 */ if (pWb35Tx->EP4vm_state == VM_RUNNING) - usb_unlink_urb( pWb35Tx->Tx4Urb ); // Only use unlink, let Wb35Tx_destroy to free them + /* Only use unlink, let Wb35Tx_destroy to free them */ + usb_unlink_urb( pWb35Tx->Tx4Urb ); pr_debug("EP4 Tx stop\n"); } -//====================================================== void Wb35Tx_destroy(struct hw_data * pHwData) { struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx; - // Wait for VM stop + /* Wait for VM stop */ do { - msleep(10); // Delay for waiting function enter 940623.1.a + msleep(10); /* Delay for waiting function enter 940623.1.a */ } while( (pWb35Tx->EP2vm_state != VM_STOP) && (pWb35Tx->EP4vm_state != VM_STOP) ); - msleep(10); // Delay for waiting function enter 940623.1.b + msleep(10); /* Delay for waiting function enter 940623.1.b */ if (pWb35Tx->Tx4Urb) usb_free_urb( pWb35Tx->Tx4Urb ); @@ -210,34 +211,34 @@ static void Wb35Tx_EP2VM_complete(struct urb * pUrb) u16 InterruptInLength; - // Variable setting + /* Variable setting */ pWb35Tx->EP2vm_state = VM_COMPLETED; pWb35Tx->EP2VM_status = pUrb->status; - // For Linux 2.4. Interrupt will always trigger - if (pHwData->SurpriseRemove) // Let WbWlanHalt to handle surprise remove + /* For Linux 2.4. Interrupt will always trigger */ + if (pHwData->SurpriseRemove) /* Let WbWlanHalt to handle surprise remove */ goto error; if (pWb35Tx->tx_halt) goto error; - //The Urb is completed, check the result + /* The Urb is completed, check the result */ if (pWb35Tx->EP2VM_status != 0) { printk("EP2 IoCompleteRoutine return error\n"); pWb35Tx->EP2vm_state= VM_STOP; goto error; } - // Update the Tx result + /* Update the Tx result */ InterruptInLength = pUrb->actual_length; - // Modify for minimum memory access and DWORD alignment. - T02.value = cpu_to_le32(pltmp[0]) >> 8; // [31:8] -> [24:0] - InterruptInLength -= 1;// 20051221.1.c Modify the follow for more stable - InterruptInLength >>= 2; // InterruptInLength/4 + /* Modify for minimum memory access and DWORD alignment. */ + T02.value = cpu_to_le32(pltmp[0]) >> 8; /* [31:8] -> [24:0] */ + InterruptInLength -= 1; /* 20051221.1.c Modify the follow for more stable */ + InterruptInLength >>= 2; /* InterruptInLength/4 */ for (i = 1; i <= InterruptInLength; i++) { T02.value |= ((cpu_to_le32(pltmp[i]) & 0xff) << 24); - TSTATUS.value = T02.value; //20061009 anson's endian + TSTATUS.value = T02.value; /* 20061009 anson's endian */ Mds_SendComplete( adapter, &TSTATUS ); T02.value = cpu_to_le32(pltmp[i]) >> 8; } @@ -262,9 +263,7 @@ static void Wb35Tx_EP2VM(struct wbsoft_priv *adapter) if (pWb35Tx->tx_halt) goto error; - // - // Issuing URB - // + /* Issuing URB */ usb_fill_int_urb( pUrb, pHwData->udev, usb_rcvintpipe(pHwData->udev,2), pltmp, MAX_INTERRUPT_LENGTH, Wb35Tx_EP2VM_complete, adapter, 32); @@ -287,7 +286,7 @@ void Wb35Tx_EP2VM_start(struct wbsoft_priv *adapter) struct hw_data * pHwData = &adapter->sHwData; struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx; - // Allow only one thread to run into function + /* Allow only one thread to run into function */ if (atomic_inc_return(&pWb35Tx->TxResultCount) == 1) { pWb35Tx->EP2vm_state = VM_RUNNING; Wb35Tx_EP2VM(adapter); -- cgit v0.10.2 From 907af425a92a3e7cfac597ca324934f514b04d85 Mon Sep 17 00:00:00 2001 From: Harsh Kumar Date: Wed, 26 Sep 2012 23:33:39 +0530 Subject: Staging: winbond: Typo corrections in comments Few typo corrections in comments Signed-off-by: Harsh Kumar Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/winbond/wb35tx.c b/drivers/staging/winbond/wb35tx.c index a4074fd..9a82695 100644 --- a/drivers/staging/winbond/wb35tx.c +++ b/drivers/staging/winbond/wb35tx.c @@ -41,7 +41,7 @@ static void Wb35Tx_complete(struct urb * pUrb) pWb35Tx->TxSendIndex++; pWb35Tx->TxSendIndex %= MAX_USB_TX_BUFFER_NUMBER; - if (pHwData->SurpriseRemove) /* Let WbWlanHalt to handle surprise remove */ + if (pHwData->SurpriseRemove) /* Let WbWlanHalt handle surprise remove */ goto error; if (pWb35Tx->tx_halt) @@ -151,13 +151,13 @@ void Wb35Tx_stop(struct hw_data * pHwData) /* Try to cancel the Trp of EP2 */ if (pWb35Tx->EP2vm_state == VM_RUNNING) - /* Only use unlink, let Wb35Tx_destroy to free them */ + /* Only use unlink, let Wb35Tx_destroy free them */ usb_unlink_urb( pWb35Tx->Tx2Urb ); pr_debug("EP2 Tx stop\n"); /* Try to cancel the Irp of EP4 */ if (pWb35Tx->EP4vm_state == VM_RUNNING) - /* Only use unlink, let Wb35Tx_destroy to free them */ + /* Only use unlink, let Wb35Tx_destroy free them */ usb_unlink_urb( pWb35Tx->Tx4Urb ); pr_debug("EP4 Tx stop\n"); } @@ -216,7 +216,7 @@ static void Wb35Tx_EP2VM_complete(struct urb * pUrb) pWb35Tx->EP2VM_status = pUrb->status; /* For Linux 2.4. Interrupt will always trigger */ - if (pHwData->SurpriseRemove) /* Let WbWlanHalt to handle surprise remove */ + if (pHwData->SurpriseRemove) /* Let WbWlanHalt handle surprise remove */ goto error; if (pWb35Tx->tx_halt) -- cgit v0.10.2 From 814164462a07bf1c8011de8d8c8878cfa2920ad1 Mon Sep 17 00:00:00 2001 From: Harsh Kumar Date: Wed, 26 Sep 2012 23:34:42 +0530 Subject: Staging: winbond: Removed undesired spaces, lines and tabs checkpatch cleanup: Removed some undesired spaces, lines and tabs to comply with coding style. Signed-off-by: Harsh Kumar Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/winbond/wb35tx.c b/drivers/staging/winbond/wb35tx.c index 9a82695..7a2024d 100644 --- a/drivers/staging/winbond/wb35tx.c +++ b/drivers/staging/winbond/wb35tx.c @@ -15,7 +15,7 @@ #include "mds_f.h" unsigned char -Wb35Tx_get_tx_buffer(struct hw_data * pHwData, u8 **pBuffer) +Wb35Tx_get_tx_buffer(struct hw_data *pHwData, u8 **pBuffer) { struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx; @@ -25,10 +25,10 @@ Wb35Tx_get_tx_buffer(struct hw_data * pHwData, u8 **pBuffer) static void Wb35Tx(struct wbsoft_priv *adapter); -static void Wb35Tx_complete(struct urb * pUrb) +static void Wb35Tx_complete(struct urb *pUrb) { struct wbsoft_priv *adapter = pUrb->context; - struct hw_data * pHwData = &adapter->sHwData; + struct hw_data *pHwData = &adapter->sHwData; struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx; struct wb35_mds *pMds = &adapter->Mds; @@ -37,7 +37,7 @@ static void Wb35Tx_complete(struct urb * pUrb) pWb35Tx->EP4vm_state = VM_COMPLETED; pWb35Tx->EP4VM_status = pUrb->status; /* Store the last result of Irp */ /* Set the owner. Free the owner bit always. */ - pMds->TxOwner[ pWb35Tx->TxSendIndex ] = 0; + pMds->TxOwner[pWb35Tx->TxSendIndex] = 0; pWb35Tx->TxSendIndex++; pWb35Tx->TxSendIndex %= MAX_USB_TX_BUFFER_NUMBER; @@ -65,15 +65,14 @@ error: static void Wb35Tx(struct wbsoft_priv *adapter) { - struct hw_data * pHwData = &adapter->sHwData; + struct hw_data *pHwData = &adapter->sHwData; struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx; u8 *pTxBufferAddress; struct wb35_mds *pMds = &adapter->Mds; - struct urb * pUrb = (struct urb *)pWb35Tx->Tx4Urb; - int retv; + struct urb *pUrb = (struct urb *)pWb35Tx->Tx4Urb; + int retv; u32 SendIndex; - if (pHwData->SurpriseRemove) goto cleanup; @@ -91,12 +90,12 @@ static void Wb35Tx(struct wbsoft_priv *adapter) /* Issuing URB */ usb_fill_bulk_urb(pUrb, pHwData->udev, usb_sndbulkpipe(pHwData->udev, 4), - pTxBufferAddress, pMds->TxBufferSize[ SendIndex ], + pTxBufferAddress, pMds->TxBufferSize[SendIndex], Wb35Tx_complete, adapter); pWb35Tx->EP4vm_state = VM_RUNNING; retv = usb_submit_urb(pUrb, GFP_ATOMIC); - if (retv<0) { + if (retv < 0) { printk("EP4 Tx Irp sending error\n"); goto cleanup; } @@ -116,7 +115,7 @@ static void Wb35Tx(struct wbsoft_priv *adapter) void Wb35Tx_start(struct wbsoft_priv *adapter) { - struct hw_data * pHwData = &adapter->sHwData; + struct hw_data *pHwData = &adapter->sHwData; struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx; /* Allow only one thread to run into function */ @@ -127,7 +126,7 @@ void Wb35Tx_start(struct wbsoft_priv *adapter) atomic_dec(&pWb35Tx->TxFireCounter); } -unsigned char Wb35Tx_initial(struct hw_data * pHwData) +unsigned char Wb35Tx_initial(struct hw_data *pHwData) { struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx; @@ -138,52 +137,52 @@ unsigned char Wb35Tx_initial(struct hw_data * pHwData) pWb35Tx->Tx2Urb = usb_alloc_urb(0, GFP_ATOMIC); if (!pWb35Tx->Tx2Urb) { - usb_free_urb( pWb35Tx->Tx4Urb ); + usb_free_urb(pWb35Tx->Tx4Urb); return false; } return true; } -void Wb35Tx_stop(struct hw_data * pHwData) +void Wb35Tx_stop(struct hw_data *pHwData) { struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx; /* Try to cancel the Trp of EP2 */ if (pWb35Tx->EP2vm_state == VM_RUNNING) /* Only use unlink, let Wb35Tx_destroy free them */ - usb_unlink_urb( pWb35Tx->Tx2Urb ); + usb_unlink_urb(pWb35Tx->Tx2Urb); pr_debug("EP2 Tx stop\n"); /* Try to cancel the Irp of EP4 */ if (pWb35Tx->EP4vm_state == VM_RUNNING) /* Only use unlink, let Wb35Tx_destroy free them */ - usb_unlink_urb( pWb35Tx->Tx4Urb ); + usb_unlink_urb(pWb35Tx->Tx4Urb); pr_debug("EP4 Tx stop\n"); } -void Wb35Tx_destroy(struct hw_data * pHwData) +void Wb35Tx_destroy(struct hw_data *pHwData) { struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx; /* Wait for VM stop */ do { msleep(10); /* Delay for waiting function enter 940623.1.a */ - } while( (pWb35Tx->EP2vm_state != VM_STOP) && (pWb35Tx->EP4vm_state != VM_STOP) ); + } while ((pWb35Tx->EP2vm_state != VM_STOP) && (pWb35Tx->EP4vm_state != VM_STOP)); msleep(10); /* Delay for waiting function enter 940623.1.b */ if (pWb35Tx->Tx4Urb) - usb_free_urb( pWb35Tx->Tx4Urb ); + usb_free_urb(pWb35Tx->Tx4Urb); if (pWb35Tx->Tx2Urb) - usb_free_urb( pWb35Tx->Tx2Urb ); + usb_free_urb(pWb35Tx->Tx2Urb); pr_debug("Wb35Tx_destroy OK\n"); } void Wb35Tx_CurrentTime(struct wbsoft_priv *adapter, u32 TimeCount) { - struct hw_data * pHwData = &adapter->sHwData; + struct hw_data *pHwData = &adapter->sHwData; struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx; unsigned char Trigger = false; @@ -200,17 +199,16 @@ void Wb35Tx_CurrentTime(struct wbsoft_priv *adapter, u32 TimeCount) static void Wb35Tx_EP2VM(struct wbsoft_priv *adapter); -static void Wb35Tx_EP2VM_complete(struct urb * pUrb) +static void Wb35Tx_EP2VM_complete(struct urb *pUrb) { struct wbsoft_priv *adapter = pUrb->context; - struct hw_data * pHwData = &adapter->sHwData; + struct hw_data *pHwData = &adapter->sHwData; struct T02_descriptor T02, TSTATUS; struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx; - u32 * pltmp = (u32 *)pWb35Tx->EP2_buf; + u32 *pltmp = (u32 *)pWb35Tx->EP2_buf; u32 i; u16 InterruptInLength; - /* Variable setting */ pWb35Tx->EP2vm_state = VM_COMPLETED; pWb35Tx->EP2VM_status = pUrb->status; @@ -225,7 +223,7 @@ static void Wb35Tx_EP2VM_complete(struct urb * pUrb) /* The Urb is completed, check the result */ if (pWb35Tx->EP2VM_status != 0) { printk("EP2 IoCompleteRoutine return error\n"); - pWb35Tx->EP2vm_state= VM_STOP; + pWb35Tx->EP2vm_state = VM_STOP; goto error; } @@ -239,7 +237,7 @@ static void Wb35Tx_EP2VM_complete(struct urb * pUrb) T02.value |= ((cpu_to_le32(pltmp[i]) & 0xff) << 24); TSTATUS.value = T02.value; /* 20061009 anson's endian */ - Mds_SendComplete( adapter, &TSTATUS ); + Mds_SendComplete(adapter, &TSTATUS); T02.value = cpu_to_le32(pltmp[i]) >> 8; } @@ -251,10 +249,10 @@ error: static void Wb35Tx_EP2VM(struct wbsoft_priv *adapter) { - struct hw_data * pHwData = &adapter->sHwData; + struct hw_data *pHwData = &adapter->sHwData; struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx; - struct urb * pUrb = (struct urb *)pWb35Tx->Tx2Urb; - u32 * pltmp = (u32 *)pWb35Tx->EP2_buf; + struct urb *pUrb = (struct urb *)pWb35Tx->Tx2Urb; + u32 *pltmp = (u32 *)pWb35Tx->EP2_buf; int retv; if (pHwData->SurpriseRemove) @@ -264,7 +262,7 @@ static void Wb35Tx_EP2VM(struct wbsoft_priv *adapter) goto error; /* Issuing URB */ - usb_fill_int_urb( pUrb, pHwData->udev, usb_rcvintpipe(pHwData->udev,2), + usb_fill_int_urb(pUrb, pHwData->udev, usb_rcvintpipe(pHwData->udev, 2), pltmp, MAX_INTERRUPT_LENGTH, Wb35Tx_EP2VM_complete, adapter, 32); pWb35Tx->EP2vm_state = VM_RUNNING; @@ -283,7 +281,7 @@ error: void Wb35Tx_EP2VM_start(struct wbsoft_priv *adapter) { - struct hw_data * pHwData = &adapter->sHwData; + struct hw_data *pHwData = &adapter->sHwData; struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx; /* Allow only one thread to run into function */ -- cgit v0.10.2 From 926ae525111021a3fa20f26b391d091d6c945275 Mon Sep 17 00:00:00 2001 From: Harsh Kumar Date: Wed, 26 Sep 2012 23:35:42 +0530 Subject: Staging: winbond: checkpatch cleanup checkpatch cleanup: Corrected wrong placement of a brace and line exceeding 80 characters Signed-off-by: Harsh Kumar Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/winbond/wb35tx.c b/drivers/staging/winbond/wb35tx.c index 7a2024d..474cad8 100644 --- a/drivers/staging/winbond/wb35tx.c +++ b/drivers/staging/winbond/wb35tx.c @@ -135,8 +135,7 @@ unsigned char Wb35Tx_initial(struct hw_data *pHwData) return false; pWb35Tx->Tx2Urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!pWb35Tx->Tx2Urb) - { + if (!pWb35Tx->Tx2Urb) { usb_free_urb(pWb35Tx->Tx4Urb); return false; } @@ -263,7 +262,8 @@ static void Wb35Tx_EP2VM(struct wbsoft_priv *adapter) /* Issuing URB */ usb_fill_int_urb(pUrb, pHwData->udev, usb_rcvintpipe(pHwData->udev, 2), - pltmp, MAX_INTERRUPT_LENGTH, Wb35Tx_EP2VM_complete, adapter, 32); + pltmp, MAX_INTERRUPT_LENGTH, Wb35Tx_EP2VM_complete, + adapter, 32); pWb35Tx->EP2vm_state = VM_RUNNING; retv = usb_submit_urb(pUrb, GFP_ATOMIC); -- cgit v0.10.2 From ee692cfad6520f7cc60b766a3c013f9e6eba6e38 Mon Sep 17 00:00:00 2001 From: Harsh Kumar Date: Wed, 26 Sep 2012 23:36:15 +0530 Subject: Staging: winbond: usb_free_urb(NULL) is safe usb_free_urb(NULL) is safe. So, the check was removed. Signed-off-by: Harsh Kumar Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/winbond/wb35tx.c b/drivers/staging/winbond/wb35tx.c index 474cad8..30a77cc 100644 --- a/drivers/staging/winbond/wb35tx.c +++ b/drivers/staging/winbond/wb35tx.c @@ -170,11 +170,8 @@ void Wb35Tx_destroy(struct hw_data *pHwData) } while ((pWb35Tx->EP2vm_state != VM_STOP) && (pWb35Tx->EP4vm_state != VM_STOP)); msleep(10); /* Delay for waiting function enter 940623.1.b */ - if (pWb35Tx->Tx4Urb) - usb_free_urb(pWb35Tx->Tx4Urb); - - if (pWb35Tx->Tx2Urb) - usb_free_urb(pWb35Tx->Tx2Urb); + usb_free_urb(pWb35Tx->Tx4Urb); + usb_free_urb(pWb35Tx->Tx2Urb); pr_debug("Wb35Tx_destroy OK\n"); } -- cgit v0.10.2 From 27020ffed9166d65ce1e5b523051d13bfa2329b0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 26 Sep 2012 14:11:10 -0700 Subject: staging: comedi: drivers: use comedi_fc.h cmdtest helpers Use the cfc_check_trigger_src() helper for Step 1 in all the driver cmdtest functions. Use the cfc_check_trigger_is_unique() helper for Step 2 in all the driver cmdtest functions. Note that single source triggers do not need to be checked, they are already unique if they pass Step 1. For aesthetic reasons, change the comments in the cmdtest functions for steps 1 and 2 so that they are all the same. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index e2506dd..a256622 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -82,6 +82,8 @@ I/O port base address can be found in the output of 'lspci -v'. #include #include + +#include "comedi_fc.h" #include "8255.h" #define _8255_SIZE 4 @@ -229,39 +231,20 @@ static int subdev_8255_cmdtest(struct comedi_device *dev, struct comedi_cmd *cmd) { int err = 0; - unsigned int tmp; - - /* step 1 */ - - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_EXT; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_FOLLOW; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE); if (err) return 1; - /* step 2 */ + /* Step 2a : make sure trigger sources are unique */ + /* Step 2b : and mutually compatible */ if (err) return 2; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index d61fce0..f406dfb 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -479,57 +479,26 @@ int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_s struct comedi_cmd *cmd) { int err = 0; - int tmp; /* divisor1,divisor2; */ - /* step 1: make sure trigger sources are trivially valid */ + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW | TRIG_EXT; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_TIMER | TRIG_FOLLOW; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_TIMER; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, + TRIG_TIMER | TRIG_FOLLOW); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /* step 2: make sure trigger sources are unique and mutually compatible */ + /* Step 2a : make sure trigger sources are unique */ - if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) - err++; - - if (cmd->scan_begin_src != TRIG_TIMER && - cmd->scan_begin_src != TRIG_FOLLOW) - err++; - - if (cmd->convert_src != TRIG_TIMER) - err++; + err |= cfc_check_trigger_is_unique(cmd->start_src); + err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); - if (cmd->scan_end_src != TRIG_COUNT) { - cmd->scan_end_src = TRIG_COUNT; - err++; - } - - if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT) - err++; + /* Step 2b : and mutually compatible */ if (err) return 2; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c index f6f5092..38ab499 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c @@ -2560,7 +2560,6 @@ int i_APCI3200_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_s { int err = 0; - int tmp; /* divisor1,divisor2; */ unsigned int ui_ConvertTime = 0; unsigned int ui_ConvertTimeBase = 0; unsigned int ui_DelayTime = 0; @@ -2571,41 +2570,32 @@ int i_APCI3200_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_s int i_Cpt = 0; double d_ConversionTimeForAllChannels = 0.0; double d_SCANTimeNewUnit = 0.0; - /* step 1: make sure trigger sources are trivially valid */ - - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW | TRIG_EXT; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_TIMER | TRIG_FOLLOW; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_TIMER; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; - /* if(i_InterruptFlag==0) */ - if (s_BoardInfos[dev->minor].i_InterruptFlag == 0) { - err++; - /* printk("\nThe interrupt should be enabled\n"); */ - } + + /* Step 1 : check if triggers are trivially valid */ + + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, + TRIG_TIMER | TRIG_FOLLOW); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); + + if (s_BoardInfos[dev->minor].i_InterruptFlag == 0) + err |= -EINVAL; + if (err) { i_APCI3200_Reset(dev); return 1; } - if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) { - err++; - } + /* Step 2a : make sure trigger sources are unique */ + + err |= cfc_check_trigger_is_unique(&cmd->start_src); + err |= cfc_check_trigger_is_unique(&cmd->scan_begin_src); + err |= cfc_check_trigger_is_unique(&cmd->stop_src); + + /* Step 2b : and mutually compatible */ + if (cmd->start_src == TRIG_EXT) { i_TriggerEdge = cmd->start_arg & 0xFFFF; i_Triggermode = cmd->start_arg >> 16; @@ -2619,21 +2609,6 @@ int i_APCI3200_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_s } } - if (cmd->scan_begin_src != TRIG_TIMER && - cmd->scan_begin_src != TRIG_FOLLOW) - err++; - - if (cmd->convert_src != TRIG_TIMER) - err++; - - if (cmd->scan_end_src != TRIG_COUNT) { - cmd->scan_end_src = TRIG_COUNT; - err++; - } - - if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT) - err++; - if (err) { i_APCI3200_Reset(dev); return 2; diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 91efaa4..a87192a 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -332,7 +332,7 @@ static int pci9111_ai_do_cmd_test(struct comedi_device *dev, int range, reference; int i; - /* Step 1 : check if trigger are trivialy valid */ + /* Step 1 : check if triggers are trivially valid */ error |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); error |= cfc_check_trigger_src(&cmd->scan_begin_src, diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index f7b254d..06ff65c 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -1102,7 +1102,7 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev, int tmp; unsigned int divisor1 = 0, divisor2 = 0; - /* step 1: make sure trigger sources are trivially valid */ + /* Step 1 : check if triggers are trivially valid */ err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT | TRIG_INT); @@ -1124,70 +1124,31 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev, if (err) return 1; - /* - * step 2: - * make sure trigger sources are - * unique and mutually compatible - */ + /* Step 2a : make sure trigger sources are unique */ - if (cmd->start_src != TRIG_NOW && - cmd->start_src != TRIG_INT && cmd->start_src != TRIG_EXT) { - cmd->start_src = TRIG_NOW; - err++; - } - - if (cmd->scan_begin_src != TRIG_TIMER && - cmd->scan_begin_src != TRIG_EXT && - cmd->scan_begin_src != TRIG_INT && - cmd->scan_begin_src != TRIG_FOLLOW) { - cmd->scan_begin_src = TRIG_FOLLOW; - err++; - } - - if (cmd->convert_src != TRIG_TIMER && - cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW) { - cmd->convert_src = TRIG_TIMER; - err++; - } - - if (cmd->scan_end_src != TRIG_COUNT) { - cmd->scan_end_src = TRIG_COUNT; - err++; - } + err |= cfc_check_trigger_is_unique(cmd->start_src); + err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); + err |= cfc_check_trigger_is_unique(cmd->convert_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); - if (cmd->stop_src != TRIG_NONE && - cmd->stop_src != TRIG_COUNT && - cmd->stop_src != TRIG_INT && cmd->stop_src != TRIG_EXT) { - cmd->stop_src = TRIG_COUNT; - err++; - } + /* Step 2b : and mutually compatible */ - if (cmd->start_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT) { - cmd->start_src = TRIG_NOW; - err++; - } + if (cmd->start_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT) + err |= -EINVAL; - if (cmd->start_src == TRIG_INT && cmd->scan_begin_src == TRIG_INT) { - cmd->start_src = TRIG_NOW; - err++; - } + if (cmd->start_src == TRIG_INT && cmd->scan_begin_src == TRIG_INT) + err |= -EINVAL; if ((cmd->scan_begin_src & (TRIG_TIMER | TRIG_EXT)) && - (!(cmd->convert_src & (TRIG_TIMER | TRIG_NOW)))) { - cmd->convert_src = TRIG_TIMER; - err++; - } + (!(cmd->convert_src & (TRIG_TIMER | TRIG_NOW)))) + err |= -EINVAL; if ((cmd->scan_begin_src == TRIG_FOLLOW) && - (!(cmd->convert_src & (TRIG_TIMER | TRIG_EXT)))) { - cmd->convert_src = TRIG_TIMER; - err++; - } + (!(cmd->convert_src & (TRIG_TIMER | TRIG_EXT)))) + err |= -EINVAL; - if (cmd->stop_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT) { - cmd->stop_src = TRIG_COUNT; - err++; - } + if (cmd->stop_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT) + err |= -EINVAL; if (err) return 2; diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 0fd021062..def37bc 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -1046,7 +1046,7 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, int tmp; unsigned int divisor1 = 0, divisor2 = 0; - /* step 1: make sure trigger sources are trivially valid */ + /* Step 1 : check if triggers are trivially valid */ err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT); err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_FOLLOW); diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index b7cfc13..08f3052 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -210,6 +210,7 @@ order they appear in the channel list. #include "../comedidev.h" +#include "comedi_fc.h" #include "8255.h" #include "8253.h" @@ -771,52 +772,24 @@ dio200_subdev_intr_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { int err = 0; - unsigned int tmp; - /* step 1: make sure trigger sources are trivially valid */ + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->start_src; - cmd->start_src &= (TRIG_NOW | TRIG_INT); - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_EXT; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_NOW; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= (TRIG_COUNT | TRIG_NONE); - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /* step 2: make sure trigger sources are unique and mutually - compatible */ + /* Step 2a : make sure trigger sources are unique */ - /* these tests are true if more than one _src bit is set */ - if ((cmd->start_src & (cmd->start_src - 1)) != 0) - err++; - if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0) - err++; - if ((cmd->convert_src & (cmd->convert_src - 1)) != 0) - err++; - if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0) - err++; - if ((cmd->stop_src & (cmd->stop_src - 1)) != 0) - err++; + err |= cfc_check_trigger_is_unique(cmd->start_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ if (err) return 2; diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index a957cd8..eacb5e4 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -56,6 +56,7 @@ unused. #include "../comedidev.h" +#include "comedi_fc.h" #include "8255.h" #include "plx9052.h" @@ -313,39 +314,20 @@ static int pc236_intr_cmdtest(struct comedi_device *dev, struct comedi_cmd *cmd) { int err = 0; - int tmp; - /* step 1 */ + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_EXT; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_FOLLOW; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE); if (err) return 1; - /* step 2: ignored */ + /* Step 2a : make sure trigger sources are unique */ + /* Step 2b : and mutually compatible */ if (err) return 2; diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 365f911..1f65ec4 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -720,53 +720,31 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, int err = 0; unsigned int tmp; - /* Step 1: make sure trigger sources are trivially valid. */ + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->start_src; - cmd->start_src &= TRIG_INT | TRIG_EXT; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_EXT | TRIG_TIMER; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_NOW; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_EXT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_INT | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, + TRIG_EXT | TRIG_TIMER); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, + TRIG_COUNT | TRIG_EXT | TRIG_NONE); if (err) return 1; - /* Step 2: make sure trigger sources are unique and mutually - * compatible. */ + /* Step 2a : make sure trigger sources are unique */ - /* these tests are true if more than one _src bit is set */ - if ((cmd->start_src & (cmd->start_src - 1)) != 0) - err++; - if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0) - err++; - if ((cmd->convert_src & (cmd->convert_src - 1)) != 0) - err++; - if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0) - err++; - if ((cmd->stop_src & (cmd->stop_src - 1)) != 0) - err++; + err |= cfc_check_trigger_is_unique(cmd->start_src); + err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); - /* There's only one external trigger signal (which makes these - * tests easier). Only one thing can use it. */ + /* Step 2b : and mutually compatible */ + + /* + * There's only one external trigger signal (which makes these + * tests easier). Only one thing can use it. + */ tmp = 0; if (cmd->start_src & TRIG_EXT) tmp++; @@ -775,7 +753,7 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, if (cmd->stop_src & TRIG_EXT) tmp++; if (tmp > 1) - err++; + err |= -EINVAL; if (err) return 2; diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index 4c9f131..bd8fb87 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -193,6 +193,7 @@ for (or detection of) various hardware problems added by Ian Abbott. #include #include +#include "comedi_fc.h" #include "8253.h" #include "8255.h" @@ -958,23 +959,11 @@ static int pci230_ao_cmdtest(struct comedi_device *dev, int err = 0; unsigned int tmp; - /* cmdtest tests a particular command to see if it is valid. - * Using the cmdtest ioctl, a user can create a valid cmd - * and then have it executes by the cmd ioctl. - * - * cmdtest returns 1,2,3,4 or 0, depending on which tests - * the command passes. */ + /* Step 1 : check if triggers are trivially valid */ - /* Step 1: make sure trigger sources are trivially valid. - * "invalid source" returned by comedilib to user mode process - * if this fails. */ - - tmp = cmd->start_src; - cmd->start_src &= TRIG_INT; - if (!cmd->start_src || tmp != cmd->start_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_INT); - tmp = cmd->scan_begin_src; + tmp = TRIG_TIMER | TRIG_INT; if ((thisboard->min_hwver > 0) && (devpriv->hwver >= 2)) { /* * For PCI230+ hardware version 2 onwards, allow external @@ -990,46 +979,23 @@ static int pci230_ao_cmdtest(struct comedi_device *dev, * scan_begin_src==TRIG_EXT support to be a bonus rather than a * guarantee! */ - cmd->scan_begin_src &= TRIG_TIMER | TRIG_INT | TRIG_EXT; - } else { - cmd->scan_begin_src &= TRIG_TIMER | TRIG_INT; + tmp |= TRIG_EXT; } - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; + err |= cfc_check_trigger_src(&cmd->scan_begin_src, tmp); - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_NOW; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /* Step 2: make sure trigger sources are unique and mutually compatible - * "source conflict" returned by comedilib to user mode process - * if this fails. */ + /* Step 2a : make sure trigger sources are unique */ - /* these tests are true if more than one _src bit is set */ - if ((cmd->start_src & (cmd->start_src - 1)) != 0) - err++; - if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0) - err++; - if ((cmd->convert_src & (cmd->convert_src - 1)) != 0) - err++; - if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0) - err++; - if ((cmd->stop_src & (cmd->stop_src - 1)) != 0) - err++; + err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ if (err) return 2; @@ -1610,75 +1576,45 @@ static int pci230_ai_cmdtest(struct comedi_device *dev, int err = 0; unsigned int tmp; - /* cmdtest tests a particular command to see if it is valid. - * Using the cmdtest ioctl, a user can create a valid cmd - * and then have it executes by the cmd ioctl. - * - * cmdtest returns 1,2,3,4,5 or 0, depending on which tests - * the command passes. */ + /* Step 1 : check if triggers are trivially valid */ - /* Step 1: make sure trigger sources are trivially valid. - * "invalid source" returned by comedilib to user mode process - * if this fails. */ - - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW | TRIG_INT; - if (!cmd->start_src || tmp != cmd->start_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT); - tmp = cmd->scan_begin_src; - /* Unfortunately, we cannot trigger a scan off an external source - * on the PCI260 board, since it uses the PPIC0 (DIO) input, which - * isn't present on the PCI260. For PCI260+ we can use the - * EXTTRIG/EXTCONVCLK input on pin 17 instead. */ + tmp = TRIG_FOLLOW | TRIG_TIMER | TRIG_INT; if ((thisboard->have_dio) || (thisboard->min_hwver > 0)) { - cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_INT - | TRIG_EXT; - } else { - cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_INT; + /* + * Unfortunately, we cannot trigger a scan off an external + * source on the PCI260 board, since it uses the PPIC0 (DIO) + * input, which isn't present on the PCI260. For PCI260+ + * we can use the EXTTRIG/EXTCONVCLK input on pin 17 instead. + */ + tmp |= TRIG_EXT; } - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_TIMER | TRIG_INT | TRIG_EXT; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->scan_begin_src, tmp); + err |= cfc_check_trigger_src(&cmd->convert_src, + TRIG_TIMER | TRIG_INT | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /* Step 2: make sure trigger sources are unique and mutually compatible - * "source conflict" returned by comedilib to user mode process - * if this fails. */ + /* Step 2a : make sure trigger sources are unique */ - /* these tests are true if more than one _src bit is set */ - if ((cmd->start_src & (cmd->start_src - 1)) != 0) - err++; - if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0) - err++; - if ((cmd->convert_src & (cmd->convert_src - 1)) != 0) - err++; - if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0) - err++; - if ((cmd->stop_src & (cmd->stop_src - 1)) != 0) - err++; + err |= cfc_check_trigger_is_unique(cmd->start_src); + err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); + err |= cfc_check_trigger_is_unique(cmd->convert_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ - /* If scan_begin_src is not TRIG_FOLLOW, then a monostable will be - * set up to generate a fixed number of timed conversion pulses. */ + /* + * If scan_begin_src is not TRIG_FOLLOW, then a monostable will be + * set up to generate a fixed number of timed conversion pulses. + */ if ((cmd->scan_begin_src != TRIG_FOLLOW) && (cmd->convert_src != TRIG_TIMER)) - err++; + err |= -EINVAL; if (err) return 2; diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index a3d53ba..6d81d8b 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -46,6 +46,7 @@ Status: experimental #include #include +#include "comedi_fc.h" #include "8253.h" #define DAS16CS_SIZE 18 @@ -169,47 +170,26 @@ static int das16cs_ai_cmdtest(struct comedi_device *dev, int err = 0; int tmp; - /* step 1: make sure trigger sources are trivially valid */ + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_TIMER | TRIG_EXT; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, + TRIG_TIMER | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->convert_src, + TRIG_TIMER | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /* step 2: make sure trigger sources are unique and - * mutually compatible */ + /* Step 2a : make sure trigger sources are unique */ - /* note that mutual compatibility is not an issue here */ - if (cmd->scan_begin_src != TRIG_TIMER && - cmd->scan_begin_src != TRIG_EXT) - err++; - if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT) - err++; - if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) - err++; + err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); + err |= cfc_check_trigger_is_unique(cmd->convert_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ if (err) return 2; diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index 4dd87c2..de21a26 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -803,58 +803,35 @@ static int cb_pcidas_ai_cmdtest(struct comedi_device *dev, int tmp; int i, gain, start_chan; - /* step 1: trigger sources are trivially valid */ + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW | TRIG_EXT; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_TIMER | TRIG_NOW | TRIG_EXT; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, + TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->convert_src, + TRIG_TIMER | TRIG_NOW | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /* step 2: trigger sources are unique and mutually compatible */ + /* Step 2a : make sure trigger sources are unique */ - if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) - err++; - if (cmd->scan_begin_src != TRIG_FOLLOW && - cmd->scan_begin_src != TRIG_TIMER && - cmd->scan_begin_src != TRIG_EXT) - err++; - if (cmd->convert_src != TRIG_TIMER && - cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW) - err++; - if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) - err++; + err |= cfc_check_trigger_is_unique(cmd->start_src); + err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); + err |= cfc_check_trigger_is_unique(cmd->convert_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ - /* make sure trigger sources are compatible with each other */ if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW) - err++; + err |= -EINVAL; if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW) - err++; + err |= -EINVAL; if (cmd->start_src == TRIG_EXT && (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT)) - err++; + err |= -EINVAL; if (err) return 2; @@ -1079,43 +1056,24 @@ static int cb_pcidas_ao_cmdtest(struct comedi_device *dev, int err = 0; int tmp; - /* step 1: trigger sources are trivially valid */ - - tmp = cmd->start_src; - cmd->start_src &= TRIG_INT; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_NOW; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_INT); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, + TRIG_TIMER | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /* step 2: trigger sources are unique and mutually compatible */ + /* Step 2a : make sure trigger sources are unique */ - if (cmd->scan_begin_src != TRIG_TIMER && - cmd->scan_begin_src != TRIG_EXT) - err++; - if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) - err++; + err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ if (err) return 2; diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 7168883..0472a90 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -2108,74 +2108,50 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { int err = 0; - int tmp; unsigned int tmp_arg, tmp_arg2; int i; int aref; unsigned int triggers; - /* step 1: make sure trigger sources are trivially valid */ + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW | TRIG_EXT; - if (!cmd->start_src || tmp != cmd->start_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT); - tmp = cmd->scan_begin_src; triggers = TRIG_TIMER; if (board(dev)->layout == LAYOUT_4020) triggers |= TRIG_OTHER; else triggers |= TRIG_FOLLOW; - cmd->scan_begin_src &= triggers; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; + err |= cfc_check_trigger_src(&cmd->scan_begin_src, triggers); - tmp = cmd->convert_src; triggers = TRIG_TIMER; if (board(dev)->layout == LAYOUT_4020) triggers |= TRIG_NOW; else triggers |= TRIG_EXT; - cmd->convert_src &= triggers; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; + err |= cfc_check_trigger_src(&cmd->convert_src, triggers); - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_EXT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, + TRIG_COUNT | TRIG_EXT | TRIG_NONE); if (err) return 1; - /* step 2: make sure trigger sources are unique and mutually compatible */ + /* Step 2a : make sure trigger sources are unique */ - /* uniqueness check */ - if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) - err++; - if (cmd->scan_begin_src != TRIG_TIMER && - cmd->scan_begin_src != TRIG_OTHER && - cmd->scan_begin_src != TRIG_FOLLOW) - err++; - if (cmd->convert_src != TRIG_TIMER && - cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW) - err++; - if (cmd->stop_src != TRIG_COUNT && - cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_EXT) - err++; + err |= cfc_check_trigger_is_unique(cmd->start_src); + err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); + err |= cfc_check_trigger_is_unique(cmd->convert_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ - /* compatibility check */ if (cmd->convert_src == TRIG_EXT && cmd->scan_begin_src == TRIG_TIMER) - err++; + err |= -EINVAL; if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_EXT) - err++; + err |= -EINVAL; if (err) return 2; @@ -3466,55 +3442,33 @@ static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { int err = 0; - int tmp; unsigned int tmp_arg; int i; - /* step 1: make sure trigger sources are trivially valid */ + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->start_src; - cmd->start_src &= TRIG_INT | TRIG_EXT; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_NOW; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_INT | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, + TRIG_TIMER | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE); if (err) return 1; - /* step 2: make sure trigger sources are unique and mutually compatible */ + /* Step 2a : make sure trigger sources are unique */ - /* uniqueness check */ - if (cmd->start_src != TRIG_INT && cmd->start_src != TRIG_EXT) - err++; - if (cmd->scan_begin_src != TRIG_TIMER && - cmd->scan_begin_src != TRIG_EXT) - err++; + err |= cfc_check_trigger_is_unique(cmd->start_src); + err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); + + /* Step 2b : and mutually compatible */ - /* compatibility check */ if (cmd->convert_src == TRIG_EXT && cmd->scan_begin_src == TRIG_TIMER) - err++; + err |= -EINVAL; if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_EXT) - err++; + err |= -EINVAL; if (err) return 2; diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index ad9f3a3..aef946d 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -48,6 +48,7 @@ Please report success/failure with other different cards to #include "../comedidev.h" +#include "comedi_fc.h" #include "8255.h" /* PCI vendor number of ComputerBoards */ @@ -247,56 +248,26 @@ static int cb_pcidda_ai_cmdtest(struct comedi_device *dev, int err = 0; int tmp; - /* cmdtest tests a particular command to see if it is valid. - * Using the cmdtest ioctl, a user can create a valid cmd - * and then have it executes by the cmd ioctl. - * - * cmdtest returns 1,2,3,4 or 0, depending on which tests - * the command passes. */ + /* Step 1 : check if triggers are trivially valid */ - /* step 1: make sure trigger sources are trivially valid */ - - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_TIMER | TRIG_EXT; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, + TRIG_TIMER | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->convert_src, + TRIG_TIMER | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /* - * step 2: make sure trigger sources are unique and mutually - * compatible - */ + /* Step 2a : make sure trigger sources are unique */ - /* note that mutual compatibility is not an issue here */ - if (cmd->scan_begin_src != TRIG_TIMER - && cmd->scan_begin_src != TRIG_EXT) - err++; - if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT) - err++; - if (cmd->stop_src != TRIG_TIMER && cmd->stop_src != TRIG_EXT) - err++; + err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); + err |= cfc_check_trigger_is_unique(cmd->convert_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ if (err) return 2; diff --git a/drivers/staging/comedi/drivers/comedi_parport.c b/drivers/staging/comedi/drivers/comedi_parport.c index c9e40a9..22ef942 100644 --- a/drivers/staging/comedi/drivers/comedi_parport.c +++ b/drivers/staging/comedi/drivers/comedi_parport.c @@ -85,6 +85,8 @@ pin, which can be used to wake up tasks. #include #include +#include "comedi_fc.h" + #define PARPORT_SIZE 3 #define PARPORT_A 0 @@ -176,39 +178,20 @@ static int parport_intr_cmdtest(struct comedi_device *dev, struct comedi_cmd *cmd) { int err = 0; - int tmp; - - /* step 1 */ - - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_EXT; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_FOLLOW; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE); if (err) return 1; - /* step 2: ignored */ + /* Step 2a : make sure trigger sources are unique */ + /* Step 2b : and mutually compatible */ if (err) return 2; diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c index b0f0ec5..7817def 100644 --- a/drivers/staging/comedi/drivers/comedi_test.c +++ b/drivers/staging/comedi/drivers/comedi_test.c @@ -231,44 +231,23 @@ static int waveform_ai_cmdtest(struct comedi_device *dev, int err = 0; int tmp; - /* step 1: make sure trigger sources are trivially valid */ + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_TIMER; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_NOW | TRIG_TIMER; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW | TRIG_TIMER); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /* - * step 2: make sure trigger sources are unique and mutually compatible - */ + /* Step 2a : make sure trigger sources are unique */ - if (cmd->convert_src != TRIG_NOW && cmd->convert_src != TRIG_TIMER) - err++; - if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) - err++; + err |= cfc_check_trigger_is_unique(cmd->convert_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ if (err) return 2; diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c index 744376a..fcb8a32 100644 --- a/drivers/staging/comedi/drivers/das16.c +++ b/drivers/staging/comedi/drivers/das16.c @@ -402,62 +402,42 @@ static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, int gain, start_chan, i; int mask; - /* make sure triggers are valid */ - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW; - if (!cmd->start_src || tmp != cmd->start_src) - err++; + /* Step 1 : check if triggers are trivially valid */ + + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); - tmp = cmd->scan_begin_src; mask = TRIG_FOLLOW; /* if board supports burst mode */ if (board->size > 0x400) mask |= TRIG_TIMER | TRIG_EXT; - cmd->scan_begin_src &= mask; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; + err |= cfc_check_trigger_src(&cmd->scan_begin_src, mask); tmp = cmd->convert_src; mask = TRIG_TIMER | TRIG_EXT; /* if board supports burst mode */ if (board->size > 0x400) mask |= TRIG_NOW; - cmd->convert_src &= mask; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; + err |= cfc_check_trigger_src(&cmd->convert_src, mask); - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /** - * step 2: make sure trigger sources are unique and - * mutually compatible - */ - if (cmd->scan_begin_src != TRIG_TIMER && - cmd->scan_begin_src != TRIG_EXT && - cmd->scan_begin_src != TRIG_FOLLOW) - err++; - if (cmd->convert_src != TRIG_TIMER && - cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW) - err++; - if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT) - err++; + /* Step 2a : make sure trigger sources are unique */ + + err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); + err |= cfc_check_trigger_is_unique(cmd->convert_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ /* make sure scan_begin_src and convert_src dont conflict */ if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW) - err++; + err |= -EINVAL; if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW) - err++; + err |= -EINVAL; if (err) return 2; diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c index 7f0668f..3f87d75 100644 --- a/drivers/staging/comedi/drivers/das16m1.c +++ b/drivers/staging/comedi/drivers/das16m1.c @@ -170,42 +170,24 @@ static int das16m1_cmd_test(struct comedi_device *dev, const struct das16m1_board *board = comedi_board(dev); unsigned int err = 0, tmp, i; - /* make sure triggers are valid */ - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW | TRIG_EXT; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_FOLLOW; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_TIMER | TRIG_EXT; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_FOLLOW); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /* step 2: make sure trigger sources are unique and mutually compatible */ - if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) - err++; - if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) - err++; - if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT) - err++; + /* Step 2a : make sure trigger sources are unique */ + + err |= cfc_check_trigger_is_unique(cmd->start_src); + err |= cfc_check_trigger_is_unique(cmd->convert_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ if (err) return 2; diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index 711d4e2..2555f32 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -784,59 +784,35 @@ static int das1800_ai_do_cmdtest(struct comedi_device *dev, struct comedi_cmd *cmd) { int err = 0; - int tmp; unsigned int tmp_arg; int i; int unipolar; - /* step 1: make sure trigger sources are trivially valid */ + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW | TRIG_EXT; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_TIMER | TRIG_EXT; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_EXT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, + TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, + TRIG_COUNT | TRIG_EXT | TRIG_NONE); if (err) return 1; - /* step 2: make sure trigger sources are unique and mutually compatible */ + /* Step 2a : make sure trigger sources are unique */ + + err |= cfc_check_trigger_is_unique(cmd->start_src); + err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); + err |= cfc_check_trigger_is_unique(cmd->convert_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ - /* uniqueness check */ - if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) - err++; - if (cmd->scan_begin_src != TRIG_FOLLOW && - cmd->scan_begin_src != TRIG_TIMER && - cmd->scan_begin_src != TRIG_EXT) - err++; - if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT) - err++; - if (cmd->stop_src != TRIG_COUNT && - cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_EXT) - err++; - /* compatibility check */ if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_TIMER) - err++; + err |= -EINVAL; if (err) return 2; diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c index 8e89101..215deac 100644 --- a/drivers/staging/comedi/drivers/das800.c +++ b/drivers/staging/comedi/drivers/das800.c @@ -609,44 +609,24 @@ static int das800_ai_do_cmdtest(struct comedi_device *dev, int gain, startChan; int i; - /* step 1: make sure trigger sources are trivially valid */ + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW | TRIG_EXT; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_FOLLOW; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_TIMER | TRIG_EXT; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_FOLLOW); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /* step 2: make sure trigger sources are unique and mutually compatible */ + /* Step 2a : make sure trigger sources are unique */ - if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) - err++; - if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT) - err++; - if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) - err++; + err |= cfc_check_trigger_is_unique(cmd->start_src); + err |= cfc_check_trigger_is_unique(cmd->convert_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ if (err) return 2; diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c index 0703ca5..4d5c33c 100644 --- a/drivers/staging/comedi/drivers/dmm32at.c +++ b/drivers/staging/comedi/drivers/dmm32at.c @@ -41,6 +41,8 @@ Configuration Options: #include "../comedidev.h" #include +#include "comedi_fc.h" + /* Board register addresses */ #define DMM32AT_MEMSIZE 0x10 @@ -258,47 +260,26 @@ static int dmm32at_ai_cmdtest(struct comedi_device *dev, int tmp; int start_chan, gain, i; - /* step 1: make sure trigger sources are trivially valid */ - - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_TIMER /*| TRIG_EXT */ ; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_TIMER /*| TRIG_EXT */ ; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, + TRIG_TIMER /*| TRIG_EXT */); + err |= cfc_check_trigger_src(&cmd->convert_src, + TRIG_TIMER /*| TRIG_EXT */); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /* step 2: make sure trigger sources are unique and mutually - * compatible */ + /* Step 2a : make sure trigger sources are unique */ - /* note that mutual compatibility is not an issue here */ - if (cmd->scan_begin_src != TRIG_TIMER && - cmd->scan_begin_src != TRIG_EXT) - err++; - if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT) - err++; - if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) - err++; + err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); + err |= cfc_check_trigger_is_unique(cmd->convert_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ if (err) return 2; diff --git a/drivers/staging/comedi/drivers/dt2814.c b/drivers/staging/comedi/drivers/dt2814.c index ce5d837..064a8f2 100644 --- a/drivers/staging/comedi/drivers/dt2814.c +++ b/drivers/staging/comedi/drivers/dt2814.c @@ -45,6 +45,8 @@ addition, the clock does not seem to be very accurate. #include #include +#include "comedi_fc.h" + #define DT2814_SIZE 2 #define DT2814_CSR 0 @@ -129,42 +131,22 @@ static int dt2814_ai_cmdtest(struct comedi_device *dev, int err = 0; int tmp; - /* step 1: make sure trigger sources are trivially valid */ - - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_TIMER; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_NOW; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /* step 2: make sure trigger sources are - * unique and mutually compatible */ + /* Step 2a : make sure trigger sources are unique */ - /* note that mutual compatibility is not an issue here */ - if (cmd->stop_src != TRIG_TIMER && cmd->stop_src != TRIG_EXT) - err++; + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ if (err) return 2; diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c index b7c43c8..78d3407 100644 --- a/drivers/staging/comedi/drivers/dt282x.c +++ b/drivers/staging/comedi/drivers/dt282x.c @@ -582,47 +582,24 @@ static int dt282x_ai_cmdtest(struct comedi_device *dev, int err = 0; int tmp; - /* step 1: make sure trigger sources are trivially valid */ + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_EXT; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_TIMER; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, + TRIG_FOLLOW | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /* - * step 2: make sure trigger sources are unique - * and mutually compatible - */ + /* Step 2a : make sure trigger sources are unique */ - /* note that mutual compatibility is not an issue here */ - if (cmd->scan_begin_src != TRIG_FOLLOW && - cmd->scan_begin_src != TRIG_EXT) - err++; - if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) - err++; + err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ if (err) return 2; @@ -862,44 +839,22 @@ static int dt282x_ao_cmdtest(struct comedi_device *dev, int err = 0; int tmp; - /* step 1: make sure trigger sources are trivially valid */ + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->start_src; - cmd->start_src &= TRIG_INT; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_TIMER; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_NOW; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_INT); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /* - * step 2: make sure trigger sources are unique - * and mutually compatible - */ + /* Step 2a : make sure trigger sources are unique */ - /* note that mutual compatibility is not an issue here */ - if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) - err++; + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ if (err) return 2; diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index 3a940a2..43d05ef 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -63,6 +63,8 @@ AO commands are not supported. #include "../comedidev.h" #include +#include "comedi_fc.h" + #define PCI_VENDOR_ID_DT 0x1116 static const struct comedi_lrange range_dt3000_ai = { 4, { @@ -408,37 +410,19 @@ static int dt3k_ai_cmdtest(struct comedi_device *dev, int err = 0; int tmp; - /* step 1: make sure trigger sources are trivially valid */ - - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_TIMER; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_TIMER; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT); if (err) return 1; - /* step 2: make sure trigger sources are unique and mutually compatible */ + /* Step 2a : make sure trigger sources are unique */ + /* Step 2b : and mutually compatible */ if (err) return 2; diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index 5d3fa71..abff660 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -723,45 +723,24 @@ static int di_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { int err = 0; - int tmp; int i; - /* step 1: make sure trigger sources are trivially valid */ + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_EXT; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_NOW; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /* step 2: make sure trigger sources are unique and mutually - * compatible */ + /* Step 2a : make sure trigger sources are unique */ - /* uniqueness check */ - if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) - err++; + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ if (err) return 2; diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index d7c5146..22db35d 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -52,6 +52,7 @@ broken. #include #include +#include "comedi_fc.h" #include "8253.h" #if 0 @@ -895,18 +896,6 @@ static int me4000_ai_do_cmd(struct comedi_device *dev, return 0; } -/* - * me4000_ai_do_cmd_test(): - * - * The demo cmd.c in ./comedilib/demo specifies 6 return values: - * - success - * - invalid source - * - source conflict - * - invalid argument - * - argument conflict - * - invalid chanlist - * So I tried to adopt this scheme. - */ static int me4000_ai_do_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) @@ -923,81 +912,29 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev, /* Round the timer arguments */ ai_round_cmd_args(dev, s, cmd, &init_ticks, &scan_ticks, &chan_ticks); - /* - * Stage 1. Check if the trigger sources are generally valid. - */ - switch (cmd->start_src) { - case TRIG_NOW: - case TRIG_EXT: - break; - case TRIG_ANY: - cmd->start_src &= TRIG_NOW | TRIG_EXT; - err++; - break; - default: - dev_err(dev->class_dev, "Invalid start source\n"); - cmd->start_src = TRIG_NOW; - err++; - } - switch (cmd->scan_begin_src) { - case TRIG_FOLLOW: - case TRIG_TIMER: - case TRIG_EXT: - break; - case TRIG_ANY: - cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT; - err++; - break; - default: - dev_err(dev->class_dev, "Invalid scan begin source\n"); - cmd->scan_begin_src = TRIG_FOLLOW; - err++; - } - switch (cmd->convert_src) { - case TRIG_TIMER: - case TRIG_EXT: - break; - case TRIG_ANY: - cmd->convert_src &= TRIG_TIMER | TRIG_EXT; - err++; - break; - default: - dev_err(dev->class_dev, "Invalid convert source\n"); - cmd->convert_src = TRIG_TIMER; - err++; - } - switch (cmd->scan_end_src) { - case TRIG_NONE: - case TRIG_COUNT: - break; - case TRIG_ANY: - cmd->scan_end_src &= TRIG_NONE | TRIG_COUNT; - err++; - break; - default: - dev_err(dev->class_dev, "Invalid scan end source\n"); - cmd->scan_end_src = TRIG_NONE; - err++; - } - switch (cmd->stop_src) { - case TRIG_NONE: - case TRIG_COUNT: - break; - case TRIG_ANY: - cmd->stop_src &= TRIG_NONE | TRIG_COUNT; - err++; - break; - default: - dev_err(dev->class_dev, "Invalid stop source\n"); - cmd->stop_src = TRIG_NONE; - err++; - } + /* Step 1 : check if triggers are trivially valid */ + + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, + TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->scan_end_src, + TRIG_NONE | TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE | TRIG_COUNT); + if (err) return 1; - /* - * Stage 2. Check for trigger source conflicts. - */ + /* Step 2a : make sure trigger sources are unique */ + + err |= cfc_check_trigger_is_unique(cmd->start_src); + err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); + err |= cfc_check_trigger_is_unique(cmd->convert_src); + err |= cfc_check_trigger_is_unique(cmd->scan_end_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ + if (cmd->start_src == TRIG_NOW && cmd->scan_begin_src == TRIG_TIMER && cmd->convert_src == TRIG_TIMER) { @@ -1017,11 +954,7 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev, cmd->scan_begin_src == TRIG_EXT && cmd->convert_src == TRIG_EXT) { } else { - dev_err(dev->class_dev, "Invalid start trigger combination\n"); - cmd->start_src = TRIG_NOW; - cmd->scan_begin_src = TRIG_FOLLOW; - cmd->convert_src = TRIG_TIMER; - err++; + err |= -EINVAL; } if (cmd->stop_src == TRIG_NONE && cmd->scan_end_src == TRIG_NONE) { @@ -1032,11 +965,9 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev, } else if (cmd->stop_src == TRIG_COUNT && cmd->scan_end_src == TRIG_COUNT) { } else { - dev_err(dev->class_dev, "Invalid stop trigger combination\n"); - cmd->stop_src = TRIG_NONE; - cmd->scan_end_src = TRIG_NONE; - err++; + err |= -EINVAL; } + if (err) return 2; diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index 8125d50..51295f3 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -44,6 +44,7 @@ Updated: Sat, 25 Jan 2003 13:24:40 -0800 #include #include "../comedidev.h" +#include "comedi_fc.h" #include "mite.h" #define DRIVER_NAME "ni_6527" @@ -224,40 +225,20 @@ static int ni6527_intr_cmdtest(struct comedi_device *dev, struct comedi_cmd *cmd) { int err = 0; - int tmp; - /* step 1: make sure trigger sources are trivially valid */ + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_OTHER; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_FOLLOW; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_OTHER); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT); if (err) return 1; - /* step 2: make sure trigger sources are unique and */ - /* are mutually compatible */ + /* Step 2a : make sure trigger sources are unique */ + /* Step 2b : and mutually compatible */ if (err) return 2; diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index aab2b06..2a73ff5 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -55,6 +55,7 @@ except maybe the 6514. #include #include "../comedidev.h" +#include "comedi_fc.h" #include "mite.h" #define NI6514_DIO_SIZE 4096 @@ -486,40 +487,20 @@ static int ni_65xx_intr_cmdtest(struct comedi_device *dev, struct comedi_cmd *cmd) { int err = 0; - int tmp; - /* step 1: make sure trigger sources are trivially valid */ + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_OTHER; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_FOLLOW; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_OTHER); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT); if (err) return 1; - /* step 2: make sure trigger sources are unique and mutually - compatible */ + /* Step 2a : make sure trigger sources are unique */ + /* Step 2b : and mutually compatible */ if (err) return 2; diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c index 5895d4d..8395080 100644 --- a/drivers/staging/comedi/drivers/ni_at_a2150.c +++ b/drivers/staging/comedi/drivers/ni_at_a2150.c @@ -321,45 +321,23 @@ static int a2150_ai_cmdtest(struct comedi_device *dev, int startChan; int i; - /* step 1: make sure trigger sources are trivially valid */ + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW | TRIG_EXT; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_TIMER; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_NOW; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /* - * step 2: make sure trigger sources are unique and mutually - * compatible - */ + /* Step 2a : make sure trigger sources are unique */ - if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) - err++; - if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) - err++; + err |= cfc_check_trigger_is_unique(cmd->start_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ if (err) return 2; diff --git a/drivers/staging/comedi/drivers/ni_atmio16d.c b/drivers/staging/comedi/drivers/ni_atmio16d.c index 4108cbf..e91a620 100644 --- a/drivers/staging/comedi/drivers/ni_atmio16d.c +++ b/drivers/staging/comedi/drivers/ni_atmio16d.c @@ -40,6 +40,7 @@ Devices: [National Instruments] AT-MIO-16 (atmio16), AT-MIO-16D (atmio16d) #include +#include "comedi_fc.h" #include "8255.h" /* Configuration and Status Registers */ @@ -246,45 +247,26 @@ static int atmio16d_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { - int err = 0, tmp; + int err = 0; - /* make sure triggers are valid */ - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_TIMER; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, + TRIG_FOLLOW | TRIG_TIMER); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /* step 2: make sure trigger sources are unique & mutually compatible */ - /* note that mutual compatibility is not an issue here */ - if (cmd->scan_begin_src != TRIG_FOLLOW && - cmd->scan_begin_src != TRIG_EXT && - cmd->scan_begin_src != TRIG_TIMER) - err++; - if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) - err++; + /* Step 2a : make sure trigger sources are unique */ + + err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ if (err) return 2; diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index d534e63..28b91a6 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -979,55 +979,33 @@ static int labpc_ai_cmdtest(struct comedi_device *dev, { int err = 0; int tmp, tmp2; - int stop_mask; + unsigned int stop_mask; enum scan_mode mode; - /* step 1: make sure trigger sources are trivially valid */ + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW | TRIG_EXT; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_TIMER | TRIG_FOLLOW | TRIG_EXT; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_TIMER | TRIG_EXT; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, + TRIG_TIMER | TRIG_FOLLOW | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); - tmp = cmd->stop_src; stop_mask = TRIG_COUNT | TRIG_NONE; if (thisboard->register_layout == labpc_1200_layout) stop_mask |= TRIG_EXT; - cmd->stop_src &= stop_mask; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->stop_src, stop_mask); if (err) return 1; - /* step 2: make sure trigger sources are unique and mutually compatible */ + /* Step 2a : make sure trigger sources are unique */ - if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) - err++; - if (cmd->scan_begin_src != TRIG_TIMER && - cmd->scan_begin_src != TRIG_FOLLOW && - cmd->scan_begin_src != TRIG_EXT) - err++; - if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT) - err++; - if (cmd->stop_src != TRIG_COUNT && - cmd->stop_src != TRIG_EXT && cmd->stop_src != TRIG_NONE) - err++; + err |= cfc_check_trigger_is_unique(cmd->start_src); + err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); + err |= cfc_check_trigger_is_unique(cmd->convert_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ /* can't have external stop and start triggers at once */ if (cmd->start_src == TRIG_EXT && cmd->stop_src == TRIG_EXT) diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index 4bbb979..3e5fdae 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -2164,61 +2164,38 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, { int err = 0; int tmp; - int sources; + unsigned int sources; - /* step 1: make sure trigger sources are trivially valid */ + /* Step 1 : check if triggers are trivially valid */ - if ((cmd->flags & CMDF_WRITE)) { + if ((cmd->flags & CMDF_WRITE)) cmd->flags &= ~CMDF_WRITE; - } - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW | TRIG_INT | TRIG_EXT; - if (!cmd->start_src || tmp != cmd->start_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, + TRIG_NOW | TRIG_INT | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, + TRIG_TIMER | TRIG_EXT); - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; sources = TRIG_TIMER | TRIG_EXT; - if ((boardtype.reg_type == ni_reg_611x) - || (boardtype.reg_type == ni_reg_6143)) + if (boardtype.reg_type == ni_reg_611x || + boardtype.reg_type == ni_reg_6143) sources |= TRIG_NOW; - cmd->convert_src &= sources; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; + err |= cfc_check_trigger_src(&cmd->convert_src, sources); - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /* step 2: make sure trigger sources are unique and mutually compatible */ + /* Step 2a : make sure trigger sources are unique */ - /* note that mutual compatibility is not an issue here */ - if (cmd->start_src != TRIG_NOW && - cmd->start_src != TRIG_INT && cmd->start_src != TRIG_EXT) - err++; - if (cmd->scan_begin_src != TRIG_TIMER && - cmd->scan_begin_src != TRIG_EXT && - cmd->scan_begin_src != TRIG_OTHER) - err++; - if (cmd->convert_src != TRIG_TIMER && - cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW) - err++; - if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) - err++; + err |= cfc_check_trigger_is_unique(cmd->start_src); + err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); + err |= cfc_check_trigger_is_unique(cmd->convert_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ if (err) return 2; @@ -3356,44 +3333,28 @@ static int ni_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, int err = 0; int tmp; - /* step 1: make sure trigger sources are trivially valid */ + /* Step 1 : check if triggers are trivially valid */ - if ((cmd->flags & CMDF_WRITE) == 0) { + if ((cmd->flags & CMDF_WRITE) == 0) cmd->flags |= CMDF_WRITE; - } - - tmp = cmd->start_src; - cmd->start_src &= TRIG_INT | TRIG_EXT; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_NOW; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_INT | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, + TRIG_TIMER | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /* step 2: make sure trigger sources are unique and mutually compatible */ + /* Step 2a : make sure trigger sources are unique */ - if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) - err++; + err |= cfc_check_trigger_is_unique(cmd->start_src); + err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ if (err) return 2; @@ -3643,51 +3604,21 @@ static int ni_cdio_cmdtest(struct comedi_device *dev, { int err = 0; int tmp; - int sources; unsigned i; - /* step 1: make sure trigger sources are trivially valid */ + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->start_src; - sources = TRIG_INT; - cmd->start_src &= sources; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_EXT; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_NOW; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_INT); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE); if (err) return 1; - /* step 2: make sure trigger sources are unique... */ - - if (cmd->start_src != TRIG_INT) - err++; - if (cmd->scan_begin_src != TRIG_EXT) - err++; - if (cmd->convert_src != TRIG_NOW) - err++; - if (cmd->stop_src != TRIG_NONE) - err++; - /* ... and mutually compatible */ + /* Step 2a : make sure trigger sources are unique */ + /* Step 2b : and mutually compatible */ if (err) return 2; diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index 6a70e266..bc9313e 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -60,6 +60,7 @@ comedi_nonfree_firmware tarball available from http://www.comedi.org #include #include "../comedidev.h" +#include "comedi_fc.h" #include "mite.h" #undef DPRINTK @@ -683,45 +684,25 @@ static int ni_pcidio_cmdtest(struct comedi_device *dev, int err = 0; int tmp; - /* step 1: make sure trigger sources are trivially valid */ + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW | TRIG_INT; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_NOW; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, + TRIG_TIMER | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /* step 2: make sure trigger sources are unique and mutually - compatible */ + /* Step 2a : make sure trigger sources are unique */ - /* note that mutual compatibility is not an issue here */ - if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_INT) - err++; - if (cmd->scan_begin_src != TRIG_TIMER && - cmd->scan_begin_src != TRIG_EXT) - err++; + err |= cfc_check_trigger_is_unique(cmd->start_src); + err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ if (err) return 2; diff --git a/drivers/staging/comedi/drivers/ni_tiocmd.c b/drivers/staging/comedi/drivers/ni_tiocmd.c index a961158..8ee93d3 100644 --- a/drivers/staging/comedi/drivers/ni_tiocmd.c +++ b/drivers/staging/comedi/drivers/ni_tiocmd.c @@ -48,6 +48,7 @@ TODO: Support use of both banks X and Y */ +#include "comedi_fc.h" #include "ni_tio_internal.h" #include "mite.h" @@ -237,61 +238,35 @@ EXPORT_SYMBOL_GPL(ni_tio_cmd); int ni_tio_cmdtest(struct ni_gpct *counter, struct comedi_cmd *cmd) { int err = 0; - int tmp; - int sources; + unsigned int sources; - /* step 1: make sure trigger sources are trivially valid */ + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->start_src; sources = TRIG_NOW | TRIG_INT | TRIG_OTHER; if (ni_tio_counting_mode_registers_present(counter->counter_dev)) sources |= TRIG_EXT; - cmd->start_src &= sources; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_EXT | TRIG_OTHER; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - sources = TRIG_NOW | TRIG_EXT | TRIG_OTHER; - cmd->convert_src &= sources; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, sources); - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->scan_begin_src, + TRIG_FOLLOW | TRIG_EXT | TRIG_OTHER); + err |= cfc_check_trigger_src(&cmd->convert_src, + TRIG_NOW | TRIG_EXT | TRIG_OTHER); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE); if (err) return 1; - /* step 2: make sure trigger sources are unique... */ + /* Step 2a : make sure trigger sources are unique */ + + err |= cfc_check_trigger_is_unique(cmd->start_src); + err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); + err |= cfc_check_trigger_is_unique(cmd->convert_src); + + /* Step 2b : and mutually compatible */ - if (cmd->start_src != TRIG_NOW && - cmd->start_src != TRIG_INT && - cmd->start_src != TRIG_EXT && cmd->start_src != TRIG_OTHER) - err++; - if (cmd->scan_begin_src != TRIG_FOLLOW && - cmd->scan_begin_src != TRIG_EXT && - cmd->scan_begin_src != TRIG_OTHER) - err++; - if (cmd->convert_src != TRIG_OTHER && - cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW) - err++; - if (cmd->stop_src != TRIG_NONE) - err++; - /* ... and mutually compatible */ if (cmd->convert_src != TRIG_NOW && cmd->scan_begin_src != TRIG_FOLLOW) - err++; + err |= -EINVAL; if (err) return 2; diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c index ef77b15..89305a1 100644 --- a/drivers/staging/comedi/drivers/pcl711.c +++ b/drivers/staging/comedi/drivers/pcl711.c @@ -64,6 +64,7 @@ supported. #include #include +#include "comedi_fc.h" #include "8253.h" #define PCL711_SIZE 16 @@ -266,42 +267,24 @@ static int pcl711_ai_cmdtest(struct comedi_device *dev, int tmp; int err = 0; - /* step 1 */ - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_NOW; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, + TRIG_TIMER | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /* step 2 */ + /* Step 2a : make sure trigger sources are unique */ - if (cmd->scan_begin_src != TRIG_TIMER && - cmd->scan_begin_src != TRIG_EXT) - err++; - if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) - err++; + err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ if (err) return 2; diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index d196343..3cf55ff 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -117,6 +117,7 @@ #include #include +#include "comedi_fc.h" #include "8253.h" /* hardware types of the cards */ @@ -533,49 +534,31 @@ static int pcl812_ai_cmdtest(struct comedi_device *dev, { const struct pcl812_board *board = comedi_board(dev); int err = 0; + unsigned int flags; int tmp, divisor1, divisor2; - /* step 1: make sure trigger sources are trivially valid */ + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_FOLLOW; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_FOLLOW); - tmp = cmd->convert_src; if (devpriv->use_ext_trg) - cmd->convert_src &= TRIG_EXT; + flags = TRIG_EXT; else - cmd->convert_src &= TRIG_TIMER; - - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; + flags = TRIG_TIMER; + err |= cfc_check_trigger_src(&cmd->convert_src, flags); - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /* - * step 2: make sure trigger sources are - * unique and mutually compatible - */ + /* Step 2a : make sure trigger sources are unique */ - if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT) - err++; + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ if (err) return 2; diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index f65fd66..0822de0 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -41,6 +41,7 @@ Configuration Options: #include #include +#include "comedi_fc.h" #include "8253.h" #define DEBUG(x) x @@ -458,48 +459,23 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev, pcl816_cmdtest_out(-1, cmd); ); - /* step 1: make sure trigger sources are trivially valid */ - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_FOLLOW; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_EXT | TRIG_TIMER; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_FOLLOW); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_EXT | TRIG_TIMER); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; + /* Step 2a : make sure trigger sources are unique */ - /* - * step 2: make sure trigger sources - * are unique and mutually compatible - */ - - if (cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_TIMER) { - cmd->convert_src = TRIG_TIMER; - err++; - } + err |= cfc_check_trigger_is_unique(cmd->convert_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); - if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT) - err++; + /* Step 2b : and mutually compatible */ if (err) return 2; diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c index 023a27d..d4b0859 100644 --- a/drivers/staging/comedi/drivers/pcl818.c +++ b/drivers/staging/comedi/drivers/pcl818.c @@ -107,6 +107,7 @@ A word or two about DMA. Driver support DMA operations at two ways: #include #include +#include "comedi_fc.h" #include "8253.h" /* #define PCL818_MODE13_AO 1 */ @@ -1261,43 +1262,23 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, int err = 0; int tmp, divisor1 = 0, divisor2 = 0; - /* step 1: make sure trigger sources are trivially valid */ + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_FOLLOW; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_TIMER | TRIG_EXT; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_FOLLOW); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /* step 2: make sure trigger sources are unique and mutually compatible */ + /* Step 2a : make sure trigger sources are unique */ - if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT) - err++; + err |= cfc_check_trigger_is_unique(cmd->convert_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); - if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT) - err++; + /* Step 2b : and mutually compatible */ if (err) return 2; diff --git a/drivers/staging/comedi/drivers/pcm_common.c b/drivers/staging/comedi/drivers/pcm_common.c index 474af7b..85ee05e 100644 --- a/drivers/staging/comedi/drivers/pcm_common.c +++ b/drivers/staging/comedi/drivers/pcm_common.c @@ -1,60 +1,30 @@ #include "../comedidev.h" + +#include "comedi_fc.h" #include "pcm_common.h" -/* - * 'do_cmdtest' function for an 'INTERRUPT' subdevice. This is for - * the PCM drivers. - */ int comedi_pcm_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { int err = 0; - unsigned int tmp; - - /* step 1: make sure trigger sources are trivially valid */ - - tmp = cmd->start_src; - cmd->start_src &= (TRIG_NOW | TRIG_INT); - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_EXT; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_NOW; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->stop_src; - cmd->stop_src &= (TRIG_COUNT | TRIG_NONE); - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /* step 2: make sure trigger sources are unique and - * mutually compatible */ + /* Step 2a : make sure trigger sources are unique */ - /* these tests are true if more than one _src bit is set */ - if ((cmd->start_src & (cmd->start_src - 1)) != 0) - err++; - if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0) - err++; - if ((cmd->convert_src & (cmd->convert_src - 1)) != 0) - err++; - if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0) - err++; - if ((cmd->stop_src & (cmd->stop_src - 1)) != 0) - err++; + err |= cfc_check_trigger_is_unique(cmd->start_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ if (err) return 2; diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c index e95a4eb..3e276f7 100644 --- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c +++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c @@ -56,6 +56,8 @@ Devices: [Quatech] DAQP-208 (daqp), DAQP-308 #include +#include "comedi_fc.h" + /* Maximum number of separate DAQP devices we'll allow */ #define MAX_DEV 4 @@ -456,51 +458,26 @@ static int daqp_ai_cmdtest(struct comedi_device *dev, int err = 0; int tmp; - /* step 1: make sure trigger sources are trivially valid */ - - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_TIMER | TRIG_FOLLOW; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_TIMER | TRIG_NOW; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, + TRIG_TIMER | TRIG_FOLLOW); + err |= cfc_check_trigger_src(&cmd->convert_src, + TRIG_TIMER | TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /* - * step 2: make sure trigger sources - * are unique and mutually compatible - */ + /* Step 2a : make sure trigger sources are unique */ - /* note that mutual compatibility is not an issue here */ - if (cmd->scan_begin_src != TRIG_TIMER && - cmd->scan_begin_src != TRIG_FOLLOW) - err++; - if (cmd->convert_src != TRIG_NOW && cmd->convert_src != TRIG_TIMER) - err++; - if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW) - err++; - if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) - err++; + err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); + err |= cfc_check_trigger_is_unique(cmd->convert_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ if (err) return 2; diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index d0e4844..41d24b0 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -106,6 +106,8 @@ Configuration options: #include "../comedidev.h" +#include "comedi_fc.h" + #define DRV_NAME "rtd520" /*====================================================================== @@ -976,52 +978,25 @@ static int rtd_ai_cmdtest(struct comedi_device *dev, int err = 0; int tmp; - /* step 1: make sure trigger sources are trivially valid */ - - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_TIMER | TRIG_EXT; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + /* Step 1 : check if triggers are trivially valid */ + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, + TRIG_TIMER | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /* step 2: make sure trigger sources are unique - and mutually compatible */ - /* note that mutual compatibility is not an issue here */ - if (cmd->scan_begin_src != TRIG_TIMER && - cmd->scan_begin_src != TRIG_EXT) { - err++; - } - if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT) - err++; + /* Step 2a : make sure trigger sources are unique */ - if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) - err++; + err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); + err |= cfc_check_trigger_is_unique(cmd->convert_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ if (err) return 2; diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 24878c8..551d68b 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -1505,56 +1505,28 @@ static int s626_ai_cmdtest(struct comedi_device *dev, int err = 0; int tmp; - /* cmdtest tests a particular command to see if it is valid. Using - * the cmdtest ioctl, a user can create a valid cmd and then have it - * executes by the cmd ioctl. - * - * cmdtest returns 1,2,3,4 or 0, depending on which tests the - * command passes. */ - - /* step 1: make sure trigger sources are trivially valid */ - - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW | TRIG_INT | TRIG_EXT; - if (!cmd->start_src || tmp != cmd->start_src) - err++; + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT | TRIG_FOLLOW; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_TIMER | TRIG_EXT | TRIG_NOW; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, + TRIG_NOW | TRIG_INT | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, + TRIG_TIMER | TRIG_EXT | TRIG_FOLLOW); + err |= cfc_check_trigger_src(&cmd->convert_src, + TRIG_TIMER | TRIG_EXT | TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /* step 2: make sure trigger sources are unique and mutually - compatible */ + /* Step 2a : make sure trigger sources are unique */ - /* note that mutual compatibility is not an issue here */ - if (cmd->scan_begin_src != TRIG_TIMER && - cmd->scan_begin_src != TRIG_EXT - && cmd->scan_begin_src != TRIG_FOLLOW) - err++; - if (cmd->convert_src != TRIG_TIMER && - cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW) - err++; - if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) - err++; + err |= cfc_check_trigger_is_unique(cmd->start_src); + err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); + err |= cfc_check_trigger_is_unique(cmd->convert_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ if (err) return 2; diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c index eb70bac..b70cdf3 100644 --- a/drivers/staging/comedi/drivers/skel.c +++ b/drivers/staging/comedi/drivers/skel.c @@ -76,6 +76,8 @@ Configuration Options: #include /* for PCI devices */ +#include "comedi_fc.h" + /* Imaginary registers for the imaginary board */ #define SKEL_SIZE 0 @@ -349,60 +351,40 @@ static int skel_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, return n; } +/* + * cmdtest tests a particular command to see if it is valid. + * Using the cmdtest ioctl, a user can create a valid cmd + * and then have it executes by the cmd ioctl. + * + * cmdtest returns 1,2,3,4 or 0, depending on which tests + * the command passes. + */ static int skel_ai_cmdtest(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_cmd *cmd) + struct comedi_subdevice *s, + struct comedi_cmd *cmd) { int err = 0; int tmp; - /* cmdtest tests a particular command to see if it is valid. - * Using the cmdtest ioctl, a user can create a valid cmd - * and then have it executes by the cmd ioctl. - * - * cmdtest returns 1,2,3,4 or 0, depending on which tests - * the command passes. */ - - /* step 1: make sure trigger sources are trivially valid */ + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_TIMER | TRIG_EXT; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, + TRIG_TIMER | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /* step 2: make sure trigger sources are unique and mutually compatible - */ + /* Step 2a : make sure trigger sources are unique */ - /* note that mutual compatibility is not an issue here */ - if (cmd->scan_begin_src != TRIG_TIMER && - cmd->scan_begin_src != TRIG_EXT) - err++; - if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT) - err++; - if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) - err++; + err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); + err |= cfc_check_trigger_is_unique(cmd->convert_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ if (err) return 2; diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index bc5fc5c..b536bba 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -98,6 +98,8 @@ sampling rate. If you sample two channels you get 4kHz and so on. #include "../comedidev.h" +#include "comedi_fc.h" + /* timeout for the USB-transfer in ms*/ #define BULK_TIMEOUT 1000 @@ -929,9 +931,9 @@ static int usbduxsub_submit_OutURBs(struct usbduxsub *usbduxsub) static int usbdux_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { - int err = 0, tmp, i; - unsigned int tmpTimer; struct usbduxsub *this_usbduxsub = dev->private; + int err = 0, i; + unsigned int tmpTimer; if (!(this_usbduxsub->probed)) return -ENODEV; @@ -939,51 +941,23 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev, dev_dbg(&this_usbduxsub->interface->dev, "comedi%d: usbdux_ai_cmdtest\n", dev->minor); - /* make sure triggers are valid */ - /* Only immediate triggers are allowed */ - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW | TRIG_INT; - if (!cmd->start_src || tmp != cmd->start_src) - err++; + /* Step 1 : check if triggers are trivially valid */ - /* trigger should happen timed */ - tmp = cmd->scan_begin_src; - /* start a new _scan_ with a timer */ - cmd->scan_begin_src &= TRIG_TIMER; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - /* scanning is continuous */ - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_NOW; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - /* issue a trigger when scan is finished and start a new scan */ - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - /* trigger at the end of count events or not, stop condition or not */ - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /* - * step 2: make sure trigger sources are unique and mutually compatible - * note that mutual compatibility is not an issue here - */ - if (cmd->scan_begin_src != TRIG_FOLLOW && - cmd->scan_begin_src != TRIG_EXT && - cmd->scan_begin_src != TRIG_TIMER) - err++; - if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) - err++; + /* Step 2a : make sure trigger sources are unique */ + + err |= cfc_check_trigger_is_unique(cmd->start_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ if (err) return 2; @@ -1488,8 +1462,9 @@ static int usbdux_ao_inttrig(struct comedi_device *dev, static int usbdux_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { - int err = 0, tmp; struct usbduxsub *this_usbduxsub = dev->private; + int err = 0; + unsigned int flags; if (!this_usbduxsub) return -EFAULT; @@ -1500,69 +1475,46 @@ static int usbdux_ao_cmdtest(struct comedi_device *dev, dev_dbg(&this_usbduxsub->interface->dev, "comedi%d: usbdux_ao_cmdtest\n", dev->minor); - /* make sure triggers are valid */ - /* Only immediate triggers are allowed */ - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW | TRIG_INT; - if (!cmd->start_src || tmp != cmd->start_src) - err++; + /* Step 1 : check if triggers are trivially valid */ + + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT); - /* trigger should happen timed */ - tmp = cmd->scan_begin_src; - /* just now we scan also in the high speed mode every frame */ - /* this is due to ehci driver limitations */ if (0) { /* (this_usbduxsub->high_speed) */ - /* start immediately a new scan */ /* the sampling rate is set by the coversion rate */ - cmd->scan_begin_src &= TRIG_FOLLOW; + flags = TRIG_FOLLOW; } else { /* start a new scan (output at once) with a timer */ - cmd->scan_begin_src &= TRIG_TIMER; + flags = TRIG_TIMER; } - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; + err |= cfc_check_trigger_src(&cmd->scan_begin_src, flags); - /* scanning is continuous */ - tmp = cmd->convert_src; - /* we always output at 1kHz just now all channels at once */ if (0) { /* (this_usbduxsub->high_speed) */ /* - * in usb-2.0 only one conversion it transmitted but with 8kHz/n + * in usb-2.0 only one conversion it transmitted + * but with 8kHz/n */ - cmd->convert_src &= TRIG_TIMER; + flags = TRIG_TIMER; } else { - /* all conversion events happen simultaneously with a rate of - * 1kHz/n */ - cmd->convert_src &= TRIG_NOW; + /* + * all conversion events happen simultaneously with + * a rate of 1kHz/n + */ + flags = TRIG_NOW; } - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - /* issue a trigger when scan is finished and start a new scan */ - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; + err |= cfc_check_trigger_src(&cmd->convert_src, flags); - /* trigger at the end of count events or not, stop condition or not */ - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /* - * step 2: make sure trigger sources are unique and mutually compatible - * note that mutual compatibility is not an issue here - */ - if (cmd->scan_begin_src != TRIG_FOLLOW && - cmd->scan_begin_src != TRIG_EXT && - cmd->scan_begin_src != TRIG_TIMER) - err++; - if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) - err++; + /* Step 2a : make sure trigger sources are unique */ + + err |= cfc_check_trigger_is_unique(cmd->start_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ if (err) return 2; diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index 0f6c139..1154a7e 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -549,10 +549,10 @@ static int usbduxfast_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { - int err = 0, stop_mask = 0; + struct usbduxfastsub_s *udfs = dev->private; + int err = 0; long int steps, tmp; int minSamplPer; - struct usbduxfastsub_s *udfs = dev->private; if (!udfs->probed) return -ENODEV; @@ -563,57 +563,31 @@ static int usbduxfast_ai_cmdtest(struct comedi_device *dev, "scan_begin_arg=%u\n", dev->minor, cmd->convert_arg, cmd->scan_begin_arg); #endif - /* step 1: make sure trigger sources are trivially valid */ - - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW | TRIG_EXT | TRIG_INT; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_TIMER | TRIG_FOLLOW | TRIG_EXT; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_TIMER | TRIG_EXT; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->stop_src; - stop_mask = TRIG_COUNT | TRIG_NONE; - cmd->stop_src &= stop_mask; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, + TRIG_NOW | TRIG_EXT | TRIG_INT); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, + TRIG_TIMER | TRIG_FOLLOW | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /* - * step 2: make sure trigger sources are unique and mutually compatible - */ + /* Step 2a : make sure trigger sources are unique */ - if (cmd->start_src != TRIG_NOW && - cmd->start_src != TRIG_EXT && cmd->start_src != TRIG_INT) - err++; - if (cmd->scan_begin_src != TRIG_TIMER && - cmd->scan_begin_src != TRIG_FOLLOW && - cmd->scan_begin_src != TRIG_EXT) - err++; - if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT) - err++; - if (cmd->stop_src != TRIG_COUNT && - cmd->stop_src != TRIG_EXT && cmd->stop_src != TRIG_NONE) - err++; + err |= cfc_check_trigger_is_unique(cmd->start_src); + err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); + err |= cfc_check_trigger_is_unique(cmd->convert_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ /* can't have external stop and start triggers at once */ if (cmd->start_src == TRIG_EXT && cmd->stop_src == TRIG_EXT) - err++; + err |= -EINVAL; if (err) return 2; diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index b4ab83f..b169412 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -897,9 +897,9 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { - int err = 0, tmp, i; - unsigned int tmpTimer; struct usbduxsub *this_usbduxsub = dev->private; + int err = 0, i; + unsigned int tmpTimer; if (!(this_usbduxsub->probed)) return -ENODEV; @@ -907,51 +907,23 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev, dev_dbg(&this_usbduxsub->interface->dev, "comedi%d: usbdux_ai_cmdtest\n", dev->minor); - /* make sure triggers are valid */ - /* Only immediate triggers are allowed */ - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW | TRIG_INT; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - /* trigger should happen timed */ - tmp = cmd->scan_begin_src; - /* start a new _scan_ with a timer */ - cmd->scan_begin_src &= TRIG_TIMER; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - /* scanning is continuous */ - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_NOW; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - /* issue a trigger when scan is finished and start a new scan */ - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; + /* Step 1 : check if triggers are trivially valid */ - /* trigger at the end of count events or not, stop condition or not */ - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /* - * step 2: make sure trigger sources are unique and mutually compatible - * note that mutual compatibility is not an issue here - */ - if (cmd->scan_begin_src != TRIG_FOLLOW && - cmd->scan_begin_src != TRIG_EXT && - cmd->scan_begin_src != TRIG_TIMER) - err++; - if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) - err++; + /* Step 2a : make sure trigger sources are unique */ + + err |= cfc_check_trigger_is_unique(cmd->start_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ if (err) return 2; @@ -1558,8 +1530,9 @@ static int usbdux_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { - int err = 0, tmp; struct usbduxsub *this_usbduxsub = dev->private; + int err = 0; + unsigned int flags; if (!this_usbduxsub) return -EFAULT; @@ -1570,63 +1543,35 @@ static int usbdux_ao_cmdtest(struct comedi_device *dev, dev_dbg(&this_usbduxsub->interface->dev, "comedi%d: usbdux_ao_cmdtest\n", dev->minor); - /* make sure triggers are valid */ - /* Only immediate triggers are allowed */ - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW | TRIG_INT; - if (!cmd->start_src || tmp != cmd->start_src) - err++; + /* Step 1 : check if triggers are trivially valid */ + + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT); - /* trigger should happen timed */ - tmp = cmd->scan_begin_src; - /* just now we scan also in the high speed mode every frame */ - /* this is due to ehci driver limitations */ if (0) { /* (this_usbduxsub->high_speed) */ - /* start immediately a new scan */ - /* the sampling rate is set by the coversion rate */ - cmd->scan_begin_src &= TRIG_FOLLOW; + /* + * start immediately a new scan + * the sampling rate is set by the coversion rate + */ + flags = TRIG_FOLLOW; } else { /* start a new scan (output at once) with a timer */ - cmd->scan_begin_src &= TRIG_TIMER; + flags = TRIG_TIMER; } - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - /* scanning is continuous */ - tmp = cmd->convert_src; + err |= cfc_check_trigger_src(&cmd->scan_begin_src, flags); - /* all conversion events happen simultaneously */ - cmd->convert_src &= TRIG_NOW; - - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - /* issue a trigger when scan is finished and start a new scan */ - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - /* trigger at the end of count events or not, stop condition or not */ - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /* - * step 2: make sure trigger sources - * are unique and mutually compatible - * note that mutual compatibility is not an issue here - */ - if (cmd->scan_begin_src != TRIG_FOLLOW && - cmd->scan_begin_src != TRIG_EXT && - cmd->scan_begin_src != TRIG_TIMER) - err++; - if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) - err++; + /* Step 2a : make sure trigger sources are unique */ + + err |= cfc_check_trigger_is_unique(cmd->start_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ if (err) return 2; -- cgit v0.10.2 From e1878957b4676a17cf398f7f5723b365e9a2ca48 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 27 Sep 2012 17:45:27 +0100 Subject: staging: comedi: jr3_pci: fix iomem dereference Correct a direct dereference of I/O memory to use an appropriate I/O memory access function. Note that the pointer being dereferenced is not currently tagged with `__iomem` but I plan to correct that for 3.7. Cc: stable Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index 360107c..4a108ea 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -885,7 +885,7 @@ static int jr3_pci_attach(struct comedi_device *dev, } /* Reset DSP card */ - devpriv->iobase->channel[0].reset = 0; + writel(0, &devpriv->iobase->channel[0].reset); result = comedi_load_firmware(dev, "jr3pci.idm", jr3_download_firmware); dev_dbg(dev->class_dev, "Firmare load %d\n", result); -- cgit v0.10.2