Re: [PATCH V6 0/4] [SCSI] ufs: Adds glue drivers to ufshcd

2013-02-12 Thread vinayak holikatti
Hi James,

look like these patches are fine. Can you please integrate these
patches in your tree.


On Tue, Feb 5, 2013 at 10:17 PM,   wrote:
> From: Vinayak Holikatti 
>
> This patch set adds following features
>  - Seggregate PCI specific code in ufshcd.c and corrected copyright
>  - Adds PCI glue driver ufshcd-pci.c and ufshcd.c become core module
>  - Adds Platform glue driver ufshcd-pltfrm.c
>  - Update correct transfer size in Command UPIU
>
> Vinayak Holikatti (4):
>   [SCSI] drivers/scsi/ufs: Seggregate PCI Specific Code
>   [SCSI] drivers/scsi/ufs: Separate PCI code into glue driver
>   [SCSI] ufs: Add Platform glue driver for ufshcd
>   [SCSI] ufs: Correct the expected data transfersize
>
>  drivers/scsi/ufs/Kconfig |   87 +---
>  drivers/scsi/ufs/Makefile|2 +
>  drivers/scsi/ufs/ufs.h   |   44 ++---
>  drivers/scsi/ufs/ufshcd-pci.c|  211 +++
>  drivers/scsi/ufs/ufshcd-pltfrm.c |  217 +++
>  drivers/scsi/ufs/ufshcd.c|  426 
> --
>  drivers/scsi/ufs/ufshcd.h|  202 ++
>  drivers/scsi/ufs/ufshci.h|   44 ++---
>  8 files changed, 811 insertions(+), 422 deletions(-)
>  create mode 100644 drivers/scsi/ufs/ufshcd-pci.c
>  create mode 100644 drivers/scsi/ufs/ufshcd-pltfrm.c
>  create mode 100644 drivers/scsi/ufs/ufshcd.h
>
> --
> 1.7.5.4
>
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [scsi:misc 61/65] drivers/scsi/fnic/fnic_scsi.c:441:3: warning: cast from pointer to integer of different size

2013-02-12 Thread Hiral Patel (hiralpat)
Hi James,

I have fixed fnic patches 3-10 for sparse and smatch errors.

Thanks,
Hiral

On 1/29/13 10:26 PM, "kbuild test robot"  wrote:

>tree:   git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git misc
>head:   52cb5cbe9b8ed89db0f8c9eeec8410fcfb0887fd
>commit: 6f3b5679f2af1ef3becbf7832d2bce977907c08a [61/65] [SCSI] fnic:
>fixing issues in device and firmware reset code
>config: make ARCH=i386 allmodconfig
>
>All warnings:
>
>   drivers/scsi/fnic/fnic_scsi.c:190:39: sparse: context imbalance in
>'__fnic_set_state_flags' - unexpected unlock
>   drivers/scsi/fnic/fnic_scsi.c:419:19: sparse: context imbalance in
>'fnic_queuecommand_lck' - unexpected unlock
>   drivers/scsi/fnic/fnic_scsi.c:2411:49: sparse: context imbalance in
>'fnic_is_abts_pending' - different lock contexts for basic block
>   drivers/scsi/fnic/fnic_scsi.c: In function 'fnic_queuecommand_lck':
>>> drivers/scsi/fnic/fnic_scsi.c:441:3: warning: cast from pointer to
>>>integer of different size [-Wpointer-to-int-cast]
>>> drivers/scsi/fnic/fnic_scsi.c:441:3: warning: cast from pointer to
>>>integer of different size [-Wpointer-to-int-cast]
>>> drivers/scsi/fnic/fnic_scsi.c:493:3: warning: cast from pointer to
>>>integer of different size [-Wpointer-to-int-cast]
>>> drivers/scsi/fnic/fnic_scsi.c:493:3: warning: cast from pointer to
>>>integer of different size [-Wpointer-to-int-cast]
>>> drivers/scsi/fnic/fnic_scsi.c:515:2: warning: cast from pointer to
>>>integer of different size [-Wpointer-to-int-cast]
>>> drivers/scsi/fnic/fnic_scsi.c:515:2: warning: cast from pointer to
>>>integer of different size [-Wpointer-to-int-cast]
>>> drivers/scsi/fnic/fnic_scsi.c:515:2: warning: cast from pointer to
>>>integer of different size [-Wpointer-to-int-cast]
>   drivers/scsi/fnic/fnic_scsi.c: In function 'fnic_fcpio_ack_handler':
>>> drivers/scsi/fnic/fnic_scsi.c:703:2: warning: cast from pointer to
>>>integer of different size [-Wpointer-to-int-cast]
>   drivers/scsi/fnic/fnic_scsi.c: In function
>'fnic_fcpio_icmnd_cmpl_handler':
>>> drivers/scsi/fnic/fnic_scsi.c:747:3: warning: cast from pointer to
>>>integer of different size [-Wpointer-to-int-cast]
>>> drivers/scsi/fnic/fnic_scsi.c:747:3: warning: cast from pointer to
>>>integer of different size [-Wpointer-to-int-cast]
>>> drivers/scsi/fnic/fnic_scsi.c:904:2: warning: cast from pointer to
>>>integer of different size [-Wpointer-to-int-cast]
>>> drivers/scsi/fnic/fnic_scsi.c:904:2: warning: cast from pointer to
>>>integer of different size [-Wpointer-to-int-cast]
>>> drivers/scsi/fnic/fnic_scsi.c:904:2: warning: cast from pointer to
>>>integer of different size [-Wpointer-to-int-cast]
>   drivers/scsi/fnic/fnic_scsi.c: In function
>'fnic_fcpio_itmf_cmpl_handler':
>>> drivers/scsi/fnic/fnic_scsi.c:1022:5: warning: cast from pointer to
>>>integer of different size [-Wpointer-to-int-cast]
>>> drivers/scsi/fnic/fnic_scsi.c:1022:5: warning: cast from pointer to
>>>integer of different size [-Wpointer-to-int-cast]
>>> drivers/scsi/fnic/fnic_scsi.c:1022:5: warning: cast from pointer to
>>>integer of different size [-Wpointer-to-int-cast]
>>> drivers/scsi/fnic/fnic_scsi.c:1044:4: warning: cast from pointer to
>>>integer of different size [-Wpointer-to-int-cast]
>>> drivers/scsi/fnic/fnic_scsi.c:1044:4: warning: cast from pointer to
>>>integer of different size [-Wpointer-to-int-cast]
>>> drivers/scsi/fnic/fnic_scsi.c:1044:4: warning: cast from pointer to
>>>integer of different size [-Wpointer-to-int-cast]
>>> drivers/scsi/fnic/fnic_scsi.c:1059:4: warning: cast from pointer to
>>>integer of different size [-Wpointer-to-int-cast]
>--
>   drivers/scsi/fnic/fnic_trace.c: In function 'fnic_trace_get_buf':
>>> drivers/scsi/fnic/fnic_trace.c:80:9: warning: cast to pointer from
>>>integer of different size [-Wint-to-pointer-cast]
>   drivers/scsi/fnic/fnic_trace.c: In function 'fnic_get_trace_data':
>>> drivers/scsi/fnic/fnic_trace.c:112:10: warning: cast to pointer from
>>>integer of different size [-Wint-to-pointer-cast]
>>> drivers/scsi/fnic/fnic_trace.c:149:10: warning: cast to pointer from
>>>integer of different size [-Wint-to-pointer-cast]
>   drivers/scsi/fnic/fnic_trace.c: In function 'fnic_trace_buf_init':
>>> drivers/scsi/fnic/fnic_trace.c:200:21: warning: cast from pointer to
>>>integer of different size [-Wpointer-to-int-cast]
>>> drivers/scsi/fnic/fnic_trace.c:207:2: warning: cast to pointer from
>>>integer of different size [-Wint-to-pointer-cast]
>>> drivers/scsi/fnic/fnic_trace.c:215:10: warning: cast to pointer from
>>>integer of different size [-Wint-to-pointer-cast]
>   drivers/scsi/fnic/fnic_trace.c: In function 'fnic_trace_free':
>>> drivers/scsi/fnic/fnic_trace.c:260:9: warning: cast to pointer from
>>>integer of different size [-Wint-to-pointer-cast]
>
>sparse warnings: (new ones prefixed by >>)
>
>>> drivers/scsi/fnic/fnic_scsi.c:190:39: sparse: context imbalance in
>>>'__fnic_set_state_flags' - unexpected unlock
>   drivers/scsi/fnic/fnic_scsi.c:419:19: sparse: context imbalance i

[PATCH 07/10] fnic: Fnic Trace Utility

2013-02-12 Thread Hiral Patel
Fnic Trace utility is a tracing functionality built directly into fnic driver
to trace events. The benefit that trace buffer brings to fnic driver is the
ability to see what it happening inside the fnic driver. It also provides the
capability to trace every IO event inside fnic driver to debug panics, hangs
and potentially IO corruption issues. This feature makes it easy to find
problems in fnic driver and it also helps in tracking down strange bugs in a
more manageable way. Trace buffer is shared across all fnic instances for
this implementation.

Signed-off-by: Hiral Patel 
---
 drivers/scsi/fnic/Makefile   |2 +
 drivers/scsi/fnic/fnic.h |1 +
 drivers/scsi/fnic/fnic_debugfs.c |  314 ++
 drivers/scsi/fnic/fnic_main.c|   14 ++
 drivers/scsi/fnic/fnic_scsi.c|  120 +--
 drivers/scsi/fnic/fnic_trace.c   |  273 +
 drivers/scsi/fnic/fnic_trace.h   |   90 +++
 7 files changed, 803 insertions(+), 11 deletions(-)
 create mode 100644 drivers/scsi/fnic/fnic_debugfs.c
 create mode 100644 drivers/scsi/fnic/fnic_trace.c
 create mode 100644 drivers/scsi/fnic/fnic_trace.h

diff --git a/drivers/scsi/fnic/Makefile b/drivers/scsi/fnic/Makefile
index 37c3440..383598f 100644
--- a/drivers/scsi/fnic/Makefile
+++ b/drivers/scsi/fnic/Makefile
@@ -7,6 +7,8 @@ fnic-y  := \
fnic_res.o \
fnic_fcs.o \
fnic_scsi.o \
+   fnic_trace.o \
+   fnic_debugfs.o \
vnic_cq.o \
vnic_dev.o \
vnic_intr.o \
diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h
index 9c95a1a..98436c3 100644
--- a/drivers/scsi/fnic/fnic.h
+++ b/drivers/scsi/fnic/fnic.h
@@ -26,6 +26,7 @@
 #include 
 #include "fnic_io.h"
 #include "fnic_res.h"
+#include "fnic_trace.h"
 #include "vnic_dev.h"
 #include "vnic_wq.h"
 #include "vnic_rq.h"
diff --git a/drivers/scsi/fnic/fnic_debugfs.c b/drivers/scsi/fnic/fnic_debugfs.c
new file mode 100644
index 000..adc1f7f
--- /dev/null
+++ b/drivers/scsi/fnic/fnic_debugfs.c
@@ -0,0 +1,314 @@
+/*
+ * Copyright 2012 Cisco Systems, Inc.  All rights reserved.
+ *
+ * This program is free software; you may redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include 
+#include 
+#include 
+#include "fnic.h"
+
+static struct dentry *fnic_trace_debugfs_root;
+static struct dentry *fnic_trace_debugfs_file;
+static struct dentry *fnic_trace_enable;
+
+/*
+ * fnic_trace_ctrl_open - Open the trace_enable file
+ * @inode: The inode pointer.
+ * @file: The file pointer to attach the trace enable/disable flag.
+ *
+ * Description:
+ * This routine opens a debugsfs file trace_enable.
+ *
+ * Returns:
+ * This function returns zero if successful.
+ */
+static int fnic_trace_ctrl_open(struct inode *inode, struct file *filp)
+{
+   filp->private_data = inode->i_private;
+   return 0;
+}
+
+/*
+ * fnic_trace_ctrl_read - Read a trace_enable debugfs file
+ * @filp: The file pointer to read from.
+ * @ubuf: The buffer to copy the data to.
+ * @cnt: The number of bytes to read.
+ * @ppos: The position in the file to start reading from.
+ *
+ * Description:
+ * This routine reads value of variable fnic_tracing_enabled
+ * and stores into local @buf. It will start reading file at @ppos and
+ * copy up to @cnt of data to @ubuf from @buf.
+ *
+ * Returns:
+ * This function returns the amount of data that was read.
+ */
+static ssize_t fnic_trace_ctrl_read(struct file *filp,
+ char __user *ubuf,
+ size_t cnt, loff_t *ppos)
+{
+   char buf[64];
+   int len;
+   len = sprintf(buf, "%u\n", fnic_tracing_enabled);
+
+   return simple_read_from_buffer(ubuf, cnt, ppos, buf, len);
+}
+
+/*
+ * fnic_trace_ctrl_write - Write to trace_enable debugfs file
+ * @filp: The file pointer to write from.
+ * @ubuf: The buffer to copy the data from.
+ * @cnt: The number of bytes to write.
+ * @ppos: The position in the file to start writing to.
+ *
+ * Description:
+ * This routine writes data from user buffer @ubuf to buffer @buf and
+ * sets fnic_tracing_enabled value as per user input.
+ *
+ * Returns:
+ * This function returns the amount of data that was written.
+ */
+static ssize_t fnic_trace_ctrl_write(struct file *filp,
+ const char __user *ubuf,
+ 

[PATCH 08/10] fnic: FIP VLAN Discovery Feature Support

2013-02-12 Thread Hiral Patel
FIP VLAN discovery discovers the FCoE VLAN that will be used by all other FIP 
protocols
as well as by the FCoE encapsulation for Fibre Channel payloads on the 
established
virtual link. One of the goals of FC-BB-5 was to be as nonintrusive as possible 
on
initiators and targets, and therefore FIP VLAN discovery occurs in the native 
VLAN
used by the initiator or target to exchange Ethernet traffic. The FIP VLAN 
discovery
protocol is the only FIP protocol running on the native VLAN; all other FIP 
protocols
run on the discovered FCoE VLANs.

If an administrator has manually configured FCoE VLANs on ENodes and FCFs, 
there is no need
to use this protocol. FIP and FCoE will run over the configured VLANs.

An ENode without FCoE VLANs configuration would use this automated discovery 
protocol to
discover over which VLANs FCoE is running.

The ENode sends a FIP VLAN discovery request to a multicast MAC address called 
All-FCF-MACs,
which is a multicast MAC address to which all FCFs listen.

All FCFs that can be reached in the native VLAN of the ENode are expected to 
respond on the
same VLAN with a response that lists one or more FCoE VLANs that are available 
for the ENode's
VN_Port login. This protocol has the sole purpose of allowing the ENode to 
discover all the
available FCoE VLANs.

Now the ENode may enable a subset of these VLANs for FCoE Running the FIP 
protocol in these
VLANs on a per VLAN basis. And FCoE data transactions also would occur on this 
VLAN. Hence,
Except for FIP VLAN discovery, all other FIP and FCoE traffic runs on the 
selected FCoE VLAN.
Its only the FIP VLAN Discovery protocol that is permitted to run on the 
Default native VLAN
of the system.

[ NOTE ]
We are working on moving this feature definitions and functionality to libfcoe 
module. We need
this patch to be approved, as Suse is looking forward to merge this feature in 
SLES 11 SP3 release.
Once this patch is approved, we will submit patch which should move vlan 
discovery feature to libfoce.

Signed-off-by: Anantha Prakash T 
Signed-off-by: Hiral Patel 
---
 drivers/scsi/fnic/fnic.h|   32 +++
 drivers/scsi/fnic/fnic_fcs.c|  558 ++-
 drivers/scsi/fnic/fnic_fip.h|   68 +
 drivers/scsi/fnic/fnic_main.c   |   51 +++-
 drivers/scsi/fnic/vnic_dev.c|   10 +
 drivers/scsi/fnic/vnic_dev.h|2 +
 drivers/scsi/fnic/vnic_devcmd.h |   67 +
 7 files changed, 784 insertions(+), 4 deletions(-)
 create mode 100644 drivers/scsi/fnic/fnic_fip.h

diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h
index 98436c3..acec42a 100644
--- a/drivers/scsi/fnic/fnic.h
+++ b/drivers/scsi/fnic/fnic.h
@@ -192,6 +192,18 @@ enum fnic_state {
 
 struct mempool;
 
+enum fnic_evt {
+   FNIC_EVT_START_VLAN_DISC = 1,
+   FNIC_EVT_START_FCF_DISC = 2,
+   FNIC_EVT_MAX,
+};
+
+struct fnic_event {
+   struct list_head list;
+   struct fnic *fnic;
+   enum fnic_evt event;
+};
+
 /* Per-instance private data structure */
 struct fnic {
struct fc_lport *lport;
@@ -254,6 +266,18 @@ struct fnic {
struct sk_buff_head frame_queue;
struct sk_buff_head tx_queue;
 
+   /*** FIP related data members  -- start ***/
+   void (*set_vlan)(struct fnic *, u16 vlan);
+   struct work_struct  fip_frame_work;
+   struct sk_buff_head fip_frame_queue;
+   struct timer_list   fip_timer;
+   struct list_headvlans;
+   spinlock_t  vlans_lock;
+
+   struct work_struct  event_work;
+   struct list_headevlist;
+   /*** FIP related data members  -- end ***/
+
/* copy work queue cache line section */
cacheline_aligned struct vnic_wq_copy wq_copy[FNIC_WQ_COPY_MAX];
/* completion queue cache line section */
@@ -278,6 +302,7 @@ static inline struct fnic *fnic_from_ctlr(struct fcoe_ctlr 
*fip)
 }
 
 extern struct workqueue_struct *fnic_event_queue;
+extern struct workqueue_struct *fnic_fip_queue;
 extern struct device_attribute *fnic_attrs[];
 
 void fnic_clear_intr_mode(struct fnic *fnic);
@@ -289,6 +314,7 @@ int fnic_send(struct fc_lport *, struct fc_frame *);
 void fnic_free_wq_buf(struct vnic_wq *wq, struct vnic_wq_buf *buf);
 void fnic_handle_frame(struct work_struct *work);
 void fnic_handle_link(struct work_struct *work);
+void fnic_handle_event(struct work_struct *work);
 int fnic_rq_cmpl_handler(struct fnic *fnic, int);
 int fnic_alloc_rq_frame(struct vnic_rq *rq);
 void fnic_free_rq_buf(struct vnic_rq *rq, struct vnic_rq_buf *buf);
@@ -321,6 +347,12 @@ void fnic_handle_link_event(struct fnic *fnic);
 
 int fnic_is_abts_pending(struct fnic *, struct scsi_cmnd *);
 
+void fnic_handle_fip_frame(struct work_struct *work);
+void fnic_handle_fip_event(struct fnic *fnic);
+void fnic_fcoe_reset_vlans(struct fnic *fnic);
+void fnic_fcoe_evlist_free(struct fnic *fnic);
+extern void fnic_handle_fip_timer(struct fnic *fnic);
+
 static inline int
 fnic_chk_sta

[PATCH 10/10] fnic: Incremented driver version

2013-02-12 Thread Hiral Patel
Incrementing driver versio after bug fixes and new feature commits.

Signed-off-by: Brian Uchino 
Signed-off-by: Hiral Patel 
---
 drivers/scsi/fnic/fnic.h |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h
index acec42a..b6d1f92 100644
--- a/drivers/scsi/fnic/fnic.h
+++ b/drivers/scsi/fnic/fnic.h
@@ -38,7 +38,7 @@
 
 #define DRV_NAME   "fnic"
 #define DRV_DESCRIPTION"Cisco FCoE HBA Driver"
-#define DRV_VERSION"1.5.0.2"
+#define DRV_VERSION"1.5.0.22"
 #define PFXDRV_NAME ": "
 #define DFX DRV_NAME "%d: "
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 09/10] fnic: Kernel panic due to FIP mode misconfiguration

2013-02-12 Thread Hiral Patel
If switch configured in FIP and adapter configured in non-fip mode, driver
panics while queueing FIP frame in non-existing fip_frame_queue. Added config
check before queueing FIP frame in misconfiguration case to avoid kernel panic.

Signed-off-by: Hiral Patel 
---
 drivers/scsi/fnic/fnic_fcs.c |6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/scsi/fnic/fnic_fcs.c b/drivers/scsi/fnic/fnic_fcs.c
index 41faca4..a0092e8 100644
--- a/drivers/scsi/fnic/fnic_fcs.c
+++ b/drivers/scsi/fnic/fnic_fcs.c
@@ -603,6 +603,12 @@ static inline int fnic_import_rq_eth_pkt(struct fnic 
*fnic, struct sk_buff *skb)
skb_reset_mac_header(skb);
}
if (eh->h_proto == htons(ETH_P_FIP)) {
+   if (!(fnic->config.flags & VFCF_FIP_CAPABLE)) {
+   printk(KERN_ERR "Dropped FIP frame, as firmware "
+   "uses non-FIP mode, Enable FIP "
+   "using UCSM\n");
+   goto drop;
+   }
skb_queue_tail(&fnic->fip_frame_queue, skb);
queue_work(fnic_fip_queue, &fnic->fip_frame_work);
return 1;   /* let caller know packet was used */
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 06/10] fnic: New debug flags and debug log messages

2013-02-12 Thread Hiral Patel
Added new fnic debug flags for identifying IO state at every stage of IO while 
debugging
and also added more log messages for better debugging capability.

Signed-off-by: Sesidhar Baddela 
Signed-off-by: Hiral Patel 
---
 drivers/scsi/fnic/fnic.h  |   31 ---
 drivers/scsi/fnic/fnic_io.h   |4 +-
 drivers/scsi/fnic/fnic_scsi.c |  118 -
 3 files changed, 132 insertions(+), 21 deletions(-)

diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h
index b8e6644..9c95a1a 100644
--- a/drivers/scsi/fnic/fnic.h
+++ b/drivers/scsi/fnic/fnic.h
@@ -59,14 +59,29 @@
  * Command flags to identify the type of command and for other future
  * use.
  */
-#define FNIC_NO_FLAGS  0
-#define FNIC_CDB_REQ   BIT(1)  /* All IOs with a valid CDB */
-#define FNIC_BLOCKING_REQ  BIT(2)  /* All blocking Requests */
-#define FNIC_DEVICE_RESET  BIT(3)  /* Device reset request */
-#define FNIC_DEV_RST_PENDING   BIT(4)  /* Device reset pending */
-#define FNIC_DEV_RST_TIMED_OUT BIT(5)  /* Device reset timed out */
-#define FNIC_DEV_RST_TERM_ISSUED   BIT(6)  /* Device reset terminate */
-#define FNIC_DEV_RST_DONE  BIT(7)  /* Device reset done */
+#define FNIC_NO_FLAGS   0
+#define FNIC_IO_INITIALIZED BIT(0)
+#define FNIC_IO_ISSUED  BIT(1)
+#define FNIC_IO_DONEBIT(2)
+#define FNIC_IO_REQ_NULLBIT(3)
+#define FNIC_IO_ABTS_PENDINGBIT(4)
+#define FNIC_IO_ABORTED BIT(5)
+#define FNIC_IO_ABTS_ISSUED BIT(6)
+#define FNIC_IO_TERM_ISSUED BIT(7)
+#define FNIC_IO_INTERNAL_TERM_ISSUEDBIT(8)
+#define FNIC_IO_ABT_TERM_DONE   BIT(9)
+#define FNIC_IO_ABT_TERM_REQ_NULL   BIT(10)
+#define FNIC_IO_ABT_TERM_TIMED_OUT  BIT(11)
+#define FNIC_DEVICE_RESET   BIT(12)  /* Device reset request */
+#define FNIC_DEV_RST_ISSUED BIT(13)
+#define FNIC_DEV_RST_TIMED_OUT  BIT(14)
+#define FNIC_DEV_RST_ABTS_ISSUEDBIT(15)
+#define FNIC_DEV_RST_TERM_ISSUEDBIT(16)
+#define FNIC_DEV_RST_DONE   BIT(17)
+#define FNIC_DEV_RST_REQ_NULL   BIT(18)
+#define FNIC_DEV_RST_ABTS_DONE  BIT(19)
+#define FNIC_DEV_RST_TERM_DONE  BIT(20)
+#define FNIC_DEV_RST_ABTS_PENDING   BIT(21)
 
 /*
  * Usage of the scsi_cmnd scratchpad.
diff --git a/drivers/scsi/fnic/fnic_io.h b/drivers/scsi/fnic/fnic_io.h
index 3455c34..c35b8f1 100644
--- a/drivers/scsi/fnic/fnic_io.h
+++ b/drivers/scsi/fnic/fnic_io.h
@@ -45,7 +45,8 @@ enum fnic_sgl_list_type {
 };
 
 enum fnic_ioreq_state {
-   FNIC_IOREQ_CMD_PENDING = 0,
+   FNIC_IOREQ_NOT_INITED = 0,
+   FNIC_IOREQ_CMD_PENDING,
FNIC_IOREQ_ABTS_PENDING,
FNIC_IOREQ_ABTS_COMPLETE,
FNIC_IOREQ_CMD_COMPLETE,
@@ -60,6 +61,7 @@ struct fnic_io_req {
u8 sgl_type; /* device DMA descriptor list type */
u8 io_completed:1; /* set to 1 when fw completes IO */
u32 port_id; /* remote port DID */
+   unsigned long start_time; /* in jiffies */
struct completion *abts_done; /* completion for abts */
struct completion *dr_done; /* completion for device reset */
 };
diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c
index 6483081..7cb65330 100644
--- a/drivers/scsi/fnic/fnic_scsi.c
+++ b/drivers/scsi/fnic/fnic_scsi.c
@@ -47,6 +47,7 @@ const char *fnic_state_str[] = {
 };
 
 static const char *fnic_ioreq_state_str[] = {
+   [FNIC_IOREQ_NOT_INITED] = "FNIC_IOREQ_NOT_INITED",
[FNIC_IOREQ_CMD_PENDING] = "FNIC_IOREQ_CMD_PENDING",
[FNIC_IOREQ_ABTS_PENDING] = "FNIC_IOREQ_ABTS_PENDING",
[FNIC_IOREQ_ABTS_COMPLETE] = "FNIC_IOREQ_ABTS_COMPLETE",
@@ -349,6 +350,8 @@ static inline int fnic_queue_wq_copy_desc(struct fnic *fnic,
 
if (unlikely(!vnic_wq_copy_desc_avail(wq))) {
spin_unlock_irqrestore(&fnic->wq_copy_lock[0], intr_flags);
+   FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host,
+ "fnic_queue_wq_copy_desc failure - no descriptors\n");
return SCSI_MLQUEUE_HOST_BUSY;
}
 
@@ -420,7 +423,8 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void 
(*done)(struct scsi_
 * caller disabling them.
 */
spin_unlock(lp->host->host_lock);
-   CMD_FLAGS(sc) = FNIC_CDB_REQ;
+   CMD_STATE(sc) = FNIC_IOREQ_NOT_INITED;
+   CMD_FLAGS(sc) = FNIC_NO_FLAGS;
 
/* Get a new io_req for this SCSI IO */
io_req = mempool_alloc(fnic->io_req_pool, GFP_ATOMIC);
@@ -467,8 +471,10 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, 
void (*done)(struct scsi_
 
/* initialize rest of io_req */
io_req->port_id = rport->port_id;
+   io_req->start_time = jiffies;
CMD_STATE(sc) = FNIC_IOREQ_CMD_PENDING;
CMD_SP(sc) = (char *)io_req;
+   CMD_F

[PATCH 05/10] fnic: fnic driver may hit BUG_ON on device reset

2013-02-12 Thread Hiral Patel
The issue was observed when LUN Reset is issued through IOCTL or sg_reset
utility.

fnic driver issues LUN RESET to firmware. On successful completion of device
reset, driver cleans up all the pending IOs that were issued prior to device
reset. These pending IOs are expected to be in ABTS_PENDING state. This works
fine, when the device reset operation resulted from midlayer, but not when
device reset was triggered from IOCTL path as the pending IOs were not in
ABTS_PENDING state. execution path hits panic if the pending IO is not in
ABTS_PENDING state.

Changes:
The fix replaces BUG_ON check in fnic_clean_pending_aborts() with marking
pending IOs as ABTS_PENDING if they were not in ABTS_PENDING state and skips
if they were already in ABTS_PENDING state. An extra check is added to validate
the abort status of the commands after a delay of 2 * E_D_TOV using a
helper function. The helper function returns 1 if it finds any pending IO in
ABTS_PENDING state, belong to the LUN on which device reset was issued else 0.
With this, device reset operation returns success only if the helper funciton
returns 0, otherwise it returns failure.

Other changes:
- Removed code in fnic_clean_pending_aborts() that returns failure if it finds
  io_req NULL, instead of returning failure added code to continue with next io
- Added device reset flags for debugging in fnic_terminate_rport_io,
  fnic_rport_exch_reset, and fnic_clean_pending_aborts

Signed-off-by: Narsimhulu Musini 
Signed-off-by: Hiral Patel 
---
 drivers/scsi/fnic/fnic.h  |2 +
 drivers/scsi/fnic/fnic_scsi.c |  121 ++---
 2 files changed, 116 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h
index 63b35c8..b8e6644 100644
--- a/drivers/scsi/fnic/fnic.h
+++ b/drivers/scsi/fnic/fnic.h
@@ -303,6 +303,8 @@ const char *fnic_state_to_str(unsigned int state);
 void fnic_log_q_error(struct fnic *fnic);
 void fnic_handle_link_event(struct fnic *fnic);
 
+int fnic_is_abts_pending(struct fnic *, struct scsi_cmnd *);
+
 static inline int
 fnic_chk_state_flags_locked(struct fnic *fnic, unsigned long st_flags)
 {
diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c
index 2f46509..6483081 100644
--- a/drivers/scsi/fnic/fnic_scsi.c
+++ b/drivers/scsi/fnic/fnic_scsi.c
@@ -1271,7 +1271,8 @@ static void fnic_rport_exch_reset(struct fnic *fnic, u32 
port_id)
spin_unlock_irqrestore(io_lock, flags);
} else {
spin_lock_irqsave(io_lock, flags);
-   CMD_FLAGS(sc) |= FNIC_DEV_RST_TERM_ISSUED;
+   if (CMD_FLAGS(sc) & FNIC_DEVICE_RESET)
+   CMD_FLAGS(sc) |= FNIC_DEV_RST_TERM_ISSUED;
spin_unlock_irqrestore(io_lock, flags);
}
}
@@ -1379,7 +1380,8 @@ void fnic_terminate_rport_io(struct fc_rport *rport)
spin_unlock_irqrestore(io_lock, flags);
} else {
spin_lock_irqsave(io_lock, flags);
-   CMD_FLAGS(sc) |= FNIC_DEV_RST_TERM_ISSUED;
+   if (CMD_FLAGS(sc) & FNIC_DEVICE_RESET)
+   CMD_FLAGS(sc) |= FNIC_DEV_RST_TERM_ISSUED;
spin_unlock_irqrestore(io_lock, flags);
}
}
@@ -1592,7 +1594,7 @@ lr_io_req_end:
 static int fnic_clean_pending_aborts(struct fnic *fnic,
 struct scsi_cmnd *lr_sc)
 {
-   int tag;
+   int tag, abt_tag;
struct fnic_io_req *io_req;
spinlock_t *io_lock;
unsigned long flags;
@@ -1601,6 +1603,7 @@ static int fnic_clean_pending_aborts(struct fnic *fnic,
struct scsi_lun fc_lun;
struct scsi_device *lun_dev = lr_sc->device;
DECLARE_COMPLETION_ONSTACK(tm_done);
+   enum fnic_ioreq_state old_ioreq_state;
 
for (tag = 0; tag < FNIC_MAX_IO_REQ; tag++) {
sc = scsi_host_find_tag(fnic->lport->host, tag);
@@ -1629,7 +1632,41 @@ static int fnic_clean_pending_aborts(struct fnic *fnic,
  "Found IO in %s on lun\n",
  fnic_ioreq_state_to_str(CMD_STATE(sc)));
 
-   BUG_ON(CMD_STATE(sc) != FNIC_IOREQ_ABTS_PENDING);
+   if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING) {
+   spin_unlock_irqrestore(io_lock, flags);
+   continue;
+   }
+   if ((CMD_FLAGS(sc) & FNIC_DEVICE_RESET) &&
+   (!(CMD_FLAGS(sc) & FNIC_DEV_RST_PENDING))) {
+   FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host,
+   "%s dev rst not pending sc 0x%p\n", __func__,
+   sc);
+   spin_unlock_irqrestore(io_lock, flags);
+   continue;
+   }
+   old_ioreq_state = CMD_STATE(sc);
+

[PATCH 03/10] fnic:fixing issues in device and firmware reset code

2013-02-12 Thread Hiral Patel
1. Handling overlapped firmware resets
 This fix serialize multiple firmware resets to avoid situation where fnic
 device fails to come up for link up event, when firmware resets are issued
 back to back. If there are overlapped firmware resets are issued,
 the firmware reset operation checks whether there is any firmware reset in
 progress, if so it polls for its completion in a loop with 100ms delay.

2. Handling device reset timeout
 fnic_device_reset code has been modified to handle Device reset timeout:
 - Issue terminate on device reset timeout.
 - Introduced flags field (one of the scratch fields in scsi_cmnd).
 With this, device reset request would have DEVICE_RESET flag set for other
 routines to determine the type of the request.
 Also modified fnic_terminate_rport_io, fnic_rport_exch_rset, completion
 routines to handle SCSI commands with DEVICE_RESET flag.

3. LUN/Device Reset hangs when issued through IOCTL using utilities like
   sg_reset.
 Each SCSI command is associated with a valid tag, fnic uses this tag to
 retrieve associated scsi command on completion. the LUN/Device Reset issued
 through IOCTL resulting into a SCSI command that is not associated with a
 valid tag. So fnic fails to retrieve associated scsi command on completion,
 which causes hang. This fix allocates tag, associates it with the
 scsi command and frees the tag, when the operation completed.

4. Preventing IOs during firmware reset.
 Current fnic implementation allows IO submissions during firmware reset.
 This fix synchronizes IO submissions and firmware reset operations.
 It ensures that IOs issued to fnic prior to reset will be issued to the
 firmware before firmware reset.

Signed-off-by: Narsimhulu Musini 
Signed-off-by: Hiral Patel 
---
 drivers/scsi/fnic/fnic.h  |   42 +
 drivers/scsi/fnic/fnic_main.c |3 +
 drivers/scsi/fnic/fnic_scsi.c |  384 +
 3 files changed, 397 insertions(+), 32 deletions(-)

diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h
index 95a5ba2..63b35c8 100644
--- a/drivers/scsi/fnic/fnic.h
+++ b/drivers/scsi/fnic/fnic.h
@@ -56,6 +56,19 @@
 #define FNIC_NO_TAG -1
 
 /*
+ * Command flags to identify the type of command and for other future
+ * use.
+ */
+#define FNIC_NO_FLAGS  0
+#define FNIC_CDB_REQ   BIT(1)  /* All IOs with a valid CDB */
+#define FNIC_BLOCKING_REQ  BIT(2)  /* All blocking Requests */
+#define FNIC_DEVICE_RESET  BIT(3)  /* Device reset request */
+#define FNIC_DEV_RST_PENDING   BIT(4)  /* Device reset pending */
+#define FNIC_DEV_RST_TIMED_OUT BIT(5)  /* Device reset timed out */
+#define FNIC_DEV_RST_TERM_ISSUED   BIT(6)  /* Device reset terminate */
+#define FNIC_DEV_RST_DONE  BIT(7)  /* Device reset done */
+
+/*
  * Usage of the scsi_cmnd scratchpad.
  * These fields are locked by the hashed io_req_lock.
  */
@@ -64,6 +77,7 @@
 #define CMD_ABTS_STATUS(Cmnd)  ((Cmnd)->SCp.Message)
 #define CMD_LR_STATUS(Cmnd)((Cmnd)->SCp.have_data_in)
 #define CMD_TAG(Cmnd)   ((Cmnd)->SCp.sent_command)
+#define CMD_FLAGS(Cmnd) ((Cmnd)->SCp.Status)
 
 #define FCPIO_INVALID_CODE 0x100 /* hdr_status value unused by firmware */
 
@@ -71,9 +85,28 @@
 #define FNIC_HOST_RESET_TIMEOUT 1  /* mSec */
 #define FNIC_RMDEVICE_TIMEOUT1000   /* mSec */
 #define FNIC_HOST_RESET_SETTLE_TIME  30 /* Sec */
+#define FNIC_ABT_TERM_DELAY_TIMEOUT  500/* mSec */
 
 #define FNIC_MAX_FCP_TARGET 256
 
+/**
+ * state_flags to identify host state along along with fnic's state
+ **/
+#define __FNIC_FLAGS_FWRESET   BIT(0) /* fwreset in progress */
+#define __FNIC_FLAGS_BLOCK_IO  BIT(1) /* IOs are blocked */
+
+#define FNIC_FLAGS_NONE(0)
+#define FNIC_FLAGS_FWRESET (__FNIC_FLAGS_FWRESET | \
+   __FNIC_FLAGS_BLOCK_IO)
+
+#define FNIC_FLAGS_IO_BLOCKED  (__FNIC_FLAGS_BLOCK_IO)
+
+#define fnic_set_state_flags(fnicp, st_flags)  \
+   __fnic_set_state_flags(fnicp, st_flags, 0)
+
+#define fnic_clear_state_flags(fnicp, st_flags)  \
+   __fnic_set_state_flags(fnicp, st_flags, 1)
+
 extern unsigned int fnic_log_level;
 
 #define FNIC_MAIN_LOGGING 0x01
