Merge tag 'iio-for-3.13c' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23...
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 6 Oct 2013 19:39:52 +0000 (12:39 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 6 Oct 2013 19:39:52 +0000 (12:39 -0700)
Jonathan writes:

Third set of new functionality and cleanups for IIO in the 3.13 cycle.

Driver New Functionality
* MXS - new interrupt driven touch screen support for i.MX23/28. Old
  polled implementation dropped.

Driver Cleanups
* Some spi_sync boilerplate dropped by using spi_sync_transfer
* Some switching of drivers to the fractional type for scale reading.
  Moves the ugly calculation into one place.
* Fix the documentation for *_voltage_scale which is never been correct
  or as implemented in any driver.
* HID sensor hub and children : Open the sensor hub only when someone cares.
* hmc5843 - various minor

40 files changed:
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/ced1401/ced_ioc.c
drivers/staging/comedi/Kconfig
drivers/staging/comedi/drivers/ni_6527.c
drivers/staging/comedi/drivers/ni_at_ao.c
drivers/staging/dgnc/dgnc_driver.c
drivers/staging/dgnc/dgnc_mgmt.c
drivers/staging/dgnc/dgnc_tty.c
drivers/staging/dwc2/core.h
drivers/staging/lustre/lustre/llite/rw26.c
drivers/staging/mt29f_spinand/Kconfig [new file with mode: 0644]
drivers/staging/mt29f_spinand/Makefile [new file with mode: 0644]
drivers/staging/mt29f_spinand/TODO [new file with mode: 0644]
drivers/staging/mt29f_spinand/mt29f_spinand.c [new file with mode: 0644]
drivers/staging/mt29f_spinand/mt29f_spinand.h [new file with mode: 0644]
drivers/staging/nvec/nvec.c
drivers/staging/octeon-usb/cvmx-usb.c
drivers/staging/octeon-usb/cvmx-usb.h
drivers/staging/octeon-usb/octeon-hcd.c
drivers/staging/rtl8712/os_intfs.c
drivers/staging/rtl8712/rtl8712_cmd.c
drivers/staging/rtl8712/rtl8712_efuse.c
drivers/staging/rtl8712/rtl8712_recv.c
drivers/staging/rtl8712/rtl871x_cmd.c
drivers/staging/rtl8712/rtl871x_ioctl_linux.c
drivers/staging/rtl8712/rtl871x_ioctl_rtl.c
drivers/staging/rtl8712/rtl871x_mlme.c
drivers/staging/rtl8712/rtl871x_mp.c
drivers/staging/rtl8712/rtl871x_security.c
drivers/staging/rtl8712/rtl871x_sta_mgt.c
drivers/staging/rtl8712/xmit_linux.c
drivers/staging/sep/sep_main.c
drivers/staging/silicom/bp_mod.h
drivers/staging/speakup/main.c
drivers/staging/speakup/speakup_audptr.c
drivers/staging/speakup/varhandlers.c
drivers/staging/vt6656/rxtx.c
drivers/staging/vt6656/rxtx.h
drivers/staging/xillybus/Kconfig

index 3626dbc8eb0bba5134f89aa19178fedb3e504e98..3bfdaa8d80a9ccb9b299d6bd4fde693ed4d03652 100644 (file)
@@ -136,6 +136,8 @@ source "drivers/staging/goldfish/Kconfig"
 
 source "drivers/staging/netlogic/Kconfig"
 
+source "drivers/staging/mt29f_spinand/Kconfig"
+
 source "drivers/staging/dwc2/Kconfig"
 
 source "drivers/staging/lustre/Kconfig"
index d1b4b8003c2d4de3898796e74d973cb2aa25f888..b0d3303b46808f224578c3757006aef96099e4cd 100644 (file)
@@ -66,3 +66,4 @@ obj-$(CONFIG_USB_BTMTK)               += btmtk_usb/
 obj-$(CONFIG_XILLYBUS)         += xillybus/
 obj-$(CONFIG_DGNC)                     += dgnc/
 obj-$(CONFIG_DGAP)                     += dgap/
+obj-$(CONFIG_MTD_SPINAND_MT29F)        += mt29f_spinand/
index 2dbaf39e2fc296b0b5acfc6b32fd0f9bb67d80e3..62efd74b8c04746da6cb1ccfa425139fa67e89bf 100644 (file)
@@ -692,10 +692,7 @@ static int SetArea(DEVICE_EXTENSION *pdx, int nArea, char __user *puBuf,
                __func__, puBuf, dwLength, bCircular);
 
        /*  To pin down user pages we must first acquire the mapping semaphore. */
-       down_read(&current->mm->mmap_sem);      /*  get memory map semaphore */
-       nPages = get_user_pages(current, current->mm, ulStart, len, 1, 0,
-                               pPages, NULL);
-       up_read(&current->mm->mmap_sem);        /*  release the semaphore */
+       nPages = get_user_pages_fast(ulStart, len, 1, pPages);
        dev_dbg(&pdx->interface->dev, "%s nPages = %d", __func__, nPages);
 
        if (nPages > 0) {               /*  if we succeeded */
index 24f3cf273e5b1d9461045540a1a69423902fa6ef..bfa27e7fc0169feb81a0dc631c7a85f565dea107 100644 (file)
@@ -991,8 +991,6 @@ config COMEDI_ME_DAQ
 
 config COMEDI_NI_6527
        tristate "NI 6527 support"
-       depends on HAS_DMA
-       select COMEDI_MITE
        ---help---
          Enable support for the National Instruments 6527 PCI card
 
index 44557c9671ace9b1050010e5b59bbb517484ee7b..85aa9609d6a280994bffaa8ad72f0eac5c3c3861 100644 (file)
@@ -1,41 +1,33 @@
 /*
-    comedi/drivers/ni_6527.c
-    driver for National Instruments PCI-6527
-
-    COMEDI - Linux Control and Measurement Device Interface
-    Copyright (C) 1999,2002,2003 David A. Schleef <ds@schleef.org>
-
-    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.
-*/
-/*
-Driver: ni_6527
-Description: National Instruments 6527
-Author: ds
-Status: works
-Devices: [National Instruments] PCI-6527 (ni6527), PXI-6527
-Updated: Sat, 25 Jan 2003 13:24:40 -0800
-
-
-*/
+ * ni_6527.c
+ * Comedi driver for National Instruments PCI-6527
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 1999,2002,2003 David A. Schleef <ds@schleef.org>
+ *
+ * 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.
+ */
 
 /*
-   Manuals (available from ftp://ftp.natinst.com/support/manuals)
-
-       370106b.pdf     6527 Register Level Programmer Manual
-
+ * Driver: ni_6527
+ * Description: National Instruments 6527
+ * Devices: (National Instruments) PCI-6527 [pci-6527]
+ *          (National Instruments) PXI-6527 [pxi-6527]
+ * Author: David A. Schleef <ds@schleef.org>
+ * Updated: Sat, 25 Jan 2003 13:24:40 -0800
+ * Status: works
+ *
+ * Configuration Options: not applicable, uses PCI auto config
  */
 
-#define DEBUG 1
-#define DEBUG_FLAGS
-
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
@@ -43,39 +35,41 @@ Updated: Sat, 25 Jan 2003 13:24:40 -0800
 #include "../comedidev.h"
 
 #include "comedi_fc.h"
-#include "mite.h"
-
-#define DRIVER_NAME "ni_6527"
-
-#define NI6527_DIO_SIZE 4096
-#define NI6527_MITE_SIZE 4096
-
-#define Port_Register(x)                       (0x00+(x))
-#define ID_Register                            0x06
 
-#define Clear_Register                         0x07
-#define ClrEdge                                0x08
-#define ClrOverflow                    0x04
-#define ClrFilter                      0x02
-#define ClrInterval                    0x01
-
-#define Filter_Interval(x)                     (0x08+(x))
-#define Filter_Enable(x)                       (0x0c+(x))
-
-#define Change_Status                          0x14
-#define MasterInterruptStatus          0x04
-#define Overflow                       0x02
-#define EdgeStatus                     0x01
-
-#define Master_Interrupt_Control               0x15
-#define FallingEdgeIntEnable           0x10
-#define RisingEdgeIntEnable            0x08
-#define MasterInterruptEnable          0x04
-#define OverflowIntEnable              0x02
-#define EdgeIntEnable                  0x01
-
-#define Rising_Edge_Detection_Enable(x)                (0x018+(x))
-#define Falling_Edge_Detection_Enable(x)       (0x020+(x))
+/*
+ * PCI BAR1 - Register memory map
+ *
+ * Manuals (available from ftp://ftp.natinst.com/support/manuals)
+ *     370106b.pdf     6527 Register Level Programmer Manual
+ */
+#define NI6527_DI_REG(x)               (0x00 + (x))
+#define NI6527_DO_REG(x)               (0x03 + (x))
+#define NI6527_ID_REG                  0x06
+#define NI6527_CLR_REG                 0x07
+#define NI6527_CLR_EDGE                        (1 << 3)
+#define NI6527_CLR_OVERFLOW            (1 << 2)
+#define NI6527_CLR_FILT                        (1 << 1)
+#define NI6527_CLR_INTERVAL            (1 << 0)
+#define NI6527_CLR_IRQS                        (NI6527_CLR_EDGE | NI6527_CLR_OVERFLOW)
+#define NI6527_CLR_RESET_FILT          (NI6527_CLR_FILT | NI6527_CLR_INTERVAL)
+#define NI6527_FILT_INTERVAL_REG(x)    (0x08 + (x))
+#define NI6527_FILT_ENA_REG(x)         (0x0c + (x))
+#define NI6527_STATUS_REG              0x14
+#define NI6527_STATUS_IRQ              (1 << 2)
+#define NI6527_STATUS_OVERFLOW         (1 << 1)
+#define NI6527_STATUS_EDGE             (1 << 0)
+#define NI6527_CTRL_REG                        0x15
+#define NI6527_CTRL_FALLING            (1 << 4)
+#define NI6527_CTRL_RISING             (1 << 3)
+#define NI6527_CTRL_IRQ                        (1 << 2)
+#define NI6527_CTRL_OVERFLOW           (1 << 1)
+#define NI6527_CTRL_EDGE               (1 << 0)
+#define NI6527_CTRL_DISABLE_IRQS       0
+#define NI6527_CTRL_ENABLE_IRQS                (NI6527_CTRL_FALLING | \
+                                        NI6527_CTRL_RISING | \
+                                        NI6527_CTRL_IRQ | NI6527_CTRL_EDGE)
+#define NI6527_RISING_EDGE_REG(x)      (0x18 + (x))
+#define NI6527_FALLING_EDGE_REG(x)     (0x20 + (x))
 
 enum ni6527_boardid {
        BOARD_PCI6527,
@@ -96,67 +90,87 @@ static const struct ni6527_board ni6527_boards[] = {
 };
 
 struct ni6527_private {
-       struct mite_struct *mite;
+       void __iomem *mmio_base;
        unsigned int filter_interval;
        unsigned int filter_enable;
 };
 
+static void ni6527_set_filter_interval(struct comedi_device *dev,
+                                      unsigned int val)
+{
+       struct ni6527_private *devpriv = dev->private;
+       void __iomem *mmio = devpriv->mmio_base;
+
+       if (val != devpriv->filter_interval) {
+               writeb(val & 0xff, mmio + NI6527_FILT_INTERVAL_REG(0));
+               writeb((val >> 8) & 0xff, mmio + NI6527_FILT_INTERVAL_REG(1));
+               writeb((val >> 16) & 0x0f, mmio + NI6527_FILT_INTERVAL_REG(2));
+
+               writeb(NI6527_CLR_INTERVAL, mmio + NI6527_CLR_REG);
+
+               devpriv->filter_interval = val;
+       }
+}
+
+static void ni6527_set_filter_enable(struct comedi_device *dev,
+                                    unsigned int val)
+{
+       struct ni6527_private *devpriv = dev->private;
+       void __iomem *mmio = devpriv->mmio_base;
+
+       writeb(val & 0xff, mmio + NI6527_FILT_ENA_REG(0));
+       writeb((val >> 8) & 0xff, mmio + NI6527_FILT_ENA_REG(1));
+       writeb((val >> 16) & 0xff, mmio + NI6527_FILT_ENA_REG(2));
+}
+
 static int ni6527_di_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 ni6527_private *devpriv = dev->private;
-       int chan = CR_CHAN(insn->chanspec);
+       unsigned int chan = CR_CHAN(insn->chanspec);
        unsigned int interval;
 
-       if (insn->n != 2)
-               return -EINVAL;
-
-       if (data[0] != INSN_CONFIG_FILTER)
-               return -EINVAL;
-
-       if (data[1]) {
+       switch (data[0]) {
+       case INSN_CONFIG_FILTER:
+               /*
+                * The deglitch filter interval is specified in nanoseconds.
+                * The hardware supports intervals in 200ns increments. Round
+                * the user values up and return the actual interval.
+                */
                interval = (data[1] + 100) / 200;
                data[1] = interval * 200;
 
-               if (interval != devpriv->filter_interval) {
-                       writeb(interval & 0xff,
-                              devpriv->mite->daq_io_addr + Filter_Interval(0));
-                       writeb((interval >> 8) & 0xff,
-                              devpriv->mite->daq_io_addr + Filter_Interval(1));
-                       writeb((interval >> 16) & 0x0f,
-                              devpriv->mite->daq_io_addr + Filter_Interval(2));
-
-                       writeb(ClrInterval,
-                              devpriv->mite->daq_io_addr + Clear_Register);
-
-                       devpriv->filter_interval = interval;
+               if (interval) {
+                       ni6527_set_filter_interval(dev, interval);
+                       devpriv->filter_enable |= 1 << chan;
+               } else {
+                       devpriv->filter_enable &= ~(1 << chan);
                }
-
-               devpriv->filter_enable |= 1 << chan;
-       } else {
-               devpriv->filter_enable &= ~(1 << chan);
+               ni6527_set_filter_enable(dev, devpriv->filter_enable);
+               break;
+       default:
+               return -EINVAL;
        }
 
-       writeb(devpriv->filter_enable,
-              devpriv->mite->daq_io_addr + Filter_Enable(0));
-       writeb(devpriv->filter_enable >> 8,
-              devpriv->mite->daq_io_addr + Filter_Enable(1));
-       writeb(devpriv->filter_enable >> 16,
-              devpriv->mite->daq_io_addr + Filter_Enable(2));
-
-       return 2;
+       return insn->n;
 }
 
 static int ni6527_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)
 {
        struct ni6527_private *devpriv = dev->private;
+       void __iomem *mmio = devpriv->mmio_base;
+       unsigned int val;
 
-       data[1] = readb(devpriv->mite->daq_io_addr + Port_Register(0));
-       data[1] |= readb(devpriv->mite->daq_io_addr + Port_Register(1)) << 8;
-       data[1] |= readb(devpriv->mite->daq_io_addr + Port_Register(2)) << 16;
+       val = readb(mmio + NI6527_DI_REG(0));
+       val |= (readb(mmio + NI6527_DI_REG(1)) << 8);
+       val |= (readb(mmio + NI6527_DI_REG(2)) << 16);
+
+       data[1] = val;
 
        return insn->n;
 }
@@ -167,23 +181,20 @@ static int ni6527_do_insn_bits(struct comedi_device *dev,
                               unsigned int *data)
 {
        struct ni6527_private *devpriv = dev->private;
+       void __iomem *mmio = devpriv->mmio_base;
        unsigned int mask;
 
        mask = comedi_dio_update_state(s, data);
        if (mask) {
                /* Outputs are inverted */
-               if (mask & 0x0000ff) {
-                       writeb(s->state ^ 0xff,
-                              devpriv->mite->daq_io_addr + Port_Register(3));
-               }
-               if (mask & 0x00ff00) {
-                       writeb((s->state >> 8) ^ 0xff,
-                              devpriv->mite->daq_io_addr + Port_Register(4));
-               }
-               if (mask & 0xff0000) {
-                       writeb((s->state >> 16) ^ 0xff,
-                              devpriv->mite->daq_io_addr + Port_Register(5));
-               }
+               unsigned int val = s->state ^ 0xffffff;
+
+               if (mask & 0x0000ff)
+                       writeb(val & 0xff, mmio + NI6527_DO_REG(0));
+               if (mask & 0x00ff00)
+                       writeb((val >> 8) & 0xff, mmio + NI6527_DO_REG(1));
+               if (mask & 0xff0000)
+                       writeb((val >> 16) & 0xff, mmio + NI6527_DO_REG(2));
        }
 
        data[1] = s->state;
@@ -195,21 +206,22 @@ static irqreturn_t ni6527_interrupt(int irq, void *d)
 {
        struct comedi_device *dev = d;
        struct ni6527_private *devpriv = dev->private;
-       struct comedi_subdevice *s = &dev->subdevices[2];
+       struct comedi_subdevice *s = dev->read_subdev;
+       void __iomem *mmio = devpriv->mmio_base;
        unsigned int status;
 
-       status = readb(devpriv->mite->daq_io_addr + Change_Status);
-       if ((status & MasterInterruptStatus) == 0)
-               return IRQ_NONE;
-       if ((status & EdgeStatus) == 0)
+       status = readb(mmio + NI6527_STATUS_REG);
+       if (!(status & NI6527_STATUS_IRQ))
                return IRQ_NONE;
 
-       writeb(ClrEdge | ClrOverflow,
-              devpriv->mite->daq_io_addr + Clear_Register);
+       if (status & NI6527_STATUS_EDGE) {
+               comedi_buf_put(s->async, 0);
+               s->async->events |= COMEDI_CB_EOS;
+               comedi_event(dev, s);
+       }
+
+       writeb(NI6527_CLR_IRQS, mmio + NI6527_CLR_REG);
 
-       comedi_buf_put(s->async, 0);
-       s->async->events |= COMEDI_CB_EOS;
-       comedi_event(dev, s);
        return IRQ_HANDLED;
 }
 
@@ -259,13 +271,10 @@ static int ni6527_intr_cmd(struct comedi_device *dev,
                           struct comedi_subdevice *s)
 {
        struct ni6527_private *devpriv = dev->private;
-       /* struct comedi_cmd *cmd = &s->async->cmd; */
+       void __iomem *mmio = devpriv->mmio_base;
 
-       writeb(ClrEdge | ClrOverflow,
-              devpriv->mite->daq_io_addr + Clear_Register);
-       writeb(FallingEdgeIntEnable | RisingEdgeIntEnable |
-              MasterInterruptEnable | EdgeIntEnable,
-              devpriv->mite->daq_io_addr + Master_Interrupt_Control);
+       writeb(NI6527_CLR_IRQS, mmio + NI6527_CLR_REG);
+       writeb(NI6527_CTRL_ENABLE_IRQS, mmio + NI6527_CTRL_REG);
 
        return 0;
 }
@@ -274,8 +283,9 @@ static int ni6527_intr_cancel(struct comedi_device *dev,
                              struct comedi_subdevice *s)
 {
        struct ni6527_private *devpriv = dev->private;
+       void __iomem *mmio = devpriv->mmio_base;
 
-       writeb(0x00, devpriv->mite->daq_io_addr + Master_Interrupt_Control);
+       writeb(NI6527_CTRL_DISABLE_IRQS, mmio + NI6527_CTRL_REG);
 
        return 0;
 }
@@ -288,32 +298,54 @@ static int ni6527_intr_insn_bits(struct comedi_device *dev,
        return insn->n;
 }
 
+static void ni6527_set_edge_detection(struct comedi_device *dev,
+                                     unsigned int rising,
+                                     unsigned int falling)
+{
+       struct ni6527_private *devpriv = dev->private;
+       void __iomem *mmio = devpriv->mmio_base;
+
+       /* enable rising-edge detection channels */
+       writeb(rising & 0xff, mmio + NI6527_RISING_EDGE_REG(0));
+       writeb((rising >> 8) & 0xff, mmio + NI6527_RISING_EDGE_REG(1));
+       writeb((rising >> 16) & 0xff, mmio + NI6527_RISING_EDGE_REG(2));
+
+       /* enable falling-edge detection channels */
+       writeb(falling & 0xff, mmio + NI6527_FALLING_EDGE_REG(0));
+       writeb((falling >> 8) & 0xff, mmio + NI6527_FALLING_EDGE_REG(1));
+       writeb((falling >> 16) & 0xff, mmio + NI6527_FALLING_EDGE_REG(2));
+}
+
 static int ni6527_intr_insn_config(struct comedi_device *dev,
                                   struct comedi_subdevice *s,
-                                  struct comedi_insn *insn, unsigned int *data)
+                                  struct comedi_insn *insn,
+                                  unsigned int *data)
+{
+       switch (data[0]) {
+       case INSN_CONFIG_CHANGE_NOTIFY:
+               /* check_insn_config_length() does not check this instruction */
+               if (insn->n != 3)
+                       return -EINVAL;
+               ni6527_set_edge_detection(dev, data[1], data[2]);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return insn->n;
+}
+
+static void ni6527_reset(struct comedi_device *dev)
 {
        struct ni6527_private *devpriv = dev->private;
+       void __iomem *mmio = devpriv->mmio_base;
 
-       if (insn->n < 1)
-               return -EINVAL;
-       if (data[0] != INSN_CONFIG_CHANGE_NOTIFY)
-               return -EINVAL;
+       /* disable deglitch filters on all channels */
+       ni6527_set_filter_enable(dev, 0);
 
-       writeb(data[1],
-              devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(0));
-       writeb(data[1] >> 8,
-              devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(1));
-       writeb(data[1] >> 16,
-              devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(2));
-
-       writeb(data[2],
-              devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(0));
-       writeb(data[2] >> 8,
-              devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(1));
-       writeb(data[2] >> 16,
-              devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(2));
-
-       return 2;
+       writeb(NI6527_CLR_IRQS | NI6527_CLR_RESET_FILT,
+              mmio + NI6527_CLR_REG);
+       writeb(NI6527_CTRL_DISABLE_IRQS, mmio + NI6527_CTRL_REG);
 }
 
 static int ni6527_auto_attach(struct comedi_device *dev,
@@ -332,75 +364,69 @@ static int ni6527_auto_attach(struct comedi_device *dev,
        dev->board_ptr = board;
        dev->board_name = board->name;
 
+       devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
+       if (!devpriv)
+               return -ENOMEM;
+
        ret = comedi_pci_enable(dev);
        if (ret)
                return ret;
 
-       devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
-       if (!devpriv)
+       devpriv->mmio_base = pci_ioremap_bar(pcidev, 1);
+       if (!devpriv->mmio_base)
                return -ENOMEM;
 
-       devpriv->mite = mite_alloc(pcidev);
-       if (!devpriv->mite)
-               return -ENOMEM;
+       /* make sure this is actually a 6527 device */
+       if (readb(devpriv->mmio_base + NI6527_ID_REG) != 0x27)
+               return -ENODEV;
 
-       ret = mite_setup(devpriv->mite);
-       if (ret < 0) {
-               dev_err(dev->class_dev, "error setting up mite\n");
-               return ret;
-       }
+       ni6527_reset(dev);
 
-       dev_info(dev->class_dev, "board: %s, ID=0x%02x\n", dev->board_name,
-                readb(devpriv->mite->daq_io_addr + ID_Register));
+       ret = request_irq(pcidev->irq, ni6527_interrupt, IRQF_SHARED,
+                         dev->board_name, dev);
+       if (ret == 0)
+               dev->irq = pcidev->irq;
 
        ret = comedi_alloc_subdevices(dev, 3);
        if (ret)
                return ret;
 
+       /* Digital Input subdevice */
        s = &dev->subdevices[0];
-       s->type = COMEDI_SUBD_DI;
-       s->subdev_flags = SDF_READABLE;
-       s->n_chan = 24;
-       s->range_table = &range_digital;
-       s->maxdata = 1;
-       s->insn_config = ni6527_di_insn_config;
-       s->insn_bits = ni6527_di_insn_bits;
-
+       s->type         = COMEDI_SUBD_DI;
+       s->subdev_flags = SDF_READABLE;
+       s->n_chan       = 24;
+       s->maxdata      = 1;
+       s->range_table  = &range_digital;
+       s->insn_config  = ni6527_di_insn_config;
+       s->insn_bits    = ni6527_di_insn_bits;
+
+       /* Digital Output subdevice */
        s = &dev->subdevices[1];
-       s->type = COMEDI_SUBD_DO;
-       s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
-       s->n_chan = 24;
-       s->range_table = &range_unknown;  /* FIXME: actually conductance */
-       s->maxdata = 1;
-       s->insn_bits = ni6527_do_insn_bits;
-
+       s->type         = COMEDI_SUBD_DO;
+       s->subdev_flags = SDF_WRITABLE;
+       s->n_chan       = 24;
+       s->maxdata      = 1;
+       s->range_table  = &range_digital;
+       s->insn_bits    = ni6527_do_insn_bits;
+
+       /* Edge detection interrupt subdevice */
        s = &dev->subdevices[2];
-       dev->read_subdev = s;
-       s->type = COMEDI_SUBD_DI;
-       s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
-       s->n_chan = 1;
-       s->range_table = &range_unknown;
-       s->maxdata = 1;
-       s->do_cmdtest = ni6527_intr_cmdtest;
-       s->do_cmd = ni6527_intr_cmd;
-       s->cancel = ni6527_intr_cancel;
-       s->insn_bits = ni6527_intr_insn_bits;
-       s->insn_config = ni6527_intr_insn_config;
-
-       writeb(0x00, devpriv->mite->daq_io_addr + Filter_Enable(0));
-       writeb(0x00, devpriv->mite->daq_io_addr + Filter_Enable(1));
-       writeb(0x00, devpriv->mite->daq_io_addr + Filter_Enable(2));
-
-       writeb(ClrEdge | ClrOverflow | ClrFilter | ClrInterval,
-              devpriv->mite->daq_io_addr + Clear_Register);
-       writeb(0x00, devpriv->mite->daq_io_addr + Master_Interrupt_Control);
-
-       ret = request_irq(mite_irq(devpriv->mite), ni6527_interrupt,
-                         IRQF_SHARED, DRIVER_NAME, dev);
-       if (ret < 0)
-               dev_warn(dev->class_dev, "irq not available\n");
-       else
-               dev->irq = mite_irq(devpriv->mite);
+       if (dev->irq) {
+               dev->read_subdev = s;
+               s->type         = COMEDI_SUBD_DI;
+               s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
+               s->n_chan       = 1;
+               s->maxdata      = 1;
+               s->range_table  = &range_digital;
+               s->insn_config  = ni6527_intr_insn_config;
+               s->insn_bits    = ni6527_intr_insn_bits;
+               s->do_cmdtest   = ni6527_intr_cmdtest;
+               s->do_cmd       = ni6527_intr_cmd;
+               s->cancel       = ni6527_intr_cancel;
+       } else {
+               s->type = COMEDI_SUBD_UNUSED;
+       }
 
        return 0;
 }
@@ -409,23 +435,18 @@ static void ni6527_detach(struct comedi_device *dev)
 {
        struct ni6527_private *devpriv = dev->private;
 
-       if (devpriv && devpriv->mite && devpriv->mite->daq_io_addr)
-               writeb(0x00,
-                      devpriv->mite->daq_io_addr + Master_Interrupt_Control);
+       if (devpriv && devpriv->mmio_base)
+               ni6527_reset(dev);
        if (dev->irq)
                free_irq(dev->irq, dev);
-       if (devpriv && devpriv->mite) {
-               mite_unsetup(devpriv->mite);
-               mite_free(devpriv->mite);
-       }
        comedi_pci_disable(dev);
 }
 
 static struct comedi_driver ni6527_driver = {
-       .driver_name = DRIVER_NAME,
-       .module = THIS_MODULE,
-       .auto_attach = ni6527_auto_attach,
-       .detach = ni6527_detach,
+       .driver_name    = "ni_6527",
+       .module         = THIS_MODULE,
+       .auto_attach    = ni6527_auto_attach,
+       .detach         = ni6527_detach,
 };
 
 static int ni6527_pci_probe(struct pci_dev *dev,
@@ -442,7 +463,7 @@ static DEFINE_PCI_DEVICE_TABLE(ni6527_pci_table) = {
 MODULE_DEVICE_TABLE(pci, ni6527_pci_table);
 
 static struct pci_driver ni6527_pci_driver = {
-       .name           = DRIVER_NAME,
+       .name           = "ni_6527",
        .id_table       = ni6527_pci_table,
        .probe          = ni6527_pci_probe,
        .remove         = comedi_pci_auto_unconfig,
@@ -450,5 +471,5 @@ static struct pci_driver ni6527_pci_driver = {
 module_comedi_pci_driver(ni6527_driver, ni6527_pci_driver);
 
 MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_DESCRIPTION("Comedi driver for National Instruments PCI-6527");
 MODULE_LICENSE("GPL");
index 3545d294c4ae16907689b091a0a2d208fc0a4be3..10e3e9475ee2c544336ea3075755df30972240e1 100644 (file)
 /*
-    comedi/drivers/ni_at_ao.c
-    Driver for NI AT-AO-6/10 boards
-
-    COMEDI - Linux Control and Measurement Device Interface
-    Copyright (C) 2000,2002 David A. Schleef <ds@schleef.org>
-
-    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.
-*/
-/*
-Driver: ni_at_ao
-Description: National Instruments AT-AO-6/10
-Devices: [National Instruments] AT-AO-6 (at-ao-6), AT-AO-10 (at-ao-10)
-Status: should work
-Author: ds
-Updated: Sun Dec 26 12:26:28 EST 2004
-
-Configuration options:
-  [0] - I/O port base address
-  [1] - IRQ (unused)
-  [2] - DMA (unused)
-  [3] - analog output range, set by jumpers on hardware (0 for -10 to 10V
-       bipolar, 1 for 0V to 10V unipolar)
-
-*/
+ * ni_at_ao.c
+ * Driver for NI AT-AO-6/10 boards
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 2000,2002 David A. Schleef <ds@schleef.org>
+ *
+ * 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.
+ */
+
 /*
- * Register-level programming information can be found in NI
- * document 320379.pdf.
+ * Driver: ni_at_ao
+ * Description: National Instruments AT-AO-6/10
+ * Devices: (National Instruments) AT-AO-6 [at-ao-6]
+ *          (National Instruments) AT-AO-10 [at-ao-10]
+ * Status: should work
+ * Author: David A. Schleef <ds@schleef.org>
+ * Updated: Sun Dec 26 12:26:28 EST 2004
+ *
+ * Configuration options:
+ *   [0] - I/O port base address
+ *   [1] - IRQ (unused)
+ *   [2] - DMA (unused)
+ *   [3] - analog output range, set by jumpers on hardware
+ *         0 for -10 to 10V bipolar
+ *         1 for 0V to 10V unipolar
  */
 
 #include <linux/module.h>
-#include "../comedidev.h"
 
-/* board egisters */
-/* registers with _2_ are accessed when GRP2WR is set in CFG1 */
+#include "../comedidev.h"
 
-#define ATAO_SIZE 0x20
-
-#define ATAO_2_DMATCCLR                0x00    /* W 16 */
-#define ATAO_DIN               0x00    /* R 16 */
-#define ATAO_DOUT              0x00    /* W 16 */
-
-#define ATAO_CFG2              0x02    /* W 16 */
-#define CALLD1 0x8000
-#define CALLD0 0x4000
-#define FFRTEN 0x2000
-#define DAC2S8 0x1000
-#define DAC2S6 0x0800
-#define DAC2S4 0x0400
-#define DAC2S2 0x0200
-#define DAC2S0 0x0100
-#define LDAC8          0x0080
-#define LDAC6          0x0040
-#define LDAC4          0x0020
-#define LDAC2          0x0010
-#define LDAC0          0x0008
-#define PROMEN 0x0004
-#define SCLK           0x0002
-#define SDATA          0x0001
-
-#define ATAO_2_INT1CLR         0x02    /* W 16 */
-
-#define ATAO_CFG3              0x04    /* W 16 */
-#define DMAMODE        0x0040
-#define CLKOUT 0x0020
-#define RCLKEN 0x0010
-#define DOUTEN2        0x0008
-#define DOUTEN1        0x0004
-#define EN2_5V 0x0002
-#define SCANEN 0x0001
-
-#define ATAO_2_INT2CLR         0x04    /* W 16 */
-
-#define ATAO_82C53_BASE                0x06    /* RW 8 */
-
-#define ATAO_82C53_CNTR1       0x06    /* RW 8 */
-#define ATAO_82C53_CNTR2       0x07    /* RW 8 */
-#define ATAO_82C53_CNTR3       0x08    /* RW 8 */
-#define ATAO_82C53_CNTRCMD     0x09    /* W 8 */
-#define CNTRSEL1       0x80
-#define CNTRSEL0       0x40
-#define RWSEL1 0x20
-#define RWSEL0 0x10
-#define MODESEL2       0x08
-#define MODESEL1       0x04
-#define MODESEL0       0x02
-#define BCDSEL 0x01
-  /* read-back command */
-#define COUNT          0x20
-#define STATUS 0x10
-#define CNTR3          0x08
-#define CNTR2          0x04
-#define CNTR1          0x02
-  /* status */
-#define OUT            0x80
-#define _NULL          0x40
-#define RW1            0x20
-#define RW0            0x10
-#define MODE2          0x08
-#define MODE1          0x04
-#define MODE0          0x02
-#define BCD            0x01
-
-#define ATAO_2_RTSISHFT                0x06    /* W 8 */
-#define ATAO_RTSISHFT_RSI      (1 << 0)
-
-#define ATAO_2_RTSISTRB                0x07    /* W 8 */
-
-#define ATAO_CFG1              0x0a    /* W 16 */
-#define EXTINT2EN      0x8000
-#define EXTINT1EN      0x4000
-#define CNTINT2EN      0x2000
-#define CNTINT1EN      0x1000
-#define TCINTEN        0x0800
-#define CNT1SRC        0x0400
-#define CNT2SRC        0x0200
-#define FIFOEN 0x0100
-#define GRP2WR 0x0080
-#define EXTUPDEN       0x0040
-#define DMARQ          0x0020
-#define DMAEN          0x0010
-#define CH_mask        0x000f
-#define ATAO_STATUS            0x0a    /* R 16 */
-#define FH             0x0040
-#define FE             0x0020
-#define FF             0x0010
-#define INT2           0x0008
-#define INT1           0x0004
-#define TCINT          0x0002
-#define PROMOUT        0x0001
-
-#define ATAO_FIFO_WRITE                0x0c    /* W 16 */
-#define ATAO_FIFO_CLEAR                0x0c    /* R 16 */
-#define ATAO_DACn(x)           (0x0c + 2*(x))  /* W */
+#include "8253.h"
 
 /*
- * 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.
+ * Register map
+ *
+ * Register-level programming information can be found in NI
+ * document 320379.pdf.
  */
+#define ATAO_DIO_REG           0x00
+#define ATAO_CFG2_REG          0x02
+#define ATAO_CFG2_CALLD_NOP    (0 << 14)
+#define ATAO_CFG2_CALLD(x)     ((((x) >> 3) + 1) << 14)
+#define ATAO_CFG2_FFRTEN       (1 << 13)
+#define ATAO_CFG2_DACS(x)      (1 << (((x) / 2) + 8))
+#define ATAO_CFG2_LDAC(x)      (1 << (((x) / 2) + 3))
+#define ATAO_CFG2_PROMEN       (1 << 2)
+#define ATAO_CFG2_SCLK         (1 << 1)
+#define ATAO_CFG2_SDATA                (1 << 0)
+#define ATAO_CFG3_REG          0x04
+#define ATAO_CFG3_DMAMODE      (1 << 6)
+#define ATAO_CFG3_CLKOUT       (1 << 5)
+#define ATAO_CFG3_RCLKEN       (1 << 4)
+#define ATAO_CFG3_DOUTEN2      (1 << 3)
+#define ATAO_CFG3_DOUTEN1      (1 << 2)
+#define ATAO_CFG3_EN2_5V       (1 << 1)
+#define ATAO_CFG3_SCANEN       (1 << 0)
+#define ATAO_82C53_BASE                0x06
+#define ATAO_CFG1_REG          0x0a
+#define ATAO_CFG1_EXTINT2EN    (1 << 15)
+#define ATAO_CFG1_EXTINT1EN    (1 << 14)
+#define ATAO_CFG1_CNTINT2EN    (1 << 13)
+#define ATAO_CFG1_CNTINT1EN    (1 << 12)
+#define ATAO_CFG1_TCINTEN      (1 << 11)
+#define ATAO_CFG1_CNT1SRC      (1 << 10)
+#define ATAO_CFG1_CNT2SRC      (1 << 9)
+#define ATAO_CFG1_FIFOEN       (1 << 8)
+#define ATAO_CFG1_GRP2WR       (1 << 7)
+#define ATAO_CFG1_EXTUPDEN     (1 << 6)
+#define ATAO_CFG1_DMARQ                (1 << 5)
+#define ATAO_CFG1_DMAEN                (1 << 4)
+#define ATAO_CFG1_CH(x)                (((x) & 0xf) << 0)
+#define ATAO_STATUS_REG                0x0a
+#define ATAO_STATUS_FH         (1 << 6)
+#define ATAO_STATUS_FE         (1 << 5)
+#define ATAO_STATUS_FF         (1 << 4)
+#define ATAO_STATUS_INT2       (1 << 3)
+#define ATAO_STATUS_INT1       (1 << 2)
+#define ATAO_STATUS_TCINT      (1 << 1)
+#define ATAO_STATUS_PROMOUT    (1 << 0)
+#define ATAO_FIFO_WRITE_REG    0x0c
+#define ATAO_FIFO_CLEAR_REG    0x0c
+#define ATAO_AO_REG(x)         (0x0c + ((x) * 2))
+
+/* registers with _2_ are accessed when GRP2WR is set in CFG1 */
+#define ATAO_2_DMATCCLR_REG    0x00
+#define ATAO_2_INT1CLR_REG     0x02
+#define ATAO_2_INT2CLR_REG     0x04
+#define ATAO_2_RTSISHFT_REG    0x06
+#define ATAO_2_RTSISHFT_RSI    (1 << 0)
+#define ATAO_2_RTSISTRB_REG    0x07
+
 struct atao_board {
        const char *name;
        int n_ao_chans;
 };
 
-struct atao_private {
+static const struct atao_board atao_boards[] = {
+       {
+               .name           = "at-ao-6",
+               .n_ao_chans     = 6,
+       }, {
+               .name           = "at-ao-10",
+               .n_ao_chans     = 10,
+       },
+};
 
+struct atao_private {
        unsigned short cfg1;
-       unsigned short cfg2;
        unsigned short cfg3;
 
        /* Used for AO readback */
        unsigned int ao_readback[10];
+
+       /* Used for caldac readback */
+       unsigned char caldac[21];
 };
 
-static void atao_reset(struct comedi_device *dev)
+static void atao_select_reg_group(struct comedi_device *dev, int group)
 {
        struct atao_private *devpriv = dev->private;
 
-       /* This is the reset sequence described in the manual */
-
-       devpriv->cfg1 = 0;
-       outw(devpriv->cfg1, dev->iobase + ATAO_CFG1);
-
-       outb(RWSEL0 | MODESEL2, dev->iobase + ATAO_82C53_CNTRCMD);
-       outb(0x03, dev->iobase + ATAO_82C53_CNTR1);
-       outb(CNTRSEL0 | RWSEL0 | MODESEL2, dev->iobase + ATAO_82C53_CNTRCMD);
-
-       devpriv->cfg2 = 0;
-       outw(devpriv->cfg2, dev->iobase + ATAO_CFG2);
-
-       devpriv->cfg3 = 0;
-       outw(devpriv->cfg3, dev->iobase + ATAO_CFG3);
-
-       inw(dev->iobase + ATAO_FIFO_CLEAR);
-
-       devpriv->cfg1 |= GRP2WR;
-       outw(devpriv->cfg1, dev->iobase + ATAO_CFG1);
-
-       outw(0, dev->iobase + ATAO_2_INT1CLR);
-       outw(0, dev->iobase + ATAO_2_INT2CLR);
-       outw(0, dev->iobase + ATAO_2_DMATCCLR);
-
-       devpriv->cfg1 &= ~GRP2WR;
-       outw(devpriv->cfg1, dev->iobase + ATAO_CFG1);
+       if (group)
+               devpriv->cfg1 |= ATAO_CFG1_GRP2WR;
+       else
+               devpriv->cfg1 &= ~ATAO_CFG1_GRP2WR;
+       outw(devpriv->cfg1, dev->iobase + ATAO_CFG1_REG);
 }
 
-static int atao_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
-                        struct comedi_insn *insn, unsigned int *data)
+static int atao_ao_insn_write(struct comedi_device *dev,
+                             struct comedi_subdevice *s,
+                             struct comedi_insn *insn,
+                             unsigned int *data)
 {
        struct atao_private *devpriv = dev->private;
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       unsigned int val;
        int i;
-       int chan = CR_CHAN(insn->chanspec);
-       short bits;
+
+       if (chan == 0)
+               atao_select_reg_group(dev, 1);
 
        for (i = 0; i < insn->n; i++) {
-               bits = data[i] - 0x800;
-               if (chan == 0) {
-                       devpriv->cfg1 |= GRP2WR;
-                       outw(devpriv->cfg1, dev->iobase + ATAO_CFG1);
-               }
-               outw(bits, dev->iobase + ATAO_DACn(chan));
-               if (chan == 0) {
-                       devpriv->cfg1 &= ~GRP2WR;
-                       outw(devpriv->cfg1, dev->iobase + ATAO_CFG1);
-               }
-               devpriv->ao_readback[chan] = data[i];
+               val = data[i];
+               devpriv->ao_readback[chan] = val;
+
+               /* munge offset binary (unsigned) to two's complement */
+               val = comedi_offset_munge(s, val);
+               outw(val, dev->iobase + ATAO_AO_REG(chan));
        }
 
-       return i;
+       if (chan == 0)
+               atao_select_reg_group(dev, 0);
+
+       return insn->n;
 }
 
-static int atao_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
-                        struct comedi_insn *insn, unsigned int *data)
+static int atao_ao_insn_read(struct comedi_device *dev,
+                            struct comedi_subdevice *s,
+                            struct comedi_insn *insn,
+                            unsigned int *data)
 {
        struct atao_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];
 
-       return i;
+       return insn->n;
 }
 
 static int atao_dio_insn_bits(struct comedi_device *dev,
@@ -237,9 +185,9 @@ static int atao_dio_insn_bits(struct comedi_device *dev,
                              unsigned int *data)
 {
        if (comedi_dio_update_state(s, data))
-               outw(s->state, dev->iobase + ATAO_DOUT);
+               outw(s->state, dev->iobase + ATAO_DIO_REG);
 
-       data[1] = inw(dev->iobase + ATAO_DIN);
+       data[1] = inw(dev->iobase + ATAO_DIO_REG);
 
        return insn->n;
 }
@@ -264,57 +212,128 @@ static int atao_dio_insn_config(struct comedi_device *dev,
                return ret;
 
        if (s->io_bits & 0x0f)
-               devpriv->cfg3 |= DOUTEN1;
+               devpriv->cfg3 |= ATAO_CFG3_DOUTEN1;
        else
-               devpriv->cfg3 &= ~DOUTEN1;
+               devpriv->cfg3 &= ~ATAO_CFG3_DOUTEN1;
        if (s->io_bits & 0xf0)
-               devpriv->cfg3 |= DOUTEN2;
+               devpriv->cfg3 |= ATAO_CFG3_DOUTEN2;
        else
-               devpriv->cfg3 &= ~DOUTEN2;
+               devpriv->cfg3 &= ~ATAO_CFG3_DOUTEN2;
 
-       outw(devpriv->cfg3, dev->iobase + ATAO_CFG3);
+       outw(devpriv->cfg3, dev->iobase + ATAO_CFG3_REG);
 
        return insn->n;
 }
 
 /*
- * Figure 2-1 in the manual shows 3 chips labeled DAC8800, which
- * are 8-channel 8-bit DACs.  These are most likely the calibration
- * DACs.  It is not explicitly stated in the manual how to access
- * the caldacs, but we can guess.
+ * There are three DAC8800 TrimDACs on the board. These are 8-channel,
+ * 8-bit DACs that are used to calibrate the Analog Output channels.
+ * The factory default calibration values are stored in the EEPROM.
+ * The TrimDACs, and EEPROM addresses, are mapped as:
+ *
+ *        Channel       EEPROM  Description
+ *   -----------------  ------  -----------------------------------
+ *    0 - DAC0 Chan 0    0x30   AO Channel 0 Offset
+ *    1 - DAC0 Chan 1    0x31   AO Channel 0 Gain
+ *    2 - DAC0 Chan 2    0x32   AO Channel 1 Offset
+ *    3 - DAC0 Chan 3    0x33   AO Channel 1 Gain
+ *    4 - DAC0 Chan 4    0x34   AO Channel 2 Offset
+ *    5 - DAC0 Chan 5    0x35   AO Channel 2 Gain
+ *    6 - DAC0 Chan 6    0x36   AO Channel 3 Offset
+ *    7 - DAC0 Chan 7    0x37   AO Channel 3 Gain
+ *    8 - DAC1 Chan 0    0x38   AO Channel 4 Offset
+ *    9 - DAC1 Chan 1    0x39   AO Channel 4 Gain
+ *   10 - DAC1 Chan 2    0x3a   AO Channel 5 Offset
+ *   11 - DAC1 Chan 3    0x3b   AO Channel 5 Gain
+ *   12 - DAC1 Chan 4    0x3c   2.5V Offset
+ *   13 - DAC1 Chan 5    0x3d   AO Channel 6 Offset (at-ao-10 only)
+ *   14 - DAC1 Chan 6    0x3e   AO Channel 6 Gain   (at-ao-10 only)
+ *   15 - DAC1 Chan 7    0x3f   AO Channel 7 Offset (at-ao-10 only)
+ *   16 - DAC2 Chan 0    0x40   AO Channel 7 Gain   (at-ao-10 only)
+ *   17 - DAC2 Chan 1    0x41   AO Channel 8 Offset (at-ao-10 only)
+ *   18 - DAC2 Chan 2    0x42   AO Channel 8 Gain   (at-ao-10 only)
+ *   19 - DAC2 Chan 3    0x43   AO Channel 9 Offset (at-ao-10 only)
+ *   20 - DAC2 Chan 4    0x44   AO Channel 9 Gain   (at-ao-10 only)
+ *        DAC2 Chan 5    0x45   Reserved
+ *        DAC2 Chan 6    0x46   Reserved
+ *        DAC2 Chan 7    0x47   Reserved
  */
+static int atao_calib_insn_write(struct comedi_device *dev,
+                                struct comedi_subdevice *s,
+                                struct comedi_insn *insn,
+                                unsigned int *data)
+{
+       struct atao_private *devpriv = dev->private;
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       unsigned int bitstring;
+       unsigned int val;
+       int bit;
+
+       if (insn->n == 0)
+               return 0;
+
+       devpriv->caldac[chan] = data[insn->n - 1] & s->maxdata;
+
+       /* write the channel and last data value to the caldac */
+       bitstring = ((chan & 0x7) << 8) | devpriv->caldac[chan];
+
+       /* clock the bitstring to the caldac; MSB -> LSB */
+       for (bit = 1 << 10; bit; bit >>= 1) {
+               val = (bit & bitstring) ? ATAO_CFG2_SDATA : 0;
+
+               outw(val, dev->iobase + ATAO_CFG2_REG);
+               outw(val | ATAO_CFG2_SCLK, dev->iobase + ATAO_CFG2_REG);
+       }
+
+       /* strobe the caldac to load the value */
+       outw(ATAO_CFG2_CALLD(chan), dev->iobase + ATAO_CFG2_REG);
+       outw(ATAO_CFG2_CALLD_NOP, dev->iobase + ATAO_CFG2_REG);
+
+       return insn->n;
+}
+
 static int atao_calib_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 atao_private *devpriv = dev->private;
+       unsigned int chan = CR_CHAN(insn->chanspec);
        int i;
+
        for (i = 0; i < insn->n; i++)
-               data[i] = 0;    /* XXX */
+               data[i] = devpriv->caldac[chan];
+
        return insn->n;
 }
 
-static int atao_calib_insn_write(struct comedi_device *dev,
-                                struct comedi_subdevice *s,
-                                struct comedi_insn *insn, unsigned int *data)
+static void atao_reset(struct comedi_device *dev)
 {
        struct atao_private *devpriv = dev->private;
-       unsigned int bitstring, bit;
-       unsigned int chan = CR_CHAN(insn->chanspec);
 
-       bitstring = ((chan & 0x7) << 8) | (data[insn->n - 1] & 0xff);
+       /* This is the reset sequence described in the manual */
 
-       for (bit = 1 << (11 - 1); bit; bit >>= 1) {
-               outw(devpriv->cfg2 | ((bit & bitstring) ? SDATA : 0),
-                    dev->iobase + ATAO_CFG2);
-               outw(devpriv->cfg2 | SCLK | ((bit & bitstring) ? SDATA : 0),
-                    dev->iobase + ATAO_CFG2);
-       }
-       /* strobe the appropriate caldac */
-       outw(devpriv->cfg2 | (((chan >> 3) + 1) << 14),
-            dev->iobase + ATAO_CFG2);
-       outw(devpriv->cfg2, dev->iobase + ATAO_CFG2);
+       devpriv->cfg1 = 0;
+       outw(devpriv->cfg1, dev->iobase + ATAO_CFG1_REG);
 
-       return insn->n;
+       /* Put outputs of counter 1 and counter 2 in a high state */
+       i8254_load(dev->iobase + ATAO_82C53_BASE, 0,
+                  0, 0x0003, I8254_MODE4 | I8254_BINARY);
+       i8254_set_mode(dev->iobase + ATAO_82C53_BASE, 0,
+                  1, I8254_MODE4 | I8254_BINARY);
+
+       outw(ATAO_CFG2_CALLD_NOP, dev->iobase + ATAO_CFG2_REG);
+
+       devpriv->cfg3 = 0;
+       outw(devpriv->cfg3, dev->iobase + ATAO_CFG3_REG);
+
+       inw(dev->iobase + ATAO_FIFO_CLEAR_REG);
+
+       atao_select_reg_group(dev, 1);
+       outw(0, dev->iobase + ATAO_2_INT1CLR_REG);
+       outw(0, dev->iobase + ATAO_2_INT2CLR_REG);
+       outw(0, dev->iobase + ATAO_2_DMATCCLR_REG);
+       atao_select_reg_group(dev, 0);
 }
 
 static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it)
@@ -322,12 +341,9 @@ static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it)
        const struct atao_board *board = comedi_board(dev);
        struct atao_private *devpriv;
        struct comedi_subdevice *s;
-       int ao_unipolar;
        int ret;
 
-       ao_unipolar = it->options[3];
-
-       ret = comedi_request_region(dev, it->options[0], ATAO_SIZE);
+       ret = comedi_request_region(dev, it->options[0], 0x20);
        if (ret)
                return ret;
 
@@ -339,60 +355,44 @@ static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it)
        if (ret)
                return ret;
 
+       /* Analog Output subdevice */
        s = &dev->subdevices[0];
-       /* analog output subdevice */
-       s->type = COMEDI_SUBD_AO;
-       s->subdev_flags = SDF_WRITABLE;
-       s->n_chan = board->n_ao_chans;
-       s->maxdata = (1 << 12) - 1;
-       if (ao_unipolar)
-               s->range_table = &range_unipolar10;
-       else
-               s->range_table = &range_bipolar10;
-       s->insn_write = &atao_ao_winsn;
-       s->insn_read = &atao_ao_rinsn;
-
+       s->type         = COMEDI_SUBD_AO;
+       s->subdev_flags = SDF_WRITABLE;
+       s->n_chan       = board->n_ao_chans;
+       s->maxdata      = 0x0fff;
+       s->range_table  = it->options[3] ? &range_unipolar10 : &range_bipolar10;
+       s->insn_write   = atao_ao_insn_write;
+       s->insn_read    = atao_ao_insn_read;
+
+       /* Digital I/O subdevice */
        s = &dev->subdevices[1];
-       /* digital i/o subdevice */
-       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 = atao_dio_insn_bits;
-       s->insn_config = atao_dio_insn_config;
+       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    = atao_dio_insn_bits;
+       s->insn_config  = atao_dio_insn_config;
 
-       s = &dev->subdevices[2];
        /* caldac subdevice */
-       s->type = COMEDI_SUBD_CALIB;
-       s->subdev_flags = SDF_WRITABLE | SDF_INTERNAL;
-       s->n_chan = 21;
-       s->maxdata = 0xff;
-       s->insn_read = atao_calib_insn_read;
-       s->insn_write = atao_calib_insn_write;
-
+       s = &dev->subdevices[2];
+       s->type         = COMEDI_SUBD_CALIB;
+       s->subdev_flags = SDF_WRITABLE | SDF_INTERNAL;
+       s->n_chan       = (board->n_ao_chans * 2) + 1;
+       s->maxdata      = 0xff;
+       s->insn_read    = atao_calib_insn_read;
+       s->insn_write   = atao_calib_insn_write;
+
+       /* EEPROM subdevice */
        s = &dev->subdevices[3];
-       /* eeprom subdevice */
-       /* s->type=COMEDI_SUBD_EEPROM; */
-       s->type = COMEDI_SUBD_UNUSED;
+       s->type         = COMEDI_SUBD_UNUSED;
 
        atao_reset(dev);
 
-       printk(KERN_INFO "\n");
-
        return 0;
 }
 
-static const struct atao_board atao_boards[] = {
-       {
-               .name           = "ai-ao-6",
-               .n_ao_chans     = 6,
-       }, {
-               .name           = "ai-ao-10",
-               .n_ao_chans     = 10,
-       },
-};
-
 static struct comedi_driver ni_at_ao_driver = {
        .driver_name    = "ni_at_ao",
        .module         = THIS_MODULE,
@@ -405,5 +405,5 @@ static struct comedi_driver ni_at_ao_driver = {
 module_comedi_driver(ni_at_ao_driver);
 
 MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_DESCRIPTION("Comedi driver for NI AT-AO-6/10 boards");
 MODULE_LICENSE("GPL");
index c398193e9b85c81a8bafb0464f3e16bcbde41588..4271fa38a46c563641ef2c7b01e5c7ab14be8bcb 100644 (file)
@@ -487,7 +487,7 @@ static int dgnc_found_board(struct pci_dev *pdev, int id)
 
        /* get the board structure and prep it */
        brd = dgnc_Board[dgnc_NumBoards] =
-               kzalloc(sizeof(struct dgnc_board), GFP_KERNEL);
+               kzalloc(sizeof(*brd), GFP_KERNEL);
        if (!brd) {
                APR(("memory allocation for board structure failed\n"));
                return -ENOMEM;
@@ -495,7 +495,7 @@ static int dgnc_found_board(struct pci_dev *pdev, int id)
 
        /* make a temporary message buffer for the boot messages */
        brd->msgbuf = brd->msgbuf_head =
-               kzalloc(sizeof(char) * 8192, GFP_KERNEL);
+               kzalloc(sizeof(u8) * 8192, GFP_KERNEL);
        if (!brd->msgbuf) {
                kfree(brd);
                APR(("memory allocation for board msgbuf failed\n"));
index bb39f5dfa0431cca78ab881fffe881bd91749d6e..354458c5068eb4bcc36792e6023da1682b9d0659 100644 (file)
@@ -209,7 +209,7 @@ long dgnc_mgmt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                uint board = 0;
                uint channel = 0;
 
-               if (copy_from_user(&ni, uarg, sizeof(struct ni_info))) {
+               if (copy_from_user(&ni, uarg, sizeof(ni))) {
                        return -EFAULT;
                }
 
index 1350d62665248f90442157dcca621627df0ab865..c6fee11632f7d7433e8246975dceab598df6126d 100644 (file)
@@ -200,8 +200,8 @@ int dgnc_tty_register(struct dgnc_board *brd)
 
        DPR_INIT(("tty_register start\n"));
 
-       memset(&brd->SerialDriver, 0, sizeof(struct tty_driver));
-       memset(&brd->PrintDriver, 0, sizeof(struct tty_driver));
+       memset(&brd->SerialDriver, 0, sizeof(brd->SerialDriver));
+       memset(&brd->PrintDriver, 0, sizeof(brd->PrintDriver));
 
        brd->SerialDriver.magic = TTY_DRIVER_MAGIC;
 
@@ -222,12 +222,12 @@ int dgnc_tty_register(struct dgnc_board *brd)
         * The kernel wants space to store pointers to
         * tty_struct's and termios's.
         */
-       brd->SerialDriver.ttys = kzalloc(brd->maxports * sizeof(struct tty_struct *), GFP_KERNEL);
+       brd->SerialDriver.ttys = kzalloc(brd->maxports * sizeof(*brd->SerialDriver.ttys), GFP_KERNEL);
        if (!brd->SerialDriver.ttys)
                return -ENOMEM;
 
        kref_init(&brd->SerialDriver.kref);
-       brd->SerialDriver.termios = kzalloc(brd->maxports * sizeof(struct ktermios *), GFP_KERNEL);
+       brd->SerialDriver.termios = kzalloc(brd->maxports * sizeof(*brd->SerialDriver.termios), GFP_KERNEL);
        if (!brd->SerialDriver.termios)
                return -ENOMEM;
 
@@ -271,11 +271,11 @@ int dgnc_tty_register(struct dgnc_board *brd)
         * tty_struct's and termios's.  Must be separated from
         * the Serial Driver so we don't get confused
         */
-       brd->PrintDriver.ttys = kzalloc(brd->maxports * sizeof(struct tty_struct *), GFP_KERNEL);
+       brd->PrintDriver.ttys = kzalloc(brd->maxports * sizeof(*brd->PrintDriver.ttys), GFP_KERNEL);
        if (!brd->PrintDriver.ttys)
                return -ENOMEM;
        kref_init(&brd->PrintDriver.kref);
-       brd->PrintDriver.termios = kzalloc(brd->maxports * sizeof(struct ktermios *), GFP_KERNEL);
+       brd->PrintDriver.termios = kzalloc(brd->maxports * sizeof(*brd->PrintDriver.termios), GFP_KERNEL);
        if (!brd->PrintDriver.termios)
                return -ENOMEM;
 
@@ -341,7 +341,7 @@ int dgnc_tty_init(struct dgnc_board *brd)
                         * Okay to malloc with GFP_KERNEL, we are not at
                         * interrupt context, and there are no locks held.
                         */
-                       brd->channels[i] = kzalloc(sizeof(struct channel_t), GFP_KERNEL);
+                       brd->channels[i] = kzalloc(sizeof(*brd->channels[i]), GFP_KERNEL);
                        if (!brd->channels[i]) {
                                DPR_CORE(("%s:%d Unable to allocate memory for channel struct\n",
                                    __FILE__, __LINE__));
@@ -2664,7 +2664,7 @@ static int dgnc_tty_digiseta(struct tty_struct *tty, struct digi_t __user *new_i
        if (!bd || bd->magic != DGNC_BOARD_MAGIC)
                return -EFAULT;
 
-       if (copy_from_user(&new_digi, new_info, sizeof(struct digi_t))) {
+       if (copy_from_user(&new_digi, new_info, sizeof(new_digi))) {
                DPR_IOCTL(("DIGI_SETA failed copy_from_user\n"));
                return -EFAULT;
        }
@@ -2687,7 +2687,7 @@ static int dgnc_tty_digiseta(struct tty_struct *tty, struct digi_t __user *new_i
        if ((ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE) && !(new_digi.digi_flags & DIGI_DTR_TOGGLE))
                ch->ch_mostat |= (UART_MCR_DTR);
 
-       memcpy(&ch->ch_digi, &new_digi, sizeof(struct digi_t));
+       memcpy(&ch->ch_digi, &new_digi, sizeof(new_digi));
 
        if (ch->ch_digi.digi_maxcps < 1)
                ch->ch_digi.digi_maxcps = 1;
@@ -3369,7 +3369,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
 
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
 
-               if (copy_to_user(uarg, &buf, sizeof(struct digi_getcounter))) {
+               if (copy_to_user(uarg, &buf, sizeof(buf))) {
                        return -EFAULT;
                }
                return 0;
@@ -3417,7 +3417,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                /*
                 * Get data from user first.
                 */
-               if (copy_from_user(&buf, uarg, sizeof(struct digi_getbuffer))) {
+               if (copy_from_user(&buf, uarg, sizeof(buf))) {
                        return -EFAULT;
                }
 
@@ -3463,7 +3463,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
 
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
 
-               if (copy_to_user(uarg, &buf, sizeof(struct digi_getbuffer))) {
+               if (copy_to_user(uarg, &buf, sizeof(buf))) {
                        return -EFAULT;
                }
                return 0;
index f7ba34b7071cc7e344e44f86240b779a96bf1a33..fab718d9b326344860ed6af876a9a2e840893bb1 100644 (file)
@@ -294,7 +294,7 @@ struct dwc2_hw_params {
        unsigned dev_token_q_depth:5;
        unsigned max_transfer_size:26;
        unsigned max_packet_count:11;
-       unsigned host_channels:4;
+       unsigned host_channels:5;
        unsigned hs_phy_type:2;
        unsigned fs_phy_type:2;
        unsigned i2c_enable:1;
index 96c29ad2fc8c5cd2992e766cba674bd4981fba06..7e3e0967993b5f6fecc7bfa965ef9a444cd0037f 100644 (file)
@@ -202,11 +202,8 @@ static inline int ll_get_user_pages(int rw, unsigned long user_addr,
 
        OBD_ALLOC_LARGE(*pages, *max_pages * sizeof(**pages));
        if (*pages) {
-               down_read(&current->mm->mmap_sem);
-               result = get_user_pages(current, current->mm, user_addr,
-                                       *max_pages, (rw == READ), 0, *pages,
-                                       NULL);
-               up_read(&current->mm->mmap_sem);
+               result = get_user_pages_fast(user_addr, *max_pages,
+                                            (rw == READ), *pages);
                if (unlikely(result <= 0))
                        OBD_FREE_LARGE(*pages, *max_pages * sizeof(**pages));
        }
diff --git a/drivers/staging/mt29f_spinand/Kconfig b/drivers/staging/mt29f_spinand/Kconfig
new file mode 100644 (file)
index 0000000..4031748
--- /dev/null
@@ -0,0 +1,16 @@
+config MTD_SPINAND_MT29F
+       tristate "SPINAND Device Support for Micron"
+       depends on MTD_NAND && SPI
+       help
+         This enables support for accessing Micron SPI NAND flash
+         devices.
+         If you have Micron SPI NAND chip say yes.
+
+         If unsure, say no here.
+
+config MTD_SPINAND_ONDIEECC
+       bool "Use SPINAND internal ECC"
+       depends on MTD_SPINAND_MT29F
+       help
+         Internel ECC.
+         Enables Hardware ECC support for Micron SPI NAND.
diff --git a/drivers/staging/mt29f_spinand/Makefile b/drivers/staging/mt29f_spinand/Makefile
new file mode 100644 (file)
index 0000000..e47af0f
--- /dev/null
@@ -0,0 +1 @@
+obj-$(CONFIG_MTD_SPINAND_MT29F) += mt29f_spinand.o
diff --git a/drivers/staging/mt29f_spinand/TODO b/drivers/staging/mt29f_spinand/TODO
new file mode 100644 (file)
index 0000000..a2209b7
--- /dev/null
@@ -0,0 +1,13 @@
+TODO:
+       - Tested on XLP platform, needs to be tested on other platforms.
+       - Checkpatch.pl cleanups
+       - Sparce fixes.
+       - Clean up coding style to meet kernel standard.
+
+Please send patches
+To:
+Kamlakant Patel <kamlakant.patel@broadcom.com>
+Cc:
+Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Mona Anonuevo <manonuevo@micron.com>
+linux-mtd@lists.infradead.org
diff --git a/drivers/staging/mt29f_spinand/mt29f_spinand.c b/drivers/staging/mt29f_spinand/mt29f_spinand.c
new file mode 100644 (file)
index 0000000..8e95a57
--- /dev/null
@@ -0,0 +1,962 @@
+/*
+ * Copyright (c) 2003-2013 Broadcom Corporation
+ *
+ * Copyright (c) 2009-2010 Micron Technology, 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 <linux/module.h>
+#include <linux/delay.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand.h>
+#include <linux/spi/spi.h>
+
+#include "mt29f_spinand.h"
+
+#define BUFSIZE (10 * 64 * 2048)
+#define CACHE_BUF 2112
+/*
+ * OOB area specification layout:  Total 32 available free bytes.
+ */
+#ifdef CONFIG_MTD_SPINAND_ONDIEECC
+static int enable_hw_ecc;
+static int enable_read_hw_ecc;
+
+static inline struct spinand_state *mtd_to_state(struct mtd_info *mtd)
+{
+       struct nand_chip *chip = (struct nand_chip *)mtd->priv;
+       struct spinand_info *info = (struct spinand_info *)chip->priv;
+       struct spinand_state *state = (struct spinand_state *)info->priv;
+
+       return state;
+}
+
+static struct nand_ecclayout spinand_oob_64 = {
+       .eccbytes = 24,
+       .eccpos = {
+               1, 2, 3, 4, 5, 6,
+               17, 18, 19, 20, 21, 22,
+               33, 34, 35, 36, 37, 38,
+               49, 50, 51, 52, 53, 54, },
+       .oobavail = 32,
+       .oobfree = {
+               {.offset = 8,
+                       .length = 8},
+               {.offset = 24,
+                       .length = 8},
+               {.offset = 40,
+                       .length = 8},
+               {.offset = 56,
+                       .length = 8},
+       }
+};
+#endif
+
+/*
+ * spinand_cmd - to process a command to send to the SPI Nand
+ * Description:
+ *    Set up the command buffer to send to the SPI controller.
+ *    The command buffer has to initialized to 0.
+ */
+
+static int spinand_cmd(struct spi_device *spi, struct spinand_cmd *cmd)
+{
+       struct spi_message message;
+       struct spi_transfer x[4];
+       u8 dummy = 0xff;
+
+       spi_message_init(&message);
+       memset(x, 0, sizeof(x));
+
+       x[0].len = 1;
+       x[0].tx_buf = &cmd->cmd;
+       spi_message_add_tail(&x[0], &message);
+
+       if (cmd->n_addr) {
+               x[1].len = cmd->n_addr;
+               x[1].tx_buf = cmd->addr;
+               spi_message_add_tail(&x[1], &message);
+       }
+
+       if (cmd->n_dummy) {
+               x[2].len = cmd->n_dummy;
+               x[2].tx_buf = &dummy;
+               spi_message_add_tail(&x[2], &message);
+       }
+
+       if (cmd->n_tx) {
+               x[3].len = cmd->n_tx;
+               x[3].tx_buf = cmd->tx_buf;
+               spi_message_add_tail(&x[3], &message);
+       }
+
+       if (cmd->n_rx) {
+               x[3].len = cmd->n_rx;
+               x[3].rx_buf = cmd->rx_buf;
+               spi_message_add_tail(&x[3], &message);
+       }
+
+       return spi_sync(spi, &message);
+}
+
+/*
+ * spinand_read_id- Read SPI Nand ID
+ * Description:
+ *    Read ID: read two ID bytes from the SPI Nand device
+ */
+static int spinand_read_id(struct spi_device *spi_nand, u8 *id)
+{
+       int retval;
+       u8 nand_id[3];
+       struct spinand_cmd cmd = {0};
+
+       cmd.cmd = CMD_READ_ID;
+       cmd.n_rx = 3;
+       cmd.rx_buf = &nand_id[0];
+
+       retval = spinand_cmd(spi_nand, &cmd);
+       if (retval < 0) {
+               dev_err(&spi_nand->dev, "error %d reading id\n", retval);
+               return retval;
+       }
+       id[0] = nand_id[1];
+       id[1] = nand_id[2];
+       return retval;
+}
+
+/*
+ * spinand_read_status- send command 0xf to the SPI Nand status register
+ * Description:
+ *    After read, write, or erase, the Nand device is expected to set the
+ *    busy status.
+ *    This function is to allow reading the status of the command: read,
+ *    write, and erase.
+ *    Once the status turns to be ready, the other status bits also are
+ *    valid status bits.
+ */
+static int spinand_read_status(struct spi_device *spi_nand, uint8_t *status)
+{
+       struct spinand_cmd cmd = {0};
+       int ret;
+
+       cmd.cmd = CMD_READ_REG;
+       cmd.n_addr = 1;
+       cmd.addr[0] = REG_STATUS;
+       cmd.n_rx = 1;
+       cmd.rx_buf = status;
+
+       ret = spinand_cmd(spi_nand, &cmd);
+       if (ret < 0)
+               dev_err(&spi_nand->dev, "err: %d read status register\n", ret);
+
+       return ret;
+}
+
+#define MAX_WAIT_JIFFIES  (40 * HZ)
+static int wait_till_ready(struct spi_device *spi_nand)
+{
+       unsigned long deadline;
+       int retval;
+       u8 stat = 0;
+
+       deadline = jiffies + MAX_WAIT_JIFFIES;
+       do {
+               retval = spinand_read_status(spi_nand, &stat);
+               if (retval < 0)
+                       return -1;
+               else if (!(stat & 0x1))
+                       break;
+
+               cond_resched();
+       } while (!time_after_eq(jiffies, deadline));
+
+       if ((stat & 0x1) == 0)
+               return 0;
+
+       return -1;
+}
+/**
+ * spinand_get_otp- send command 0xf to read the SPI Nand OTP register
+ * Description:
+ *   There is one bit( bit 0x10 ) to set or to clear the internal ECC.
+ *   Enable chip internal ECC, set the bit to 1
+ *   Disable chip internal ECC, clear the bit to 0
+ */
+static int spinand_get_otp(struct spi_device *spi_nand, u8 *otp)
+{
+       struct spinand_cmd cmd = {0};
+       int retval;
+
+       cmd.cmd = CMD_READ_REG;
+       cmd.n_addr = 1;
+       cmd.addr[0] = REG_OTP;
+       cmd.n_rx = 1;
+       cmd.rx_buf = otp;
+
+       retval = spinand_cmd(spi_nand, &cmd);
+       if (retval < 0)
+               dev_err(&spi_nand->dev, "error %d get otp\n", retval);
+       return retval;
+}
+
+/**
+ * spinand_set_otp- send command 0x1f to write the SPI Nand OTP register
+ * Description:
+ *   There is one bit( bit 0x10 ) to set or to clear the internal ECC.
+ *   Enable chip internal ECC, set the bit to 1
+ *   Disable chip internal ECC, clear the bit to 0
+ */
+static int spinand_set_otp(struct spi_device *spi_nand, u8 *otp)
+{
+       int retval;
+       struct spinand_cmd cmd = {0};
+
+       cmd.cmd = CMD_WRITE_REG,
+       cmd.n_addr = 1,
+       cmd.addr[0] = REG_OTP,
+       cmd.n_tx = 1,
+       cmd.tx_buf = otp,
+
+       retval = spinand_cmd(spi_nand, &cmd);
+       if (retval < 0)
+               dev_err(&spi_nand->dev, "error %d set otp\n", retval);
+
+       return retval;
+}
+
+#ifdef CONFIG_MTD_SPINAND_ONDIEECC
+/**
+ * spinand_enable_ecc- send command 0x1f to write the SPI Nand OTP register
+ * Description:
+ *   There is one bit( bit 0x10 ) to set or to clear the internal ECC.
+ *   Enable chip internal ECC, set the bit to 1
+ *   Disable chip internal ECC, clear the bit to 0
+ */
+static int spinand_enable_ecc(struct spi_device *spi_nand)
+{
+       int retval;
+       u8 otp = 0;
+
+       retval = spinand_get_otp(spi_nand, &otp);
+       if (retval < 0)
+               return retval;
+
+       if ((otp & OTP_ECC_MASK) == OTP_ECC_MASK) {
+               return 0;
+       } else {
+               otp |= OTP_ECC_MASK;
+               retval = spinand_set_otp(spi_nand, &otp);
+               if (retval < 0)
+                       return retval;
+               return spinand_get_otp(spi_nand, &otp);
+       }
+}
+#endif
+
+static int spinand_disable_ecc(struct spi_device *spi_nand)
+{
+       int retval;
+       u8 otp = 0;
+
+       retval = spinand_get_otp(spi_nand, &otp);
+       if (retval < 0)
+               return retval;
+
+       if ((otp & OTP_ECC_MASK) == OTP_ECC_MASK) {
+               otp &= ~OTP_ECC_MASK;
+               retval = spinand_set_otp(spi_nand, &otp);
+               if (retval < 0)
+                       return retval;
+               return spinand_get_otp(spi_nand, &otp);
+       } else
+               return 0;
+}
+
+/**
+ * spinand_write_enable- send command 0x06 to enable write or erase the
+ * Nand cells
+ * Description:
+ *   Before write and erase the Nand cells, the write enable has to be set.
+ *   After the write or erase, the write enable bit is automatically
+ *   cleared (status register bit 2)
+ *   Set the bit 2 of the status register has the same effect
+ */
+static int spinand_write_enable(struct spi_device *spi_nand)
+{
+       struct spinand_cmd cmd = {0};
+
+       cmd.cmd = CMD_WR_ENABLE;
+       return spinand_cmd(spi_nand, &cmd);
+}
+
+static int spinand_read_page_to_cache(struct spi_device *spi_nand, u16 page_id)
+{
+       struct spinand_cmd cmd = {0};
+       u16 row;
+
+       row = page_id;
+       cmd.cmd = CMD_READ;
+       cmd.n_addr = 3;
+       cmd.addr[1] = (u8)((row & 0xff00) >> 8);
+       cmd.addr[2] = (u8)(row & 0x00ff);
+
+       return spinand_cmd(spi_nand, &cmd);
+}
+
+/*
+ * spinand_read_from_cache- send command 0x03 to read out the data from the
+ * cache register(2112 bytes max)
+ * Description:
+ *   The read can specify 1 to 2112 bytes of data read at the corresponding
+ *   locations.
+ *   No tRd delay.
+ */
+static int spinand_read_from_cache(struct spi_device *spi_nand, u16 page_id,
+               u16 byte_id, u16 len, u8 *rbuf)
+{
+       struct spinand_cmd cmd = {0};
+       u16 column;
+
+       column = byte_id;
+       cmd.cmd = CMD_READ_RDM;
+       cmd.n_addr = 3;
+       cmd.addr[0] = (u8)((column & 0xff00) >> 8);
+       cmd.addr[0] |= (u8)(((page_id >> 6) & 0x1) << 4);
+       cmd.addr[1] = (u8)(column & 0x00ff);
+       cmd.addr[2] = (u8)(0xff);
+       cmd.n_dummy = 0;
+       cmd.n_rx = len;
+       cmd.rx_buf = rbuf;
+
+       return spinand_cmd(spi_nand, &cmd);
+}
+
+/*
+ * spinand_read_page-to read a page with:
+ * @page_id: the physical page number
+ * @offset:  the location from 0 to 2111
+ * @len:     number of bytes to read
+ * @rbuf:    read buffer to hold @len bytes
+ *
+ * Description:
+ *   The read includes two commands to the Nand: 0x13 and 0x03 commands
+ *   Poll to read status to wait for tRD time.
+ */
+static int spinand_read_page(struct spi_device *spi_nand, u16 page_id,
+               u16 offset, u16 len, u8 *rbuf)
+{
+       int ret;
+       u8 status = 0;
+
+#ifdef CONFIG_MTD_SPINAND_ONDIEECC
+       if (enable_read_hw_ecc) {
+               if (spinand_enable_ecc(spi_nand) < 0)
+                       dev_err(&spi_nand->dev, "enable HW ECC failed!");
+       }
+#endif
+       ret = spinand_read_page_to_cache(spi_nand, page_id);
+       if (ret < 0)
+               return ret;
+
+       if (wait_till_ready(spi_nand))
+               dev_err(&spi_nand->dev, "WAIT timedout!!!\n");
+
+       while (1) {
+               ret = spinand_read_status(spi_nand, &status);
+               if (ret < 0) {
+                       dev_err(&spi_nand->dev,
+                                       "err %d read status register\n", ret);
+                       return ret;
+               }
+
+               if ((status & STATUS_OIP_MASK) == STATUS_READY) {
+                       if ((status & STATUS_ECC_MASK) == STATUS_ECC_ERROR) {
+                               dev_err(&spi_nand->dev, "ecc error, page=%d\n",
+                                               page_id);
+                               return 0;
+                       }
+                       break;
+               }
+       }
+
+       ret = spinand_read_from_cache(spi_nand, page_id, offset, len, rbuf);
+       if (ret < 0) {
+               dev_err(&spi_nand->dev, "read from cache failed!!\n");
+               return ret;
+       }
+
+#ifdef CONFIG_MTD_SPINAND_ONDIEECC
+       if (enable_read_hw_ecc) {
+               ret = spinand_disable_ecc(spi_nand);
+               if (ret < 0) {
+                       dev_err(&spi_nand->dev, "disable ecc failed!!\n");
+                       return ret;
+               }
+               enable_read_hw_ecc = 0;
+       }
+#endif
+       return ret;
+}
+
+/*
+ * spinand_program_data_to_cache--to write a page to cache with:
+ * @byte_id: the location to write to the cache
+ * @len:     number of bytes to write
+ * @rbuf:    read buffer to hold @len bytes
+ *
+ * Description:
+ *   The write command used here is 0x84--indicating that the cache is
+ *   not cleared first.
+ *   Since it is writing the data to cache, there is no tPROG time.
+ */
+static int spinand_program_data_to_cache(struct spi_device *spi_nand,
+               u16 page_id, u16 byte_id, u16 len, u8 *wbuf)
+{
+       struct spinand_cmd cmd = {0};
+       u16 column;
+
+       column = byte_id;
+       cmd.cmd = CMD_PROG_PAGE_CLRCACHE;
+       cmd.n_addr = 2;
+       cmd.addr[0] = (u8)((column & 0xff00) >> 8);
+       cmd.addr[0] |= (u8)(((page_id >> 6) & 0x1) << 4);
+       cmd.addr[1] = (u8)(column & 0x00ff);
+       cmd.n_tx = len;
+       cmd.tx_buf = wbuf;
+
+       return spinand_cmd(spi_nand, &cmd);
+}
+
+/**
+ * spinand_program_execute--to write a page from cache to the Nand array with
+ * @page_id: the physical page location to write the page.
+ *
+ * Description:
+ *   The write command used here is 0x10--indicating the cache is writing to
+ *   the Nand array.
+ *   Need to wait for tPROG time to finish the transaction.
+ */
+static int spinand_program_execute(struct spi_device *spi_nand, u16 page_id)
+{
+       struct spinand_cmd cmd = {0};
+       u16 row;
+
+       row = page_id;
+       cmd.cmd = CMD_PROG_PAGE_EXC;
+       cmd.n_addr = 3;
+       cmd.addr[1] = (u8)((row & 0xff00) >> 8);
+       cmd.addr[2] = (u8)(row & 0x00ff);
+
+       return spinand_cmd(spi_nand, &cmd);
+}
+
+/**
+ * spinand_program_page--to write a page with:
+ * @page_id: the physical page location to write the page.
+ * @offset:  the location from the cache starting from 0 to 2111
+ * @len:     the number of bytes to write
+ * @wbuf:    the buffer to hold the number of bytes
+ *
+ * Description:
+ *   The commands used here are 0x06, 0x84, and 0x10--indicating that
+ *   the write enable is first sent, the write cache command, and the
+ *   write execute command.
+ *   Poll to wait for the tPROG time to finish the transaction.
+ */
+static int spinand_program_page(struct spi_device *spi_nand,
+               u16 page_id, u16 offset, u16 len, u8 *buf)
+{
+       int retval;
+       u8 status = 0;
+       uint8_t *wbuf;
+#ifdef CONFIG_MTD_SPINAND_ONDIEECC
+       unsigned int i, j;
+
+       enable_read_hw_ecc = 0;
+       wbuf = devm_kzalloc(&spi_nand->dev, CACHE_BUF, GFP_KERNEL);
+       spinand_read_page(spi_nand, page_id, 0, CACHE_BUF, wbuf);
+
+       for (i = offset, j = 0; i < len; i++, j++)
+               wbuf[i] &= buf[j];
+
+       if (enable_hw_ecc) {
+               retval = spinand_enable_ecc(spi_nand);
+               if (retval < 0) {
+                       dev_err(&spi_nand->dev, "enable ecc failed!!\n");
+                       return retval;
+               }
+       }
+#else
+       wbuf = buf;
+#endif
+       retval = spinand_write_enable(spi_nand);
+       if (retval < 0) {
+               dev_err(&spi_nand->dev, "write enable failed!!\n");
+               return retval;
+       }
+       if (wait_till_ready(spi_nand))
+               dev_err(&spi_nand->dev, "wait timedout!!!\n");
+
+       retval = spinand_program_data_to_cache(spi_nand, page_id,
+                       offset, len, wbuf);
+       if (retval < 0)
+               return retval;
+       retval = spinand_program_execute(spi_nand, page_id);
+       if (retval < 0)
+               return retval;
+       while (1) {
+               retval = spinand_read_status(spi_nand, &status);
+               if (retval < 0) {
+                       dev_err(&spi_nand->dev,
+                                       "error %d reading status register\n",
+                                       retval);
+                       return retval;
+               }
+
+               if ((status & STATUS_OIP_MASK) == STATUS_READY) {
+                       if ((status & STATUS_P_FAIL_MASK) == STATUS_P_FAIL) {
+                               dev_err(&spi_nand->dev,
+                                       "program error, page %d\n", page_id);
+                               return -1;
+                       } else
+                               break;
+               }
+       }
+#ifdef CONFIG_MTD_SPINAND_ONDIEECC
+       if (enable_hw_ecc) {
+               retval = spinand_disable_ecc(spi_nand);
+               if (retval < 0) {
+                       dev_err(&spi_nand->dev, "disable ecc failed!!\n");
+                       return retval;
+               }
+               enable_hw_ecc = 0;
+       }
+#endif
+
+       return 0;
+}
+
+/**
+ * spinand_erase_block_erase--to erase a page with:
+ * @block_id: the physical block location to erase.
+ *
+ * Description:
+ *   The command used here is 0xd8--indicating an erase command to erase
+ *   one block--64 pages
+ *   Need to wait for tERS.
+ */
+static int spinand_erase_block_erase(struct spi_device *spi_nand, u16 block_id)
+{
+       struct spinand_cmd cmd = {0};
+       u16 row;
+
+       row = block_id;
+       cmd.cmd = CMD_ERASE_BLK;
+       cmd.n_addr = 3;
+       cmd.addr[1] = (u8)((row & 0xff00) >> 8);
+       cmd.addr[2] = (u8)(row & 0x00ff);
+
+       return spinand_cmd(spi_nand, &cmd);
+}
+
+/**
+ * spinand_erase_block--to erase a page with:
+ * @block_id: the physical block location to erase.
+ *
+ * Description:
+ *   The commands used here are 0x06 and 0xd8--indicating an erase
+ *   command to erase one block--64 pages
+ *   It will first to enable the write enable bit (0x06 command),
+ *   and then send the 0xd8 erase command
+ *   Poll to wait for the tERS time to complete the tranaction.
+ */
+static int spinand_erase_block(struct spi_device *spi_nand, u16 block_id)
+{
+       int retval;
+       u8 status = 0;
+
+       retval = spinand_write_enable(spi_nand);
+       if (wait_till_ready(spi_nand))
+               dev_err(&spi_nand->dev, "wait timedout!!!\n");
+
+       retval = spinand_erase_block_erase(spi_nand, block_id);
+       while (1) {
+               retval = spinand_read_status(spi_nand, &status);
+               if (retval < 0) {
+                       dev_err(&spi_nand->dev,
+                                       "error %d reading status register\n",
+                                       (int) retval);
+                       return retval;
+               }
+
+               if ((status & STATUS_OIP_MASK) == STATUS_READY) {
+                       if ((status & STATUS_E_FAIL_MASK) == STATUS_E_FAIL) {
+                               dev_err(&spi_nand->dev,
+                                       "erase error, block %d\n", block_id);
+                               return -1;
+                       } else
+                               break;
+               }
+       }
+       return 0;
+}
+
+#ifdef CONFIG_MTD_SPINAND_ONDIEECC
+static int spinand_write_page_hwecc(struct mtd_info *mtd,
+               struct nand_chip *chip, const uint8_t *buf, int oob_required)
+{
+       const uint8_t *p = buf;
+       int eccsize = chip->ecc.size;
+       int eccsteps = chip->ecc.steps;
+
+       enable_hw_ecc = 1;
+       chip->write_buf(mtd, p, eccsize * eccsteps);
+       return 0;
+}
+
+static int spinand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
+               uint8_t *buf, int oob_required, int page)
+{
+       u8 retval, status;
+       uint8_t *p = buf;
+       int eccsize = chip->ecc.size;
+       int eccsteps = chip->ecc.steps;
+       struct spinand_info *info = (struct spinand_info *)chip->priv;
+
+       enable_read_hw_ecc = 1;
+
+       chip->read_buf(mtd, p, eccsize * eccsteps);
+       if (oob_required)
+               chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+       while (1) {
+               retval = spinand_read_status(info->spi, &status);
+               if ((status & STATUS_OIP_MASK) == STATUS_READY) {
+                       if ((status & STATUS_ECC_MASK) == STATUS_ECC_ERROR) {
+                               pr_info("spinand: ECC error\n");
+                               mtd->ecc_stats.failed++;
+                       } else if ((status & STATUS_ECC_MASK) ==
+                                       STATUS_ECC_1BIT_CORRECTED)
+                               mtd->ecc_stats.corrected++;
+                       break;
+               }
+       }
+       return 0;
+
+}
+#endif
+
+static void spinand_select_chip(struct mtd_info *mtd, int dev)
+{
+}
+
+static uint8_t spinand_read_byte(struct mtd_info *mtd)
+{
+       struct spinand_state *state = mtd_to_state(mtd);
+       u8 data;
+
+       data = state->buf[state->buf_ptr];
+       state->buf_ptr++;
+       return data;
+}
+
+
+static int spinand_wait(struct mtd_info *mtd, struct nand_chip *chip)
+{
+       struct spinand_info *info = (struct spinand_info *)chip->priv;
+
+       unsigned long timeo = jiffies;
+       int retval, state = chip->state;
+       u8 status;
+
+       if (state == FL_ERASING)
+               timeo += (HZ * 400) / 1000;
+       else
+               timeo += (HZ * 20) / 1000;
+
+       while (time_before(jiffies, timeo)) {
+               retval = spinand_read_status(info->spi, &status);
+               if ((status & STATUS_OIP_MASK) == STATUS_READY)
+                       return 0;
+
+               cond_resched();
+       }
+       return 0;
+}
+
+static void spinand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
+{
+
+       struct spinand_state *state = mtd_to_state(mtd);
+       memcpy(state->buf + state->buf_ptr, buf, len);
+       state->buf_ptr += len;
+}
+
+static void spinand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+       struct spinand_state *state = mtd_to_state(mtd);
+       memcpy(buf, state->buf + state->buf_ptr, len);
+       state->buf_ptr += len;
+}
+
+/*
+ * spinand_reset- send RESET command "0xff" to the Nand device.
+ */
+static void spinand_reset(struct spi_device *spi_nand)
+{
+       struct spinand_cmd cmd = {0};
+
+       cmd.cmd = CMD_RESET;
+
+       if (spinand_cmd(spi_nand, &cmd) < 0)
+               pr_info("spinand reset failed!\n");
+
+       /* elapse 1ms before issuing any other command */
+       udelay(1000);
+
+       if (wait_till_ready(spi_nand))
+               dev_err(&spi_nand->dev, "wait timedout!\n");
+}
+
+static void spinand_cmdfunc(struct mtd_info *mtd, unsigned int command,
+               int column, int page)
+{
+       struct nand_chip *chip = (struct nand_chip *)mtd->priv;
+       struct spinand_info *info = (struct spinand_info *)chip->priv;
+       struct spinand_state *state = (struct spinand_state *)info->priv;
+
+       switch (command) {
+       /*
+        * READ0 - read in first  0x800 bytes
+        */
+       case NAND_CMD_READ1:
+       case NAND_CMD_READ0:
+               state->buf_ptr = 0;
+               spinand_read_page(info->spi, page, 0x0, 0x840, state->buf);
+               break;
+       /* READOOB reads only the OOB because no ECC is performed. */
+       case NAND_CMD_READOOB:
+               state->buf_ptr = 0;
+               spinand_read_page(info->spi, page, 0x800, 0x40, state->buf);
+               break;
+       case NAND_CMD_RNDOUT:
+               state->buf_ptr = column;
+               break;
+       case NAND_CMD_READID:
+               state->buf_ptr = 0;
+               spinand_read_id(info->spi, (u8 *)state->buf);
+               break;
+       case NAND_CMD_PARAM:
+               state->buf_ptr = 0;
+               break;
+       /* ERASE1 stores the block and page address */
+       case NAND_CMD_ERASE1:
+               spinand_erase_block(info->spi, page);
+               break;
+       /* ERASE2 uses the block and page address from ERASE1 */
+       case NAND_CMD_ERASE2:
+               break;
+       /* SEQIN sets up the addr buffer and all registers except the length */
+       case NAND_CMD_SEQIN:
+               state->col = column;
+               state->row = page;
+               state->buf_ptr = 0;
+               break;
+       /* PAGEPROG reuses all of the setup from SEQIN and adds the length */
+       case NAND_CMD_PAGEPROG:
+               spinand_program_page(info->spi, state->row, state->col,
+                               state->buf_ptr, state->buf);
+               break;
+       case NAND_CMD_STATUS:
+               spinand_get_otp(info->spi, state->buf);
+               if (!(state->buf[0] & 0x80))
+                       state->buf[0] = 0x80;
+               state->buf_ptr = 0;
+               break;
+       /* RESET command */
+       case NAND_CMD_RESET:
+               if (wait_till_ready(info->spi))
+                       dev_err(&info->spi->dev, "WAIT timedout!!!\n");
+               /* a minimum of 250us must elapse before issuing RESET cmd*/
+               udelay(250);
+               spinand_reset(info->spi);
+               break;
+       default:
+               dev_err(&mtd->dev, "Unknown CMD: 0x%x\n", command);
+       }
+}
+
+/**
+ * spinand_lock_block- send write register 0x1f command to the Nand device
+ *
+ * Description:
+ *    After power up, all the Nand blocks are locked.  This function allows
+ *    one to unlock the blocks, and so it can be written or erased.
+ */
+static int spinand_lock_block(struct spi_device *spi_nand, u8 lock)
+{
+       struct spinand_cmd cmd = {0};
+       int ret;
+       u8 otp = 0;
+
+       ret = spinand_get_otp(spi_nand, &otp);
+
+       cmd.cmd = CMD_WRITE_REG;
+       cmd.n_addr = 1;
+       cmd.addr[0] = REG_BLOCK_LOCK;
+       cmd.n_tx = 1;
+       cmd.tx_buf = &lock;
+
+       ret = spinand_cmd(spi_nand, &cmd);
+       if (ret < 0)
+               dev_err(&spi_nand->dev, "error %d lock block\n", ret);
+
+       return ret;
+}
+/*
+ * spinand_probe - [spinand Interface]
+ * @spi_nand: registered device driver.
+ *
+ * Description:
+ *   To set up the device driver parameters to make the device available.
+ */
+static int spinand_probe(struct spi_device *spi_nand)
+{
+       struct mtd_info *mtd;
+       struct nand_chip *chip;
+       struct spinand_info *info;
+       struct spinand_state *state;
+       struct mtd_part_parser_data ppdata;
+
+       info  = devm_kzalloc(&spi_nand->dev, sizeof(struct spinand_info),
+                       GFP_KERNEL);
+       if (!info)
+               return -ENOMEM;
+
+       info->spi = spi_nand;
+
+       spinand_lock_block(spi_nand, BL_ALL_UNLOCKED);
+
+       state = devm_kzalloc(&spi_nand->dev, sizeof(struct spinand_state),
+                       GFP_KERNEL);
+       if (!state)
+               return -ENOMEM;
+
+       info->priv      = state;
+       state->buf_ptr  = 0;
+       state->buf      = devm_kzalloc(&spi_nand->dev, BUFSIZE, GFP_KERNEL);
+       if (!state->buf)
+               return -ENOMEM;
+
+       chip = devm_kzalloc(&spi_nand->dev, sizeof(struct nand_chip),
+                       GFP_KERNEL);
+       if (!chip)
+               return -ENOMEM;
+
+#ifdef CONFIG_MTD_SPINAND_ONDIEECC
+       chip->ecc.mode  = NAND_ECC_HW;
+       chip->ecc.size  = 0x200;
+       chip->ecc.bytes = 0x6;
+       chip->ecc.steps = 0x4;
+
+       chip->ecc.strength = 1;
+       chip->ecc.total = chip->ecc.steps * chip->ecc.bytes;
+       chip->ecc.layout = &spinand_oob_64;
+       chip->ecc.read_page = spinand_read_page_hwecc;
+       chip->ecc.write_page = spinand_write_page_hwecc;
+#else
+       chip->ecc.mode  = NAND_ECC_SOFT;
+       if (spinand_disable_ecc(spi_nand) < 0)
+               pr_info("%s: disable ecc failed!\n", __func__);
+#endif
+
+       chip->priv      = info;
+       chip->read_buf  = spinand_read_buf;
+       chip->write_buf = spinand_write_buf;
+       chip->read_byte = spinand_read_byte;
+       chip->cmdfunc   = spinand_cmdfunc;
+       chip->waitfunc  = spinand_wait;
+       chip->options   |= NAND_CACHEPRG;
+       chip->select_chip = spinand_select_chip;
+
+       mtd = devm_kzalloc(&spi_nand->dev, sizeof(struct mtd_info), GFP_KERNEL);
+       if (!mtd)
+               return -ENOMEM;
+
+       dev_set_drvdata(&spi_nand->dev, mtd);
+
+       mtd->priv = chip;
+       mtd->name = dev_name(&spi_nand->dev);
+       mtd->owner = THIS_MODULE;
+       mtd->oobsize = 64;
+
+       if (nand_scan(mtd, 1))
+               return -ENXIO;
+
+       ppdata.of_node = spi_nand->dev.of_node;
+       return mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
+}
+
+/*
+ * spinand_remove: Remove the device driver
+ * @spi: the spi device.
+ *
+ * Description:
+ *   To remove the device driver parameters and free up allocated memories.
+ */
+static int spinand_remove(struct spi_device *spi)
+{
+       mtd_device_unregister(dev_get_drvdata(&spi->dev));
+
+       return 0;
+}
+
+static const struct of_device_id spinand_dt[] = {
+       { .compatible = "spinand,mt29f", },
+};
+
+/*
+ * Device name structure description
+ */
+static struct spi_driver spinand_driver = {
+       .driver = {
+               .name           = "mt29f",
+               .bus            = &spi_bus_type,
+               .owner          = THIS_MODULE,
+               .of_match_table = spinand_dt,
+       },
+       .probe          = spinand_probe,
+       .remove         = spinand_remove,
+};
+
+/*
+ * Device driver registration
+ */
+static int __init spinand_init(void)
+{
+       return spi_register_driver(&spinand_driver);
+}
+
+/*
+ * unregister Device driver.
+ */
+static void __exit spinand_exit(void)
+{
+       spi_unregister_driver(&spinand_driver);
+}
+module_init(spinand_init);
+module_exit(spinand_exit);
+
+MODULE_DESCRIPTION("SPI NAND driver for Micron");
+MODULE_AUTHOR("Henry Pan <hspan@micron.com>, Kamlakant Patel <kamlakant.patel@broadcom.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/mt29f_spinand/mt29f_spinand.h b/drivers/staging/mt29f_spinand/mt29f_spinand.h
new file mode 100644 (file)
index 0000000..7f2c24d
--- /dev/null
@@ -0,0 +1,107 @@
+/*-
+ * Copyright 2013 Broadcom Corporation
+ *
+ * Copyright (c) 2009-2010 Micron Technology, Inc.
+ *
+ * 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.
+ *
+ * Henry Pan <hspan@micron.com>
+ *
+ * based on nand.h
+ */
+#ifndef __LINUX_MTD_SPI_NAND_H
+#define __LINUX_MTD_SPI_NAND_H
+
+#include <linux/wait.h>
+#include <linux/spinlock.h>
+#include <linux/mtd/mtd.h>
+
+/* cmd */
+#define CMD_READ                       0x13
+#define CMD_READ_RDM                   0x03
+#define CMD_PROG_PAGE_CLRCACHE         0x02
+#define CMD_PROG_PAGE                  0x84
+#define CMD_PROG_PAGE_EXC              0x10
+#define CMD_ERASE_BLK                  0xd8
+#define CMD_WR_ENABLE                  0x06
+#define CMD_WR_DISABLE                 0x04
+#define CMD_READ_ID                    0x9f
+#define CMD_RESET                      0xff
+#define CMD_READ_REG                   0x0f
+#define CMD_WRITE_REG                  0x1f
+
+/* feature/ status reg */
+#define REG_BLOCK_LOCK                 0xa0
+#define REG_OTP                                0xb0
+#define REG_STATUS                     0xc0/* timing */
+
+/* status */
+#define STATUS_OIP_MASK                        0x01
+#define STATUS_READY                   (0 << 0)
+#define STATUS_BUSY                    (1 << 0)
+
+#define STATUS_E_FAIL_MASK             0x04
+#define STATUS_E_FAIL                  (1 << 2)
+
+#define STATUS_P_FAIL_MASK             0x08
+#define STATUS_P_FAIL                  (1 << 3)
+
+#define STATUS_ECC_MASK                        0x30
+#define STATUS_ECC_1BIT_CORRECTED      (1 << 4)
+#define STATUS_ECC_ERROR               (2 << 4)
+#define STATUS_ECC_RESERVED            (3 << 4)
+
+/*ECC enable defines*/
+#define OTP_ECC_MASK                   0x10
+#define OTP_ECC_OFF                    0
+#define OTP_ECC_ON                     1
+
+#define ECC_DISABLED
+#define ECC_IN_NAND
+#define ECC_SOFT
+
+/* block lock */
+#define BL_ALL_LOCKED      0x38
+#define BL_1_2_LOCKED      0x30
+#define BL_1_4_LOCKED      0x28
+#define BL_1_8_LOCKED      0x20
+#define BL_1_16_LOCKED     0x18
+#define BL_1_32_LOCKED     0x10
+#define BL_1_64_LOCKED     0x08
+#define BL_ALL_UNLOCKED    0
+
+struct spinand_info {
+       struct nand_ecclayout *ecclayout;
+       struct spi_device *spi;
+       void *priv;
+};
+
+struct spinand_state {
+       uint32_t        col;
+       uint32_t        row;
+       int             buf_ptr;
+       u8              *buf;
+};
+
+struct spinand_cmd {
+       u8              cmd;
+       u32             n_addr;         /* Number of address */
+       u8              addr[3];        /* Reg Offset */
+       u32             n_dummy;        /* Dummy use */
+       u32             n_tx;           /* Number of tx bytes */
+       u8              *tx_buf;        /* Tx buf */
+       u32             n_rx;           /* Number of rx bytes */
+       u8              *rx_buf;        /* Rx buf */
+};
+
+extern int spinand_mtd(struct mtd_info *mtd);
+extern void spinand_mtd_release(struct mtd_info *mtd);
+
+#endif /* __LINUX_MTD_SPI_NAND_H */
index 5a5c6397e74069000d66350c07fcc1fafafc01a6..3066ee2e753be3ed887d11b9615b41b78261b6bb 100644 (file)
@@ -802,7 +802,7 @@ static int tegra_nvec_probe(struct platform_device *pdev)
                unmute_speakers[] = { NVEC_OEM0, 0x10, 0x59, 0x95 },
                enable_event[7] = { NVEC_SYS, CNF_EVENT_REPORTING, true };
 
-       if(!pdev->dev.of_node) {
+       if (!pdev->dev.of_node) {
                dev_err(&pdev->dev, "must be instantiated using device tree\n");
                return -ENODEV;
        }
index 45dfe94199ae4ecd951a8142fb6f9140d226942c..910a657b629250c076d7f7147646cd8fca3f9acf 100644 (file)
  *     derived from this software without specific prior written
  *     permission.
 
- * This Software, including technical data, may be subject to U.S. export  control
- * laws, including the U.S. Export Administration Act and its  associated
+ * This Software, including technical data, may be subject to U.S. export
+ * control laws, including the U.S. Export Administration Act and its associated
  * regulations, and may be subject to export or import  regulations in other
  * countries.
 
  * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
- * AND WITH ALL FAULTS AND CAVIUM  NETWORKS MAKES NO PROMISES, REPRESENTATIONS OR
+ * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS OR
  * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
- * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR
- * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
+ * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION
+ * OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
  * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
  * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
  * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
 #include <asm/octeon/cvmx-helper.h>
 #include <asm/octeon/cvmx-helper-board.h>
 
-#define CVMX_PREFETCH0(address) CVMX_PREFETCH(address, 0)
-#define CVMX_PREFETCH128(address) CVMX_PREFETCH(address, 128)
-// a normal prefetch
-#define CVMX_PREFETCH(address, offset) CVMX_PREFETCH_PREF0(address, offset)
-// normal prefetches that use the pref instruction
-#define CVMX_PREFETCH_PREFX(X, address, offset) asm volatile ("pref %[type], %[off](%[rbase])" : : [rbase] "d" (address), [off] "I" (offset), [type] "n" (X))
-#define CVMX_PREFETCH_PREF0(address, offset) CVMX_PREFETCH_PREFX(0, address, offset)
-#define CVMX_CLZ(result, input) asm ("clz %[rd],%[rs]" : [rd] "=d" (result) : [rs] "d" (input))
-
-#define MAX_RETRIES            3               /* Maximum number of times to retry failed transactions */
-#define MAX_PIPES              32              /* Maximum number of pipes that can be open at once */
-#define MAX_TRANSACTIONS       256             /* Maximum number of outstanding transactions across all pipes */
-#define MAX_CHANNELS           8               /* Maximum number of hardware channels supported by the USB block */
-#define MAX_USB_ADDRESS                127             /* The highest valid USB device address */
-#define MAX_USB_ENDPOINT       15              /* The highest valid USB endpoint number */
-#define MAX_USB_HUB_PORT       15              /* The highest valid port number on a hub */
-#define MAX_TRANSFER_BYTES     ((1<<19)-1)     /* The low level hardware can transfer a maximum of this number of bytes in each transfer. The field is 19 bits wide */
-#define MAX_TRANSFER_PACKETS   ((1<<10)-1)     /* The low level hardware can transfer a maximum of this number of packets in each transfer. The field is 10 bits wide */
+/* Normal prefetch that use the pref instruction. */
+#define CVMX_PREFETCH(address, offset) asm volatile ("pref %[type], %[off](%[rbase])" : : [rbase] "d" (address), [off] "I" (offset), [type] "n" (0))
+
+/* Maximum number of times to retry failed transactions */
+#define MAX_RETRIES            3
+
+/* Maximum number of pipes that can be open at once */
+#define MAX_PIPES              32
+
+/* Maximum number of outstanding transactions across all pipes */
+#define MAX_TRANSACTIONS       256
+
+/* Maximum number of hardware channels supported by the USB block */
+#define MAX_CHANNELS           8
+
+/* The highest valid USB device address */
+#define MAX_USB_ADDRESS                127
+
+/* The highest valid USB endpoint number */
+#define MAX_USB_ENDPOINT       15
+
+/* The highest valid port number on a hub */
+#define MAX_USB_HUB_PORT       15
+
+/*
+ * The low level hardware can transfer a maximum of this number of bytes in each
+ * transfer. The field is 19 bits wide
+ */
+#define MAX_TRANSFER_BYTES     ((1<<19)-1)
 
 /*
- * These defines disable the normal read and write csr. This is so I can add
- * extra debug stuff to the usb specific version and I won't use the normal
- * version by mistake
+ * The low level hardware can transfer a maximum of this number of packets in
+ * each transfer. The field is 10 bits wide
  */
-#define cvmx_read_csr use_cvmx_usb_read_csr64_instead_of_cvmx_read_csr
-#define cvmx_write_csr use_cvmx_usb_write_csr64_instead_of_cvmx_write_csr
+#define MAX_TRANSFER_PACKETS   ((1<<10)-1)
 
 enum cvmx_usb_transaction_flags {
        __CVMX_USB_TRANSACTION_FLAGS_IN_USE = 1<<16,
@@ -552,20 +561,15 @@ static inline void __cvmx_usb_remove_pipe(struct cvmx_usb_pipe_list *list, struc
  *              functions.
  * @usb_port_number:
  *              Which Octeon USB port to initialize.
- * @flags:      Flags to control hardware initialization. See
- *              enum cvmx_usb_initialize_flags for the flag
- *              definitions. Some flags are mandatory.
  *
  * Returns: 0 or a negative error code.
  */
-int cvmx_usb_initialize(struct cvmx_usb_state *state, int usb_port_number,
-                       enum cvmx_usb_initialize_flags flags)
+int cvmx_usb_initialize(struct cvmx_usb_state *state, int usb_port_number)
 {
        union cvmx_usbnx_clk_ctl usbn_clk_ctl;
        union cvmx_usbnx_usbp_ctl_status usbn_usbp_ctl_status;
        struct cvmx_usb_internal_state *usb = (struct cvmx_usb_internal_state *)state;
-
-       usb->init_flags = flags;
+       enum cvmx_usb_initialize_flags flags = 0;
 
        /* Make sure that state is large enough to store the internal state */
        if (sizeof(*state) < sizeof(*usb))
@@ -577,31 +581,26 @@ int cvmx_usb_initialize(struct cvmx_usb_state *state, int usb_port_number,
        if (!OCTEON_IS_MODEL(OCTEON_CN52XX) && (usb_port_number > 0))
                return -EINVAL;
        /* Try to determine clock type automatically */
-       if ((flags & (CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_XI |
-                     CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND)) == 0) {
-               if (octeon_usb_get_clock_type() == USB_CLOCK_TYPE_CRYSTAL_12)
-                       flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_XI;  /* Only 12 MHZ crystals are supported */
-               else
-                       flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND;
-       }
+       if (octeon_usb_get_clock_type() == USB_CLOCK_TYPE_CRYSTAL_12) {
+               /* Only 12 MHZ crystals are supported */
+               flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_XI;
+       } else {
+               flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND;
 
-       if (flags & CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND) {
-               /* Check for auto ref clock frequency */
-               if (!(flags & CVMX_USB_INITIALIZE_FLAGS_CLOCK_MHZ_MASK))
-                       switch (octeon_usb_get_clock_type()) {
-                       case USB_CLOCK_TYPE_REF_12:
-                               flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ;
-                               break;
-                       case USB_CLOCK_TYPE_REF_24:
-                               flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_24MHZ;
-                               break;
-                       case USB_CLOCK_TYPE_REF_48:
-                               flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_48MHZ;
-                               break;
-                       default:
-                               return -EINVAL;
-                               break;
-                       }
+               switch (octeon_usb_get_clock_type()) {
+               case USB_CLOCK_TYPE_REF_12:
+                       flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ;
+                       break;
+               case USB_CLOCK_TYPE_REF_24:
+                       flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_24MHZ;
+                       break;
+               case USB_CLOCK_TYPE_REF_48:
+                       flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_48MHZ;
+                       break;
+               default:
+                       return -EINVAL;
+                       break;
+               }
        }
 
        memset(usb, 0, sizeof(*usb));
@@ -646,12 +645,15 @@ int cvmx_usb_initialize(struct cvmx_usb_state *state, int usb_port_number,
                 * Most Octeon evaluation boards require this setting
                 */
                if (OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
-                       usbn_clk_ctl.cn31xx.p_rclk  = 1; /* From CN31XX,CN30XX manual */
+                       /* From CN31XX,CN30XX manual */
+                       usbn_clk_ctl.cn31xx.p_rclk  = 1;
                        usbn_clk_ctl.cn31xx.p_xenbn = 0;
                } else if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN50XX))
-                       usbn_clk_ctl.cn56xx.p_rtype = 2; /* From CN56XX,CN50XX manual */
+                       /* From CN56XX,CN50XX manual */
+                       usbn_clk_ctl.cn56xx.p_rtype = 2;
                else
-                       usbn_clk_ctl.cn52xx.p_rtype = 1; /* From CN52XX manual */
+                       /* From CN52XX manual */
+                       usbn_clk_ctl.cn52xx.p_rtype = 1;
 
                switch (flags & CVMX_USB_INITIALIZE_FLAGS_CLOCK_MHZ_MASK) {
                case CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ:
@@ -670,12 +672,15 @@ int cvmx_usb_initialize(struct cvmx_usb_state *state, int usb_port_number,
                 * at USB_XO and USB_XI
                 */
                if (OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
-                       usbn_clk_ctl.cn31xx.p_rclk  = 1; /* From CN31XX,CN30XX manual */
+                       /* From CN31XX,CN30XX manual */
+                       usbn_clk_ctl.cn31xx.p_rclk  = 1;
                        usbn_clk_ctl.cn31xx.p_xenbn = 1;
                } else if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN50XX))
-                       usbn_clk_ctl.cn56xx.p_rtype = 0; /* From CN56XX,CN50XX manual */
+                       /* From CN56XX,CN50XX manual */
+                       usbn_clk_ctl.cn56xx.p_rtype = 0;
                else
-                       usbn_clk_ctl.cn52xx.p_rtype = 0; /* From CN52XX manual */
+                       /* From CN52XX manual */
+                       usbn_clk_ctl.cn52xx.p_rtype = 0;
 
                usbn_clk_ctl.s.p_c_sel = 0;
        }
@@ -686,7 +691,8 @@ int cvmx_usb_initialize(struct cvmx_usb_state *state, int usb_port_number,
         */
        {
                int divisor = (octeon_get_clock_rate()+125000000-1)/125000000;
-               if (divisor < 4)  /* Lower than 4 doesn't seem to work properly */
+               /* Lower than 4 doesn't seem to work properly */
+               if (divisor < 4)
                        divisor = 4;
                usbn_clk_ctl.s.divide = divisor;
                usbn_clk_ctl.s.divide2 = 0;
@@ -783,9 +789,11 @@ int cvmx_usb_initialize(struct cvmx_usb_state *state, int usb_port_number,
                usbcx_gahbcfg.u32 = 0;
                usbcx_gahbcfg.s.dmaen = !(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA);
                if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
-                       usb->idle_hardware_channels = 0x1;  /* Only use one channel with non DMA */
+                       /* Only use one channel with non DMA */
+                       usb->idle_hardware_channels = 0x1;
                else if (OCTEON_IS_MODEL(OCTEON_CN5XXX))
-                       usb->idle_hardware_channels = 0xf7; /* CN5XXX have an errata with channel 3 */
+                       /* CN5XXX have an errata with channel 3 */
+                       usb->idle_hardware_channels = 0xf7;
                else
                        usb->idle_hardware_channels = 0xff;
                usbcx_gahbcfg.s.hbstlen = 0;
@@ -833,7 +841,10 @@ int cvmx_usb_initialize(struct cvmx_usb_state *state, int usb_port_number,
                __cvmx_usb_write_csr32(usb, CVMX_USBCX_GINTMSK(usb->index),
                                       usbcx_gintmsk.u32);
 
-               /* Disable all channel interrupts. We'll enable them per channel later */
+               /*
+                * Disable all channel interrupts. We'll enable them per channel
+                * later.
+                */
                for (channel = 0; channel < 8; channel++)
                        __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCINTMSKX(channel, usb->index), 0);
        }
@@ -956,7 +967,10 @@ int cvmx_usb_enable(struct cvmx_usb_state *state)
                                  prtena, ==, 1, 100000))
                return -ETIMEDOUT;
 
-       /* Read the port speed field to get the enumerated speed, USBC_HPRT[PRTSPD]. */
+       /*
+        * Read the port speed field to get the enumerated speed,
+        * USBC_HPRT[PRTSPD].
+        */
        usb->usbcx_hprt.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPRT(usb->index));
        usbcx_ghwcfg3.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GHWCFG3(usb->index));
 
@@ -1119,8 +1133,6 @@ static inline int __cvmx_usb_get_pipe_handle(struct cvmx_usb_internal_state *usb
  *
  * @state:          USB device state populated by
  *                  cvmx_usb_initialize().
- * @flags:          Optional pipe flags defined in
- *                  enum cvmx_usb_pipe_flags.
  * @device_addr:
  *                  USB device address to open the pipe to
  *                  (0-127).
@@ -1168,7 +1180,7 @@ static inline int __cvmx_usb_get_pipe_handle(struct cvmx_usb_internal_state *usb
  * Returns: A non negative value is a pipe handle. Negative
  *         values are error codes.
  */
-int cvmx_usb_open_pipe(struct cvmx_usb_state *state, enum cvmx_usb_pipe_flags flags,
+int cvmx_usb_open_pipe(struct cvmx_usb_state *state,
                       int device_addr, int endpoint_num,
                       enum cvmx_usb_speed device_speed, int max_packet,
                       enum cvmx_usb_transfer transfer_type,
@@ -1210,7 +1222,7 @@ int cvmx_usb_open_pipe(struct cvmx_usb_state *state, enum cvmx_usb_pipe_flags fl
        if (!pipe)
                return -ENOMEM;
        __cvmx_usb_remove_pipe(&usb->free_pipes, pipe);
-       pipe->flags = flags | __CVMX_USB_PIPE_FLAGS_OPEN;
+       pipe->flags = __CVMX_USB_PIPE_FLAGS_OPEN;
        if ((device_speed == CVMX_USB_SPEED_HIGH) &&
                (transfer_dir == CVMX_USB_DIRECTION_OUT) &&
                (transfer_type == CVMX_USB_TRANSFER_BULK))
@@ -1410,7 +1422,10 @@ static void __cvmx_usb_fill_tx_fifo(struct cvmx_usb_internal_state *usb, int cha
        if (usbc_hcsplt.s.spltena && usbc_hcsplt.s.compsplt)
                return;
 
-       /* Find out how many bytes we need to fill and convert it into 32bit words */
+       /*
+        * Find out how many bytes we need to fill and convert it into 32bit
+        * words.
+        */
        usbc_hctsiz.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index));
        if (!usbc_hctsiz.s.xfersize)
                return;
@@ -1603,13 +1618,19 @@ static void __cvmx_usb_start_channel(struct cvmx_usb_internal_state *usb,
                usbc_hcintmsk.u32 = 0;
                usbc_hcintmsk.s.chhltdmsk = 1;
                if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA) {
-                       /* Channels need these extra interrupts when we aren't in DMA mode */
+                       /*
+                        * Channels need these extra interrupts when we aren't
+                        * in DMA mode.
+                        */
                        usbc_hcintmsk.s.datatglerrmsk = 1;
                        usbc_hcintmsk.s.frmovrunmsk = 1;
                        usbc_hcintmsk.s.bblerrmsk = 1;
                        usbc_hcintmsk.s.xacterrmsk = 1;
                        if (__cvmx_usb_pipe_needs_split(usb, pipe)) {
-                               /* Splits don't generate xfercompl, so we need ACK and NYET */
+                               /*
+                                * Splits don't generate xfercompl, so we need
+                                * ACK and NYET.
+                                */
                                usbc_hcintmsk.s.nyetmsk = 1;
                                usbc_hcintmsk.s.ackmsk = 1;
                        }
@@ -1703,18 +1724,22 @@ static void __cvmx_usb_start_channel(struct cvmx_usb_internal_state *usb,
                                         * begin or the entire payload
                                         */
                                        if (bytes_to_transfer <= 188)
-                                               usbc_hcsplt.s.xactpos = 3; /* Entire payload in one go */
+                                               /* Entire payload in one go */
+                                               usbc_hcsplt.s.xactpos = 3;
                                        else
-                                               usbc_hcsplt.s.xactpos = 2; /* First part of payload */
+                                               /* First part of payload */
+                                               usbc_hcsplt.s.xactpos = 2;
                                } else {
                                        /*
                                         * Continuing the previous data, we must
                                         * either be in the middle or at the end
                                         */
                                        if (bytes_to_transfer <= 188)
-                                               usbc_hcsplt.s.xactpos = 1; /* End of payload */
+                                               /* End of payload */
+                                               usbc_hcsplt.s.xactpos = 1;
                                        else
-                                               usbc_hcsplt.s.xactpos = 0; /* Middle of payload */
+                                               /* Middle of payload */
+                                               usbc_hcsplt.s.xactpos = 0;
                                }
                                /*
                                 * Again, the transfer size is limited to 188
@@ -1896,7 +1921,10 @@ static void __cvmx_usb_schedule(struct cvmx_usb_internal_state *usb, int is_sof)
        enum cvmx_usb_transfer ttype;
 
        if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA) {
-               /* Without DMA we need to be careful to not schedule something at the end of a frame and cause an overrun */
+               /*
+                * Without DMA we need to be careful to not schedule something
+                * at the end of a frame and cause an overrun.
+                */
                union cvmx_usbcx_hfnum hfnum = {.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HFNUM(usb->index))};
                union cvmx_usbcx_hfir hfir = {.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HFIR(usb->index))};
                if (hfnum.s.frrem < hfir.s.frint/4)
@@ -1905,8 +1933,7 @@ static void __cvmx_usb_schedule(struct cvmx_usb_internal_state *usb, int is_sof)
 
        while (usb->idle_hardware_channels) {
                /* Find an idle channel */
-               CVMX_CLZ(channel, usb->idle_hardware_channels);
-               channel = 31 - channel;
+               channel = __fls(usb->idle_hardware_channels);
                if (unlikely(channel > 7))
                        break;
 
@@ -2034,9 +2061,12 @@ static void __cvmx_usb_perform_complete(struct cvmx_usb_internal_state *usb,
                 * next one
                 */
                if ((transaction->iso_number_packets > 1) && (complete_code == CVMX_USB_COMPLETE_SUCCESS)) {
-                       transaction->actual_bytes = 0;     /* No bytes transferred for this packet as of yet */
-                       transaction->iso_number_packets--; /* One less ISO waiting to transfer */
-                       transaction->iso_packets++;        /* Increment to the next location in our packet array */
+                       /* No bytes transferred for this packet as of yet */
+                       transaction->actual_bytes = 0;
+                       /* One less ISO waiting to transfer */
+                       transaction->iso_number_packets--;
+                       /* Increment to the next location in our packet array */
+                       transaction->iso_packets++;
                        transaction->stage = CVMX_USB_STAGE_NON_CONTROL;
                        goto done;
                }
@@ -2073,7 +2103,6 @@ done:
  * @pipe_handle:
  *                 Which pipe to submit to. Will be validated in this function.
  * @type:          Transaction type
- * @flags:         Flags for the transaction
  * @buffer:        User buffer for the transaction
  * @buffer_length:
  *                 User buffer's length in bytes
@@ -2094,7 +2123,6 @@ done:
 static int __cvmx_usb_submit_transaction(struct cvmx_usb_internal_state *usb,
                                         int pipe_handle,
                                         enum cvmx_usb_transfer type,
-                                        int flags,
                                         uint64_t buffer,
                                         int buffer_length,
                                         uint64_t control_header,
@@ -2121,11 +2149,11 @@ static int __cvmx_usb_submit_transaction(struct cvmx_usb_internal_state *usb,
                return -ENOMEM;
 
        transaction->type = type;
-       transaction->flags |= flags;
        transaction->buffer = buffer;
        transaction->buffer_length = buffer_length;
        transaction->control_header = control_header;
-       transaction->iso_start_frame = iso_start_frame; // FIXME: This is not used, implement it
+       /* FIXME: This is not used, implement it. */
+       transaction->iso_start_frame = iso_start_frame;
        transaction->iso_number_packets = iso_number_packets;
        transaction->iso_packets = iso_packets;
        transaction->callback = callback;
@@ -2206,7 +2234,6 @@ int cvmx_usb_submit_bulk(struct cvmx_usb_state *state, int pipe_handle,
 
        submit_handle = __cvmx_usb_submit_transaction(usb, pipe_handle,
                                                      CVMX_USB_TRANSFER_BULK,
-                                                     0, /* flags */
                                                      buffer,
                                                      buffer_length,
                                                      0, /* control_header */
@@ -2265,7 +2292,6 @@ int cvmx_usb_submit_interrupt(struct cvmx_usb_state *state, int pipe_handle,
 
        submit_handle = __cvmx_usb_submit_transaction(usb, pipe_handle,
                                                      CVMX_USB_TRANSFER_INTERRUPT,
-                                                     0, /* flags */
                                                      buffer,
                                                      buffer_length,
                                                      0, /* control_header */
@@ -2336,7 +2362,6 @@ int cvmx_usb_submit_control(struct cvmx_usb_state *state, int pipe_handle,
 
        submit_handle = __cvmx_usb_submit_transaction(usb, pipe_handle,
                                                      CVMX_USB_TRANSFER_CONTROL,
-                                                     0, /* flags */
                                                      buffer,
                                                      buffer_length,
                                                      control_header,
@@ -2359,9 +2384,6 @@ int cvmx_usb_submit_control(struct cvmx_usb_state *state, int pipe_handle,
  * @start_frame:
  *                 Number of frames into the future to schedule
  *                 this transaction.
- * @flags:         Flags to control the transfer. See
- *                 enum cvmx_usb_isochronous_flags for the flag
- *                 definitions.
  * @number_packets:
  *                 Number of sequential packets to transfer.
  *                 "packets" is a pointer to an array of this
@@ -2394,7 +2416,7 @@ int cvmx_usb_submit_control(struct cvmx_usb_state *state, int pipe_handle,
  *         failure. Negative values are error codes.
  */
 int cvmx_usb_submit_isochronous(struct cvmx_usb_state *state, int pipe_handle,
-                               int start_frame, int flags,
+                               int start_frame,
                                int number_packets,
                                struct cvmx_usb_iso_packet packets[],
                                uint64_t buffer, int buffer_length,
@@ -2407,8 +2429,6 @@ int cvmx_usb_submit_isochronous(struct cvmx_usb_state *state, int pipe_handle,
        /* Pipe handle checking is done later in a common place */
        if (unlikely(start_frame < 0))
                return -EINVAL;
-       if (unlikely(flags & ~(CVMX_USB_ISOCHRONOUS_FLAGS_ALLOW_SHORT | CVMX_USB_ISOCHRONOUS_FLAGS_ASAP)))
-               return -EINVAL;
        if (unlikely(number_packets < 1))
                return -EINVAL;
        if (unlikely(!packets))
@@ -2420,7 +2440,6 @@ int cvmx_usb_submit_isochronous(struct cvmx_usb_state *state, int pipe_handle,
 
        submit_handle = __cvmx_usb_submit_transaction(usb, pipe_handle,
                                                      CVMX_USB_TRANSFER_ISOCHRONOUS,
-                                                     flags,
                                                      buffer,
                                                      buffer_length,
                                                      0, /* control_header */
@@ -2445,7 +2464,8 @@ int cvmx_usb_submit_isochronous(struct cvmx_usb_state *state, int pipe_handle,
  * @pipe_handle:
  *              Pipe handle to cancel requests in.
  * @submit_handle:
- *              Handle to transaction to cancel, returned by the submit function.
+ *              Handle to transaction to cancel, returned by the submit
+ *              function.
  *
  * Returns: 0 or a negative error code.
  */
@@ -2484,7 +2504,10 @@ int cvmx_usb_cancel(struct cvmx_usb_state *state, int pipe_handle, int submit_ha
                CVMX_SYNCW;
 
                usbc_hcchar.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCCHARX(pipe->channel, usb->index));
-               /* If the channel isn't enabled then the transaction already completed */
+               /*
+                * If the channel isn't enabled then the transaction already
+                * completed.
+                */
                if (usbc_hcchar.s.chena) {
                        usbc_hcchar.s.chdis = 1;
                        __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCCHARX(pipe->channel, usb->index), usbc_hcchar.u32);
@@ -2667,7 +2690,10 @@ static int __cvmx_usb_poll_channel(struct cvmx_usb_internal_state *usb, int chan
                                __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCCHARX(channel, usb->index), usbc_hcchar.u32);
                                return 0;
                        } else if (usbc_hcint.s.xfercompl) {
-                               /* Successful IN/OUT with transfer complete. Channel halt isn't needed */
+                               /*
+                                * Successful IN/OUT with transfer complete.
+                                * Channel halt isn't needed.
+                                */
                        } else {
                                cvmx_dprintf("USB%d: Channel %d interrupt without halt\n", usb->index, channel);
                                return 0;
@@ -2693,7 +2719,7 @@ static int __cvmx_usb_poll_channel(struct cvmx_usb_internal_state *usb, int chan
        if (!pipe)
                return 0;
        transaction = pipe->head;
-       CVMX_PREFETCH0(transaction);
+       CVMX_PREFETCH(transaction, 0);
 
        /*
         * Disconnect this pipe from the HW channel. Later the schedule
@@ -3019,7 +3045,9 @@ static int __cvmx_usb_poll_channel(struct cvmx_usb_internal_state *usb, int chan
                        break;
                }
        } else if (usbc_hcint.s.nak) {
-               /* If this was a split then clear our split in progress marker */
+               /*
+                * If this was a split then clear our split in progress marker.
+                */
                if (usb->active_split == transaction)
                        usb->active_split = NULL;
                /*
@@ -3145,8 +3173,8 @@ int cvmx_usb_poll(struct cvmx_usb_state *state)
                usbc_haint.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HAINT(usb->index));
                while (usbc_haint.u32) {
                        int channel;
-                       CVMX_CLZ(channel, usbc_haint.u32);
-                       channel = 31 - channel;
+
+                       channel = __fls(usbc_haint.u32);
                        __cvmx_usb_poll_channel(usb, channel);
                        usbc_haint.u32 ^= 1<<channel;
                }
index 8bf36966ef15d77ae15f70e01b854975ccedde14..7b7a542cbd957470afa4573a0c7a99d24170d515 100644 (file)
  *     derived from this software without specific prior written
  *     permission.
 
- * This Software, including technical data, may be subject to U.S. export  control
- * laws, including the U.S. Export Administration Act and its  associated
+ * This Software, including technical data, may be subject to U.S. export
+ * control laws, including the U.S. Export Administration Act and its associated
  * regulations, and may be subject to export or import  regulations in other
  * countries.
 
  * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
- * AND WITH ALL FAULTS AND CAVIUM  NETWORKS MAKES NO PROMISES, REPRESENTATIONS OR
+ * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS OR
  * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
- * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR
- * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
+ * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION
+ * OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
  * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
  * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
  * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
@@ -283,8 +283,8 @@ enum cvmx_usb_direction {
  * @CVMX_USB_COMPLETE_SUCCESS:   The transaction / operation finished without
  *                               any errors
  * @CVMX_USB_COMPLETE_SHORT:     FIXME: This is currently not implemented
- * @CVMX_USB_COMPLETE_CANCEL:    The transaction was canceled while in flight by
- *                               a user call to cvmx_usb_cancel
+ * @CVMX_USB_COMPLETE_CANCEL:    The transaction was canceled while in flight
+ *                               by a user call to cvmx_usb_cancel
  * @CVMX_USB_COMPLETE_ERROR:     The transaction aborted with an unexpected
  *                               error status
  * @CVMX_USB_COMPLETE_STALL:     The transaction received a USB STALL response
@@ -427,7 +427,7 @@ typedef void (*cvmx_usb_callback_func_t)(struct cvmx_usb_state *state,
                                          int bytes_transferred, void *user_data);
 
 /**
- * enum cvmx_usb_initialize_flags - flags to pass the initialization function
+ * enum cvmx_usb_initialize_flags - flags used by the initialization function
  *
  * @CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_XI:    The USB port uses a 12MHz crystal
  *                                           as clock source at USB_XO and
@@ -435,9 +435,6 @@ typedef void (*cvmx_usb_callback_func_t)(struct cvmx_usb_state *state,
  * @CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND:   The USB port uses 12/24/48MHz 2.5V
  *                                           board clock source at USB_XO.
  *                                           USB_XI should be tied to GND.
- * @CVMX_USB_INITIALIZE_FLAGS_CLOCK_AUTO:     Automatically determine clock type
- *                                           based on function in
- *                                           cvmx-helper-board.c.
  * @CVMX_USB_INITIALIZE_FLAGS_CLOCK_MHZ_MASK: Mask for clock speed field
  * @CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ:    Speed of reference clock or
  *                                           crystal
@@ -449,7 +446,6 @@ typedef void (*cvmx_usb_callback_func_t)(struct cvmx_usb_state *state,
 enum cvmx_usb_initialize_flags {
        CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_XI           = 1 << 0,
        CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND          = 1 << 1,
-       CVMX_USB_INITIALIZE_FLAGS_CLOCK_AUTO            = 0,
        CVMX_USB_INITIALIZE_FLAGS_CLOCK_MHZ_MASK        = 3 << 3,
        CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ           = 1 << 3,
        CVMX_USB_INITIALIZE_FLAGS_CLOCK_24MHZ           = 2 << 3,
@@ -459,8 +455,7 @@ enum cvmx_usb_initialize_flags {
 };
 
 /**
- * enum cvmx_usb_pipe_flags - flags for passing when a pipe is created.
- *                           Currently no flags need to be passed.
+ * enum cvmx_usb_pipe_flags - internal flags for a pipe.
  *
  * @__CVMX_USB_PIPE_FLAGS_OPEN:             Used internally to determine if a pipe is
  *                                  open. Do not use.
@@ -477,15 +472,14 @@ enum cvmx_usb_pipe_flags {
 };
 
 extern int cvmx_usb_get_num_ports(void);
-extern int cvmx_usb_initialize(struct cvmx_usb_state *state, int usb_port_number,
-                              enum cvmx_usb_initialize_flags flags);
+extern int cvmx_usb_initialize(struct cvmx_usb_state *state,
+                              int usb_port_number);
 extern int cvmx_usb_shutdown(struct cvmx_usb_state *state);
 extern int cvmx_usb_enable(struct cvmx_usb_state *state);
 extern int cvmx_usb_disable(struct cvmx_usb_state *state);
 extern struct cvmx_usb_port_status cvmx_usb_get_status(struct cvmx_usb_state *state);
 extern void cvmx_usb_set_status(struct cvmx_usb_state *state, struct cvmx_usb_port_status port_status);
 extern int cvmx_usb_open_pipe(struct cvmx_usb_state *state,
-                              enum cvmx_usb_pipe_flags flags,
                               int device_addr, int endpoint_num,
                               enum cvmx_usb_speed device_speed, int max_packet,
                               enum cvmx_usb_transfer transfer_type,
@@ -506,23 +500,8 @@ extern int cvmx_usb_submit_control(struct cvmx_usb_state *state, int pipe_handle
                                    cvmx_usb_callback_func_t callback,
                                    void *user_data);
 
-/**
- * enum cvmx_usb_isochronous_flags - flags to pass the
- *                                  cvmx_usb_submit_isochronous() function.
- *
- * @CVMX_USB_ISOCHRONOUS_FLAGS_ALLOW_SHORT: Do not return an error if a transfer
- *                                         is less than the maximum packet size
- *                                         of the device.
- * @CVMX_USB_ISOCHRONOUS_FLAGS_ASAP:       Schedule the transaction as soon as
- *                                         possible.
- */
-enum cvmx_usb_isochronous_flags {
-       CVMX_USB_ISOCHRONOUS_FLAGS_ALLOW_SHORT  = 1 << 0,
-       CVMX_USB_ISOCHRONOUS_FLAGS_ASAP         = 1 << 1,
-};
-
 extern int cvmx_usb_submit_isochronous(struct cvmx_usb_state *state, int pipe_handle,
-                                       int start_frame, int flags,
+                                      int start_frame,
                                        int number_packets,
                                        struct cvmx_usb_iso_packet packets[],
                                        uint64_t buffer, int buffer_length,
index 5dbbd14ec615aba59d16c72a2e7acbe08f9073cf..764a8df0a16e8d317681e96b39e60e4a0e9b7c9b 100644 (file)
@@ -277,7 +277,6 @@ static int octeon_usb_urb_enqueue(struct usb_hcd *hcd,
                        }
                }
                pipe_handle = cvmx_usb_open_pipe(&priv->usb,
-                                                0,
                                                 usb_pipedevice(urb->pipe),
                                                 usb_pipeendpoint(urb->pipe),
                                                 speed,
@@ -325,7 +324,6 @@ static int octeon_usb_urb_enqueue(struct usb_hcd *hcd,
                        urb->setup_packet = (char *)iso_packet;
                        submit_handle = cvmx_usb_submit_isochronous(&priv->usb, pipe_handle,
                                                        urb->start_frame,
-                                                       0 /* flags */ ,
                                                        urb->number_of_packets,
                                                        iso_packet,
                                                        urb->transfer_dma,
@@ -705,7 +703,7 @@ static int octeon_usb_driver_probe(struct device *dev)
        tasklet_init(&priv->dequeue_tasklet, octeon_usb_urb_dequeue_work, (unsigned long)priv);
        INIT_LIST_HEAD(&priv->dequeue_list);
 
-       status = cvmx_usb_initialize(&priv->usb, usb_num, CVMX_USB_INITIALIZE_FLAGS_CLOCK_AUTO);
+       status = cvmx_usb_initialize(&priv->usb, usb_num);
        if (status) {
                dev_dbg(dev, "USB initialization failed with %d\n", status);
                kfree(hcd);
index 6e81ba0eaf1e5542346c7a04121333d4193aedc4..82a77b45fb50901df1bfb0aba005da9375313517 100644 (file)
@@ -141,7 +141,7 @@ static uint loadparam(struct _adapter *padapter, struct  net_device *pnetdev)
        registry_par->ssid.SsidLength = 3;
        registry_par->channel = (u8)channel;
        registry_par->wireless_mode = (u8)wireless_mode;
-       registry_par->vrtl_carrier_sense = (u8)vrtl_carrier_sense ;
+       registry_par->vrtl_carrier_sense = (u8)vrtl_carrier_sense;
        registry_par->vcs_type = (u8)vcs_type;
        registry_par->frag_thresh = (u16)frag_thresh;
        registry_par->preamble = (u8)preamble;
index 53f247b324e019176d2a9a7a5d48b3f455c53a63..5b6a96e3bd7b15db5f8c2a34fc9dc592a61fd2cd 100644 (file)
@@ -62,7 +62,7 @@ static void check_hw_pbc(struct _adapter *padapter)
        r8712_write8(padapter, GPIO_IO_SEL, tmp1byte);
        tmp1byte = r8712_read8(padapter, GPIO_CTRL);
        if (tmp1byte == 0xff)
-               return ;
+               return;
        if (tmp1byte&HAL_8192S_HW_GPIO_WPS_BIT) {
                /* Here we only set bPbcPressed to true
                 * After trigger PBC, the variable will be set to false */
@@ -381,7 +381,7 @@ _next:
                        *pcmdbuf = cpu_to_le32((cmdsz & 0x0000ffff) |
                                               (pcmd->cmdcode << 16) |
                                               (pcmdpriv->cmd_seq << 24));
-                       pcmdbuf += 2 ; /* 8 bytes alignment */
+                       pcmdbuf += 2; /* 8 bytes alignment */
                        memcpy((u8 *)pcmdbuf, pcmd->parmbuf, pcmd->cmdsz);
                        while (check_cmd_fifo(padapter, wr_sz) == _FAIL) {
                                if ((padapter->bDriverStopped == true) ||
index 377fca905801aa974749ac9943d13efee51d5bec..c9eeb4270ab9d84e4a8619d8f4d9270bfe9ba085 100644 (file)
@@ -231,7 +231,7 @@ u16 r8712_efuse_get_current_size(struct _adapter *padapter)
                        /* read next header */
                        efuse_addr = efuse_addr + (word_cnts * 2) + 1;
                } else
-                       bContinual = false ;
+                       bContinual = false;
        }
        return efuse_addr;
 }
index d59a74aa30489f2bf70c9f6b8a450d8ddaf4b484..ea965370d1ac9ed0bc5520721532b8d15419adfd 100644 (file)
@@ -108,7 +108,7 @@ void r8712_free_recv_priv(struct recv_priv *precvpriv)
        struct _adapter *padapter = precvpriv->adapter;
 
        precvbuf = (struct recv_buf *)precvpriv->precv_buf;
-       for (i = 0; i < NR_RECVBUFF ; i++) {
+       for (i = 0; i < NR_RECVBUFF; i++) {
                r8712_os_recvbuf_resource_free(padapter, precvbuf);
                precvbuf++;
        }
@@ -268,7 +268,7 @@ union recv_frame *r8712_recvframe_chk_defrag(struct _adapter *padapter,
        u8   *psta_addr;
        struct recv_frame_hdr *pfhdr;
        struct sta_info *psta;
-       struct  sta_priv *pstapriv ;
+       struct  sta_priv *pstapriv;
        struct list_head *phead;
        union recv_frame *prtnframe = NULL;
        struct  __queue *pfree_recv_queue, *pdefrag_q;
@@ -849,7 +849,7 @@ static void query_rx_phy_status(struct _adapter *padapter,
        } else {
                /* (1)Get RSSI for HT rate */
                for (i = 0; i < ((padapter->registrypriv.rf_config) &
-                           0x0f) ; i++) {
+                           0x0f); i++) {
                        rf_rx_num++;
                        rx_pwr[i] = ((pphy_head[PHY_STAT_GAIN_TRSW_SHT + i]
                                    & 0x3F) * 2) - 110;
index f16307f5d827e72707996c1299c8636e3448e000..7e324315e6ad30846166b9ea9a5bd0f2662e349a 100644 (file)
@@ -965,7 +965,7 @@ void r8712_createbss_cmd_callback(struct _adapter *padapter,
                        psta = r8712_alloc_stainfo(&padapter->stapriv,
                                                   pnetwork->MacAddress);
                        if (psta == NULL)
-                               goto createbss_cmd_fail ;
+                               goto createbss_cmd_fail;
                }
                r8712_indicate_connect(padapter);
        } else {
index d58aa7e3b15cef799726d8bb4f4e656ddfaf7c91..9fec6eda8731c91612f038b370d5258b7adc6c3c 100644 (file)
@@ -820,7 +820,7 @@ static int r871x_wx_set_pmkid(struct net_device *dev,
                        intReturn = true;
                blInserted = false;
                /* overwrite PMKID */
-               for (j = 0 ; j < NUM_PMKID_CACHE; j++) {
+               for (j = 0; j < NUM_PMKID_CACHE; j++) {
                        if (!memcmp(psecuritypriv->PMKIDList[j].Bssid,
                            strIssueBssid, ETH_ALEN)) {
                                /* BSSID is matched, the same AP => rewrite
@@ -845,7 +845,7 @@ static int r871x_wx_set_pmkid(struct net_device *dev,
                                PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN);
                        psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].
                                bUsed = true;
-                       psecuritypriv->PMKIDIndex++ ;
+                       psecuritypriv->PMKIDIndex++;
                        if (psecuritypriv->PMKIDIndex == NUM_PMKID_CACHE)
                                psecuritypriv->PMKIDIndex = 0;
                }
@@ -1598,7 +1598,7 @@ static int r8711_wx_set_enc(struct net_device *dev,
                wep.Length = wep.KeyLength +
                             FIELD_OFFSET(struct NDIS_802_11_WEP, KeyMaterial);
        } else {
-               wep.KeyLength = 0 ;
+               wep.KeyLength = 0;
                if (keyindex_provided == 1) { /* set key_id only, no given
                                               * KeyMaterial(erq->length==0).*/
                        padapter->securitypriv.PrivacyKeyIndex = key;
@@ -1880,7 +1880,7 @@ static int r8711_wx_write32(struct net_device *dev,
        u32 data32;
 
        get_user(addr, (u32 __user *)wrqu->data.pointer);
-       data32 = ((u32)wrqu->data.length<<16) | (u32)wrqu->data.flags ;
+       data32 = ((u32)wrqu->data.length<<16) | (u32)wrqu->data.flags;
        r8712_write32(padapter, addr, data32);
        return 0;
 }
index 5d6d55e7b38909d316b4ffa4528b5037170072ed..ac0baff7f090e5f12e9d552fb8162ec4d398e2f2 100644 (file)
@@ -153,7 +153,7 @@ uint oid_rt_get_rx_icv_err_hdl(struct oid_par_priv *poid_par_priv)
                                         padapter->recvpriv.rx_icv_err;
                *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
        } else
-               return RNDIS_STATUS_INVALID_LENGTH ;
+               return RNDIS_STATUS_INVALID_LENGTH;
        return RNDIS_STATUS_SUCCESS;
 }
 
@@ -169,7 +169,7 @@ uint oid_rt_get_preamble_mode_hdl(struct oid_par_priv *poid_par_priv)
 {
        struct _adapter *padapter = (struct _adapter *)
                                    (poid_par_priv->adapter_context);
-       u32 preamblemode = 0 ;
+       u32 preamblemode = 0;
 
        if (poid_par_priv->type_of_oid != QUERY_OID)
                return RNDIS_STATUS_NOT_ACCEPTED;
@@ -522,7 +522,7 @@ uint oid_rt_get_connect_state_hdl(struct oid_par_priv *poid_par_priv)
        else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true)
                ulInfo = ADHOCMODE;
        else
-               ulInfo = NOTASSOCIATED ;
+               ulInfo = NOTASSOCIATED;
        *(u32 *)poid_par_priv->information_buf = ulInfo;
        *poid_par_priv->bytes_rw =  poid_par_priv->information_buf_len;
        return RNDIS_STATUS_SUCCESS;
index 659615481f6f4c1b8d387c572cc063a11cd9492c..8fa0f9d49a8aedb6800d25e07b004a61c4a18531 100644 (file)
@@ -1641,7 +1641,7 @@ void r8712_update_registrypriv_dev_network(struct _adapter *adapter)
        struct wlan_network     *cur_network = &adapter->mlmepriv.cur_network;
 
        pdev_network->Privacy = cpu_to_le32(psecuritypriv->PrivacyAlgrthm
-                                           > 0 ? 1 : 0) ; /* adhoc no 802.1x */
+                                           > 0 ? 1 : 0); /* adhoc no 802.1x */
        pdev_network->Rssi = 0;
        switch (pregistrypriv->wireless_mode) {
        case WIRELESS_11B:
@@ -1786,7 +1786,7 @@ static void update_ht_cap(struct _adapter *padapter, u8 *pie, uint ie_len)
        psta = r8712_get_stainfo(&padapter->stapriv,
                                 pcur_network->network.MacAddress);
        if (psta) {
-               for (i = 0; i < 16 ; i++) {
+               for (i = 0; i < 16; i++) {
                        preorder_ctrl = &psta->recvreorder_ctrl[i];
                        preorder_ctrl->indicate_seq = 0xffff;
                        preorder_ctrl->wend_b = 0xffff;
index 5638d5e065ff7a05c919712040abb9300adcb16f..0563318a19ff40962984dd8b3094f34c3680ec29 100644 (file)
@@ -110,7 +110,7 @@ static u32 fw_iocmd_read(struct _adapter *pAdapter, struct IOCMD_STRUCT iocmd)
        u16 iocmd_value = iocmd.value;
        u8 iocmd_idx    = iocmd.index;
 
-       cmd32 = (iocmd_class << 24) | (iocmd_value << 8) | iocmd_idx ;
+       cmd32 = (iocmd_class << 24) | (iocmd_value << 8) | iocmd_idx;
        if (r8712_fw_cmd(pAdapter, cmd32))
                r8712_fw_cmd_data(pAdapter, &val32, 1);
        else
@@ -128,7 +128,7 @@ static u8 fw_iocmd_write(struct _adapter *pAdapter,
 
        r8712_fw_cmd_data(pAdapter, &value, 0);
        msleep(100);
-       cmd32 = (iocmd_class << 24) | (iocmd_value << 8) | iocmd_idx ;
+       cmd32 = (iocmd_class << 24) | (iocmd_value << 8) | iocmd_idx;
        return r8712_fw_cmd(pAdapter, cmd32);
 }
 
@@ -189,8 +189,8 @@ u32 r8712_rf_reg_read(struct _adapter *pAdapter, u8 path, u8 offset)
        u32 rf_data;
        struct IOCMD_STRUCT iocmd;
 
-       iocmd.cmdclass  = IOCMD_CLASS_BB_RF ;
-       iocmd.value     = rf_addr ;
+       iocmd.cmdclass  = IOCMD_CLASS_BB_RF;
+       iocmd.value     = rf_addr;
        iocmd.index     = IOCMD_RF_READ_IDX;
        rf_data = fw_iocmd_read(pAdapter, iocmd);
        return rf_data;
index e33fd6db246d9e80bd43aa732a2c86c23f2e1444..5349669707c04d7785564cfd1e153a90ff6e8578 100644 (file)
@@ -835,7 +835,7 @@ static void mix_column(u8 *in, u8 *out)
        u8 temp[4];
        u8 tempb[4];
 
-       for (i = 0 ; i < 4; i++) {
+       for (i = 0; i < 4; i++) {
                if ((in[i] & 0x80) == 0x80)
                        add1b[i] = 0x1b;
                else
@@ -1187,7 +1187,7 @@ u32 r8712_aes_encrypt(struct _adapter *padapter, u8 *pxmitframe)
                                        length = pxmitpriv->frag_len -
                                                 pattrib->hdrlen -
                                                 pattrib->iv_len -
-                                                pattrib->icv_len ;
+                                                pattrib->icv_len;
                                        aes_cipher(prwskey, pattrib->
                                                   hdrlen, pframe, length);
                                        pframe += pxmitpriv->frag_len;
@@ -1315,7 +1315,7 @@ static sint aes_decipher(u8 *key, uint    hdrlen,
                bitwise_xor(aes_out, padded_buffer, chain_buffer);
                aes128k128d(key, chain_buffer, aes_out);
        }
-       for (j = 0 ; j < 8; j++)
+       for (j = 0; j < 8; j++)
                mic[j] = aes_out[j];
        /* Insert MIC into payload */
        for (j = 0; j < 8; j++)
index 1247b3d9719db5f279e770bbf8cd2234d38cc7be..8db6849d4b24a0f35e438a0bf369dd9c69833465 100644 (file)
@@ -138,7 +138,7 @@ struct sta_info *r8712_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
                }
                phash_list = &(pstapriv->sta_hash[index]);
                list_insert_tail(&psta->hash_list, phash_list);
-               pstapriv->asoc_sta_count++ ;
+               pstapriv->asoc_sta_count++;
 
 /* For the SMC router, the sequence number of first packet of WPS handshake
  * will be 0. In this case, this packet will be dropped by recv_decache function
@@ -149,7 +149,7 @@ struct sta_info *r8712_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
                        memcpy(&psta->sta_recvpriv.rxcache.tid_rxseq[i],
                                &wRxSeqInitialValue, 2);
                /* for A-MPDU Rx reordering buffer control */
-               for (i = 0; i < 16 ; i++) {
+               for (i = 0; i < 16; i++) {
                        preorder_ctrl = &psta->recvreorder_ctrl[i];
                        preorder_ctrl->padapter = pstapriv->padapter;
                        preorder_ctrl->indicate_seq = 0xffff;
index 4d22bb7008f8456e378c3568d3252be7ede9a79f..0ac9130faf6cad9cb298e8b8a44e9863a81328cf 100644 (file)
@@ -51,7 +51,7 @@ void _r8712_open_pktfile(_pkt *pktptr, struct pkt_file *pfile)
        pfile->pkt = pktptr;
        pfile->cur_addr = pfile->buf_start = pktptr->data;
        pfile->pkt_len = pfile->buf_len = pktptr->len;
-       pfile->cur_buffer = pfile->buf_start ;
+       pfile->cur_buffer = pfile->buf_start;
 }
 
 uint _r8712_pktfile_read(struct pkt_file *pfile, u8 *rmem, uint rlen)
index 6a98a208bbf2895b0a978cd10658edf7e7f51ae0..11f5b211745758bb42dd6eb2190620282109ea1c 100644 (file)
@@ -1263,13 +1263,8 @@ static int sep_lock_user_pages(struct sep_device *sep,
        }
 
        /* Convert the application virtual address into a set of physical */
-       down_read(&current->mm->mmap_sem);
-       result = get_user_pages(current, current->mm, app_virt_addr,
-               num_pages,
-               ((in_out_flag == SEP_DRIVER_IN_FLAG) ? 0 : 1),
-               0, page_array, NULL);
-
-       up_read(&current->mm->mmap_sem);
+       result = get_user_pages_fast(app_virt_addr, num_pages,
+               ((in_out_flag == SEP_DRIVER_IN_FLAG) ? 0 : 1), page_array);
 
        /* Check the number of pages locked - if not all then exit with error */
        if (result != num_pages) {
index cfa1f43fa4af08a6ffaa4d09a0d9202458c15ece..8154a7bf050fe7a1d7607e80bdbc889669b3b972 100644 (file)
@@ -22,7 +22,7 @@ do {                                          \
        int  i;                                 \
        if (1) {                                \
                for (i = 0; i < 1000; i++) {    \
-                       udelay(x) ;             \
+                       udelay(x)             \
                }                               \
        } else {                                \
                msleep(x);                      \
index 14079c4949a8038e801474a2842f09e38e5bd403..47502fa5f3f60a50db71b21a90be9dc9ce9c54ba 100644 (file)
@@ -90,7 +90,7 @@ const struct st_bits_data spk_punc_info[] = {
        {"repeats", "()", CH_RPT},
        {"extended numeric", "", B_EXNUM},
        {"symbols", "", B_SYM},
-       {0, 0}
+       {NULL, NULL}
 };
 
 static char mark_cut_flag;
index 3508aee98ab0651e06b831c22d8e3dd80f975ce3..61a3ceeb0d3ae081258400749cfa68110d24e7a2 100644 (file)
@@ -39,7 +39,7 @@ static struct var_t vars[] = {
        { RATE, .u.n = {"\x05[r%d]", 10, 0, 20, 100, -10, NULL } },
        { PITCH, .u.n = {"\x05[f%d]", 80, 39, 4500, 0, 0, NULL } },
        { VOL, .u.n = {"\x05[g%d]", 21, 0, 40, 0, 0, NULL } },
-       { TONE, .u.n = {"\x05[s%d]", 9, 0, 63, 0, 0, 0 } },
+       { TONE, .u.n = {"\x05[s%d]", 9, 0, 63, 0, 0, NULL } },
        { PUNCT, .u.n = {"\x05[A%c]", 0, 0, 3, 0, 0, "nmsa" } },
        { DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL } },
        V_LAST_VAR
index 9aa2a78cd71cd87dfad5785a9fab9d2f26e497e2..70231b6dabbaab5dd51b8d8484deb364ad905948 100644 (file)
@@ -46,7 +46,7 @@ static struct st_var_header var_headers[] = {
        { "direct", DIRECT, VAR_NUM, NULL, NULL },
 };
 
-static struct st_var_header *var_ptrs[MAXVARS] = { 0, 0, 0 };
+static struct st_var_header *var_ptrs[MAXVARS] = { NULL, NULL, NULL };
 
 static struct punc_var_t punc_vars[] = {
        { PUNC_SOME, 1 },
index 6b12d0cc6ef2c6fee610bcfe3e148b7bf356b32a..93eba18a1b9952076c912da68a71848f6e5f7ae3 100644 (file)
@@ -98,15 +98,11 @@ static void s_vSaveTxPktInfo(struct vnt_private *pDevice, u8 byPktNum,
 
 static void *s_vGetFreeContext(struct vnt_private *pDevice);
 
-static void s_vGenerateTxParameter(struct vnt_private *pDevice,
+static u16 s_vGenerateTxParameter(struct vnt_private *pDevice,
        u8 byPktType, u16 wCurrentRate, struct vnt_tx_buffer *tx_buffer,
        struct vnt_mic_hdr **mic_hdr, u32 need_mic, u32 cbFrameSize,
        int bNeedACK, u32 uDMAIdx, struct ethhdr *psEthHeader, bool need_rts);
 
-static u32 s_uFillDataHead(struct vnt_private *pDevice,
-       u8 byPktType, u16 wCurrentRate, void *pTxDataHead, u32 cbFrameLength,
-       u32 uDMAIdx, int bNeedAck, u8 byFBOption);
-
 static void s_vGenerateMACHeader(struct vnt_private *pDevice,
        u8 *pbyBufferAddr, u16 wDuration, struct ethhdr *psEthHeader,
        int bNeedEncrypt, u16 wFragType, u32 uDMAIdx, u32 uFragIdx);
@@ -124,11 +120,11 @@ static unsigned int s_uGetTxRsvTime(struct vnt_private *pDevice, u8 byPktType,
 static u16 s_uGetRTSCTSRsvTime(struct vnt_private *pDevice, u8 byRTSRsvType,
        u8 byPktType, u32 cbFrameLength, u16 wCurrentRate);
 
-static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
+static u16 s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
        u8 byPktType, union vnt_tx_data_head *head, u32 cbFrameLength,
        int bNeedAck, u16 wCurrentRate, u8 byFBOption);
 
-static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
+static u16 s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
        union vnt_tx_data_head *head, u32 cbFrameLength, int bNeedAck,
        struct ethhdr *psEthHeader, u16 wCurrentRate, u8 byFBOption);
 
@@ -511,105 +507,78 @@ static u16 s_uGetRTSCTSDuration(struct vnt_private *pDevice, u8 byDurType,
        return cpu_to_le16((u16)uDurTime);
 }
 
-static u32 s_uFillDataHead(struct vnt_private *pDevice,
-       u8 byPktType, u16 wCurrentRate, void *pTxDataHead, u32 cbFrameLength,
-       u32 uDMAIdx, int bNeedAck, u8 byFBOption)
+static u16 vnt_rxtx_datahead_g(struct vnt_private *priv, u8 pkt_type, u16 rate,
+               struct vnt_tx_datahead_g *buf, u32 frame_len, int need_ack)
 {
+       /* Get SignalField,ServiceField,Length */
+       BBvCalculateParameter(priv, frame_len, rate, pkt_type, &buf->a);
+       BBvCalculateParameter(priv, frame_len, priv->byTopCCKBasicRate,
+                                                       PK_TYPE_11B, &buf->b);
 
-    if (pTxDataHead == NULL) {
-        return 0;
-    }
+       /* Get Duration and TimeStamp */
+       buf->wDuration_a = s_uGetDataDuration(priv, pkt_type, need_ack);
+       buf->wDuration_b = s_uGetDataDuration(priv, PK_TYPE_11B, need_ack);
 
-    if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
-            if (byFBOption == AUTO_FB_NONE) {
-               struct vnt_tx_datahead_g *pBuf =
-                               (struct vnt_tx_datahead_g *)pTxDataHead;
-                //Get SignalField,ServiceField,Length
-               BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate,
-                       byPktType, &pBuf->a);
-               BBvCalculateParameter(pDevice, cbFrameLength,
-                       pDevice->byTopCCKBasicRate, PK_TYPE_11B, &pBuf->b);
-                //Get Duration and TimeStamp
-               pBuf->wDuration_a = s_uGetDataDuration(pDevice,
-                                                       byPktType, bNeedAck);
-               pBuf->wDuration_b = s_uGetDataDuration(pDevice,
-                                                       PK_TYPE_11B, bNeedAck);
-
-               pBuf->wTimeStampOff_a = vnt_time_stamp_off(pDevice,
-                                                               wCurrentRate);
-               pBuf->wTimeStampOff_b = vnt_time_stamp_off(pDevice,
-                                               pDevice->byTopCCKBasicRate);
-                return (pBuf->wDuration_a);
-             } else {
-                // Auto Fallback
-               struct vnt_tx_datahead_g_fb *pBuf =
-                       (struct vnt_tx_datahead_g_fb *)pTxDataHead;
-                //Get SignalField,ServiceField,Length
-               BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate,
-                       byPktType, &pBuf->a);
-               BBvCalculateParameter(pDevice, cbFrameLength,
-                       pDevice->byTopCCKBasicRate, PK_TYPE_11B, &pBuf->b);
-                //Get Duration and TimeStamp
-               pBuf->wDuration_a = s_uGetDataDuration(pDevice,
-                                                       byPktType, bNeedAck);
-               pBuf->wDuration_b = s_uGetDataDuration(pDevice,
-                                                       PK_TYPE_11B, bNeedAck);
-               pBuf->wDuration_a_f0 = s_uGetDataDuration(pDevice,
-                                                       byPktType, bNeedAck);
-               pBuf->wDuration_a_f1 = s_uGetDataDuration(pDevice,
-                                                       byPktType, bNeedAck);
-               pBuf->wTimeStampOff_a = vnt_time_stamp_off(pDevice,
-                                                               wCurrentRate);
-               pBuf->wTimeStampOff_b = vnt_time_stamp_off(pDevice,
-                                               pDevice->byTopCCKBasicRate);
-                return (pBuf->wDuration_a);
-            } //if (byFBOption == AUTO_FB_NONE)
-    }
-    else if (byPktType == PK_TYPE_11A) {
-       if (byFBOption != AUTO_FB_NONE) {
-               struct vnt_tx_datahead_a_fb *pBuf =
-                       (struct vnt_tx_datahead_a_fb *)pTxDataHead;
-            //Get SignalField,ServiceField,Length
-               BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate,
-                       byPktType, &pBuf->a);
-            //Get Duration and TimeStampOff
-               pBuf->wDuration = s_uGetDataDuration(pDevice,
-                                       byPktType, bNeedAck);
-               pBuf->wDuration_f0 = s_uGetDataDuration(pDevice,
-                                       byPktType, bNeedAck);
-               pBuf->wDuration_f1 = s_uGetDataDuration(pDevice,
-                                                       byPktType, bNeedAck);
-               pBuf->wTimeStampOff = vnt_time_stamp_off(pDevice,
-                                                               wCurrentRate);
-            return (pBuf->wDuration);
-        } else {
-               struct vnt_tx_datahead_ab *pBuf =
-                       (struct vnt_tx_datahead_ab *)pTxDataHead;
-            //Get SignalField,ServiceField,Length
-               BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate,
-                       byPktType, &pBuf->ab);
-            //Get Duration and TimeStampOff
-               pBuf->wDuration = s_uGetDataDuration(pDevice,
-                               byPktType, bNeedAck);
-               pBuf->wTimeStampOff = vnt_time_stamp_off(pDevice,
-                                                               wCurrentRate);
-            return (pBuf->wDuration);
-        }
-    }
-    else if (byPktType == PK_TYPE_11B) {
-               struct vnt_tx_datahead_ab *pBuf =
-                       (struct vnt_tx_datahead_ab *)pTxDataHead;
-            //Get SignalField,ServiceField,Length
-               BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate,
-                       byPktType, &pBuf->ab);
-            //Get Duration and TimeStampOff
-               pBuf->wDuration = s_uGetDataDuration(pDevice,
-                               byPktType, bNeedAck);
-               pBuf->wTimeStampOff = vnt_time_stamp_off(pDevice,
-                                                               wCurrentRate);
-            return (pBuf->wDuration);
-    }
-    return 0;
+       buf->wTimeStampOff_a = vnt_time_stamp_off(priv, rate);
+       buf->wTimeStampOff_b = vnt_time_stamp_off(priv,
+                                       priv->byTopCCKBasicRate);
+
+       return buf->wDuration_a;
+}
+
+static u16 vnt_rxtx_datahead_g_fb(struct vnt_private *priv, u8 pkt_type,
+               u16 rate, struct vnt_tx_datahead_g_fb *buf,
+               u32 frame_len, int need_ack)
+{
+       /* Get SignalField,ServiceField,Length */
+       BBvCalculateParameter(priv, frame_len, rate, pkt_type, &buf->a);
+
+       BBvCalculateParameter(priv, frame_len, priv->byTopCCKBasicRate,
+                                               PK_TYPE_11B, &buf->b);
+
+       /* Get Duration and TimeStamp */
+       buf->wDuration_a = s_uGetDataDuration(priv, pkt_type, need_ack);
+       buf->wDuration_b = s_uGetDataDuration(priv, PK_TYPE_11B, need_ack);
+
+       buf->wDuration_a_f0 = s_uGetDataDuration(priv, pkt_type, need_ack);
+       buf->wDuration_a_f1 = s_uGetDataDuration(priv, pkt_type, need_ack);
+
+       buf->wTimeStampOff_a = vnt_time_stamp_off(priv, rate);
+       buf->wTimeStampOff_b = vnt_time_stamp_off(priv,
+                                               priv->byTopCCKBasicRate);
+
+       return buf->wDuration_a;
+}
+
+static u16 vnt_rxtx_datahead_a_fb(struct vnt_private *priv, u8 pkt_type,
+               u16 rate, struct vnt_tx_datahead_a_fb *buf,
+               u32 frame_len, int need_ack)
+{
+       /* Get SignalField,ServiceField,Length */
+       BBvCalculateParameter(priv, frame_len, rate, pkt_type, &buf->a);
+       /* Get Duration and TimeStampOff */
+       buf->wDuration = s_uGetDataDuration(priv, pkt_type, need_ack);
+
+       buf->wDuration_f0 = s_uGetDataDuration(priv, pkt_type, need_ack);
+       buf->wDuration_f1 = s_uGetDataDuration(priv, pkt_type, need_ack);
+
+       buf->wTimeStampOff = vnt_time_stamp_off(priv, rate);
+
+       return buf->wDuration;
+}
+
+static u16 vnt_rxtx_datahead_ab(struct vnt_private *priv, u8 pkt_type,
+               u16 rate, struct vnt_tx_datahead_ab *buf,
+               u32 frame_len, int need_ack)
+{
+       /* Get SignalField,ServiceField,Length */
+       BBvCalculateParameter(priv, frame_len, rate, pkt_type, &buf->ab);
+       /* Get Duration and TimeStampOff */
+       buf->wDuration = s_uGetDataDuration(priv, pkt_type, need_ack);
+
+       buf->wTimeStampOff = vnt_time_stamp_off(priv, rate);
+
+       return buf->wDuration;
 }
 
 static int vnt_fill_ieee80211_rts(struct vnt_private *priv,
@@ -632,7 +601,7 @@ static int vnt_fill_ieee80211_rts(struct vnt_private *priv,
        return 0;
 }
 
-static int vnt_rxtx_rts_g_head(struct vnt_private *priv,
+static u16 vnt_rxtx_rts_g_head(struct vnt_private *priv,
        struct vnt_rts_g *buf, struct ethhdr *eth_hdr,
        u8 pkt_type, u32 frame_len, int need_ack,
        u16 current_rate, u8 fb_option)
@@ -653,10 +622,11 @@ static int vnt_rxtx_rts_g_head(struct vnt_private *priv,
 
        vnt_fill_ieee80211_rts(priv, &buf->data, eth_hdr, buf->wDuration_aa);
 
-       return 0;
+       return vnt_rxtx_datahead_g(priv, pkt_type, current_rate,
+                       &buf->data_head, frame_len, need_ack);
 }
 
-static int vnt_rxtx_rts_g_fb_head(struct vnt_private *priv,
+static u16 vnt_rxtx_rts_g_fb_head(struct vnt_private *priv,
        struct vnt_rts_g_fb *buf, struct ethhdr *eth_hdr,
        u8 pkt_type, u32 frame_len, int need_ack,
        u16 current_rate, u8 fb_option)
@@ -688,10 +658,11 @@ static int vnt_rxtx_rts_g_fb_head(struct vnt_private *priv,
 
        vnt_fill_ieee80211_rts(priv, &buf->data, eth_hdr, buf->wDuration_aa);
 
-       return 0;
+       return vnt_rxtx_datahead_g_fb(priv, pkt_type, current_rate,
+                       &buf->data_head, frame_len, need_ack);
 }
 
-static int vnt_rxtx_rts_ab_head(struct vnt_private *priv,
+static u16 vnt_rxtx_rts_ab_head(struct vnt_private *priv,
        struct vnt_rts_ab *buf, struct ethhdr *eth_hdr,
        u8 pkt_type, u32 frame_len, int need_ack,
        u16 current_rate, u8 fb_option)
@@ -706,10 +677,11 @@ static int vnt_rxtx_rts_ab_head(struct vnt_private *priv,
 
        vnt_fill_ieee80211_rts(priv, &buf->data, eth_hdr, buf->wDuration);
 
-       return 0;
+       return vnt_rxtx_datahead_ab(priv, pkt_type, current_rate,
+                       &buf->data_head, frame_len, need_ack);
 }
 
-static int vnt_rxtx_rts_a_fb_head(struct vnt_private *priv,
+static u16 vnt_rxtx_rts_a_fb_head(struct vnt_private *priv,
        struct vnt_rts_a_fb *buf, struct ethhdr *eth_hdr,
        u8 pkt_type, u32 frame_len, int need_ack,
        u16 current_rate, u8 fb_option)
@@ -730,16 +702,17 @@ static int vnt_rxtx_rts_a_fb_head(struct vnt_private *priv,
 
        vnt_fill_ieee80211_rts(priv, &buf->data, eth_hdr, buf->wDuration);
 
-       return 0;
+       return vnt_rxtx_datahead_a_fb(priv, pkt_type, current_rate,
+                       &buf->data_head, frame_len, need_ack);
 }
 
-static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
+static u16 s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
        union vnt_tx_data_head *head, u32 cbFrameLength, int bNeedAck,
        struct ethhdr *psEthHeader, u16 wCurrentRate, u8 byFBOption)
 {
 
        if (!head)
-               return;
+               return 0;
 
        /* Note: So far RTSHead doesn't appear in ATIM
        *       & Beacom DMA, so we don't need to take them
@@ -750,36 +723,38 @@ static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
        case PK_TYPE_11GB:
        case PK_TYPE_11GA:
                if (byFBOption == AUTO_FB_NONE)
-                       vnt_rxtx_rts_g_head(pDevice, &head->rts_g,
+                       return vnt_rxtx_rts_g_head(pDevice, &head->rts_g,
                                psEthHeader, byPktType, cbFrameLength,
                                bNeedAck, wCurrentRate, byFBOption);
                else
-                       vnt_rxtx_rts_g_fb_head(pDevice, &head->rts_g_fb,
+                       return vnt_rxtx_rts_g_fb_head(pDevice, &head->rts_g_fb,
                                psEthHeader, byPktType, cbFrameLength,
                                bNeedAck, wCurrentRate, byFBOption);
                break;
        case PK_TYPE_11A:
                if (byFBOption) {
-                       vnt_rxtx_rts_a_fb_head(pDevice, &head->rts_a_fb,
+                       return vnt_rxtx_rts_a_fb_head(pDevice, &head->rts_a_fb,
                                psEthHeader, byPktType, cbFrameLength,
                                bNeedAck, wCurrentRate, byFBOption);
                        break;
                }
        case PK_TYPE_11B:
-               vnt_rxtx_rts_ab_head(pDevice, &head->rts_ab,
+               return vnt_rxtx_rts_ab_head(pDevice, &head->rts_ab,
                        psEthHeader, byPktType, cbFrameLength,
                        bNeedAck, wCurrentRate, byFBOption);
        }
+
+       return 0;
 }
 
-static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
+static u16 s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
        u8 byPktType, union vnt_tx_data_head *head, u32 cbFrameLength,
        int bNeedAck, u16 wCurrentRate, u8 byFBOption)
 {
        u32 uCTSFrameLen = 14;
 
        if (!head)
-               return;
+               return 0;
 
        if (byFBOption != AUTO_FB_NONE) {
                /* Auto Fall back */
@@ -802,6 +777,9 @@ static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
                pBuf->data.duration = pBuf->wDuration_ba;
                pBuf->data.frame_control = TYPE_CTL_CTS;
                memcpy(pBuf->data.ra, pDevice->abyCurrentNetAddr, ETH_ALEN);
+
+               return vnt_rxtx_datahead_g_fb(pDevice, byPktType, wCurrentRate,
+                               &pBuf->data_head, cbFrameLength, bNeedAck);
        } else {
                struct vnt_cts *pBuf = &head->cts_g;
                /* Get SignalField,ServiceField,Length */
@@ -815,7 +793,12 @@ static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
                pBuf->data.duration = pBuf->wDuration_ba;
                pBuf->data.frame_control = TYPE_CTL_CTS;
                memcpy(pBuf->data.ra, pDevice->abyCurrentNetAddr, ETH_ALEN);
+
+               return vnt_rxtx_datahead_g(pDevice, byPktType, wCurrentRate,
+                               &pBuf->data_head, cbFrameLength, bNeedAck);
         }
+
+       return 0;
 }
 
 /*+
@@ -841,7 +824,7 @@ static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
  *
 -*/
 
-static void s_vGenerateTxParameter(struct vnt_private *pDevice,
+static u16 s_vGenerateTxParameter(struct vnt_private *pDevice,
        u8 byPktType, u16 wCurrentRate, struct vnt_tx_buffer *tx_buffer,
        struct vnt_mic_hdr **mic_hdr, u32 need_mic, u32 cbFrameSize,
        int bNeedACK, u32 uDMAIdx, struct ethhdr *psEthHeader, bool need_rts)
@@ -864,7 +847,7 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice,
     }
 
        if (!pFifoHead)
-               return;
+               return 0;
 
     if (pDevice->bLongHeader)
         cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6;
@@ -894,7 +877,7 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice,
                }
 
                /* Fill RTS */
-               s_vFillRTSHead(pDevice, byPktType, head, cbFrameSize,
+               return s_vFillRTSHead(pDevice, byPktType, head, cbFrameSize,
                        bNeedACK, psEthHeader, wCurrentRate, byFBOption);
         }
         else {//RTS_needless, PCF mode
@@ -917,11 +900,18 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice,
                }
 
                /* Fill CTS */
-               s_vFillCTSHead(pDevice, uDMAIdx, byPktType, head,
+               return s_vFillCTSHead(pDevice, uDMAIdx, byPktType, head,
                        cbFrameSize, bNeedACK, wCurrentRate, byFBOption);
         }
     }
     else if (byPktType == PK_TYPE_11A) {
+       if (need_mic) {
+               *mic_hdr = &tx_buffer->tx_head.tx_ab.tx.mic.hdr;
+               head = &tx_buffer->tx_head.tx_ab.tx.mic.head;
+       } else {
+               head = &tx_buffer->tx_head.tx_ab.tx.head;
+       }
+
        if (need_rts) {
             //Fill RsvTime
                struct vnt_rrv_time_ab *pBuf = &tx_buffer->tx_head.tx_ab.ab;
@@ -931,28 +921,28 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice,
                pBuf->wTxRrvTime = vnt_rxtx_rsvtime_le16(pDevice, byPktType,
                                cbFrameSize, wCurrentRate, bNeedACK);
 
-               if (need_mic) {
-                       *mic_hdr = &tx_buffer->tx_head.tx_ab.tx.mic.hdr;
-                       head = &tx_buffer->tx_head.tx_ab.tx.mic.head;
-               } else {
-                       head = &tx_buffer->tx_head.tx_ab.tx.head;
-               }
-
                /* Fill RTS */
-               s_vFillRTSHead(pDevice, byPktType, head, cbFrameSize,
+               return s_vFillRTSHead(pDevice, byPktType, head, cbFrameSize,
                        bNeedACK, psEthHeader, wCurrentRate, byFBOption);
        } else {
             //Fill RsvTime
                struct vnt_rrv_time_ab *pBuf = &tx_buffer->tx_head.tx_ab.ab;
 
-               if (need_mic)
-                       *mic_hdr = &tx_buffer->tx_head.tx_ab.tx.mic.hdr;
-
                pBuf->wTxRrvTime = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11A,
                        cbFrameSize, wCurrentRate, bNeedACK);
+
+               return vnt_rxtx_datahead_a_fb(pDevice, byPktType, wCurrentRate,
+                       &head->data_head_a_fb, cbFrameSize, bNeedACK);
         }
     }
     else if (byPktType == PK_TYPE_11B) {
+       if (need_mic) {
+               *mic_hdr = &tx_buffer->tx_head.tx_ab.tx.mic.hdr;
+               head = &tx_buffer->tx_head.tx_ab.tx.mic.head;
+       } else {
+               head = &tx_buffer->tx_head.tx_ab.tx.head;
+       }
+
        if (need_rts) {
             //Fill RsvTime
                struct vnt_rrv_time_ab *pBuf = &tx_buffer->tx_head.tx_ab.ab;
@@ -962,29 +952,24 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice,
                pBuf->wTxRrvTime = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B,
                                cbFrameSize, wCurrentRate, bNeedACK);
 
-               if (need_mic) {
-                       *mic_hdr = &tx_buffer->tx_head.tx_ab.tx.mic.hdr;
-                       head = &tx_buffer->tx_head.tx_ab.tx.mic.head;
-               } else {
-                       head = &tx_buffer->tx_head.tx_ab.tx.head;
-               }
-
                /* Fill RTS */
-               s_vFillRTSHead(pDevice, byPktType, head, cbFrameSize,
+               return s_vFillRTSHead(pDevice, byPktType, head, cbFrameSize,
                        bNeedACK, psEthHeader, wCurrentRate, byFBOption);
         }
         else { //RTS_needless, non PCF mode
             //Fill RsvTime
                struct vnt_rrv_time_ab *pBuf = &tx_buffer->tx_head.tx_ab.ab;
 
-               if (need_mic)
-                       *mic_hdr = &tx_buffer->tx_head.tx_ab.tx.mic.hdr;
-
                pBuf->wTxRrvTime = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B,
                        cbFrameSize, wCurrentRate, bNeedACK);
+
+               return vnt_rxtx_datahead_ab(pDevice, byPktType, wCurrentRate,
+                       &head->data_head_ab, cbFrameSize, bNeedACK);
         }
     }
     //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter END.\n");
+
+       return 0;
 }
 /*
     u8 * pbyBuffer,//point to pTxBufHead
@@ -1013,14 +998,13 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
        u32 uDuration;
        u32 cbHeaderLength = 0, uPadding = 0;
        struct vnt_mic_hdr *pMICHDR;
-       void *pvTxDataHd;
        u8 byFBOption = AUTO_FB_NONE, byFragType;
        u16 wTxBufSize;
        u32 dwMICKey0, dwMICKey1, dwMIC_Priority;
        u32 *pdwMIC_L, *pdwMIC_R;
        int bSoftWEP = false;
 
-       pMICHDR = pvTxDataHd = NULL;
+       pMICHDR = NULL;
 
        if (bNeedEncryption && pTransmitKey->pvKeyTable) {
                if (((PSKeyTable)pTransmitKey->pvKeyTable)->bSoftWEP == true)
@@ -1147,70 +1131,42 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
     if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
         if (byFBOption == AUTO_FB_NONE) {
             if (bRTS == true) {//RTS_need
-               pvTxDataHd = (struct vnt_tx_datahead_g *) (pbyTxBufferAddr +
-                       wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
-                               cbMICHDR + sizeof(struct vnt_rts_g));
                cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
-                       cbMICHDR + sizeof(struct vnt_rts_g) +
-                               sizeof(struct vnt_tx_datahead_g);
+                       cbMICHDR + sizeof(struct vnt_rts_g);
             }
             else { //RTS_needless
-               pvTxDataHd = (struct vnt_tx_datahead_g *)(pbyTxBufferAddr +
-                       wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
-                               cbMICHDR + sizeof(struct vnt_cts));
                cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
-                       cbMICHDR + sizeof(struct vnt_cts) +
-                               sizeof(struct vnt_tx_datahead_g);
+                       cbMICHDR + sizeof(struct vnt_cts);
             }
         } else {
             // Auto Fall Back
             if (bRTS == true) {//RTS_need
-               pvTxDataHd = (struct vnt_tx_datahead_g_fb *) (pbyTxBufferAddr +
-                       wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
-                               cbMICHDR + sizeof(struct vnt_rts_g_fb));
                cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
-                       cbMICHDR + sizeof(struct vnt_rts_g_fb) +
-                               sizeof(struct vnt_tx_datahead_g_fb);
+                       cbMICHDR + sizeof(struct vnt_rts_g_fb);
             }
             else if (bRTS == false) { //RTS_needless
-               pvTxDataHd = (struct vnt_tx_datahead_g_fb *) (pbyTxBufferAddr +
-                       wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
-                               cbMICHDR + sizeof(struct vnt_cts_fb));
                cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
-                               cbMICHDR + sizeof(struct vnt_cts_fb) +
-                                       sizeof(struct vnt_tx_datahead_g_fb);
+                               cbMICHDR + sizeof(struct vnt_cts_fb);
             }
         } // Auto Fall Back
     }
     else {//802.11a/b packet
         if (byFBOption == AUTO_FB_NONE) {
             if (bRTS == true) {//RTS_need
-               pvTxDataHd = (struct vnt_tx_datahead_ab *)(pbyTxBufferAddr +
-                       wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR +
-                                               sizeof(struct vnt_rts_ab));
                cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
-                       cbMICHDR + sizeof(struct vnt_rts_ab) +
-                               sizeof(struct vnt_tx_datahead_ab);
+                       cbMICHDR + sizeof(struct vnt_rts_ab);
             }
             else if (bRTS == false) { //RTS_needless, no MICHDR
-               pvTxDataHd = (struct vnt_tx_datahead_ab *)(pbyTxBufferAddr +
-                       wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
                cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
                                cbMICHDR + sizeof(struct vnt_tx_datahead_ab);
             }
         } else {
             // Auto Fall Back
             if (bRTS == true) {//RTS_need
-               pvTxDataHd = (struct vnt_tx_datahead_a_fb *)(pbyTxBufferAddr +
-                       wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR +
-                                       sizeof(struct vnt_rts_a_fb));
                cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
-                       cbMICHDR + sizeof(struct vnt_rts_a_fb) +
-                                       sizeof(struct vnt_tx_datahead_a_fb);
+                       cbMICHDR + sizeof(struct vnt_rts_a_fb);
             }
             else if (bRTS == false) { //RTS_needless
-               pvTxDataHd = (struct vnt_tx_datahead_a_fb *)(pbyTxBufferAddr +
-                       wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
                cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
                        cbMICHDR + sizeof(struct vnt_tx_datahead_a_fb);
             }
@@ -1229,13 +1185,11 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
     //uDMAIdx = TYPE_AC0DMA;
     //pTxBufHead = (PSTxBufHead) &(pTxBufHead->adwTxKey[0]);
 
-    //Fill FIFO,RrvTime,RTS,and CTS
-    s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate,
-               tx_buffer, &pMICHDR, cbMICHDR,
-               cbFrameSize, bNeedACK, uDMAIdx, psEthHeader, bRTS);
-    //Fill DataHead
-    uDuration = s_uFillDataHead(pDevice, byPktType, wCurrentRate, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK,
-                               byFBOption);
+       /* Fill FIFO, RrvTime, RTS and CTS */
+       uDuration = s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate,
+                       tx_buffer, &pMICHDR, cbMICHDR,
+                       cbFrameSize, bNeedACK, uDMAIdx, psEthHeader, bRTS);
+
     // Generate TX MAC Header
     s_vGenerateMACHeader(pDevice, pbyMacHdr, (u16)uDuration, psEthHeader, bNeedEncryption,
                            byFragType, uDMAIdx, 0);
@@ -1468,7 +1422,6 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice,
        struct ieee80211_hdr *pMACHeader;
        struct ethhdr sEthHeader;
        u8 byPktType, *pbyTxBufferAddr;
-       void *pvTxDataHd;
        struct vnt_mic_hdr *pMICHDR = NULL;
        u32 uDuration, cbReqCount, cbHeaderSize, cbFrameBodySize, cbFrameSize;
        int bNeedACK, bIsPSPOLL = false;
@@ -1601,14 +1554,10 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice,
 
     //Set RrvTime/RTS/CTS Buffer
     if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
-       pvTxDataHd = (struct vnt_tx_datahead_g *)(pbyTxBufferAddr + wTxBufSize +
-               sizeof(struct vnt_rrv_time_cts) + sizeof(struct vnt_cts));
        cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
-               sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);
+               sizeof(struct vnt_cts);
     }
     else { // 802.11a/b packet
-       pvTxDataHd = (struct vnt_tx_datahead_ab *) (pbyTxBufferAddr +
-               wTxBufSize + sizeof(struct vnt_rrv_time_ab));
        cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
                sizeof(struct vnt_tx_datahead_ab);
     }
@@ -1625,14 +1574,10 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice,
     pTxBufHead->wFragCtl |= (u16)FRAGCTL_NONFRAG;
 
        /* Fill FIFO,RrvTime,RTS,and CTS */
-       s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate,
+       uDuration = s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate,
                pTX_Buffer, &pMICHDR, 0,
                cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader, false);
 
-    //Fill DataHead
-    uDuration = s_uFillDataHead(pDevice, byPktType, wCurrentRate, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK,
-                               AUTO_FB_NONE);
-
     pMACHeader = (struct ieee80211_hdr *) (pbyTxBufferAddr + cbHeaderSize);
 
     cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + cbFrameBodySize;
@@ -1695,12 +1640,16 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice,
         // 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) {
-               ((struct vnt_tx_datahead_g *)pvTxDataHd)->wDuration_a =
+               struct vnt_tx_datahead_g *data_head = &pTX_Buffer->tx_head.
+                                               tx_cts.tx.head.cts_g.data_head;
+               data_head->wDuration_a =
                        cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
-               ((struct vnt_tx_datahead_g *)pvTxDataHd)->wDuration_b =
+               data_head->wDuration_b =
                        cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
        } else {
-               ((struct vnt_tx_datahead_ab *)pvTxDataHd)->wDuration =
+               struct vnt_tx_datahead_ab *data_head = &pTX_Buffer->tx_head.
+                                       tx_ab.tx.head.data_head_ab;
+               data_head->wDuration =
                        cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
        }
     }
@@ -1819,7 +1768,6 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb)
        struct vnt_tx_fifo_head *pTxBufHead;
        u8 byPktType;
        u8 *pbyTxBufferAddr;
-       void *pvTxDataHd;
        u32 uDuration, cbReqCount;
        struct ieee80211_hdr *pMACHeader;
        u32 cbHeaderSize, cbFrameBodySize;
@@ -1845,7 +1793,7 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb)
        u32 cbExtSuppRate = 0;
        struct vnt_usb_send_context *pContext;
 
-       pMICHDR = pvTxDataHd = NULL;
+       pMICHDR = NULL;
 
     if(skb->len <= WLAN_HDR_ADDR3_LEN) {
        cbFrameBodySize = 0;
@@ -2004,16 +1952,11 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb)
     //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter()
 
     if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
-       pvTxDataHd = (struct vnt_tx_datahead_g *) (pbyTxBufferAddr +
-               wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR +
-                                       sizeof(struct vnt_cts));
        cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR +
-               sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);
+               sizeof(struct vnt_cts);
 
     }
     else {//802.11a/b packet
-       pvTxDataHd = (struct vnt_tx_datahead_ab *)(pbyTxBufferAddr +
-               wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
        cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR +
                                        sizeof(struct vnt_tx_datahead_ab);
     }
@@ -2029,15 +1972,11 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb)
     pTxBufHead->wFragCtl |= (u16)FRAGCTL_NONFRAG;
 
        /* Fill FIFO,RrvTime,RTS,and CTS */
-       s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate,
+       uDuration = s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate,
                pTX_Buffer, &pMICHDR, cbMICHDR,
                cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader, false);
 
-    //Fill DataHead
-    uDuration = s_uFillDataHead(pDevice, byPktType, wCurrentRate, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK,
-                               AUTO_FB_NONE);
-
-    pMACHeader = (struct ieee80211_hdr *) (pbyTxBufferAddr + cbHeaderSize);
+       pMACHeader = (struct ieee80211_hdr *) (pbyTxBufferAddr + cbHeaderSize);
 
     cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + (cbFrameBodySize + cbMIClen) + cbExtSuppRate;
 
@@ -2145,12 +2084,16 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb)
         // 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) {
-               ((struct vnt_tx_datahead_g *)pvTxDataHd)->wDuration_a =
+               struct vnt_tx_datahead_g *data_head = &pTX_Buffer->tx_head.
+                                               tx_cts.tx.head.cts_g.data_head;
+               data_head->wDuration_a =
                        cpu_to_le16(p80211Header->sA2.wDurationID);
-               ((struct vnt_tx_datahead_g *)pvTxDataHd)->wDuration_b =
+               data_head->wDuration_b =
                        cpu_to_le16(p80211Header->sA2.wDurationID);
        } else {
-               ((struct vnt_tx_datahead_ab *)pvTxDataHd)->wDuration =
+               struct vnt_tx_datahead_ab *data_head = &pTX_Buffer->tx_head.
+                                       tx_ab.tx.head.data_head_ab;
+               data_head->wDuration =
                        cpu_to_le16(p80211Header->sA2.wDurationID);
        }
     }
index bbda9a3a83c030f36e72af9a4c18fae2f75ba81e..eecbe890027e50976461925022ac87e8dac9dfc8 100644 (file)
@@ -117,6 +117,7 @@ struct vnt_rts_g {
        u16 wDuration_bb;
        u16 wReserved;
        struct ieee80211_rts data;
+       struct vnt_tx_datahead_g data_head;
 } __packed;
 
 struct vnt_rts_g_fb {
@@ -131,6 +132,7 @@ struct vnt_rts_g_fb {
        u16 wRTSDuration_ba_f1;
        u16 wRTSDuration_aa_f1;
        struct ieee80211_rts data;
+       struct vnt_tx_datahead_g_fb data_head;
 } __packed;
 
 struct vnt_rts_ab {
@@ -138,6 +140,7 @@ struct vnt_rts_ab {
        u16 wDuration;
        u16 wReserved;
        struct ieee80211_rts data;
+       struct vnt_tx_datahead_ab data_head;
 } __packed;
 
 struct vnt_rts_a_fb {
@@ -147,6 +150,7 @@ struct vnt_rts_a_fb {
        u16 wRTSDuration_f0;
        u16 wRTSDuration_f1;
        struct ieee80211_rts data;
+       struct vnt_tx_datahead_a_fb data_head;
 } __packed;
 
 /* CTS buffer header */
@@ -156,6 +160,7 @@ struct vnt_cts {
        u16 wReserved;
        struct ieee80211_cts data;
        u16 reserved2;
+       struct vnt_tx_datahead_g data_head;
 } __packed;
 
 struct vnt_cts_fb {
@@ -166,6 +171,7 @@ struct vnt_cts_fb {
        u16 wCTSDuration_ba_f1;
        struct ieee80211_cts data;
        u16 reserved2;
+       struct vnt_tx_datahead_g_fb data_head;
 } __packed;
 
 union vnt_tx_data_head {
@@ -178,6 +184,9 @@ union vnt_tx_data_head {
        /* cts g */
        struct vnt_cts cts_g;
        struct vnt_cts_fb cts_g_fb;
+       /* no rts/cts */
+       struct vnt_tx_datahead_a_fb data_head_a_fb;
+       struct vnt_tx_datahead_ab data_head_ab;
 };
 
 struct vnt_tx_mic_hdr {
index 8a4181f846a107df9b68b1bf1e8cdc5b94930332..b15f778b4c6815e43a4320cd94862e79dfe4b529 100644 (file)
@@ -16,14 +16,14 @@ if XILLYBUS
 
 config XILLYBUS_PCIE
        tristate "Xillybus over PCIe"
-       depends on XILLYBUS && PCI
+       depends on PCI
        help
          Set to M if you want Xillybus to use PCI Express for communicating
          with the FPGA.
 
 config XILLYBUS_OF
        tristate "Xillybus over Device Tree"
-       depends on XILLYBUS && OF_ADDRESS && OF_IRQ
+       depends on OF_ADDRESS && OF_IRQ
        help
          Set to M if you want Xillybus to find its resources from the
          Open Firmware Flattened Device Tree. If the target is an embedded