@@ -170,6 +203,9 @@ struct fnic {
 
struct completion *remove_wait; /* device remove thread blocks */
 
+   atomic_t in_flight; /* io counter */
+   u32 _reserved;  /* fill hole */
+   unsigned long state_flags;  /* protected by host lock */
enum fnic_state state;
spinlock_t fnic_lock;
 
@@ -267,4 +303,10 @@ const char *fnic_state_to_str(unsigned int state);
 void fnic_log_q_error(struct fnic *fnic);
 void fnic_handle_link_event(struct fnic *fnic);
 
+static inline int
+fnic_chk_state_flags_locked(

[PATCH 04/10] fnic: Fix SGEs limit

2013-02-12 Thread Hiral Patel
Driver allows IOs with more SGEs than max SGEs supported by Palo. The current 
max SGEs
supported by the fnic driver is 1024. The current register settings on Palo 
supports
a max of 256 only. Palo would return any IO with more than 256 SGEs with an 
error
indicating INVALID_SGLS. Fnic driver should limit the max supported SGLs in
the driver to 256 to avoid this error.

Signed-off-by: Sesidhar Baddela 
Signed-off-by: Hiral Patel 
---
 drivers/scsi/fnic/fnic_io.h |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/fnic/fnic_io.h b/drivers/scsi/fnic/fnic_io.h
index f0b8969..3455c34 100644
--- a/drivers/scsi/fnic/fnic_io.h
+++ b/drivers/scsi/fnic/fnic_io.h
@@ -21,7 +21,7 @@
 #include 
 
 #define FNIC_DFLT_SG_DESC_CNT  32
-#define FNIC_MAX_SG_DESC_CNT1024/* Maximum descriptors per sgl */
+#define FNIC_MAX_SG_DESC_CNT256 /* Maximum descriptors per sgl */
 #define FNIC_SG_DESC_ALIGN  16  /* Descriptor address alignment */
 
 struct host_sg_desc {
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Use a more selective error recovery strategy based on device capabilities

2013-02-12 Thread Jeremy Linton
On 2/12/2013 2:57 PM, Elliott, Robert (Server Storage) wrote:
> Ideally the device driver for the SCSI initiator port would report those
> attributes, and higher level code would combine them with support
> information from the device server (REPORT SUPPORTED TMF command, REPORT
> SUPPORTED OPCODES command, etc.) to decide what is supported.


Well, for the eh_xxx_handler functions, that is basically what happens now.

The host driver can fail to set a callback for the eh_xxx_handlers if it
doesn't support the operation. At that point, even if the target device
supports a function (say target reset) if the host driver doesn't, then the
target reset will be skipped.

Of course, a number of the drivers define functions their underlying
protocol's don't support. For example, bus reset on fibre channel. Which I
personally believe is an error.


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH] Use a more selective error recovery strategy based on device capabilities

2013-02-12 Thread Elliott, Robert (Server Storage)
I like that concept.  

Since TMFs are protocol specific, though, it is possible that the SCSI 
initiator port doesn't know how to send a TMF even though the device server 
supports that TMF.  The SCSI Architecture Model (SAM-5) standard includes an 
annex listing a variety of SCSI Initiator Port attributes and SCSI Target Port 
attributes that can limit what an application client and device server can do:
- LUN size
- Maximum CDB length
- Command Identifier size (i.e. tag size)
- Task Attributes supported (which ones) (e.g., SIMPLE, HEAD OF QUEUE, ORDERED, 
ACA)
- Maximum Data-In Buffer size
- Maximum Data-Out Buffer size
- Command Reference Number supported?
- Command Priority supported?
- Maximum Sense Data length
- Status Qualifier supported?
- Additional Response Information supported?
- Bidirectional Commands supported?
- TMFs supported (which ones)

How the application client determines what the SCSI initiator port supports is 
outside the scope of the SCSI standards - there's no SCSI command or TMF to 
report that information.  These attributes are first constrained by the SCSI 
transport protocol (e.g., SRP doesn't define an encoding for QUERY TASK), then 
by implementation choices (e.g., bidirectional commands and >16-byte CDBs are 
still not widely supported).

Ideally the device driver for the SCSI initiator port would report those 
attributes, and higher level code would combine them with support information 
from the device server (REPORT SUPPORTED TMF command, REPORT SUPPORTED OPCODES 
command, etc.) to decide what is supported.

---
Rob ElliottHP Server Storage







> -Original Message-
> From: linux-scsi-ow...@vger.kernel.org [mailto:linux-scsi-
> ow...@vger.kernel.org] On Behalf Of Jeremy Linton
> Sent: Tuesday, 12 February, 2013 12:20 PM
> To: Linux Scsi
> Subject: [PATCH] Use a more selective error recovery strategy based on device
> capabilities
> 
> Ideally, Linux should not be sending task management commands to devices
> that
> don't support the given task mgmt operation.
> 
> This patch uses the REPORT SUPPORTED TASK MGMT FUNCTIONS command to
> enable or
> disable error recovery paths for a given device. For older devices, we make an
> educated guess about what kind of error recovery the device supports. This 
> isn't
> going to be 100% accurate as it should probably take the transport as well as
> the SCSI version into account, but it is a start.
> 
> While this patch improves the error recovery paths for modern SCSI networks,
> the
> error recovery logic continues to fall through to host reset. It also 
> continues
> to send bus and target resets in cases where they may affect working devices. 
> I
> have a partial set of patches which attempt to make intelligent decisions in
> these cases, but they are far more intrusive and at this point not as clear 
> cut.
> 
> 
> Just in case...
> Signed-off-by: Jeremy Linton 
> ---
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] Use a more selective error recovery strategy based on device capabilities

2013-02-12 Thread Jeremy Linton
Ideally, Linux should not be sending task management commands to devices that
don't support the given task mgmt operation.

This patch uses the REPORT SUPPORTED TASK MGMT FUNCTIONS command to enable or
disable error recovery paths for a given device. For older devices, we make an
educated guess about what kind of error recovery the device supports. This isn't
going to be 100% accurate as it should probably take the transport as well as
the SCSI version into account, but it is a start.

While this patch improves the error recovery paths for modern SCSI networks, the
error recovery logic continues to fall through to host reset. It also continues
to send bus and target resets in cases where they may affect working devices. I
have a partial set of patches which attempt to make intelligent decisions in
these cases, but they are far more intrusive and at this point not as clear cut.


Just in case...
Signed-off-by: Jeremy Linton 
---
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index c1b05a8..b249c2f 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -572,24 +572,25 @@ static int scsi_try_host_reset(struct scsi_cmnd *scmd)
 static int scsi_try_bus_reset(struct scsi_cmnd *scmd)
 {
 	unsigned long flags;
-	int rtn;
+	int rtn = FAILED ;
 	struct Scsi_Host *host = scmd->device->host;
 	struct scsi_host_template *hostt = host->hostt;
+	struct scsi_device *sdev = scmd->device;
 
 	SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Snd Bus RST\n",
 	  __func__));
 
-	if (!hostt->eh_bus_reset_handler)
-		return FAILED;
+	if ((sdev->bus_reset_ok) && (hostt->eh_bus_reset_handler)) {
 
-	rtn = hostt->eh_bus_reset_handler(scmd);
+		rtn = hostt->eh_bus_reset_handler(scmd);
 
-	if (rtn == SUCCESS) {
-		if (!hostt->skip_settle_delay)
-			ssleep(BUS_RESET_SETTLE_TIME);
-		spin_lock_irqsave(host->host_lock, flags);
-		scsi_report_bus_reset(host, scmd_channel(scmd));
-		spin_unlock_irqrestore(host->host_lock, flags);
+		if (rtn == SUCCESS) {
+			if (!hostt->skip_settle_delay)
+ssleep(BUS_RESET_SETTLE_TIME);
+			spin_lock_irqsave(host->host_lock, flags);
+			scsi_report_bus_reset(host, scmd_channel(scmd));
+			spin_unlock_irqrestore(host->host_lock, flags);
+		}
 	}
 
 	return rtn;
@@ -601,6 +602,7 @@ static void __scsi_report_device_reset(struct scsi_device *sdev, void *data)
 	sdev->expecting_cc_ua = 1;
 }
 
+
 /**
  * scsi_try_target_reset - Ask host to perform a target reset
  * @scmd:	SCSI cmd used to send a target reset
@@ -614,19 +616,26 @@ static void __scsi_report_device_reset(struct scsi_device *sdev, void *data)
 static int scsi_try_target_reset(struct scsi_cmnd *scmd)
 {
 	unsigned long flags;
-	int rtn;
+	int rtn = FAILED;
+	struct scsi_device *sdev = scmd->device;
 	struct Scsi_Host *host = scmd->device->host;
 	struct scsi_host_template *hostt = host->hostt;
 
-	if (!hostt->eh_target_reset_handler)
-		return FAILED;
+	if ((sdev->target_reset_ok) && (hostt->eh_target_reset_handler)) {
 
-	rtn = hostt->eh_target_reset_handler(scmd);
-	if (rtn == SUCCESS) {
-		spin_lock_irqsave(host->host_lock, flags);
-		__starget_for_each_device(scsi_target(scmd->device), NULL,
-	  __scsi_report_device_reset);
-		spin_unlock_irqrestore(host->host_lock, flags);
+		// TODO: Determine if other devices on this IT are experiencing
+		// issues. If not, return success without doing anything. 
+		SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Snd target RST\n", 
+		  __func__));
+
+		rtn = hostt->eh_target_reset_handler(scmd);
+
+		if (rtn == SUCCESS) {
+			spin_lock_irqsave(host->host_lock, flags);
+			__starget_for_each_device(scsi_target(scmd->device), NULL,
+		 __scsi_report_device_reset);
+			spin_unlock_irqrestore(host->host_lock, flags);
+		}
 	}
 
 	return rtn;
@@ -644,24 +653,36 @@ static int scsi_try_target_reset(struct scsi_cmnd *scmd)
  */
 static int scsi_try_bus_device_reset(struct scsi_cmnd *scmd)
 {
-	int rtn;
+	int rtn = FAILED;
 	struct scsi_host_template *hostt = scmd->device->host->hostt;
+	struct scsi_device *sdev = scmd->device;
 
-	if (!hostt->eh_device_reset_handler)
-		return FAILED;
+	if ((sdev->task_unit_reset_ok) && (hostt->eh_device_reset_handler)) {
+	   SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Snd LUN RST\n", 
+		 __func__));
+		rtn = hostt->eh_device_reset_handler(scmd);
+
+		if (rtn == SUCCESS)
+		__scsi_report_device_reset(scmd->device, NULL);
+	}
 
-	rtn = hostt->eh_device_reset_handler(scmd);
-	if (rtn == SUCCESS)
-		__scsi_report_device_reset(scmd->device, NULL);
 	return rtn;
 }
 
 static int scsi_try_to_abort_cmd(struct scsi_host_template *hostt, struct scsi_cmnd *scmd)
 {
-	if (!hostt->eh_abort_handler)
-		return FAILED;
+	int rtn = FAILED;
+	struct scsi_device *sdev = scmd->device;
+
+	if ((sdev->task_abort_ok) && (hostt->eh_abort_handler))
+	{
+		SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Snd Host RST\n", 
+		  __func__));
 
-	return hostt->eh_abort_handler(scmd);
+		rtn=hostt->eh_abort_handler(scmd);
+	}
+
+	return rtn;
 }
 
 static void sc

Re: Incorrect LBA Returned from scsi_get_lba() and blk_rq_pos() (Possible DIF Impact)

2013-02-12 Thread Martin K. Petersen
> "Sami" == Sami Waheed  writes:

Sami> I am testing a SCSI/SAS target with a block size of 4K.  I noticed
Sami> that scsi_get_lba which calls blk_rq_pos is returning an incorrect
Sami> LBA.  The returned LBA value is 8x the actual LBA specified in the
Sami> CDB:

The block layer always uses 512-byte sectors internally, regardless of
the logical block size of the actual disk.


Sami> I, also, noticed that several drivers use the scsi_get_lba inline
Sami> in scsi_cmnd.h to set/check ref tag for DIF.  On a 4K device, this
Sami> is resulting in an incorrect ref tag.

I have some patches in the pipeline that fixes this. They also add
support for protection intervals different from the logical block size.

-- 
Martin K. Petersen  Oracle Linux Engineering
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Incorrect LBA Returned from scsi_get_lba() and blk_rq_pos() (Possible DIF Impact)

2013-02-12 Thread Sami Waheed
Hello,

I am testing a SCSI/SAS target with a block size of 4K.I noticed
that scsi_get_lba which calls blk_rq_pos is returning an incorrect LBA.
The returned LBA value is 8x the actual LBA specified in the CDB:

The following "end_request:" message is printed from blk-core.c:

[  812.451579] sd 6:0:0:0: [sdb]  
[  812.451582] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
[  812.451585] sd 6:0:0:0: [sdb]  
[  812.451587] Sense Key : Aborted Command [current] 
[  812.451591] sd 6:0:0:0: [sdb]  
[  812.451593] Add. Sense: No additional sense information
[  812.451596] sd 6:0:0:0: [sdb] CDB: 
[  812.451597] Write(10): 2a 20 00 00 03 e8 00 00 01 00
[  812.451606] end_request: I/O error, dev sdb, sector 8000

Above CDB has LBA=0x3e8 which is 1000d.  Printed sector size above is
8000d


I, also, noticed that several drivers use the scsi_get_lba inline in
scsi_cmnd.h to set/check ref tag for DIF.  On a 4K device, this is
resulting in an incorrect ref tag.

Tested with kernel 3.7.5.

Regards,
--sami
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] qla2xxx: Update firmware link in Kconfig file.

2013-02-12 Thread Chad Dupuis
Signed-off-by: Giridhar Malavali 
Signed-off-by: Chad Dupuis 
---
 drivers/scsi/qla2xxx/Kconfig |4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/qla2xxx/Kconfig b/drivers/scsi/qla2xxx/Kconfig
index 317a7fd..23d6072 100644
--- a/drivers/scsi/qla2xxx/Kconfig
+++ b/drivers/scsi/qla2xxx/Kconfig
@@ -24,7 +24,9 @@ config SCSI_QLA_FC
 
Firmware images can be retrieved from:
 
-   ftp://ftp.qlogic.com/outgoing/linux/firmware/
+   http://ldriver.qlogic.com/firmware/
+
+   They are also included in the linux-firmware tree as well.
 
 config TCM_QLA2XXX
tristate "TCM_QLA2XXX fabric module for Qlogic 2xxx series target mode 
HBAs"
-- 
1.7.7

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] scsi_debug: Fix endianess in partition table

2013-02-12 Thread Douglas Gilbert

On 13-02-12 04:03 AM, Martin Peschke wrote:

On Mon, 2013-02-11 at 18:34 +0100, Martin Peschke wrote:

Both start_sect and nr_sects in struct partition are __le32 and
require cpu_to_le32() on assignment.


Steffen Maier has pointed me at:

block/partitions/msdos.c:   return
(sector_t)get_unaligned_le32(&p->start_sect);

Unfortunately, both get_unaligned_le32() and le32_to_cpu() appear to be
in use for start_sect and nr_sects.

Any one who would argue for changing my patch from cpu_to_le32 to
put_unaligned_le32()?


No (because I don't know). However since SCSI is big
endian and you are introducing some "le" code then a line
or so of explanation (comments) in your revised patch might
be helpful.


BTW Finding a big endian architecture to test this patch on is
not easy. The openwrt in my router is big endian (MIPS) but
openwrt don't distribute the scsi_debug module :-(

Doug Gilbert


Without this fix tools like fdisk show an invalid partition table
for SCSI devices emulated by scsi_debug on big-endian architectures,
like s390x. Besides a kernel message like this was emitted:

sda: p1 start 536870912 is beyond EOD, enabling native capacity
sda: p1 start 536870912 is beyond EOD, truncated

For verification 'xxd -l 512 /dev/sda' has been used to make sure
that this fix makes scsi_debug generated partition tables on s390x
look like the ones generated on my laptop.

Signed-off-by: Martin Peschke 
Reviewed-by: Steffen Maier 

---
  drivers/scsi/scsi_debug.c |4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -2662,8 +2662,8 @@ static void __init sdebug_build_parts(un
   / sdebug_sectors_per;
pp->end_sector = (end_sec % sdebug_sectors_per) + 1;

-   pp->start_sect = start_sec;
-   pp->nr_sects = end_sec - start_sec + 1;
+   pp->start_sect = cpu_to_le32(start_sec);
+   pp->nr_sects = cpu_to_le32(end_sec - start_sec + 1);
pp->sys_ind = 0x83;  /* plain Linux partition */
}
  }


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html




--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html



--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 06/23] qla2xxx: Update the FTP site references in the driver sources.

2013-02-12 Thread Chad Dupuis



On Mon, 11 Feb 2013, Xose Vazquez Perez wrote:


Giridhar Malavali wrote:


From: Giridhar Malavali 

Signed-off-by: Giridhar Malavali 
Signed-off-by: Saurav Kashyap 
---
 drivers/scsi/qla2xxx/qla_init.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index a581c85..bbf5688 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -5054,7 +5054,7 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t 
*srisc_addr,
 return rval;
 }

-#define QLA_FW_URL "ftp://ftp.qlogic.com/outgoing/linux/firmware/";
+#define QLA_FW_URL "http://ldriver.qlogic.com/firmware/";

 int
 qla2x00_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr)
--


qla2xxx/Kconfig should also be changed:

  Firmware images can be retrieved from:

   ftp://ftp.qlogic.com/outgoing/linux/firmware/


FYI, they are also included in linux-firmware.


Thanks for pointing this out Xose.  We'll be posting a patch soon to fix
the firmware link in the Kconfig files.


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html






This message and any attached documents contain information from QLogic 
Corporation or its wholly-owned subsidiaries that may be confidential. If you 
are not the intended recipient, you may not read, copy, distribute, or use this 
information. If you have received this transmission in error, please notify the 
sender immediately by reply e-mail and then delete this message.

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 0/5] virtio-scsi multiqueue

2013-02-12 Thread Paolo Bonzini
This series implements virtio-scsi queue steering, which gives
performance improvements of up to 50% (measured both with QEMU and
tcm_vhost backends).  The patches build on top of the new virtio APIs
at http://permalink.gmane.org/gmane.linux.kernel.virtualization/18431;
the new API simplifies the locking of the virtio-scsi driver nicely,
thus it makes sense to require them as a prerequisite.

Changes from the previous post, which can be found at
http://permalink.gmane.org/gmane.linux.kernel.virtualization/17869:

- patches 1 and 2 ("virtio: add functions for piecewise addition of
  buffers", "virtio-scsi: use functions for piecewise composition of
  buffers") split into their own series

- new cleanup patch "virtio-scsi: push vq lock/unlock into virtscsi_vq_done"

- reorganized code to move ACCESS_ONCE in a clearer place

- included Wanlong Gao's CPU hotplug patches

Ok for 3.9?  It would probably be easier to get it in via Rusty's tree
because of the prerequisites.  James, can I get your Acked-by?

Paolo

Paolo Bonzini (4):
  virtio-scsi: redo allocation of target data
  virtio-scsi: pass struct virtio_scsi to virtqueue completion function
  virtio-scsi: push vq lock/unlock into virtscsi_vq_done
  virtio-scsi: introduce multiqueue support

Wanlong Gao (1):
  virtio-scsi: reset virtqueue affinity when doing cpu hotplug

 drivers/scsi/virtio_scsi.c |  360 +++-
 1 files changed, 292 insertions(+), 68 deletions(-)

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 5/5] virtio-scsi: reset virtqueue affinity when doing cpu hotplug

2013-02-12 Thread Paolo Bonzini
From: Wanlong Gao 

Add hot cpu notifier to reset the request virtqueue affinity
when doing cpu hotplug.

Cc: linux-scsi@vger.kernel.org
Signed-off-by: Wanlong Gao 
[ The version that doesn't get/put_online_cpus is now called
  __virtscsi_set_affinity - Paolo ]
Signed-off-by: Paolo Bonzini 
---
 drivers/scsi/virtio_scsi.c |   31 +++
 1 files changed, 31 insertions(+), 0 deletions(-)

diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c
index a2bdae1..733307a 100644
--- a/drivers/scsi/virtio_scsi.c
+++ b/drivers/scsi/virtio_scsi.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -109,6 +110,9 @@ struct virtio_scsi {
/* Does the affinity hint is set for virtqueues? */
bool affinity_hint_set;
 
+   /* CPU hotplug notifier */
+   struct notifier_block nb;
+
struct virtio_scsi_vq ctrl_vq;
struct virtio_scsi_vq event_vq;
struct virtio_scsi_vq req_vqs[];
@@ -734,6 +738,7 @@ static void __virtscsi_set_affinity(struct virtio_scsi 
*vscsi, bool affinity)
}
 }
 
+
 static void virtscsi_set_affinity(struct virtio_scsi *vscsi, bool affinity)
 {
get_online_cpus();
@@ -741,6 +746,23 @@ static void virtscsi_set_affinity(struct virtio_scsi 
*vscsi, bool affinity)
put_online_cpus();
 }
 
+static int virtscsi_cpu_callback(struct notifier_block *nfb,
+unsigned long action, void *hcpu)
+{
+   struct virtio_scsi *vscsi = container_of(nfb, struct virtio_scsi, nb);
+   switch(action) {
+   case CPU_ONLINE:
+   case CPU_ONLINE_FROZEN:
+   case CPU_DEAD:
+   case CPU_DEAD_FROZEN:
+   __virtscsi_set_affinity(vscsi, true);
+   break;
+   default:
+   break;
+   }
+   return NOTIFY_OK;
+}
+
 static void virtscsi_init_vq(struct virtio_scsi_vq *virtscsi_vq,
 struct virtqueue *vq)
 {
@@ -885,6 +907,13 @@ static int virtscsi_probe(struct virtio_device *vdev)
if (err)
goto virtscsi_init_failed;
 
+   vscsi->nb.notifier_call = &virtscsi_cpu_callback;
+   err = register_hotcpu_notifier(&vscsi->nb);
+   if (err) {
+   pr_err("virtio_scsi: registering cpu notifier failed\n");
+   goto scsi_add_host_failed;
+   }
+
cmd_per_lun = virtscsi_config_get(vdev, cmd_per_lun) ?: 1;
shost->cmd_per_lun = min_t(u32, cmd_per_lun, shost->can_queue);
shost->max_sectors = virtscsi_config_get(vdev, max_sectors) ?: 0x;
@@ -922,6 +951,8 @@ static void virtscsi_remove(struct virtio_device *vdev)
 
scsi_remove_host(shost);
 
+   unregister_hotcpu_notifier(&vscsi->nb);
+
virtscsi_remove_vqs(vdev);
scsi_host_put(shost);
 }
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 3/5] virtio-scsi: push vq lock/unlock into virtscsi_vq_done

2013-02-12 Thread Paolo Bonzini
Avoid duplicated code in all of the callers.

Cc: linux-scsi@vger.kernel.org
Signed-off-by: Paolo Bonzini 
---
 drivers/scsi/virtio_scsi.c |   22 +-
 1 files changed, 9 insertions(+), 13 deletions(-)

diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c
index 3dd4ec5..3d77210 100644
--- a/drivers/scsi/virtio_scsi.c
+++ b/drivers/scsi/virtio_scsi.c
@@ -165,28 +165,30 @@ static void virtscsi_complete_cmd(struct virtio_scsi 
*vscsi, void *buf)
sc->scsi_done(sc);
 }
 
-static void virtscsi_vq_done(struct virtio_scsi *vscsi, struct virtqueue *vq,
+static void virtscsi_vq_done(struct virtio_scsi *vscsi,
+struct virtio_scsi_vq *virtscsi_vq,
 void (*fn)(struct virtio_scsi *vscsi, void *buf))
 {
void *buf;
unsigned int len;
+   unsigned long flags;
+   struct virtqueue *vq = virtscsi_vq->vq;
 
+   spin_lock_irqsave(&virtscsi_vq->vq_lock, flags);
do {
virtqueue_disable_cb(vq);
while ((buf = virtqueue_get_buf(vq, &len)) != NULL)
fn(vscsi, buf);
} while (!virtqueue_enable_cb(vq));
+   spin_unlock_irqrestore(&virtscsi_vq->vq_lock, flags);
 }
 
 static void virtscsi_req_done(struct virtqueue *vq)
 {
struct Scsi_Host *sh = virtio_scsi_host(vq->vdev);
struct virtio_scsi *vscsi = shost_priv(sh);
-   unsigned long flags;
 
-   spin_lock_irqsave(&vscsi->req_vq.vq_lock, flags);
-   virtscsi_vq_done(vscsi, vq, virtscsi_complete_cmd);
-   spin_unlock_irqrestore(&vscsi->req_vq.vq_lock, flags);
+   virtscsi_vq_done(vscsi, &vscsi->req_vq, virtscsi_complete_cmd);
 };
 
 static void virtscsi_complete_free(struct virtio_scsi *vscsi, void *buf)
@@ -203,11 +205,8 @@ static void virtscsi_ctrl_done(struct virtqueue *vq)
 {
struct Scsi_Host *sh = virtio_scsi_host(vq->vdev);
struct virtio_scsi *vscsi = shost_priv(sh);
-   unsigned long flags;
 
-   spin_lock_irqsave(&vscsi->ctrl_vq.vq_lock, flags);
-   virtscsi_vq_done(vscsi, vq, virtscsi_complete_free);
-   spin_unlock_irqrestore(&vscsi->ctrl_vq.vq_lock, flags);
+   virtscsi_vq_done(vscsi, &vscsi->ctrl_vq, virtscsi_complete_free);
 };
 
 static int virtscsi_kick_event(struct virtio_scsi *vscsi,
@@ -342,11 +341,8 @@ static void virtscsi_event_done(struct virtqueue *vq)
 {
struct Scsi_Host *sh = virtio_scsi_host(vq->vdev);
struct virtio_scsi *vscsi = shost_priv(sh);
-   unsigned long flags;
 
-   spin_lock_irqsave(&vscsi->event_vq.vq_lock, flags);
-   virtscsi_vq_done(vscsi, vq, virtscsi_complete_event);
-   spin_unlock_irqrestore(&vscsi->event_vq.vq_lock, flags);
+   virtscsi_vq_done(vscsi, &vscsi->event_vq, virtscsi_complete_event);
 };
 
 /**
-- 
1.7.1


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 4/5] virtio-scsi: introduce multiqueue support

2013-02-12 Thread Paolo Bonzini
This patch adds queue steering to virtio-scsi.  When a target is sent
multiple requests, we always drive them to the same queue so that FIFO
processing order is kept.  However, if a target was idle, we can choose
a queue arbitrarily.  In this case the queue is chosen according to the
current VCPU, so the driver expects the number of request queues to be
equal to the number of VCPUs.  This makes it easy and fast to select
the queue, and also lets the driver optimize the IRQ affinity for the
virtqueues (each virtqueue's affinity is set to the CPU that "owns"
the queue).

The speedup comes from improving cache locality and giving CPU affinity
to the virtqueues, which is why this scheme was selected.  Assuming that
the thread that is sending requests to the device is I/O-bound, it is
likely to be sleeping at the time the ISR is executed, and thus executing
the ISR on the same processor that sent the requests is cheap.

However, the kernel will not execute the ISR on the "best" processor
unless you explicitly set the affinity.  This is because in practice
you will have many such I/O-bound processes and thus many otherwise
idle processors.  Then the kernel will execute the ISR on a random
processor, rather than the one that is sending requests to the device.

The alternative to per-CPU virtqueues is per-target virtqueues.  To
achieve the same locality, we could dynamically choose the virtqueue's
affinity based on the CPU of the last task that sent a request.  This
is less appealing because we do not set the affinity directly---we only
provide a hint to the irqbalanced running in userspace.  Dynamically
changing the affinity only works if the userspace applies the hint
fast enough.

Cc: linux-scsi@vger.kernel.org
Signed-off-by: Wanlong Gao 
Signed-off-by: Paolo Bonzini 
---
 drivers/scsi/virtio_scsi.c |  269 +++-
 1 files changed, 240 insertions(+), 29 deletions(-)

diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c
index 3d77210..a2bdae1 100644
--- a/drivers/scsi/virtio_scsi.c
+++ b/drivers/scsi/virtio_scsi.c
@@ -26,6 +26,7 @@
 
 #define VIRTIO_SCSI_MEMPOOL_SZ 64
 #define VIRTIO_SCSI_EVENT_LEN 8
+#define VIRTIO_SCSI_VQ_BASE 2
 
 /* Command queue element */
 struct virtio_scsi_cmd {
@@ -57,24 +58,60 @@ struct virtio_scsi_vq {
struct virtqueue *vq;
 };
 
-/* Per-target queue state */
+/*
+ * Per-target queue state.
+ *
+ * This struct holds the data needed by the queue steering policy.  When a
+ * target is sent multiple requests, we need to drive them to the same queue so
+ * that FIFO processing order is kept.  However, if a target was idle, we can
+ * choose a queue arbitrarily.  In this case the queue is chosen according to
+ * the current VCPU, so the driver expects the number of request queues to be
+ * equal to the number of VCPUs.  This makes it easy and fast to select the
+ * queue, and also lets the driver optimize the IRQ affinity for the virtqueues
+ * (each virtqueue's affinity is set to the CPU that "owns" the queue).
+ *
+ * An interesting effect of this policy is that only writes to req_vq need to
+ * take the tgt_lock.  Read can be done outside the lock because:
+ *
+ * - writes of req_vq only occur when atomic_inc_return(&tgt->reqs) returns 1.
+ *   In that case, no other CPU is reading req_vq: even if they were in
+ *   virtscsi_queuecommand_multi, they would be spinning on tgt_lock.
+ *
+ * - reads of req_vq only occur when the target is not idle (reqs != 0).
+ *   A CPU that enters virtscsi_queuecommand_multi will not modify req_vq.
+ *
+ * Similarly, decrements of reqs are never concurrent with writes of req_vq.
+ * Thus they can happen outside the tgt_lock, provided of course we make reqs
+ * an atomic_t.
+ */
 struct virtio_scsi_target_state {
-   /* Never held at the same time as vq_lock.  */
+   /* This spinlock ever held at the same time as vq_lock.  */
spinlock_t tgt_lock;
+
+   /* Count of outstanding requests.  */
+   atomic_t reqs;
+
+   /* Currently active virtqueue for requests sent to this target.  */
+   struct virtio_scsi_vq *req_vq;
 };
 
 /* Driver instance state */
 struct virtio_scsi {
struct virtio_device *vdev;
 
-   struct virtio_scsi_vq ctrl_vq;
-   struct virtio_scsi_vq event_vq;
-   struct virtio_scsi_vq req_vq;
-
/* Get some buffers ready for event vq */
struct virtio_scsi_event_node event_list[VIRTIO_SCSI_EVENT_LEN];
 
struct virtio_scsi_target_state *tgt;
+
+   u32 num_queues;
+
+   /* Does the affinity hint is set for virtqueues? */
+   bool affinity_hint_set;
+
+   struct virtio_scsi_vq ctrl_vq;
+   struct virtio_scsi_vq event_vq;
+   struct virtio_scsi_vq req_vqs[];
 };
 
 static struct kmem_cache *virtscsi_cmd_cache;
@@ -109,6 +146,7 @@ static void virtscsi_complete_cmd(struct virtio_scsi 
*vscsi, void *buf)
struct virtio_scsi_cmd *cmd = buf;
struct scsi_cmnd *sc = cmd->sc;
s

[PATCH v3 2/5] virtio-scsi: pass struct virtio_scsi to virtqueue completion function

2013-02-12 Thread Paolo Bonzini
This will be needed soon in order to retrieve the per-target
struct.

Cc: linux-scsi@vger.kernel.org
Signed-off-by: Paolo Bonzini 
---
 drivers/scsi/virtio_scsi.c |   17 +
 1 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c
index 3f15568..3dd4ec5 100644
--- a/drivers/scsi/virtio_scsi.c
+++ b/drivers/scsi/virtio_scsi.c
@@ -104,7 +104,7 @@ static void virtscsi_compute_resid(struct scsi_cmnd *sc, 
u32 resid)
  *
  * Called with vq_lock held.
  */
-static void virtscsi_complete_cmd(void *buf)
+static void virtscsi_complete_cmd(struct virtio_scsi *vscsi, void *buf)
 {
struct virtio_scsi_cmd *cmd = buf;
struct scsi_cmnd *sc = cmd->sc;
@@ -165,7 +165,8 @@ static void virtscsi_complete_cmd(void *buf)
sc->scsi_done(sc);
 }
 
-static void virtscsi_vq_done(struct virtqueue *vq, void (*fn)(void *buf))
+static void virtscsi_vq_done(struct virtio_scsi *vscsi, struct virtqueue *vq,
+void (*fn)(struct virtio_scsi *vscsi, void *buf))
 {
void *buf;
unsigned int len;
@@ -173,7 +174,7 @@ static void virtscsi_vq_done(struct virtqueue *vq, void 
(*fn)(void *buf))
do {
virtqueue_disable_cb(vq);
while ((buf = virtqueue_get_buf(vq, &len)) != NULL)
-   fn(buf);
+   fn(vscsi, buf);
} while (!virtqueue_enable_cb(vq));
 }
 
@@ -184,11 +185,11 @@ static void virtscsi_req_done(struct virtqueue *vq)
unsigned long flags;
 
spin_lock_irqsave(&vscsi->req_vq.vq_lock, flags);
-   virtscsi_vq_done(vq, virtscsi_complete_cmd);
+   virtscsi_vq_done(vscsi, vq, virtscsi_complete_cmd);
spin_unlock_irqrestore(&vscsi->req_vq.vq_lock, flags);
 };
 
-static void virtscsi_complete_free(void *buf)
+static void virtscsi_complete_free(struct virtio_scsi *vscsi, void *buf)
 {
struct virtio_scsi_cmd *cmd = buf;
 
@@ -205,7 +206,7 @@ static void virtscsi_ctrl_done(struct virtqueue *vq)
unsigned long flags;
 
spin_lock_irqsave(&vscsi->ctrl_vq.vq_lock, flags);
-   virtscsi_vq_done(vq, virtscsi_complete_free);
+   virtscsi_vq_done(vscsi, vq, virtscsi_complete_free);
spin_unlock_irqrestore(&vscsi->ctrl_vq.vq_lock, flags);
 };
 
@@ -329,7 +330,7 @@ static void virtscsi_handle_event(struct work_struct *work)
virtscsi_kick_event(vscsi, event_node);
 }
 
-static void virtscsi_complete_event(void *buf)
+static void virtscsi_complete_event(struct virtio_scsi *vscsi, void *buf)
 {
struct virtio_scsi_event_node *event_node = buf;
 
@@ -344,7 +345,7 @@ static void virtscsi_event_done(struct virtqueue *vq)
unsigned long flags;
 
spin_lock_irqsave(&vscsi->event_vq.vq_lock, flags);
-   virtscsi_vq_done(vq, virtscsi_complete_event);
+   virtscsi_vq_done(vscsi, vq, virtscsi_complete_event);
spin_unlock_irqrestore(&vscsi->event_vq.vq_lock, flags);
 };
 
-- 
1.7.1


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 1/5] virtio-scsi: redo allocation of target data

2013-02-12 Thread Paolo Bonzini
virtio_scsi_target_state is now empty, but we will find new uses
for it in the next few patches.  However, dropping the sglist lets
us turn the array-of-pointers into a simple array, which simplifies
the allocation.

However, we do not leave the virtio_scsi_target_state structs in the
flexible array member at the end of struct virtio_scsi, because
we will place the virtqueues there in the next patches.

Cc: linux-scsi@vger.kernel.org
Signed-off-by: Paolo Bonzini 
---
 drivers/scsi/virtio_scsi.c |   39 ---
 1 files changed, 12 insertions(+), 27 deletions(-)

diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c
index 8b90c17..3f15568 100644
--- a/drivers/scsi/virtio_scsi.c
+++ b/drivers/scsi/virtio_scsi.c
@@ -74,7 +74,7 @@ struct virtio_scsi {
/* Get some buffers ready for event vq */
struct virtio_scsi_event_node event_list[VIRTIO_SCSI_EVENT_LEN];
 
-   struct virtio_scsi_target_state *tgt[];
+   struct virtio_scsi_target_state *tgt;
 };
 
 static struct kmem_cache *virtscsi_cmd_cache;
@@ -574,19 +574,9 @@ static void virtscsi_init_vq(struct virtio_scsi_vq 
*virtscsi_vq,
virtscsi_vq->vq = vq;
 }
 
-static struct virtio_scsi_target_state *virtscsi_alloc_tgt(
-   struct virtio_device *vdev, int sg_elems)
+static void virtscsi_init_tgt(struct virtio_scsi_target_state *tgt)
 {
-   struct virtio_scsi_target_state *tgt;
-   gfp_t gfp_mask = GFP_KERNEL;
-
-   /* We need extra sg elements at head and tail.  */
-   tgt = kmalloc(sizeof(*tgt), gfp_mask);
-   if (!tgt)
-   return NULL;
-
spin_lock_init(&tgt->tgt_lock);
-   return tgt;
 }
 
 static void virtscsi_scan(struct virtio_device *vdev)
@@ -600,16 +590,12 @@ static void virtscsi_remove_vqs(struct virtio_device 
*vdev)
 {
struct Scsi_Host *sh = virtio_scsi_host(vdev);
struct virtio_scsi *vscsi = shost_priv(sh);
-   u32 i, num_targets;
 
/* Stop all the virtqueues. */
vdev->config->reset(vdev);
 
-   num_targets = sh->max_id;
-   for (i = 0; i < num_targets; i++) {
-   kfree(vscsi->tgt[i]);
-   vscsi->tgt[i] = NULL;
-   }
+   kfree(vscsi->tgt);
+   vscsi->tgt = NULL;
 
vdev->config->del_vqs(vdev);
 }
@@ -650,13 +636,14 @@ static int virtscsi_init(struct virtio_device *vdev,
/* We need to know how many segments before we allocate.  */
sg_elems = virtscsi_config_get(vdev, seg_max) ?: 1;
 
-   for (i = 0; i < num_targets; i++) {
-   vscsi->tgt[i] = virtscsi_alloc_tgt(vdev, sg_elems);
-   if (!vscsi->tgt[i]) {
-   err = -ENOMEM;
-   goto out;
-   }
+   vscsi->tgt = kmalloc(num_targets * sizeof(vscsi->tgt[0]), GFP_KERNEL);
+   if (!vscsi->tgt) {
+   err = -ENOMEM;
+   goto out;
}
+   for (i = 0; i < num_targets; i++)
+   virtscsi_init_tgt(&vscsi->tgt[i]);
+
err = 0;
 
 out:
@@ -675,9 +662,7 @@ static int virtscsi_probe(struct virtio_device *vdev)
 
/* Allocate memory and link the structs together.  */
num_targets = virtscsi_config_get(vdev, max_target) + 1;
-   shost = scsi_host_alloc(&virtscsi_host_template,
-   sizeof(*vscsi)
-   + num_targets * sizeof(struct virtio_scsi_target_state));
+   shost = scsi_host_alloc(&virtscsi_host_template, sizeof(*vscsi));
 
if (!shost)
return -ENOMEM;
-- 
1.7.1


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 15/15] pm80xx: thermal, sas controller config and error handling update

2013-02-12 Thread Anand
>From 9c620d9273640b416054ba76cd267aebaf455ed2 Mon Sep 17 00:00:00 2001
From: Sakthivel K 
Date: Wed, 6 Feb 2013 17:39:43 +0530
Subject: [PATCH 15/15] pm80xx: thermal, sas controller config and error 
handling update

Modified thermal configuration to happen after interrupt registration
Added SAS controller configuration during initialization
Added error handling logic to handle I_T_Nexus errors and variants

Signed-off-by: Anand Kumar S 
---
 drivers/scsi/pm8001/pm8001_hwi.c  |2 +-
 drivers/scsi/pm8001/pm8001_init.c |2 +
 drivers/scsi/pm8001/pm8001_sas.c  |   66 
 drivers/scsi/pm8001/pm8001_sas.h  |2 +
 drivers/scsi/pm8001/pm80xx_hwi.c  |  150 +
 drivers/scsi/pm8001/pm80xx_hwi.h  |   44 +++-
 6 files changed, 249 insertions(+), 17 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index a90c002..d18f421 100755
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -1670,7 +1670,7 @@ void pm8001_work_fn(struct work_struct *work)
}   break;
case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS:
dev = pm8001_dev->sas_device;
-   pm8001_I_T_nexus_reset(dev);
+   pm8001_I_T_nexus_event_handler(dev);
break;
case IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY:
dev = pm8001_dev->sas_device;
diff --git a/drivers/scsi/pm8001/pm8001_init.c 
b/drivers/scsi/pm8001/pm8001_init.c
index b884a58..289c2a5 100755
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -1795,6 +1795,8 @@ static int pm8001_pci_probe(struct pci_dev *pdev,
if (pm8001_ha->chip_id != chip_8001) {
for (i = 1; i < pm8001_ha->number_of_intr; i++)
PM8001_CHIP_DISP->interrupt_enable(pm8001_ha, i);
+   /* setup thermal configuration. */
+   pm80xx_set_thermal_config(pm8001_ha);
}
 
pm8001_init_sas_add(pm8001_ha);
diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
index c720917..9af9585 100755
--- a/drivers/scsi/pm8001/pm8001_sas.c
+++ b/drivers/scsi/pm8001/pm8001_sas.c
@@ -1018,6 +1018,72 @@ int pm8001_I_T_nexus_reset(struct domain_device *dev)
return rc;
 }
 
+/*
+* This function handle the IT_NEXUS_XXX event or completion
+* status code for SSP/SATA/SMP I/O request.
+*/
+int pm8001_I_T_nexus_event_handler(struct domain_device *dev)
+{
+   int rc = TMF_RESP_FUNC_FAILED;
+   struct pm8001_device *pm8001_dev;
+   struct pm8001_hba_info *pm8001_ha;
+   struct sas_phy *phy;
+   u32 device_id = 0;
+
+   if (!dev || !dev->lldd_dev)
+   return -1;
+
+   pm8001_dev = dev->lldd_dev;
+   device_id = pm8001_dev->device_id;
+   pm8001_ha = pm8001_find_ha_by_dev(dev);
+
+   PM8001_EH_DBG(pm8001_ha,
+   pm8001_printk("I_T_Nexus handler invoked !!"));
+
+   phy = sas_get_local_phy(dev);
+
+   if (dev_is_sata(dev)) {
+   DECLARE_COMPLETION_ONSTACK(completion_setstate);
+   if (scsi_is_sas_phy_local(phy)) {
+   rc = 0;
+   goto out;
+   }
+   /* send internal ssp/sata/smp abort command to FW */
+   rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev ,
+   dev, 1, 0);
+   msleep(100);
+
+   /* deregister the target device */
+   pm8001_dev_gone_notify(dev);
+   msleep(200);
+
+   /*send phy reset to hard reset target */
+   rc = sas_phy_reset(phy, 1);
+   msleep(2000);
+   pm8001_dev->setds_completion = &completion_setstate;
+
+   wait_for_completion(&completion_setstate);
+   } else {
+   /* send internal ssp/sata/smp abort command to FW */
+   rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev ,
+   dev, 1, 0);
+   msleep(100);
+
+   /* deregister the target device */
+   pm8001_dev_gone_notify(dev);
+   msleep(200);
+
+   /*send phy reset to hard reset target */
+   rc = sas_phy_reset(phy, 1);
+   msleep(2000);
+   }
+   PM8001_EH_DBG(pm8001_ha, pm8001_printk(" for device[%x]:rc=%d\n",
+   pm8001_dev->device_id, rc));
+out:
+   sas_put_local_phy(phy);
+
+   return rc;
+}
 /* mandatory SAM-3, the task reset the specified LUN*/
 int pm8001_lu_reset(struct domain_device *dev, u8 *lun)
 {
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index c1598dc..fbb65d5 100755
--- a/drivers/scsi/pm8001/pm8001_sas.h
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -562,6 +562,7 @@ int pm8001_dev_found(struct domain_device *dev);
 void pm8001_dev_gone(struct do

[PATCH 14/15] pm80xx: NCQ error handling changes

2013-02-12 Thread Anand
>From 97d4edce607941e931b77d1fed12096294ff6c8e Mon Sep 17 00:00:00 2001
From: Sakthivel K 
Date: Wed, 6 Feb 2013 17:27:22 +0530
Subject: [PATCH 14/15] pm80xx: NCQ error handling changes

Handled NCQ errors in the low level driver as the FW
is not providing the faulty tag for NCQ errors for libsas
to recover.

Signed-off-by: Anand Kumar S 
---
 drivers/scsi/pm8001/pm8001_hwi.c |  270 --
 drivers/scsi/pm8001/pm8001_sas.c |   22 +++-
 drivers/scsi/pm8001/pm8001_sas.h |   15 ++-
 drivers/scsi/pm8001/pm80xx_hwi.c |  262 +++--
 drivers/scsi/pm8001/pm80xx_hwi.h |1 +
 5 files changed, 543 insertions(+), 27 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index 265dbf4..a90c002 100755
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -1707,6 +1707,123 @@ int pm8001_handle_event(struct pm8001_hba_info 
*pm8001_ha, void *data,
return ret;
 }
 
+static void pm8001_send_abort_all(struct pm8001_hba_info *pm8001_ha,
+   struct pm8001_device *pm8001_ha_dev)
+{
+   int res;
+   u32 ccb_tag;
+   struct pm8001_ccb_info *ccb;
+   struct sas_task *task = NULL;
+   struct task_abort_req task_abort;
+   struct inbound_queue_table *circularQ;
+   u32 opc = OPC_INB_SATA_ABORT;
+   int ret;
+
+   if (!pm8001_ha_dev) {
+   PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("dev is null \n"));
+   return;
+   }
+
+   task = sas_alloc_slow_task(GFP_ATOMIC);
+
+   if (!task) {
+   PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("cannot "
+   "allocate task \n"));
+   return;
+   }
+
+   task->task_done = pm8001_task_done;
+
+   res = pm8001_tag_alloc(pm8001_ha, &ccb_tag);
+   if (res)
+   return;
+
+   ccb = &pm8001_ha->ccb_info[ccb_tag];
+   ccb->device = pm8001_ha_dev;
+   ccb->ccb_tag = ccb_tag;
+   ccb->task = task;
+
+   circularQ = &pm8001_ha->inbnd_q_tbl[0];
+
+   memset(&task_abort, 0, sizeof(task_abort));
+   task_abort.abort_all = cpu_to_le32(1);
+   task_abort.device_id = cpu_to_le32(pm8001_ha_dev->device_id);
+   task_abort.tag = cpu_to_le32(ccb_tag);
+
+   ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &task_abort, 0);
+
+}
+
+static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha,
+   struct pm8001_device *pm8001_ha_dev)
+{
+   struct sata_start_req sata_cmd;
+   int res;
+   u32 ccb_tag;
+   struct pm8001_ccb_info *ccb;
+   struct sas_task *task = NULL;
+   struct host_to_dev_fis fis;
+   struct domain_device *dev;
+   struct inbound_queue_table *circularQ;
+   u32 opc = OPC_INB_SATA_HOST_OPSTART;
+
+   task = sas_alloc_slow_task(GFP_ATOMIC);
+
+   if (!task) {
+   PM8001_FAIL_DBG(pm8001_ha,
+   pm8001_printk("cannot allocate task !!!\n"));
+   return;
+   }
+   task->task_done = pm8001_task_done;
+
+   res = pm8001_tag_alloc(pm8001_ha, &ccb_tag);
+   if (res) {
+   PM8001_FAIL_DBG(pm8001_ha,
+   pm8001_printk("cannot allocate tag !!!\n"));
+   return;
+   }
+
+   /* allocate domain device by ourselves as libsas
+* is not going to provide any
+   */
+   dev = kzalloc(sizeof(struct domain_device), GFP_ATOMIC);
+   if (!dev) {
+   PM8001_FAIL_DBG(pm8001_ha,
+   pm8001_printk("Domain device cannot be allocated \n"));
+   sas_free_task(task);
+   return;
+   } else {
+   task->dev = dev;
+   task->dev->lldd_dev = pm8001_ha_dev;
+   }
+
+   ccb = &pm8001_ha->ccb_info[ccb_tag];
+   ccb->device = pm8001_ha_dev;
+   ccb->ccb_tag = ccb_tag;
+   ccb->task = task;
+   pm8001_ha_dev->id |= NCQ_READ_LOG_FLAG;
+   pm8001_ha_dev->id |= NCQ_2ND_RLE_FLAG;
+
+   memset(&sata_cmd, 0, sizeof(sata_cmd));
+   circularQ = &pm8001_ha->inbnd_q_tbl[0];
+
+   /* construct read log FIS */
+   memset(&fis, 0, sizeof(struct host_to_dev_fis));
+   fis.fis_type = 0x27;
+   fis.flags = 0x80;
+   fis.command = ATA_CMD_READ_LOG_EXT;
+   fis.lbal = 0x10;
+   fis.sector_count = 0x1;
+
+   sata_cmd.tag = cpu_to_le32(ccb_tag);
+   sata_cmd.device_id = cpu_to_le32(pm8001_ha_dev->device_id);
+   sata_cmd.ncqtag_atap_dir_m |= ((0x1 << 7) | (0x5 << 9));
+   memcpy(&sata_cmd.sata_fis, &fis, sizeof(struct host_to_dev_fis));
+
+   res = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &sata_cmd, 0);
+
+}
+
 /**
  * mpi_ssp_completion- process the event that FW response to the SSP request.
  * @pm8001_ha: our hba card information
@@ -2170,16 +2287,44 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, 
void *piomb)
status = le32_to_c

[PATCH 13/15] pm80xx: WWN Modification for PM8081/88/89 controllers

2013-02-12 Thread Anand
>From 43681f8bc5a857318ead1a9173d6b796f238738c Mon Sep 17 00:00:00 2001
From: Sakthivel K 
Date: Tue, 5 Feb 2013 12:07:19 +0530
Subject: [PATCH 13/15] pm80xx: WWN Modification for PM8081/88/89 controllers

Individual WWN read operations based on controller.
PM8081 - Read WWN from Flash VPD.
PM8088/89 - Read WWN from EEPROM.
PM8001 - Read WWN from NVM.

Signed-off-by: Sakthivel K 
Signed-off-by: Anand Kumar S 
---
 drivers/scsi/pm8001/pm8001_init.c |   43 +++--
 1 files changed, 36 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_init.c 
b/drivers/scsi/pm8001/pm8001_init.c
index a9e6db0..b884a58 100755
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -1566,21 +1566,50 @@ static void  pm8001_post_sas_ha_init(struct Scsi_Host 
*shost,
  */
 static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha)
 {
-   u8 i;
+   u8 i, j;
 #ifdef PM8001_READ_VPD
+   /* For new SPC controllers WWN is stored in flash vpd
+   *  For SPC/SPCve controllers WWN is stored in EEPROM
+   *  For Older SPC WWN is stored in NVMD
+   */
DECLARE_COMPLETION_ONSTACK(completion);
struct pm8001_ioctl_payload payload;
+   u16 deviceid;
+   pci_read_config_word(pm8001_ha->pdev, PCI_DEVICE_ID, &deviceid);
pm8001_ha->nvmd_completion = &completion;
-   payload.minor_function = 0;
-   payload.length = 128;
-   payload.func_specific = kzalloc(128, GFP_KERNEL);
+
+   if (pm8001_ha->chip_id == chip_8001) {
+   if (deviceid == 0x8081) {
+   payload.minor_function = 4;
+   payload.length = 4096;
+   } else {
+   payload.minor_function = 0;
+   payload.length = 128;
+   }
+   } else {
+   payload.minor_function = 1;
+   payload.length = 4096;
+   }
+   payload.offset = 0;
+   payload.func_specific = kzalloc(payload.length, GFP_KERNEL);
PM8001_CHIP_DISP->get_nvmd_req(pm8001_ha, &payload);
wait_for_completion(&completion);
+
+   for (i = 0, j = 0; i <= 7; i++, j++) {
+   if (pm8001_ha->chip_id == chip_8001) {
+   if (deviceid == 0x8081)
+   pm8001_ha->sas_addr[j] =
+   payload.func_specific[0x704 + i];
+   } else
+   pm8001_ha->sas_addr[j] =
+   payload.func_specific[0x804 + i];
+   }
+
for (i = 0; i < pm8001_ha->chip->n_phy; i++) {
-   memcpy(&pm8001_ha->phy[i].dev_sas_addr, pm8001_ha->sas_addr,
-   SAS_ADDR_SIZE);
+   memcpy(&pm8001_ha->phy[i].dev_sas_addr,
+   pm8001_ha->sas_addr, SAS_ADDR_SIZE);
PM8001_INIT_DBG(pm8001_ha,
-   pm8001_printk("phy %d sas_addr = %016llx \n", i,
+   pm8001_printk("phy %d sas_addr = %016llx\n", i,
pm8001_ha->phy[i].dev_sas_addr));
}
 #else
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 12/15] pm80xx: Changed module name and debug messages update

2013-02-12 Thread Anand
>From 78eaee73dd18671795fb6781bb34dc4c5e3410ce Mon Sep 17 00:00:00 2001
From: Sakthivel K 
Date: Tue, 5 Feb 2013 11:48:05 +0530
Subject: [PATCH 12/15] pm80xx: Changed module name and debug messages update

Changed name in driver to pm80xx. Updated debug messages.

Signed-off-by: Sakthivel K 
Signed-off-by: Anand Kumar S 
---
 drivers/scsi/pm8001/Makefile  |7 ---
 drivers/scsi/pm8001/pm8001_hwi.c  |   11 ++-
 drivers/scsi/pm8001/pm8001_init.c |   14 ++
 drivers/scsi/pm8001/pm8001_sas.h  |6 +++---
 4 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/drivers/scsi/pm8001/Makefile b/drivers/scsi/pm8001/Makefile
index 52f0429..ce4cd87 100755
--- a/drivers/scsi/pm8001/Makefile
+++ b/drivers/scsi/pm8001/Makefile
@@ -4,9 +4,10 @@
 # Copyright (C) 2008-2009  USI Co., Ltd.
 
 
-obj-$(CONFIG_SCSI_PM8001) += pm8001.o
-pm8001-y += pm8001_init.o \
+obj-$(CONFIG_SCSI_PM8001) += pm80xx.o
+pm80xx-y += pm8001_init.o \
pm8001_sas.o  \
pm8001_ctl.o  \
-   pm8001_hwi.o
+   pm8001_hwi.o  \
+   pm80xx_hwi.o
 
diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index c124fc6..265dbf4 100755
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -2506,9 +2506,9 @@ static void mpi_sata_event(struct pm8001_hba_info 
*pm8001_ha , void *piomb)
if (unlikely(!t || !t->lldd_task || !t->dev))
return;
ts = &t->task_status;
-   PM8001_IO_DBG(pm8001_ha,
-   pm8001_printk("port_id = %x,device_id = %x\n",
-   port_id, dev_id));
+   PM8001_IO_DBG(pm8001_ha, pm8001_printk(
+   "port_id:0x%x, device_id:0x%x, tag:0x%x, event:0x%x\n",
+   port_id, dev_id, tag, event));
switch (event) {
case IO_OVERFLOW:
PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_UNDERFLOW\n"));
@@ -4409,8 +4409,9 @@ int pm8001_chip_abort_task(struct pm8001_hba_info 
*pm8001_ha,
 {
u32 opc, device_id;
int rc = TMF_RESP_FUNC_FAILED;
-   PM8001_EH_DBG(pm8001_ha, pm8001_printk("cmd_tag = %x, abort task tag"
-   " = %x", cmd_tag, task_tag));
+   PM8001_EH_DBG(pm8001_ha,
+   pm8001_printk("cmd_tag = %x, abort task tag = 0x%x",
+   cmd_tag, task_tag));
if (pm8001_dev->dev_type == SAS_END_DEV)
opc = OPC_INB_SSP_ABORT;
else if (pm8001_dev->dev_type == SATA_DEV)
diff --git a/drivers/scsi/pm8001/pm8001_init.c 
b/drivers/scsi/pm8001/pm8001_init.c
index cb17cb9..a9e6db0 100755
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -1698,7 +1698,7 @@ static int pm8001_pci_probe(struct pci_dev *pdev,
const struct pm8001_chip_info *chip;
 
dev_printk(KERN_INFO, &pdev->dev,
-   "pm8001: driver version %s\n", DRV_VERSION);
+   "pm80xx: driver version %s\n", DRV_VERSION);
rc = pci_enable_device(pdev);
if (rc)
goto err_out_enable;
@@ -1746,15 +1746,21 @@ static int pm8001_pci_probe(struct pci_dev *pdev,
list_add_tail(&pm8001_ha->list, &hba_list);
PM8001_CHIP_DISP->chip_soft_rst(pm8001_ha);
rc = PM8001_CHIP_DISP->chip_init(pm8001_ha);
-   if (rc)
+   if (rc) {
+   PM8001_FAIL_DBG(pm8001_ha, pm8001_printk(
+   "chip_init failed [ret: %d]\n", rc));
goto err_out_ha_free;
+   }
 
rc = scsi_add_host(shost, &pdev->dev);
if (rc)
goto err_out_ha_free;
rc = pm8001_request_irq(pm8001_ha);
-   if (rc)
+   if (rc) {
+   PM8001_FAIL_DBG(pm8001_ha, pm8001_printk(
+   "pm8001_request_irq failed [ret: %d]\n", rc));
goto err_out_shost;
+   }
 
PM8001_CHIP_DISP->interrupt_enable(pm8001_ha, 0);
if (pm8001_ha->chip_id != chip_8001) {
@@ -2131,7 +2137,7 @@ static int __init pm8001_init(void)
 {
int rc = -ENOMEM;
 
-   pm8001_wq = alloc_workqueue("pm8001", 0, 0);
+   pm8001_wq = alloc_workqueue("pm80xx", 0, 0);
if (!pm8001_wq)
goto err;
 
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index 466934d..53d7f3b 100755
--- a/drivers/scsi/pm8001/pm8001_sas.h
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -57,7 +57,7 @@
 #include 
 #include "pm8001_defs.h"
 
-#define DRV_NAME   "pm8001"
+#define DRV_NAME   "pm80xx"
 #define DRV_VERSION"0.1.36"
 #define PM8001_FAIL_LOGGING0x01 /* Error message logging */
 #define PM8001_INIT_LOGGING0x02 /* driver init logging */
@@ -66,8 +66,8 @@
 #define PM8001_EH_LOGGING  0x10 /* libsas EH function logging*/
 #define PM8001_IOCTL_LOGGING   0x20 /* IOCTL message logging */
 #define PM8001_MSG_LOGGING 0x40 /* misc message logging */
-#define pm8001_printk(format, arg...)  printk(KERN_INFO "%s %d:" form

[PATCH 11/15] pm80xx: Firmware flash memory free fix, with addition of new memory, region for it

2013-02-12 Thread Anand
>From d3f1b3ea4b638f154a7979773f6a839fa455564b Mon Sep 17 00:00:00 2001
From: Sakthivel K 
Date: Tue, 5 Feb 2013 11:06:51 +0530
Subject: [PATCH 11/15] pm80xx: Firmware flash memory free fix, with addition of 
new memory
 region for it

Performing pci_free_consistent in tasklet had result in a core dump. So
allocated a new memory region for it. Fix for passing proper address
and operation in firmware flash update.

Signed-off-by: Sakthivel K 
Signed-off-by: Anand Kumar S 
---
 drivers/scsi/pm8001/pm8001_ctl.c  |5 +++--
 drivers/scsi/pm8001/pm8001_defs.h |3 ++-
 drivers/scsi/pm8001/pm8001_hwi.c  |   30 ++
 drivers/scsi/pm8001/pm8001_init.c |3 +++
 4 files changed, 14 insertions(+), 27 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c
index ae2b124..d99f41c 100755
--- a/drivers/scsi/pm8001/pm8001_ctl.c
+++ b/drivers/scsi/pm8001/pm8001_ctl.c
@@ -400,10 +400,11 @@ static int pm8001_set_nvmd(struct pm8001_hba_info 
*pm8001_ha)
goto out;
}
payload = (struct pm8001_ioctl_payload *)ioctlbuffer;
-   memcpy((u8 *)payload->func_specific, (u8 *)pm8001_ha->fw_image->data,
+   memcpy((u8 *)&payload->func_specific, (u8 *)pm8001_ha->fw_image->data,
pm8001_ha->fw_image->size);
payload->length = pm8001_ha->fw_image->size;
payload->id = 0;
+   payload->minor_function = 0x1;
pm8001_ha->nvmd_completion = &completion;
ret = PM8001_CHIP_DISP->set_nvmd_req(pm8001_ha, payload);
wait_for_completion(&completion);
@@ -450,7 +451,7 @@ static int pm8001_update_flash(struct pm8001_hba_info 
*pm8001_ha)
payload->length = 1024*16;
payload->id = 0;
fwControl =
- (struct fw_control_info *)payload->func_specific;
+ (struct fw_control_info *)&payload->func_specific;
fwControl->len = IOCTL_BUF_SIZE;   /* IN */
fwControl->size = partitionSize + HEADER_LEN;/* IN */
fwControl->retcode = 0;/* OUT */
diff --git a/drivers/scsi/pm8001/pm8001_defs.h 
b/drivers/scsi/pm8001/pm8001_defs.h
index 26a2ee6..479c5a7 100755
--- a/drivers/scsi/pm8001/pm8001_defs.h
+++ b/drivers/scsi/pm8001/pm8001_defs.h
@@ -86,7 +86,7 @@ enum port_type {
 #definePM8001_MAX_DEVICES   2048   /* max supported device */
 #definePM8001_MAX_MSIX_VEC  64 /* max msi-x int for spcv/ve */
 
-#define USI_MAX_MEMCNT_BASE4
+#define USI_MAX_MEMCNT_BASE5
 #define IB (USI_MAX_MEMCNT_BASE + 1)
 #define CI (IB + PM8001_MAX_SPCV_INB_NUM)
 #define OB (CI + PM8001_MAX_SPCV_INB_NUM)
@@ -99,6 +99,7 @@ enum memory_region_num {
NVMD,   /* NVM device */
DEV_MEM,/* memory for devices */
CCB_MEM,/* memory for command control block */
+   FW_FLASH/* memory for fw flash update */
 };
 #definePM8001_EVENT_LOG_SIZE(128 * 1024)
 
diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index 3adf499..c124fc6 100755
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -3481,10 +3481,6 @@ int pm8001_mpi_fw_flash_update_resp(struct 
pm8001_hba_info *pm8001_ha,
break;
}
ccb->fw_control_context->fw_control->retcode = status;
-   pci_free_consistent(pm8001_ha->pdev,
-   fw_control_context.len,
-   fw_control_context.virtAddr,
-   fw_control_context.phys_addr);
complete(pm8001_ha->nvmd_completion);
ccb->task = NULL;
ccb->ccb_tag = 0x;
@@ -4474,7 +4470,7 @@ int pm8001_chip_get_nvmd_req(struct pm8001_hba_info 
*pm8001_ha,
fw_control_context = kzalloc(sizeof(struct fw_control_ex), GFP_KERNEL);
if (!fw_control_context)
return -ENOMEM;
-   fw_control_context->usrAddr = (u8 *)&ioctl_payload->func_specific[0];
+   fw_control_context->usrAddr = (u8 *)ioctl_payload->func_specific;
fw_control_context->len = ioctl_payload->length;
circularQ = &pm8001_ha->inbnd_q_tbl[0];
memset(&nvmd_req, 0, sizeof(nvmd_req));
@@ -4556,7 +4552,7 @@ int pm8001_chip_set_nvmd_req(struct pm8001_hba_info 
*pm8001_ha,
return -ENOMEM;
circularQ = &pm8001_ha->inbnd_q_tbl[0];
memcpy(pm8001_ha->memoryMap.region[NVMD].virt_ptr,
-   ioctl_payload->func_specific,
+   &ioctl_payload->func_specific,
ioctl_payload->length);
memset(&nvmd_req, 0, sizeof(nvmd_req));
rc = pm8001_tag_alloc(pm8001_ha, &tag);
@@ -4658,29 +4654,14 @@ pm8001_chip_fw_flash_update_req(struct pm8001_hba_info 
*pm8001_ha,
int rc;
u32 tag;
struct pm8001_ccb_info *ccb;
-   void *buffer = NULL;
-   

[PATCH 00/15] Support for PMC 8081/8088/8089 controllers

2013-02-12 Thread Anand
James/Linux-scsi,

The following patchset provides support for PMC 8081/88/89 series of 
controllers.

>From 9c620d9273640b416054ba76cd267aebaf455ed2 Mon Sep 17 00:00:00 2001
From: Sakthivel K 
Date: Thu, 7 Feb 2013 17:03:42 +0530
Subject: [PATCH 00/15] Support for PMC 8081/8088/8089 controllers.

Support for PMC 8081/8088/8089 series of controllers. 

New data structures and hardware functionality files have been added
to support 8088/8089 controllers. The hardware specific file contains
new functionality specific to 8088/8089 controllers including support
for encryption, thermal settings, FW upgradation. Since 8081/8088/8089 
controllers are built on top of 8001 controller most of the data 
structures and functions of 8001 controller are reused.

MSI-X support for 8081/8088/8089 and many more error handling logic to
handle controller specific errors have been introduced. Functionality
to support multiple inbound and outbound queues have been added for 
8088/8089 controllers.

Fixes for 8001 driver include memory region fix, NCQ error handling logic,
WWN number retrieval for the controller. In addition new memory regions
have been introduced for FW flash. 

Sakthivel K (15):
  pm80xx: fix for memory region free
  pm80xx: Added vendor and device ids for SPCv/SPCve controllers
  pm80xx: Added and modified structures, variables and macros for
SPCv/ve
  pm80xx: Structure and variable name update for SPC
  pm80xx: Multiple inbound/outbound queue configuration
  pm80xx: Updated common functions common for SPC and SPCv/ve
  pm80xx: MSI-X implementation for using 64 interrupts
  pm80xx: Added SPCv/ve specific hardware functionalities
  pm80xx: SPCv/ve specific changes in common files
  pm80xx: SPC new firmware changes for device id 0x8081 alone
  pm80xx: Firmware flash memory free fix, with addition of new memory  
  region for it
  pm80xx: Changed module name and debug messages update
  pm80xx: WWN Modification for PM8081/88/89 controllers
  pm80xx: NCQ error handling changes
  pm80xx: thermal, sas controller config and error handling update

 drivers/scsi/pm8001/Makefile  |7 +-
 drivers/scsi/pm8001/pm8001_ctl.c  |   74 +-
 drivers/scsi/pm8001/pm8001_defs.h |   34 +-
 drivers/scsi/pm8001/pm8001_hwi.c  |  796 +---
 drivers/scsi/pm8001/pm8001_hwi.h  |4 +-
 drivers/scsi/pm8001/pm8001_init.c | 1478 +-
 drivers/scsi/pm8001/pm8001_sas.c  |  105 +-
 drivers/scsi/pm8001/pm8001_sas.h  |  176 ++-
 drivers/scsi/pm8001/pm80xx_hwi.c  | 4131 +
 drivers/scsi/pm8001/pm80xx_hwi.h  | 1524 ++
 10 files changed, 7937 insertions(+), 392 deletions(-)
 create mode 100644 drivers/scsi/pm8001/pm80xx_hwi.c
 create mode 100644 drivers/scsi/pm8001/pm80xx_hwi.h

-Anand
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 10/15] pm80xx: SPC new firmware changes for device id 0x8081 alone

2013-02-12 Thread Anand
>From 954868e338b75c829fb85e6596383b26e34b56e3 Mon Sep 17 00:00:00 2001
From: Sakthivel K 
Date: Tue, 5 Feb 2013 11:18:23 +0530
Subject: [PATCH 10/15] pm80xx: SPC new firmware changes for device id 0x8081 
alone

Additional bar shift for new SPC firmware, applicable to device
id 0x8081 only.

Signed-off-by: Sakthivel K 
Signed-off-by: Anand Kumar S 
---
 drivers/scsi/pm8001/pm8001_hwi.c |   31 ---
 drivers/scsi/pm8001/pm8001_hwi.h |2 ++
 2 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index c335ae8..3adf499 100755
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -640,6 +640,18 @@ static void init_pci_device_addresses(struct 
pm8001_hba_info *pm8001_ha)
 static int pm8001_chip_init(struct pm8001_hba_info *pm8001_ha)
 {
u8 i = 0;
+   u16 deviceid;
+   pci_read_config_word(pm8001_ha->pdev, PCI_DEVICE_ID, &deviceid);
+   /* 8081 controllers need BAR shift to access MPI space
+   * as this is shared with BIOS data */
+   if (deviceid == 0x8081) {
+   if (-1 == pm8001_bar4_shift(pm8001_ha, GSM_SM_BASE)) {
+   PM8001_FAIL_DBG(pm8001_ha,
+   pm8001_printk("Shift Bar4 to 0x%x failed\n",
+   GSM_SM_BASE));
+   return -1;
+   }
+   }
/* check the firmware status */
if (-1 == check_fw_ready(pm8001_ha)) {
PM8001_FAIL_DBG(pm8001_ha,
@@ -660,9 +672,12 @@ static int pm8001_chip_init(struct pm8001_hba_info 
*pm8001_ha)
update_inbnd_queue_table(pm8001_ha, i);
for (i = 0; i < PM8001_MAX_OUTB_NUM; i++)
update_outbnd_queue_table(pm8001_ha, i);
-   mpi_set_phys_g3_with_ssc(pm8001_ha, 0);
-   /* 7->130ms, 34->500ms, 119->1.5s */
-   mpi_set_open_retry_interval_reg(pm8001_ha, 119);
+   /* 8081 controller donot require these operations */
+   if (deviceid != 0x8081) {
+   mpi_set_phys_g3_with_ssc(pm8001_ha, 0);
+   /* 7->130ms, 34->500ms, 119->1.5s */
+   mpi_set_open_retry_interval_reg(pm8001_ha, 119);
+   }
/* notify firmware update finished and check initialization status */
if (0 == mpi_init_check(pm8001_ha)) {
PM8001_INIT_DBG(pm8001_ha,
@@ -684,6 +699,16 @@ static int mpi_uninit_check(struct pm8001_hba_info 
*pm8001_ha)
u32 max_wait_count;
u32 value;
u32 gst_len_mpistate;
+   u16 deviceid;
+   pci_read_config_word(pm8001_ha->pdev, PCI_DEVICE_ID, &deviceid);
+   if (deviceid == 0x8081) {
+   if (-1 == pm8001_bar4_shift(pm8001_ha, GSM_SM_BASE)) {
+   PM8001_FAIL_DBG(pm8001_ha,
+   pm8001_printk("Shift Bar4 to 0x%x failed\n",
+   GSM_SM_BASE));
+   return -1;
+   }
+   }
init_pci_device_addresses(pm8001_ha);
/* Write bit1=1 to Inbound DoorBell Register to tell the SPC FW the
table is stop */
diff --git a/drivers/scsi/pm8001/pm8001_hwi.h b/drivers/scsi/pm8001/pm8001_hwi.h
index 2399aab..d7c1e20 100755
--- a/drivers/scsi/pm8001/pm8001_hwi.h
+++ b/drivers/scsi/pm8001/pm8001_hwi.h
@@ -131,6 +131,8 @@
 #define LINKRATE_30(0x02 << 8)
 #define LINKRATE_60(0x04 << 8)
 
+/* for new SPC controllers MEMBASE III is shared between BIOS and DATA */
+#define GSM_SM_BASE0x4F
 struct mpi_msg_hdr{
__le32  header; /* Bits [11:0]  - Message operation code */
/* Bits [15:12] - Message Category */
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 09/15] pm80xx: SPCv/ve specific changes in common files

2013-02-12 Thread Anand
>From 14c5d89e766cab606b067d0ded2baa8836414e8a Mon Sep 17 00:00:00 2001
From: Sakthivel K 
Date: Tue, 5 Feb 2013 11:00:39 +0530
Subject: [PATCH 09/15] pm80xx: SPCv/ve specific changes in common files

Changing common functionalities for SPCv/ve operations. Conditional
checks for SPC specific operations.

Signed-off-by: Sakthivel K 
Signed-off-by: Anand Kumar S 
---
 drivers/scsi/pm8001/pm8001_hwi.c  |4 ++--
 drivers/scsi/pm8001/pm8001_hwi.h  |2 +-
 drivers/scsi/pm8001/pm8001_init.c |   13 +
 drivers/scsi/pm8001/pm8001_sas.c  |   17 +++--
 drivers/scsi/pm8001/pm8001_sas.h  |4 ++--
 5 files changed, 25 insertions(+), 15 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index 26f5197..c335ae8 100755
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -785,14 +785,14 @@ static u32 soft_reset_ready_check(struct pm8001_hba_info 
*pm8001_ha)
  * pm8001_chip_soft_rst - soft reset the PM8001 chip, so that the clear all
  * the FW register status to the originated status.
  * @pm8001_ha: our hba card information
- * @signature: signature in host scratch pad0 register.
  */
 static int
-pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature)
+pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha)
 {
u32 regVal, toggleVal;
u32 max_wait_count;
u32 regVal1, regVal2, regVal3;
+   u32 signature = 0x252acbcd; /* for host scratch pad0 */
unsigned long flags;
 
/* step1: Check FW is ready for soft reset */
diff --git a/drivers/scsi/pm8001/pm8001_hwi.h b/drivers/scsi/pm8001/pm8001_hwi.h
index d437309..2399aab 100755
--- a/drivers/scsi/pm8001/pm8001_hwi.h
+++ b/drivers/scsi/pm8001/pm8001_hwi.h
@@ -298,7 +298,7 @@ struct local_phy_ctl_resp {
 
 
 #define OP_BITS 0xFF00
-#define ID_BITS 0x000F
+#define ID_BITS 0x00FF
 
 /*
  * brief the data structure of PORT Control Command
diff --git a/drivers/scsi/pm8001/pm8001_init.c 
b/drivers/scsi/pm8001/pm8001_init.c
index f0c5075..9dcd72c 100755
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -1741,7 +1741,7 @@ static int pm8001_pci_probe(struct pci_dev *pdev,
goto err_out_free;
}
list_add_tail(&pm8001_ha->list, &hba_list);
-   PM8001_CHIP_DISP->chip_soft_rst(pm8001_ha, 0x252acbcd);
+   PM8001_CHIP_DISP->chip_soft_rst(pm8001_ha);
rc = PM8001_CHIP_DISP->chip_init(pm8001_ha);
if (rc)
goto err_out_ha_free;
@@ -1795,7 +1795,7 @@ static void pm8001_pci_remove(struct pci_dev *pdev)
list_del(&pm8001_ha->list);
scsi_remove_host(pm8001_ha->shost);
PM8001_CHIP_DISP->interrupt_disable(pm8001_ha, 0xFF);
-   PM8001_CHIP_DISP->chip_soft_rst(pm8001_ha, 0x252acbcd);
+   PM8001_CHIP_DISP->chip_soft_rst(pm8001_ha);
 
 #ifdef PM8001_USE_MSIX
for (i = 0; i < pm8001_ha->number_of_intr; i++)
@@ -1843,7 +1843,7 @@ static int pm8001_pci_suspend(struct pci_dev *pdev, 
pm_message_t state)
return -ENODEV;
}
PM8001_CHIP_DISP->interrupt_disable(pm8001_ha, 0xFF);
-   PM8001_CHIP_DISP->chip_soft_rst(pm8001_ha, 0x252acbcd);
+   PM8001_CHIP_DISP->chip_soft_rst(pm8001_ha);
 #ifdef PM8001_USE_MSIX
for (i = 0; i < pm8001_ha->number_of_intr; i++)
synchronize_irq(pm8001_ha->msix_entries[i].vector);
@@ -1904,7 +1904,12 @@ static int pm8001_pci_resume(struct pci_dev *pdev)
if (rc)
goto err_out_disable;
 
-   PM8001_CHIP_DISP->chip_soft_rst(pm8001_ha, 0x252acbcd);
+   /* chip soft rst only for spc */
+   if (pm8001_ha->chip_id == chip_8001) {
+   PM8001_CHIP_DISP->chip_soft_rst(pm8001_ha);
+   PM8001_INIT_DBG(pm8001_ha,
+   pm8001_printk("chip soft reset successful\n"));
+   }
rc = PM8001_CHIP_DISP->chip_init(pm8001_ha);
if (rc)
goto err_out_disable;
diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
index b961112..6bba59c 100755
--- a/drivers/scsi/pm8001/pm8001_sas.c
+++ b/drivers/scsi/pm8001/pm8001_sas.c
@@ -1,5 +1,5 @@
 /*
- * PMC-Sierra SPC 8001 SAS/SATA based host adapters driver
+ * PMC-Sierra PM8001/8081/8088/8089 SAS/SATA based host adapters driver
  *
  * Copyright (c) 2008-2009 USI Co., Ltd.
  * All rights reserved.
@@ -212,10 +212,12 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum 
phy_func func,
break;
case PHY_FUNC_GET_EVENTS:
spin_lock_irqsave(&pm8001_ha->lock, flags);
-   if (-1 == pm8001_bar4_shift(pm8001_ha,
+   if (pm8001_ha->chip_id == chip_8001) {
+   if (-1 == pm8001_bar4_shift(pm8001_ha,
(phy_id < 4) ? 0x3 : 0x4)) {
-   spin_unlock_irqrestore(&pm8001_ha->lock, flags);
-   return -E

[PATCH 07/15] pm80xx: MSI-X implementation for using 64 interrupts

2013-02-12 Thread Anand
>From 952973b812c65eb2a7d70ed8c333b7837fb39191 Mon Sep 17 00:00:00 2001
From: Sakthivel K 
Date: Mon, 4 Feb 2013 18:02:22 +0530
Subject: [PATCH 07/15] pm80xx: MSI-X implementation for using 64 interrupts

Implementation of 64 interrupt handlers and tasklets to support
upto 64 interrupt for the device.

Signed-off-by: Sakthivel K 
Signed-off-by: Anand Kumar S 
---
 drivers/scsi/pm8001/pm8001_init.c | 1233 -
 1 files changed, 1203 insertions(+), 30 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_init.c 
b/drivers/scsi/pm8001/pm8001_init.c
index e8a983f..f0c5075 100755
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -163,7 +163,13 @@ static void pm8001_free(struct pm8001_hba_info *pm8001_ha)
 }
 
 #ifdef PM8001_USE_TASKLET
-static void pm8001_tasklet(unsigned long opaque)
+
+/**
+ * tasklets for 64 msi-x interrupt handlers
+ * @opaque: the passed general host adapter struct
+ * Note: pm8001_tasklet0 is common for pm8001 & pm80xx
+ */
+static void pm8001_tasklet0(unsigned long opaque)
 {
struct pm8001_hba_info *pm8001_ha;
pm8001_ha = (struct pm8001_hba_info *)opaque;
@@ -171,16 +177,521 @@ static void pm8001_tasklet(unsigned long opaque)
BUG_ON(1);
PM8001_CHIP_DISP->isr(pm8001_ha, 0);
 }
+static void pm8001_tasklet1(unsigned long opaque)
+{
+   struct pm8001_hba_info *pm8001_ha;
+   pm8001_ha = (struct pm8001_hba_info *)opaque;
+   if (unlikely(!pm8001_ha))
+   BUG_ON(1);
+   PM8001_CHIP_DISP->isr(pm8001_ha, 1);
+}
+static void pm8001_tasklet2(unsigned long opaque)
+{
+   struct pm8001_hba_info *pm8001_ha;
+   pm8001_ha = (struct pm8001_hba_info *)opaque;
+   if (unlikely(!pm8001_ha))
+   BUG_ON(1);
+   PM8001_CHIP_DISP->isr(pm8001_ha, 2);
+}
+static void pm8001_tasklet3(unsigned long opaque)
+{
+   struct pm8001_hba_info *pm8001_ha;
+   pm8001_ha = (struct pm8001_hba_info *)opaque;
+   if (unlikely(!pm8001_ha))
+   BUG_ON(1);
+   PM8001_CHIP_DISP->isr(pm8001_ha, 3);
+}
+static void pm8001_tasklet4(unsigned long opaque)
+{
+   struct pm8001_hba_info *pm8001_ha;
+   pm8001_ha = (struct pm8001_hba_info *)opaque;
+   if (unlikely(!pm8001_ha))
+   BUG_ON(1);
+   PM8001_CHIP_DISP->isr(pm8001_ha, 4);
+}
+static void pm8001_tasklet5(unsigned long opaque)
+{
+   struct pm8001_hba_info *pm8001_ha;
+   pm8001_ha = (struct pm8001_hba_info *)opaque;
+   if (unlikely(!pm8001_ha))
+   BUG_ON(1);
+   PM8001_CHIP_DISP->isr(pm8001_ha, 5);
+}
+static void pm8001_tasklet6(unsigned long opaque)
+{
+   struct pm8001_hba_info *pm8001_ha;
+   pm8001_ha = (struct pm8001_hba_info *)opaque;
+   if (unlikely(!pm8001_ha))
+   BUG_ON(1);
+   PM8001_CHIP_DISP->isr(pm8001_ha, 6);
+}
+static void pm8001_tasklet7(unsigned long opaque)
+{
+   struct pm8001_hba_info *pm8001_ha;
+   pm8001_ha = (struct pm8001_hba_info *)opaque;
+   if (unlikely(!pm8001_ha))
+   BUG_ON(1);
+   PM8001_CHIP_DISP->isr(pm8001_ha, 7);
+}
+static void pm8001_tasklet8(unsigned long opaque)
+{
+   struct pm8001_hba_info *pm8001_ha;
+   pm8001_ha = (struct pm8001_hba_info *)opaque;
+   if (unlikely(!pm8001_ha))
+   BUG_ON(1);
+   PM8001_CHIP_DISP->isr(pm8001_ha, 8);
+}
+static void pm8001_tasklet9(unsigned long opaque)
+{
+   struct pm8001_hba_info *pm8001_ha;
+   pm8001_ha = (struct pm8001_hba_info *)opaque;
+   if (unlikely(!pm8001_ha))
+   BUG_ON(1);
+   PM8001_CHIP_DISP->isr(pm8001_ha, 9);
+}
+static void pm8001_tasklet10(unsigned long opaque)
+{
+   struct pm8001_hba_info *pm8001_ha;
+   pm8001_ha = (struct pm8001_hba_info *)opaque;
+   if (unlikely(!pm8001_ha))
+   BUG_ON(1);
+   PM8001_CHIP_DISP->isr(pm8001_ha, 10);
+}
+static void pm8001_tasklet11(unsigned long opaque)
+{
+   struct pm8001_hba_info *pm8001_ha;
+   pm8001_ha = (struct pm8001_hba_info *)opaque;
+   if (unlikely(!pm8001_ha))
+   BUG_ON(1);
+   PM8001_CHIP_DISP->isr(pm8001_ha, 11);
+}
+static void pm8001_tasklet12(unsigned long opaque)
+{
+   struct pm8001_hba_info *pm8001_ha;
+   pm8001_ha = (struct pm8001_hba_info *)opaque;
+   if (unlikely(!pm8001_ha))
+   BUG_ON(1);
+   PM8001_CHIP_DISP->isr(pm8001_ha, 12);
+}
+static void pm8001_tasklet13(unsigned long opaque)
+{
+   struct pm8001_hba_info *pm8001_ha;
+   pm8001_ha = (struct pm8001_hba_info *)opaque;
+   if (unlikely(!pm8001_ha))
+   BUG_ON(1);
+   PM8001_CHIP_DISP->isr(pm8001_ha, 13);
+}
+static void pm8001_tasklet14(unsigned long opaque)
+{
+   struct pm8001_hba_info *pm8001_ha;
+   pm8001_ha = (struct pm8001_hba_info *)opaque;
+   if (unlikely(!pm8001_ha))
+   BUG_ON(1);
+   PM8001_CHIP_DISP->isr(pm8001_ha, 14);
+}
+static void pm8001_tasklet15

[PATCH 07/15] pm80xx: MSI-X implementation for using 64 interrupts

2013-02-12 Thread Anand
>From 952973b812c65eb2a7d70ed8c333b7837fb39191 Mon Sep 17 00:00:00 2001
From: Sakthivel K 
Date: Mon, 4 Feb 2013 18:02:22 +0530
Subject: [PATCH 07/15] pm80xx: MSI-X implementation for using 64 interrupts

Implementation of 64 interrupt handlers and tasklets to support
upto 64 interrupt for the device.

Signed-off-by: Sakthivel K 
Signed-off-by: Anand Kumar S 
---
 drivers/scsi/pm8001/pm8001_init.c | 1233
-
 1 files changed, 1203 insertions(+), 30 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_init.c
b/drivers/scsi/pm8001/pm8001_init.c
index e8a983f..f0c5075 100755
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -163,7 +163,13 @@ static void pm8001_free(struct pm8001_hba_info
*pm8001_ha)
 }

 #ifdef PM8001_USE_TASKLET
-static void pm8001_tasklet(unsigned long opaque)
+
+/**
+ * tasklets for 64 msi-x interrupt handlers
+ * @opaque: the passed general host adapter struct
+ * Note: pm8001_tasklet0 is common for pm8001 & pm80xx
+ */
+static void pm8001_tasklet0(unsigned long opaque)
 {
struct pm8001_hba_info *pm8001_ha;
pm8001_ha = (struct pm8001_hba_info *)opaque;
@@ -171,16 +177,521 @@ static void pm8001_tasklet(unsigned long opaque)
BUG_ON(1);
PM8001_CHIP_DISP->isr(pm8001_ha, 0);
 }
+static void pm8001_tasklet1(unsigned long opaque)
+{
+   struct pm8001_hba_info *pm8001_ha;
+   pm8001_ha = (struct pm8001_hba_info *)opaque;
+   if (unlikely(!pm8001_ha))
+   BUG_ON(1);
+   PM8001_CHIP_DISP->isr(pm8001_ha, 1);
+}
+static void pm8001_tasklet2(unsigned long opaque)
+{
+   struct pm8001_hba_info *pm8001_ha;
+   pm8001_ha = (struct pm8001_hba_info *)opaque;
+   if (unlikely(!pm8001_ha))
+   BUG_ON(1);
+   PM8001_CHIP_DISP->isr(pm8001_ha, 2);
+}
+static void pm8001_tasklet3(unsigned long opaque)
+{
+   struct pm8001_hba_info *pm8001_ha;
+   pm8001_ha = (struct pm8001_hba_info *)opaque;
+   if (unlikely(!pm8001_ha))
+   BUG_ON(1);
+   PM8001_CHIP_DISP->isr(pm8001_ha, 3);
+}
+static void pm8001_tasklet4(unsigned long opaque)
+{
+   struct pm8001_hba_info *pm8001_ha;
+   pm8001_ha = (struct pm8001_hba_info *)opaque;
+   if (unlikely(!pm8001_ha))
+   BUG_ON(1);
+   PM8001_CHIP_DISP->isr(pm8001_ha, 4);
+}
+static void pm8001_tasklet5(unsigned long opaque)
+{
+   struct pm8001_hba_info *pm8001_ha;
+   pm8001_ha = (struct pm8001_hba_info *)opaque;
+   if (unlikely(!pm8001_ha))
+   BUG_ON(1);
+   PM8001_CHIP_DISP->isr(pm8001_ha, 5);
+}
+static void pm8001_tasklet6(unsigned long opaque)
+{
+   struct pm8001_hba_info *pm8001_ha;
+   pm8001_ha = (struct pm8001_hba_info *)opaque;
+   if (unlikely(!pm8001_ha))
+   BUG_ON(1);
+   PM8001_CHIP_DISP->isr(pm8001_ha, 6);
+}
+static void pm8001_tasklet7(unsigned long opaque)
+{
+   struct pm8001_hba_info *pm8001_ha;
+   pm8001_ha = (struct pm8001_hba_info *)opaque;
+   if (unlikely(!pm8001_ha))
+   BUG_ON(1);
+   PM8001_CHIP_DISP->isr(pm8001_ha, 7);
+}
+static void pm8001_tasklet8(unsigned long opaque)
+{
+   struct pm8001_hba_info *pm8001_ha;
+   pm8001_ha = (struct pm8001_hba_info *)opaque;
+   if (unlikely(!pm8001_ha))
+   BUG_ON(1);
+   PM8001_CHIP_DISP->isr(pm8001_ha, 8);
+}
+static void pm8001_tasklet9(unsigned long opaque)
+{
+   struct pm8001_hba_info *pm8001_ha;
+   pm8001_ha = (struct pm8001_hba_info *)opaque;
+   if (unlikely(!pm8001_ha))
+   BUG_ON(1);
+   PM8001_CHIP_DISP->isr(pm8001_ha, 9);
+}
+static void pm8001_tasklet10(unsigned long opaque)
+{
+   struct pm8001_hba_info *pm8001_ha;
+   pm8001_ha = (struct pm8001_hba_info *)opaque;
+   if (unlikely(!pm8001_ha))
+   BUG_ON(1);
+   PM8001_CHIP_DISP->isr(pm8001_ha, 10);
+}
+static void pm8001_tasklet11(unsigned long opaque)
+{
+   struct pm8001_hba_info *pm8001_ha;
+   pm8001_ha = (struct pm8001_hba_info *)opaque;
+   if (unlikely(!pm8001_ha))
+   BUG_ON(1);
+   PM8001_CHIP_DISP->isr(pm8001_ha, 11);
+}
+static void pm8001_tasklet12(unsigned long opaque)
+{
+   struct pm8001_hba_info *pm8001_ha;
+   pm8001_ha = (struct pm8001_hba_info *)opaque;
+   if (unlikely(!pm8001_ha))
+   BUG_ON(1);
+   PM8001_CHIP_DISP->isr(pm8001_ha, 12);
+}
+static void pm8001_tasklet13(unsigned long opaque)
+{
+   struct pm8001_hba_info *pm8001_ha;
+   pm8001_ha = (struct pm8001_hba_info *)opaque;
+   if (unlikely(!pm8001_ha))
+   BUG_ON(1);
+   PM8001_CHIP_DISP->isr(pm8001_ha, 13);
+}
+static void pm8001_tasklet14(unsigned long opaque)
+{
+   struct pm8001_hba_info *pm8001_ha;
+   pm8001_ha = (struct pm8001_hba_info *)opaque;
+   if (unlikely(!pm8001_ha))
+   BUG_ON(1);
+   PM8001_CHIP_DISP->isr(pm8001_ha, 14);
+}
+static void pm8001_tasklet15(u

[PATCH 06/15] pm80xx: Updated common functions common for SPC and SPCv/ve

2013-02-12 Thread Anand
>From 3fd0f7b1b3d82fc3a55dbfad6e9708ad64f17369 Mon Sep 17 00:00:00 2001
From: Sakthivel K 
Date: Mon, 4 Feb 2013 17:32:34 +0530
Subject: [PATCH 06/15] pm80xx: Updated common functions common for SPC
and SPCv/ve

Update of function prototype for common function to SPC and SPCv/ve.
Multiple queues implementation for IO.

Signed-off-by: Sakthivel K 
Signed-off-by: Anand Kumar S 
---
 drivers/scsi/pm8001/pm8001_hwi.c  |  193
+++--
 drivers/scsi/pm8001/pm8001_init.c |   20 +++--
 drivers/scsi/pm8001/pm8001_sas.h  |   60 +++-
 3 files changed, 168 insertions(+), 105 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_hwi.c
b/drivers/scsi/pm8001/pm8001_hwi.c
index 651834c..26f5197 100755
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -1158,7 +1158,7 @@ static void pm8001_hw_chip_rst(struct
pm8001_hba_info *pm8001_ha)
  * pm8001_chip_iounmap - which maped when initialized.
  * @pm8001_ha: our hba card information
  */
-static void pm8001_chip_iounmap(struct pm8001_hba_info *pm8001_ha)
+void pm8001_chip_iounmap(struct pm8001_hba_info *pm8001_ha)
 {
s8 bar, logical = 0;
for (bar = 0; bar < 6; bar++) {
@@ -1237,7 +1237,7 @@ pm8001_chip_msix_interrupt_disable(struct
pm8001_hba_info *pm8001_ha,
  * @pm8001_ha: our hba card information
  */
 static void
-pm8001_chip_interrupt_enable(struct pm8001_hba_info *pm8001_ha)
+pm8001_chip_interrupt_enable(struct pm8001_hba_info *pm8001_ha, u8 vec)
 {
 #ifdef PM8001_USE_MSIX
pm8001_chip_msix_interrupt_enable(pm8001_ha, 0);
@@ -1252,7 +1252,7 @@ pm8001_chip_interrupt_enable(struct
pm8001_hba_info *pm8001_ha)
  * @pm8001_ha: our hba card information
  */
 static void
-pm8001_chip_interrupt_disable(struct pm8001_hba_info *pm8001_ha)
+pm8001_chip_interrupt_disable(struct pm8001_hba_info *pm8001_ha, u8 vec)
 {
 #ifdef PM8001_USE_MSIX
pm8001_chip_msix_interrupt_disable(pm8001_ha, 0);
@@ -1263,12 +1263,13 @@ pm8001_chip_interrupt_disable(struct
pm8001_hba_info *pm8001_ha)
 }

 /**
- * mpi_msg_free_get- get the free message buffer for transfer inbound
queue.
+ * pm8001_mpi_msg_free_get - get the free message buffer for transfer
+ * inbound queue.
  * @circularQ: the inbound queue  we want to transfer to HBA.
  * @messageSize: the message size of this transfer, normally it is 64 bytes
  * @messagePtr: the pointer to message.
  */
-static int mpi_msg_free_get(struct inbound_queue_table *circularQ,
+int pm8001_mpi_msg_free_get(struct inbound_queue_table *circularQ,
u16 messageSize, void **messagePtr)
 {
u32 offset, consumer_index;
@@ -1276,7 +1277,7 @@ static int mpi_msg_free_get(struct
inbound_queue_table *circularQ,
u8 bcCount = 1; /* only support single buffer */

/* Checks is the requested message size can be allocated in this queue*/
-   if (messageSize > 64) {
+   if (messageSize > IOMB_SIZE_SPCV) {
*messagePtr = NULL;
return -1;
}
@@ -1290,7 +1291,7 @@ static int mpi_msg_free_get(struct
inbound_queue_table *circularQ,
return -1;
}
/* get memory IOMB buffer address */
-   offset = circularQ->producer_idx * 64;
+   offset = circularQ->producer_idx * messageSize;
/* increment to next bcCount element */
circularQ->producer_idx = (circularQ->producer_idx + bcCount)
% PM8001_MPI_QUEUE;
@@ -1302,29 +1303,30 @@ static int mpi_msg_free_get(struct
inbound_queue_table *circularQ,
 }

 /**
- * mpi_build_cmd- build the message queue for transfer, update the PI to FW
- * to tell the fw to get this message from IOMB.
+ * pm8001_mpi_build_cmd- build the message queue for transfer, update
the PI to
+ * FW to tell the fw to get this message from IOMB.
  * @pm8001_ha: our hba card information
  * @circularQ: the inbound queue we want to transfer to HBA.
  * @opCode: the operation code represents commands which LLDD and fw
recognized.
  * @payload: the command payload of each operation command.
  */
-static int mpi_build_cmd(struct pm8001_hba_info *pm8001_ha,
+int pm8001_mpi_build_cmd(struct pm8001_hba_info *pm8001_ha,
 struct inbound_queue_table *circularQ,
-u32 opCode, void *payload)
+u32 opCode, void *payload, u32 responseQueue)
 {
u32 Header = 0, hpriority = 0, bc = 1, category = 0x02;
-   u32 responseQueue = 0;
void *pMessage;

-   if (mpi_msg_free_get(circularQ, 64, &pMessage) < 0) {
+   if (pm8001_mpi_msg_free_get(circularQ, pm8001_ha->iomb_size,
+   &pMessage) < 0) {
PM8001_IO_DBG(pm8001_ha,
pm8001_printk("No free mpi buffer\n"));
return -1;
}
BUG_ON(!payload);
/*Copy to the payload*/
-   memcpy(pMessage, payload, (64 - sizeof(struct mpi_msg_hdr)));
+   memcpy(pMessage, payload, (pm8001_ha->iomb_size -
+ 

[PATCH 05/15] pm80xx: Multiple inbound/outbound queue

2013-02-12 Thread Anand
>From ea8e9d56a8f94fbf1963d9b56783a3f1cb743c1f Mon Sep 17 00:00:00 2001
From: Sakthivel K 
Date: Mon, 4 Feb 2013 16:31:43 +0530
Subject: [PATCH 05/15] pm80xx: Multiple inbound/outbound queue configuration

Memory allocation and configuration of multiple inbound and
outbound queues.

Signed-off-by: Sakthivel K 
Signed-off-by: Anand Kumar S 
---
 drivers/scsi/pm8001/pm8001_defs.h |   14 +++--
 drivers/scsi/pm8001/pm8001_hwi.c  |   43 
 drivers/scsi/pm8001/pm8001_init.c |  101
+
 3 files changed, 98 insertions(+), 60 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_defs.h
b/drivers/scsi/pm8001/pm8001_defs.h
index b25f87c..26a2ee6 100755
--- a/drivers/scsi/pm8001/pm8001_defs.h
+++ b/drivers/scsi/pm8001/pm8001_defs.h
@@ -48,8 +48,7 @@ enum chip_flavors {
chip_8018,
chip_8019
 };
-#define USI_MAX_MEMCNT 9
-#define PM8001_MAX_DMA_SG  SG_ALL
+
 enum phy_speed {
PHY_SPEED_15 = 0x01,
PHY_SPEED_30 = 0x02,
@@ -87,13 +86,16 @@ enum port_type {
 #definePM8001_MAX_DEVICES   2048   /* max supported device */
 #definePM8001_MAX_MSIX_VEC  64 /* max msi-x int for spcv/ve */

+#define USI_MAX_MEMCNT_BASE4
+#define IB (USI_MAX_MEMCNT_BASE + 1)
+#define CI (IB + PM8001_MAX_SPCV_INB_NUM)
+#define OB (CI + PM8001_MAX_SPCV_INB_NUM)
+#define PI (OB + PM8001_MAX_SPCV_OUTB_NUM)
+#define USI_MAX_MEMCNT (PI + PM8001_MAX_SPCV_OUTB_NUM)
+#define PM8001_MAX_DMA_SG  SG_ALL
 enum memory_region_num {
AAP1 = 0x0, /* application acceleration processor */
IOP,/* IO processor */
-   CI, /* consumer index */
-   PI, /* producer index */
-   IB, /* inbound queue */
-   OB, /* outbound queue */
NVMD,   /* NVM device */
DEV_MEM,/* memory for devices */
CCB_MEM,/* memory for command control block */
diff --git a/drivers/scsi/pm8001/pm8001_hwi.c
b/drivers/scsi/pm8001/pm8001_hwi.c
index d04a613..651834c 100755
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -151,10 +151,9 @@ static void read_general_status_table(struct
pm8001_hba_info *pm8001_ha)
  */
 static void read_inbnd_queue_table(struct pm8001_hba_info *pm8001_ha)
 {
-   int inbQ_num = 1;
int i;
void __iomem *address = pm8001_ha->inbnd_q_tbl_addr;
-   for (i = 0; i < inbQ_num; i++) {
+   for (i = 0; i < PM8001_MAX_INB_NUM; i++) {
u32 offset = i * 0x20;
pm8001_ha->inbnd_q_tbl[i].pi_pci_bar =
  get_pci_bar_index(pm8001_mr32(address, (offset + 0x14)));
@@ -169,10 +168,9 @@ static void read_inbnd_queue_table(struct
pm8001_hba_info *pm8001_ha)
  */
 static void read_outbnd_queue_table(struct pm8001_hba_info *pm8001_ha)
 {
-   int outbQ_num = 1;
int i;
void __iomem *address = pm8001_ha->outbnd_q_tbl_addr;
-   for (i = 0; i < outbQ_num; i++) {
+   for (i = 0; i < PM8001_MAX_OUTB_NUM; i++) {
u32 offset = i * 0x24;
pm8001_ha->outbnd_q_tbl[i].ci_pci_bar =
  get_pci_bar_index(pm8001_mr32(address, (offset + 0x14)));
@@ -225,19 +223,19 @@ static void init_default_table_values(struct
pm8001_hba_info *pm8001_ha)
pm8001_ha->inbnd_q_tbl[i].element_pri_size_cnt  =
PM8001_MPI_QUEUE | (64 << 16) | (0x00<<30);
pm8001_ha->inbnd_q_tbl[i].upper_base_addr   =
-   pm8001_ha->memoryMap.region[IB].phys_addr_hi;
+   pm8001_ha->memoryMap.region[IB + i].phys_addr_hi;
pm8001_ha->inbnd_q_tbl[i].lower_base_addr   =
-   pm8001_ha->memoryMap.region[IB].phys_addr_lo;
+   pm8001_ha->memoryMap.region[IB + i].phys_addr_lo;
pm8001_ha->inbnd_q_tbl[i].base_virt =
-   (u8 *)pm8001_ha->memoryMap.region[IB].virt_ptr;
+   (u8 *)pm8001_ha->memoryMap.region[IB + i].virt_ptr;
pm8001_ha->inbnd_q_tbl[i].total_length  =
-   pm8001_ha->memoryMap.region[IB].total_len;
+   pm8001_ha->memoryMap.region[IB + i].total_len;
pm8001_ha->inbnd_q_tbl[i].ci_upper_base_addr=
-   pm8001_ha->memoryMap.region[CI].phys_addr_hi;
+   pm8001_ha->memoryMap.region[CI + i].phys_addr_hi;
pm8001_ha->inbnd_q_tbl[i].ci_lower_base_addr=
-   pm8001_ha->memoryMap.region[CI].phys_addr_lo;
+   pm8001_ha->memoryMap.region[CI + i].phys_addr_lo;
pm8001_ha->inbnd_q_tbl[i].ci_virt   =
-   pm8001_ha->memoryMap.region[CI].virt_ptr;
+   pm8001_ha->memoryMap.region[CI + i].virt_ptr;
off

[PATCH 04/15] pm80xx: Structure and variable name update for SPC

2013-02-12 Thread Anand
>From a08478c7c29817c887469192069dbce8463a5730 Mon Sep 17 00:00:00 2001
From: Sakthivel K 
Date: Mon, 4 Feb 2013 14:26:19 +0530
Subject: [PATCH 04/15] pm80xx: Structure and variable name update for SPC

Update of structure and variable names for SPC hardware functionalities.

Signed-off-by: Sakthivel K 
Signed-off-by: Anand Kumar S 
---
 drivers/scsi/pm8001/pm8001_ctl.c |   69 ++---
 drivers/scsi/pm8001/pm8001_hwi.c |  210 +++---
 2 files changed, 181 insertions(+), 98 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c
index 45bc197..ae2b124 100755
--- a/drivers/scsi/pm8001/pm8001_ctl.c
+++ b/drivers/scsi/pm8001/pm8001_ctl.c
@@ -1,5 +1,5 @@
 /*
- * PMC-Sierra SPC 8001 SAS/SATA based host adapters driver
+ * PMC-Sierra 8001/8081/8088/8089 SAS/SATA based host adapters driver
  *
  * Copyright (c) 2008-2009 USI Co., Ltd.
  * All rights reserved.
@@ -58,8 +58,13 @@ static ssize_t pm8001_ctl_mpi_interface_rev_show(struct 
device *cdev,
struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
 
-   return snprintf(buf, PAGE_SIZE, "%d\n",
-   pm8001_ha->main_cfg_tbl.interface_rev);
+   if (pm8001_ha->chip_id == chip_8001) {
+   return snprintf(buf, PAGE_SIZE, "%d\n",
+   pm8001_ha->main_cfg_tbl.pm8001_tbl.interface_rev);
+   } else {
+   return snprintf(buf, PAGE_SIZE, "%d\n",
+   pm8001_ha->main_cfg_tbl.pm80xx_tbl.interface_rev);
+   }
 }
 static
 DEVICE_ATTR(interface_rev, S_IRUGO, pm8001_ctl_mpi_interface_rev_show, NULL);
@@ -78,11 +83,19 @@ static ssize_t pm8001_ctl_fw_version_show(struct device 
*cdev,
struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
 
-   return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n",
-  (u8)(pm8001_ha->main_cfg_tbl.firmware_rev >> 24),
-  (u8)(pm8001_ha->main_cfg_tbl.firmware_rev >> 16),
-  (u8)(pm8001_ha->main_cfg_tbl.firmware_rev >> 8),
-  (u8)(pm8001_ha->main_cfg_tbl.firmware_rev));
+   if (pm8001_ha->chip_id == chip_8001) {
+   return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n",
+   (u8)(pm8001_ha->main_cfg_tbl.pm8001_tbl.firmware_rev >> 24),
+   (u8)(pm8001_ha->main_cfg_tbl.pm8001_tbl.firmware_rev >> 16),
+   (u8)(pm8001_ha->main_cfg_tbl.pm8001_tbl.firmware_rev >> 8),
+   (u8)(pm8001_ha->main_cfg_tbl.pm8001_tbl.firmware_rev));
+   } else {
+   return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n",
+   (u8)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.firmware_rev >> 24),
+   (u8)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.firmware_rev >> 16),
+   (u8)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.firmware_rev >> 8),
+   (u8)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.firmware_rev));
+   }
 }
 static DEVICE_ATTR(fw_version, S_IRUGO, pm8001_ctl_fw_version_show, NULL);
 /**
@@ -99,8 +112,13 @@ static ssize_t pm8001_ctl_max_out_io_show(struct device 
*cdev,
struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
 
-   return snprintf(buf, PAGE_SIZE, "%d\n",
-   pm8001_ha->main_cfg_tbl.max_out_io);
+   if (pm8001_ha->chip_id == chip_8001) {
+   return snprintf(buf, PAGE_SIZE, "%d\n",
+   pm8001_ha->main_cfg_tbl.pm8001_tbl.max_out_io);
+   } else {
+   return snprintf(buf, PAGE_SIZE, "%d\n",
+   pm8001_ha->main_cfg_tbl.pm80xx_tbl.max_out_io);
+   }
 }
 static DEVICE_ATTR(max_out_io, S_IRUGO, pm8001_ctl_max_out_io_show, NULL);
 /**
@@ -117,8 +135,15 @@ static ssize_t pm8001_ctl_max_devices_show(struct device 
*cdev,
struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
 
-   return snprintf(buf, PAGE_SIZE, "%04d\n",
-   (u16)(pm8001_ha->main_cfg_tbl.max_sgl >> 16));
+   if (pm8001_ha->chip_id == chip_8001) {
+   return snprintf(buf, PAGE_SIZE, "%04d\n",
+   (u16)(pm8001_ha->main_cfg_tbl.pm8001_tbl.max_sgl >> 16)
+   );
+   } else {
+   return snprintf(buf, PAGE_SIZE, "%04d\n",
+   (u16)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.max_sgl >> 16)
+   );
+   }
 }
 static DEVICE_ATTR(max_devices, S_IRUGO, pm8001_ctl_max_devices_show, NULL);
 /**
@@ -136,8 +161,15 @@ static ssize_t pm8001_ctl_max_sg_list_show(struct device 
*cdev,
struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
 
-   return snprintf(buf, PAGE_SIZE, "%04d\n",
-   pm8001_ha->main_cfg_tbl.max_sgl &

[PATCH 03/15] pm80xx: Added and modified structures, variables and macros for SPCv/ve

2013-02-12 Thread Anand
>From 5afe6aff983aed38a46bdc9ec26d1035d79d9bb0 Mon Sep 17 00:00:00 2001
From: Sakthivel K 
Date: Mon, 4 Feb 2013 13:46:35 +0530
Subject: [PATCH 03/15] pm80xx: Added and modified structures, variables and 
macros for SPCv/ve

Added SPCv/ve related macros. Updated macros, hba info structure and
other structures for SPCv/ve.

Signed-off-by: Sakthivel K 
Signed-off-by: Anand Kumar S 
---
 drivers/scsi/pm8001/pm8001_defs.h |   19 ++--
 drivers/scsi/pm8001/pm8001_init.c |   10 -
 drivers/scsi/pm8001/pm8001_sas.h  |   96 -
 3 files changed, 108 insertions(+), 17 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_defs.h 
b/drivers/scsi/pm8001/pm8001_defs.h
index c3d20c8..b25f87c 100755
--- a/drivers/scsi/pm8001/pm8001_defs.h
+++ b/drivers/scsi/pm8001/pm8001_defs.h
@@ -1,5 +1,5 @@
 /*
- * PMC-Sierra SPC 8001 SAS/SATA based host adapters driver
+ * PMC-Sierra 8001/8081/8088/8089 SAS/SATA based host adapters driver
  *
  * Copyright (c) 2008-2009 USI Co., Ltd.
  * All rights reserved.
@@ -43,6 +43,10 @@
 
 enum chip_flavors {
chip_8001,
+   chip_8008,
+   chip_8009,
+   chip_8018,
+   chip_8019
 };
 #define USI_MAX_MEMCNT 9
 #define PM8001_MAX_DMA_SG  SG_ALL
@@ -69,12 +73,19 @@ enum port_type {
 #define PM8001_MPI_QUEUE 1024   /* maximum mpi queue entries */
 #definePM8001_MAX_INB_NUM   1
 #definePM8001_MAX_OUTB_NUM  1
+#definePM8001_MAX_SPCV_INB_NUM 1
+#definePM8001_MAX_SPCV_OUTB_NUM4
 #definePM8001_CAN_QUEUE 508/* SCSI Queue depth */
 
+/* Inbound/Outbound queue size */
+#define IOMB_SIZE_SPC  64
+#define IOMB_SIZE_SPCV 128
+
 /* unchangeable hardware details */
-#definePM8001_MAX_PHYS  8  /* max. possible phys */
-#definePM8001_MAX_PORTS 8  /* max. possible ports */
-#definePM8001_MAX_DEVICES   1024   /* max supported device */
+#definePM8001_MAX_PHYS  16 /* max. possible phys */
+#definePM8001_MAX_PORTS 16 /* max. possible ports */
+#definePM8001_MAX_DEVICES   2048   /* max supported device */
+#definePM8001_MAX_MSIX_VEC  64 /* max msi-x int for spcv/ve */
 
 enum memory_region_num {
AAP1 = 0x0, /* application acceleration processor */
diff --git a/drivers/scsi/pm8001/pm8001_init.c 
b/drivers/scsi/pm8001/pm8001_init.c
index 1d883e9..5ce8330 100755
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -44,8 +44,16 @@
 
 static struct scsi_transport_template *pm8001_stt;
 
+/**
+ * chip info structure to identify chip key functionality as
+ * encryption available/not, no of ports, hw specific function ref
+ */
 static const struct pm8001_chip_info pm8001_chips[] = {
-   [chip_8001] = {  8, &pm8001_8001_dispatch,},
+   [chip_8001] = {0,  8, &pm8001_8001_dispatch,},
+   [chip_8008] = {0,  8, &pm8001_80xx_dispatch,},
+   [chip_8009] = {1,  8, &pm8001_80xx_dispatch,},
+   [chip_8018] = {0,  16, &pm8001_80xx_dispatch,},
+   [chip_8019] = {1,  16, &pm8001_80xx_dispatch,},
 };
 static int pm8001_id;
 
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index 1100820..bf4963e 100755
--- a/drivers/scsi/pm8001/pm8001_sas.h
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -108,6 +108,7 @@ do {\
 #define PM8001_NAME_LENGTH 32/* generic length of strings */
 extern struct list_head hba_list;
 extern const struct pm8001_dispatch pm8001_8001_dispatch;
+extern const struct pm8001_dispatch pm8001_80xx_dispatch;
 
 struct pm8001_hba_info;
 struct pm8001_ccb_info;
@@ -173,6 +174,7 @@ struct pm8001_dispatch {
 };
 
 struct pm8001_chip_info {
+   u32 encrypt;
u32 n_phy;
const struct pm8001_dispatch*dispatch;
 };
@@ -256,7 +258,20 @@ struct mpi_mem_req {
struct mpi_mem  region[USI_MAX_MEMCNT];
 };
 
-struct main_cfg_table {
+struct encrypt {
+   u32 cipher_mode;
+   u32 sec_mode;
+   u32 status;
+   u32 flag;
+};
+
+struct sas_phy_attribute_table {
+   u32 phystart1_16[16];
+   u32 outbound_hw_event_pid1_16[16];
+};
+
+union main_cfg_table {
+   struct {
u32 signature;
u32 interface_rev;
u32 firmware_rev;
@@ -292,19 +307,67 @@ struct main_cfg_table {
u32 fatal_err_dump_length1;
u32 hda_mode_flag;
u32 anolog_setup_table_offset;
+   u32 rsvd[4];
+   } pm8001_tbl;
+
+   struct {
+   u32 signature;
+   u32 interface_rev;
+   u32 firmware_rev;
+   u32 max_out_io;
+   u32 max_s

[PATCH 02/15] pm80xx: Added vendor and device ids for SPCv/ve controllers

2013-02-12 Thread Anand
>From edeb2b4b89ff6c7ddbb73366a2b4f6a86815d8eb Mon Sep 17 00:00:00 2001
From: Sakthivel K 
Date: Mon, 4 Feb 2013 12:15:28 +0530
Subject: [PATCH 02/15] pm80xx: Added vendor and device ids for
SPCv/SPCve controllers

Updated of pci id table  with device, vendor, subdevice and subvendor
ids for 8081, 8088, 8089 SAS/SATA controllers

Signed-off-by: Sakthivel K 
Signed-off-by: Anand Kumar S 
---
 drivers/scsi/pm8001/pm8001_init.c |   42

 1 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_init.c
b/drivers/scsi/pm8001/pm8001_init.c
index 3d5e522..1d883e9 100755
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -1,5 +1,5 @@
 /*
- * PMC-Sierra SPC 8001 SAS/SATA based host adapters driver
+ * PMC-Sierra PM8001/8081/8088/8089 SAS/SATA based host adapters driver
  *
  * Copyright (c) 2008-2009 USI Co., Ltd.
  * All rights reserved.
@@ -843,14 +843,45 @@ err_out_enable:
return rc;
 }

+/* update of pci device, vendor id and driver data with
+ * unique value for each of the controller
+ */
 static struct pci_device_id pm8001_pci_table[] = {
-   {
-   PCI_VDEVICE(PMC_Sierra, 0x8001), chip_8001
-   },
+   { PCI_VDEVICE(PMC_Sierra, 0x8001), chip_8001 },
{
PCI_DEVICE(0x117c, 0x0042),
.driver_data = chip_8001
},
+   /* Support for SPC/SPCv/SPCve controllers */
+   { PCI_VDEVICE(ADAPTEC2, 0x8001), chip_8001 },
+   { PCI_VDEVICE(PMC_Sierra, 0x8008), chip_8008 },
+   { PCI_VDEVICE(ADAPTEC2, 0x8008), chip_8008 },
+   { PCI_VDEVICE(PMC_Sierra, 0x8018), chip_8018 },
+   { PCI_VDEVICE(ADAPTEC2, 0x8018), chip_8018 },
+   { PCI_VDEVICE(PMC_Sierra, 0x8009), chip_8009 },
+   { PCI_VDEVICE(ADAPTEC2, 0x8009), chip_8009 },
+   { PCI_VDEVICE(PMC_Sierra, 0x8019), chip_8019 },
+   { PCI_VDEVICE(ADAPTEC2, 0x8019), chip_8019 },
+   { PCI_VENDOR_ID_ADAPTEC2, 0x8081,
+   PCI_VENDOR_ID_ADAPTEC2, 0x0400, 0, 0, chip_8001 },
+   { PCI_VENDOR_ID_ADAPTEC2, 0x8081,
+   PCI_VENDOR_ID_ADAPTEC2, 0x0800, 0, 0, chip_8001 },
+   { PCI_VENDOR_ID_ADAPTEC2, 0x8088,
+   PCI_VENDOR_ID_ADAPTEC2, 0x0008, 0, 0, chip_8008 },
+   { PCI_VENDOR_ID_ADAPTEC2, 0x8088,
+   PCI_VENDOR_ID_ADAPTEC2, 0x0800, 0, 0, chip_8008 },
+   { PCI_VENDOR_ID_ADAPTEC2, 0x8089,
+   PCI_VENDOR_ID_ADAPTEC2, 0x0008, 0, 0, chip_8009 },
+   { PCI_VENDOR_ID_ADAPTEC2, 0x8089,
+   PCI_VENDOR_ID_ADAPTEC2, 0x0800, 0, 0, chip_8009 },
+   { PCI_VENDOR_ID_ADAPTEC2, 0x8088,
+   PCI_VENDOR_ID_ADAPTEC2, 0x0016, 0, 0, chip_8018 },
+   { PCI_VENDOR_ID_ADAPTEC2, 0x8088,
+   PCI_VENDOR_ID_ADAPTEC2, 0x1600, 0, 0, chip_8018 },
+   { PCI_VENDOR_ID_ADAPTEC2, 0x8089,
+   PCI_VENDOR_ID_ADAPTEC2, 0x0016, 0, 0, chip_8019 },
+   { PCI_VENDOR_ID_ADAPTEC2, 0x8089,
+   PCI_VENDOR_ID_ADAPTEC2, 0x1600, 0, 0, chip_8019 },
{} /* terminate list */
 };

@@ -902,7 +933,8 @@ module_init(pm8001_init);
 module_exit(pm8001_exit);

 MODULE_AUTHOR("Jack Wang ");
-MODULE_DESCRIPTION("PMC-Sierra PM8001 SAS/SATA controller driver");
+MODULE_DESCRIPTION(
+   "PMC-Sierra PM8001/8081/8088/8089 SAS/SATA controller driver");
 MODULE_VERSION(DRV_VERSION);
 MODULE_LICENSE("GPL");
 MODULE_DEVICE_TABLE(pci, pm8001_pci_table);
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 01/15] pm80xx: fix for memory region free

2013-02-12 Thread Anand
>From 56ee53f01663fa479c0624b81e36545ea5b1ab94 Mon Sep 17 00:00:00 2001
From: Sakthivel K 
Date: Mon, 4 Feb 2013 12:10:02 +0530
Subject: [PATCH 01/15] pm80xx: fix for memory region free

All memory regions are allocated based on variables total_len
and alignment but free was based on element_size.

Signed-off-by: Sakthivel K 
Signed-off-by: Anand Kumar S 
---
 drivers/scsi/pm8001/pm8001_init.c |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_init.c 
b/drivers/scsi/pm8001/pm8001_init.c
index 4c9fe73..3d5e522 100755
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -140,7 +140,8 @@ static void pm8001_free(struct pm8001_hba_info *pm8001_ha)
for (i = 0; i < USI_MAX_MEMCNT; i++) {
if (pm8001_ha->memoryMap.region[i].virt_ptr != NULL) {
pci_free_consistent(pm8001_ha->pdev,
-   pm8001_ha->memoryMap.region[i].element_size,
+   (pm8001_ha->memoryMap.region[i].total_len +
+   pm8001_ha->memoryMap.region[i].alignment),
pm8001_ha->memoryMap.region[i].virt_ptr,
pm8001_ha->memoryMap.region[i].phys_addr);
}
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 00/15] Support for PMC 8081/8088/8089 controllers.

2013-02-12 Thread Anand
James/Linux-scsi,

The following patchset provides support for PMC 8081/88/89 series of 
controllers.

>From 9c620d9273640b416054ba76cd267aebaf455ed2 Mon Sep 17 00:00:00 2001
From: Sakthivel K 
Date: Thu, 7 Feb 2013 17:03:42 +0530
Subject: [PATCH 00/15] Support for PMC 8081/8088/8089 controllers.

Support for PMC 8081/8088/8089 series of controllers. 

New data structures and hardware functionality files have been added
to support 8088/8089 controllers. The hardware specific file contains
new functionality specific to 8088/8089 controllers including support
for encryption, thermal settings, FW upgradation. Since 8081/8088/8089 
controllers are built on top of 8001 controller most of the data 
structures and functions of 8001 controller are reused.

MSI-X support for 8081/8088/8089 and many more error handling logic to
handle controller specific errors have been introduced. Functionality
to support multiple inbound and outbound queues have been added for 
8088/8089 controllers.

Fixes for 8001 driver include memory region fix, NCQ error handling logic,
WWN number retrieval for the controller. In addition new memory regions
have been introduced for FW flash. 

Sakthivel K (15):
  pm80xx: fix for memory region free
  pm80xx: Added vendor and device ids for SPCv/SPCve controllers
  pm80xx: Added and modified structures, variables and macros for
SPCv/ve
  pm80xx: Structure and variable name update for SPC
  pm80xx: Multiple inbound/outbound queue configuration
  pm80xx: Updated common functions common for SPC and SPCv/ve
  pm80xx: MSI-X implementation for using 64 interrupts
  pm80xx: Added SPCv/ve specific hardware functionalities
  pm80xx: SPCv/ve specific changes in common files
  pm80xx: SPC new firmware changes for device id 0x8081 alone
  pm80xx: Firmware flash memory free fix, with addition of new memory  
  region for it
  pm80xx: Changed module name and debug messages update
  pm80xx: WWN Modification for PM8081/88/89 controllers
  pm80xx: NCQ error handling changes
  pm80xx: thermal, sas controller config and error handling update

 drivers/scsi/pm8001/Makefile  |7 +-
 drivers/scsi/pm8001/pm8001_ctl.c  |   74 +-
 drivers/scsi/pm8001/pm8001_defs.h |   34 +-
 drivers/scsi/pm8001/pm8001_hwi.c  |  796 +---
 drivers/scsi/pm8001/pm8001_hwi.h  |4 +-
 drivers/scsi/pm8001/pm8001_init.c | 1478 +-
 drivers/scsi/pm8001/pm8001_sas.c  |  105 +-
 drivers/scsi/pm8001/pm8001_sas.h  |  176 ++-
 drivers/scsi/pm8001/pm80xx_hwi.c  | 4131 +
 drivers/scsi/pm8001/pm80xx_hwi.h  | 1524 ++
 10 files changed, 7937 insertions(+), 392 deletions(-)
 create mode 100644 drivers/scsi/pm8001/pm80xx_hwi.c
 create mode 100644 drivers/scsi/pm8001/pm80xx_hwi.h

-Anand

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Test mail

2013-02-12 Thread Anand Kumar S - ERS, HCL Tech




::DISCLAIMER::


The contents of this e-mail and any attachment(s) are confidential and intended 
for the named recipient(s) only.
E-mail transmission is not guaranteed to be secure or error-free as information 
could be intercepted, corrupted,
lost, destroyed, arrive late or incomplete, or may contain viruses in 
transmission. The e mail and its contents
(with or without referred errors) shall therefore not attach any liability on 
the originator or HCL or its affiliates.
Views or opinions, if any, presented in this email are solely those of the 
author and may not necessarily reflect the
views or opinions of HCL or its affiliates. Any form of reproduction, 
dissemination, copying, disclosure, modification,
distribution and / or publication of this message without the prior written 
consent of authorized representative of
HCL is strictly prohibited. If you have received this email in error please 
delete it and notify the sender immediately.
Before opening any email and/or attachments, please check them for viruses and 
other defects.



--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] scsi_debug: Fix endianess in partition table

2013-02-12 Thread Martin Peschke
On Mon, 2013-02-11 at 18:34 +0100, Martin Peschke wrote:
> Both start_sect and nr_sects in struct partition are __le32 and
> require cpu_to_le32() on assignment.

Steffen Maier has pointed me at:

block/partitions/msdos.c:   return
(sector_t)get_unaligned_le32(&p->start_sect);

Unfortunately, both get_unaligned_le32() and le32_to_cpu() appear to be
in use for start_sect and nr_sects.

Any one who would argue for changing my patch from cpu_to_le32 to
put_unaligned_le32()?

Thanks,
Martin



> 
> Without this fix tools like fdisk show an invalid partition table
> for SCSI devices emulated by scsi_debug on big-endian architectures,
> like s390x. Besides a kernel message like this was emitted:
> 
> sda: p1 start 536870912 is beyond EOD, enabling native capacity
> sda: p1 start 536870912 is beyond EOD, truncated
> 
> For verification 'xxd -l 512 /dev/sda' has been used to make sure
> that this fix makes scsi_debug generated partition tables on s390x
> look like the ones generated on my laptop.
> 
> Signed-off-by: Martin Peschke 
> Reviewed-by: Steffen Maier 
> 
> ---
>  drivers/scsi/scsi_debug.c |4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> --- a/drivers/scsi/scsi_debug.c
> +++ b/drivers/scsi/scsi_debug.c
> @@ -2662,8 +2662,8 @@ static void __init sdebug_build_parts(un
>  / sdebug_sectors_per;
>   pp->end_sector = (end_sec % sdebug_sectors_per) + 1;
> 
> - pp->start_sect = start_sec;
> - pp->nr_sects = end_sec - start_sec + 1;
> + pp->start_sect = cpu_to_le32(start_sec);
> + pp->nr_sects = cpu_to_le32(end_sec - start_sec + 1);
>   pp->sys_ind = 0x83; /* plain Linux partition */
>   }
>  }
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html