1851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria/*
2851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * Linux driver for VMware's para-virtualized SCSI HBA.
3851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria *
4851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * Copyright (C) 2008-2009, VMware, Inc. All Rights Reserved.
5851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria *
6851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * This program is free software; you can redistribute it and/or modify it
7851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * under the terms of the GNU General Public License as published by the
8851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * Free Software Foundation; version 2 of the License and no later version.
9851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria *
10851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * This program is distributed in the hope that it will be useful, but
11851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * WITHOUT ANY WARRANTY; without even the implied warranty of
12851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
13851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * NON INFRINGEMENT.  See the GNU General Public License for more
14851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * details.
15851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria *
16851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * You should have received a copy of the GNU General Public License
17851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * along with this program; if not, write to the Free Software
18851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria *
20a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar * Maintained by: Arvind Kumar <arvindkumar@vmware.com>
21851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria *
22851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria */
23851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
24851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria#include <linux/kernel.h>
25851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria#include <linux/module.h>
26851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria#include <linux/interrupt.h>
275a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
28851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria#include <linux/workqueue.h>
29851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria#include <linux/pci.h>
30851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
31851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria#include <scsi/scsi.h>
32851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria#include <scsi/scsi_host.h>
33851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria#include <scsi/scsi_cmnd.h>
34851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria#include <scsi/scsi_device.h>
35851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
36851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria#include "vmw_pvscsi.h"
37851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
38851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria#define PVSCSI_LINUX_DRIVER_DESC "VMware PVSCSI driver"
39851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
40851b164231d1117673aa44c00c7622e48b7dfcf4Alok KatariaMODULE_DESCRIPTION(PVSCSI_LINUX_DRIVER_DESC);
41851b164231d1117673aa44c00c7622e48b7dfcf4Alok KatariaMODULE_AUTHOR("VMware, Inc.");
42851b164231d1117673aa44c00c7622e48b7dfcf4Alok KatariaMODULE_LICENSE("GPL");
43851b164231d1117673aa44c00c7622e48b7dfcf4Alok KatariaMODULE_VERSION(PVSCSI_DRIVER_VERSION_STRING);
44851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
45851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria#define PVSCSI_DEFAULT_NUM_PAGES_PER_RING	8
46851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria#define PVSCSI_DEFAULT_NUM_PAGES_MSG_RING	1
47851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria#define PVSCSI_DEFAULT_QUEUE_DEPTH		64
48851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria#define SGL_SIZE				PAGE_SIZE
49851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
50851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastruct pvscsi_sg_list {
51851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct PVSCSISGElement sge[PVSCSI_MAX_NUM_SG_ENTRIES_PER_SEGMENT];
52851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria};
53851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
54851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastruct pvscsi_ctx {
55851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	/*
56851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 * The index of the context in cmd_map serves as the context ID for a
57851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 * 1-to-1 mapping completions back to requests.
58851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 */
59851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct scsi_cmnd	*cmd;
60851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct pvscsi_sg_list	*sgl;
61851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct list_head	list;
62851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	dma_addr_t		dataPA;
63851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	dma_addr_t		sensePA;
64851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	dma_addr_t		sglPA;
65851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria};
66851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
67851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastruct pvscsi_adapter {
68851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	char				*mmioBase;
69851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	unsigned int			irq;
70851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	u8				rev;
71851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	bool				use_msi;
72851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	bool				use_msix;
73851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	bool				use_msg;
74851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
75851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	spinlock_t			hw_lock;
76851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
77851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct workqueue_struct		*workqueue;
78851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct work_struct		work;
79851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
80851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct PVSCSIRingReqDesc	*req_ring;
81851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	unsigned			req_pages;
82851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	unsigned			req_depth;
83851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	dma_addr_t			reqRingPA;
84851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
85851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct PVSCSIRingCmpDesc	*cmp_ring;
86851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	unsigned			cmp_pages;
87851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	dma_addr_t			cmpRingPA;
88851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
89851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct PVSCSIRingMsgDesc	*msg_ring;
90851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	unsigned			msg_pages;
91851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	dma_addr_t			msgRingPA;
92851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
93851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct PVSCSIRingsState		*rings_state;
94851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	dma_addr_t			ringStatePA;
95851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
96851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct pci_dev			*dev;
97851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct Scsi_Host		*host;
98851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
99851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct list_head		cmd_pool;
100851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct pvscsi_ctx		*cmd_map;
101851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria};
102851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
103851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
104851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria/* Command line parameters */
105851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic int pvscsi_ring_pages     = PVSCSI_DEFAULT_NUM_PAGES_PER_RING;
106851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic int pvscsi_msg_ring_pages = PVSCSI_DEFAULT_NUM_PAGES_MSG_RING;
107851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic int pvscsi_cmd_per_lun    = PVSCSI_DEFAULT_QUEUE_DEPTH;
108851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic bool pvscsi_disable_msi;
109851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic bool pvscsi_disable_msix;
110851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic bool pvscsi_use_msg       = true;
111851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
112851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria#define PVSCSI_RW (S_IRUSR | S_IWUSR)
113851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
114851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariamodule_param_named(ring_pages, pvscsi_ring_pages, int, PVSCSI_RW);
115851b164231d1117673aa44c00c7622e48b7dfcf4Alok KatariaMODULE_PARM_DESC(ring_pages, "Number of pages per req/cmp ring - (default="
116851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		 __stringify(PVSCSI_DEFAULT_NUM_PAGES_PER_RING) ")");
117851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
118851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariamodule_param_named(msg_ring_pages, pvscsi_msg_ring_pages, int, PVSCSI_RW);
119851b164231d1117673aa44c00c7622e48b7dfcf4Alok KatariaMODULE_PARM_DESC(msg_ring_pages, "Number of pages for the msg ring - (default="
120851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		 __stringify(PVSCSI_DEFAULT_NUM_PAGES_MSG_RING) ")");
121851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
122851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariamodule_param_named(cmd_per_lun, pvscsi_cmd_per_lun, int, PVSCSI_RW);
123851b164231d1117673aa44c00c7622e48b7dfcf4Alok KatariaMODULE_PARM_DESC(cmd_per_lun, "Maximum commands per lun - (default="
124851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		 __stringify(PVSCSI_MAX_REQ_QUEUE_DEPTH) ")");
125851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
126851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariamodule_param_named(disable_msi, pvscsi_disable_msi, bool, PVSCSI_RW);
127851b164231d1117673aa44c00c7622e48b7dfcf4Alok KatariaMODULE_PARM_DESC(disable_msi, "Disable MSI use in driver - (default=0)");
128851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
129851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariamodule_param_named(disable_msix, pvscsi_disable_msix, bool, PVSCSI_RW);
130851b164231d1117673aa44c00c7622e48b7dfcf4Alok KatariaMODULE_PARM_DESC(disable_msix, "Disable MSI-X use in driver - (default=0)");
131851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
132851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariamodule_param_named(use_msg, pvscsi_use_msg, bool, PVSCSI_RW);
133851b164231d1117673aa44c00c7622e48b7dfcf4Alok KatariaMODULE_PARM_DESC(use_msg, "Use msg ring when available - (default=1)");
134851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
135851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic const struct pci_device_id pvscsi_pci_tbl[] = {
136851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	{ PCI_VDEVICE(VMWARE, PCI_DEVICE_ID_VMWARE_PVSCSI) },
137851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	{ 0 }
138851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria};
139851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
140851b164231d1117673aa44c00c7622e48b7dfcf4Alok KatariaMODULE_DEVICE_TABLE(pci, pvscsi_pci_tbl);
141851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
142851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic struct device *
143851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariapvscsi_dev(const struct pvscsi_adapter *adapter)
144851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
145851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	return &(adapter->dev->dev);
146851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
147851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
148851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic struct pvscsi_ctx *
149851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariapvscsi_find_context(const struct pvscsi_adapter *adapter, struct scsi_cmnd *cmd)
150851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
151851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct pvscsi_ctx *ctx, *end;
152851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
153851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	end = &adapter->cmd_map[adapter->req_depth];
154851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	for (ctx = adapter->cmd_map; ctx < end; ctx++)
155851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		if (ctx->cmd == cmd)
156851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			return ctx;
157851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
158851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	return NULL;
159851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
160851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
161851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic struct pvscsi_ctx *
162851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariapvscsi_acquire_context(struct pvscsi_adapter *adapter, struct scsi_cmnd *cmd)
163851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
164851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct pvscsi_ctx *ctx;
165851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
166851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (list_empty(&adapter->cmd_pool))
167851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		return NULL;
168851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
169851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	ctx = list_first_entry(&adapter->cmd_pool, struct pvscsi_ctx, list);
170851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	ctx->cmd = cmd;
171851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	list_del(&ctx->list);
172851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
173851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	return ctx;
174851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
175851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
176851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic void pvscsi_release_context(struct pvscsi_adapter *adapter,
177851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria				   struct pvscsi_ctx *ctx)
178851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
179851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	ctx->cmd = NULL;
180851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	list_add(&ctx->list, &adapter->cmd_pool);
181851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
182851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
183851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria/*
184851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * Map a pvscsi_ctx struct to a context ID field value; we map to a simple
185851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * non-zero integer. ctx always points to an entry in cmd_map array, hence
186851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * the return value is always >=1.
187851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria */
188851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic u64 pvscsi_map_context(const struct pvscsi_adapter *adapter,
189851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			      const struct pvscsi_ctx *ctx)
190851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
191851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	return ctx - adapter->cmd_map + 1;
192851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
193851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
194851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic struct pvscsi_ctx *
195851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariapvscsi_get_context(const struct pvscsi_adapter *adapter, u64 context)
196851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
197851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	return &adapter->cmd_map[context - 1];
198851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
199851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
200851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic void pvscsi_reg_write(const struct pvscsi_adapter *adapter,
201851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			     u32 offset, u32 val)
202851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
203851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	writel(val, adapter->mmioBase + offset);
204851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
205851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
206851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic u32 pvscsi_reg_read(const struct pvscsi_adapter *adapter, u32 offset)
207851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
208851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	return readl(adapter->mmioBase + offset);
209851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
210851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
211851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic u32 pvscsi_read_intr_status(const struct pvscsi_adapter *adapter)
212851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
213851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	return pvscsi_reg_read(adapter, PVSCSI_REG_OFFSET_INTR_STATUS);
214851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
215851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
216851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic void pvscsi_write_intr_status(const struct pvscsi_adapter *adapter,
217851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria				     u32 val)
218851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
219851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_reg_write(adapter, PVSCSI_REG_OFFSET_INTR_STATUS, val);
220851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
221851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
222851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic void pvscsi_unmask_intr(const struct pvscsi_adapter *adapter)
223851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
224851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	u32 intr_bits;
225851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
226851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	intr_bits = PVSCSI_INTR_CMPL_MASK;
227851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (adapter->use_msg)
228851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		intr_bits |= PVSCSI_INTR_MSG_MASK;
229851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
230851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_reg_write(adapter, PVSCSI_REG_OFFSET_INTR_MASK, intr_bits);
231851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
232851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
233851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic void pvscsi_mask_intr(const struct pvscsi_adapter *adapter)
234851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
235851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_reg_write(adapter, PVSCSI_REG_OFFSET_INTR_MASK, 0);
236851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
237851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
238851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic void pvscsi_write_cmd_desc(const struct pvscsi_adapter *adapter,
239851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria				  u32 cmd, const void *desc, size_t len)
240851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
241851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	const u32 *ptr = desc;
242851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	size_t i;
243851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
244851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	len /= sizeof(*ptr);
245851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_reg_write(adapter, PVSCSI_REG_OFFSET_COMMAND, cmd);
246851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	for (i = 0; i < len; i++)
247851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		pvscsi_reg_write(adapter,
248851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria				 PVSCSI_REG_OFFSET_COMMAND_DATA, ptr[i]);
249851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
250851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
251851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic void pvscsi_abort_cmd(const struct pvscsi_adapter *adapter,
252851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			     const struct pvscsi_ctx *ctx)
253851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
254851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct PVSCSICmdDescAbortCmd cmd = { 0 };
255851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
256851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	cmd.target = ctx->cmd->device->id;
257851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	cmd.context = pvscsi_map_context(adapter, ctx);
258851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
259851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_write_cmd_desc(adapter, PVSCSI_CMD_ABORT_CMD, &cmd, sizeof(cmd));
260851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
261851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
262851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic void pvscsi_kick_rw_io(const struct pvscsi_adapter *adapter)
263851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
264851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_reg_write(adapter, PVSCSI_REG_OFFSET_KICK_RW_IO, 0);
265851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
266851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
267851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic void pvscsi_process_request_ring(const struct pvscsi_adapter *adapter)
268851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
269851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_reg_write(adapter, PVSCSI_REG_OFFSET_KICK_NON_RW_IO, 0);
270851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
271851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
272851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic int scsi_is_rw(unsigned char op)
273851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
274851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	return op == READ_6  || op == WRITE_6 ||
275851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	       op == READ_10 || op == WRITE_10 ||
276851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	       op == READ_12 || op == WRITE_12 ||
277851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	       op == READ_16 || op == WRITE_16;
278851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
279851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
280851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic void pvscsi_kick_io(const struct pvscsi_adapter *adapter,
281851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			   unsigned char op)
282851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
283851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (scsi_is_rw(op))
284851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		pvscsi_kick_rw_io(adapter);
285851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	else
286851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		pvscsi_process_request_ring(adapter);
287851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
288851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
289851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic void ll_adapter_reset(const struct pvscsi_adapter *adapter)
290851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
291851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	dev_dbg(pvscsi_dev(adapter), "Adapter Reset on %p\n", adapter);
292851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
293851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_write_cmd_desc(adapter, PVSCSI_CMD_ADAPTER_RESET, NULL, 0);
294851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
295851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
296851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic void ll_bus_reset(const struct pvscsi_adapter *adapter)
297851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
298851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	dev_dbg(pvscsi_dev(adapter), "Reseting bus on %p\n", adapter);
299851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
300851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_write_cmd_desc(adapter, PVSCSI_CMD_RESET_BUS, NULL, 0);
301851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
302851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
303851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic void ll_device_reset(const struct pvscsi_adapter *adapter, u32 target)
304851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
305851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct PVSCSICmdDescResetDevice cmd = { 0 };
306851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
307851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	dev_dbg(pvscsi_dev(adapter), "Reseting device: target=%u\n", target);
308851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
309851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	cmd.target = target;
310851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
311851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_write_cmd_desc(adapter, PVSCSI_CMD_RESET_DEVICE,
312851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			      &cmd, sizeof(cmd));
313851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
314851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
315851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic void pvscsi_create_sg(struct pvscsi_ctx *ctx,
316851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			     struct scatterlist *sg, unsigned count)
317851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
318851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	unsigned i;
319851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct PVSCSISGElement *sge;
320851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
321851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	BUG_ON(count > PVSCSI_MAX_NUM_SG_ENTRIES_PER_SEGMENT);
322851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
323851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	sge = &ctx->sgl->sge[0];
324851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	for (i = 0; i < count; i++, sg++) {
325851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		sge[i].addr   = sg_dma_address(sg);
326851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		sge[i].length = sg_dma_len(sg);
327851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		sge[i].flags  = 0;
328851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	}
329851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
330851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
331851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria/*
332851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * Map all data buffers for a command into PCI space and
333851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * setup the scatter/gather list if needed.
334851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria */
335851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic void pvscsi_map_buffers(struct pvscsi_adapter *adapter,
336851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			       struct pvscsi_ctx *ctx, struct scsi_cmnd *cmd,
337851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			       struct PVSCSIRingReqDesc *e)
338851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
339851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	unsigned count;
340851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	unsigned bufflen = scsi_bufflen(cmd);
341851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct scatterlist *sg;
342851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
343851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	e->dataLen = bufflen;
344851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	e->dataAddr = 0;
345851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (bufflen == 0)
346851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		return;
347851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
348851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	sg = scsi_sglist(cmd);
349851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	count = scsi_sg_count(cmd);
350851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (count != 0) {
351851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		int segs = scsi_dma_map(cmd);
352851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		if (segs > 1) {
353851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			pvscsi_create_sg(ctx, sg, segs);
354851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
355851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			e->flags |= PVSCSI_FLAG_CMD_WITH_SG_LIST;
356851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			ctx->sglPA = pci_map_single(adapter->dev, ctx->sgl,
357851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria						    SGL_SIZE, PCI_DMA_TODEVICE);
358851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			e->dataAddr = ctx->sglPA;
359851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		} else
360851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			e->dataAddr = sg_dma_address(sg);
361851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	} else {
362851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		/*
363851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		 * In case there is no S/G list, scsi_sglist points
364851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		 * directly to the buffer.
365851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		 */
366851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		ctx->dataPA = pci_map_single(adapter->dev, sg, bufflen,
367851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria					     cmd->sc_data_direction);
368851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		e->dataAddr = ctx->dataPA;
369851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	}
370851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
371851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
372851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic void pvscsi_unmap_buffers(const struct pvscsi_adapter *adapter,
373851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria				 struct pvscsi_ctx *ctx)
374851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
375851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct scsi_cmnd *cmd;
376851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	unsigned bufflen;
377851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
378851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	cmd = ctx->cmd;
379851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	bufflen = scsi_bufflen(cmd);
380851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
381851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (bufflen != 0) {
382851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		unsigned count = scsi_sg_count(cmd);
383851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
384851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		if (count != 0) {
385851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			scsi_dma_unmap(cmd);
386851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			if (ctx->sglPA) {
387851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria				pci_unmap_single(adapter->dev, ctx->sglPA,
388851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria						 SGL_SIZE, PCI_DMA_TODEVICE);
389851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria				ctx->sglPA = 0;
390851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			}
391851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		} else
392851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			pci_unmap_single(adapter->dev, ctx->dataPA, bufflen,
393851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria					 cmd->sc_data_direction);
394851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	}
395851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (cmd->sense_buffer)
396851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		pci_unmap_single(adapter->dev, ctx->sensePA,
397851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria				 SCSI_SENSE_BUFFERSIZE, PCI_DMA_FROMDEVICE);
398851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
399851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
400851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic int __devinit pvscsi_allocate_rings(struct pvscsi_adapter *adapter)
401851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
402851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	adapter->rings_state = pci_alloc_consistent(adapter->dev, PAGE_SIZE,
403851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria						    &adapter->ringStatePA);
404851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (!adapter->rings_state)
405851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		return -ENOMEM;
406851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
407851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	adapter->req_pages = min(PVSCSI_MAX_NUM_PAGES_REQ_RING,
408851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria				 pvscsi_ring_pages);
409851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	adapter->req_depth = adapter->req_pages
410851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria					* PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE;
411851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	adapter->req_ring = pci_alloc_consistent(adapter->dev,
412851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria						 adapter->req_pages * PAGE_SIZE,
413851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria						 &adapter->reqRingPA);
414851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (!adapter->req_ring)
415851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		return -ENOMEM;
416851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
417851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	adapter->cmp_pages = min(PVSCSI_MAX_NUM_PAGES_CMP_RING,
418851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria				 pvscsi_ring_pages);
419851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	adapter->cmp_ring = pci_alloc_consistent(adapter->dev,
420851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria						 adapter->cmp_pages * PAGE_SIZE,
421851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria						 &adapter->cmpRingPA);
422851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (!adapter->cmp_ring)
423851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		return -ENOMEM;
424851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
425851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	BUG_ON(!IS_ALIGNED(adapter->ringStatePA, PAGE_SIZE));
426851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	BUG_ON(!IS_ALIGNED(adapter->reqRingPA, PAGE_SIZE));
427851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	BUG_ON(!IS_ALIGNED(adapter->cmpRingPA, PAGE_SIZE));
428851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
429851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (!adapter->use_msg)
430851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		return 0;
431851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
432851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	adapter->msg_pages = min(PVSCSI_MAX_NUM_PAGES_MSG_RING,
433851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria				 pvscsi_msg_ring_pages);
434851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	adapter->msg_ring = pci_alloc_consistent(adapter->dev,
435851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria						 adapter->msg_pages * PAGE_SIZE,
436851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria						 &adapter->msgRingPA);
437851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (!adapter->msg_ring)
438851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		return -ENOMEM;
439851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	BUG_ON(!IS_ALIGNED(adapter->msgRingPA, PAGE_SIZE));
440851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
441851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	return 0;
442851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
443851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
444851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic void pvscsi_setup_all_rings(const struct pvscsi_adapter *adapter)
445851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
446851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct PVSCSICmdDescSetupRings cmd = { 0 };
447851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	dma_addr_t base;
448851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	unsigned i;
449851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
450851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	cmd.ringsStatePPN   = adapter->ringStatePA >> PAGE_SHIFT;
451851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	cmd.reqRingNumPages = adapter->req_pages;
452851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	cmd.cmpRingNumPages = adapter->cmp_pages;
453851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
454851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	base = adapter->reqRingPA;
455851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	for (i = 0; i < adapter->req_pages; i++) {
456851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		cmd.reqRingPPNs[i] = base >> PAGE_SHIFT;
457851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		base += PAGE_SIZE;
458851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	}
459851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
460851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	base = adapter->cmpRingPA;
461851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	for (i = 0; i < adapter->cmp_pages; i++) {
462851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		cmd.cmpRingPPNs[i] = base >> PAGE_SHIFT;
463851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		base += PAGE_SIZE;
464851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	}
465851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
466851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	memset(adapter->rings_state, 0, PAGE_SIZE);
467851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	memset(adapter->req_ring, 0, adapter->req_pages * PAGE_SIZE);
468851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	memset(adapter->cmp_ring, 0, adapter->cmp_pages * PAGE_SIZE);
469851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
470851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_write_cmd_desc(adapter, PVSCSI_CMD_SETUP_RINGS,
471851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			      &cmd, sizeof(cmd));
472851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
473851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (adapter->use_msg) {
474851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		struct PVSCSICmdDescSetupMsgRing cmd_msg = { 0 };
475851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
476851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		cmd_msg.numPages = adapter->msg_pages;
477851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
478851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		base = adapter->msgRingPA;
479851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		for (i = 0; i < adapter->msg_pages; i++) {
480851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			cmd_msg.ringPPNs[i] = base >> PAGE_SHIFT;
481851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			base += PAGE_SIZE;
482851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		}
483851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		memset(adapter->msg_ring, 0, adapter->msg_pages * PAGE_SIZE);
484851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
485851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		pvscsi_write_cmd_desc(adapter, PVSCSI_CMD_SETUP_MSG_RING,
486851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria				      &cmd_msg, sizeof(cmd_msg));
487851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	}
488851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
489851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
490851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria/*
491851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * Pull a completion descriptor off and pass the completion back
492851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * to the SCSI mid layer.
493851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria */
494851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic void pvscsi_complete_request(struct pvscsi_adapter *adapter,
495851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria				    const struct PVSCSIRingCmpDesc *e)
496851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
497851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct pvscsi_ctx *ctx;
498851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct scsi_cmnd *cmd;
499851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	u32 btstat = e->hostStatus;
500851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	u32 sdstat = e->scsiStatus;
501851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
502851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	ctx = pvscsi_get_context(adapter, e->context);
503851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	cmd = ctx->cmd;
504851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_unmap_buffers(adapter, ctx);
505851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_release_context(adapter, ctx);
506851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	cmd->result = 0;
507851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
508851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (sdstat != SAM_STAT_GOOD &&
509851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	    (btstat == BTSTAT_SUCCESS ||
510851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	     btstat == BTSTAT_LINKED_COMMAND_COMPLETED ||
511851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	     btstat == BTSTAT_LINKED_COMMAND_COMPLETED_WITH_FLAG)) {
512851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		cmd->result = (DID_OK << 16) | sdstat;
513851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		if (sdstat == SAM_STAT_CHECK_CONDITION && cmd->sense_buffer)
514851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			cmd->result |= (DRIVER_SENSE << 24);
515851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	} else
516851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		switch (btstat) {
517851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		case BTSTAT_SUCCESS:
518851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		case BTSTAT_LINKED_COMMAND_COMPLETED:
519851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		case BTSTAT_LINKED_COMMAND_COMPLETED_WITH_FLAG:
520851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			/* If everything went fine, let's move on..  */
521851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			cmd->result = (DID_OK << 16);
522851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			break;
523851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
524851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		case BTSTAT_DATARUN:
525851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		case BTSTAT_DATA_UNDERRUN:
526851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			/* Report residual data in underruns */
527851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			scsi_set_resid(cmd, scsi_bufflen(cmd) - e->dataLen);
528851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			cmd->result = (DID_ERROR << 16);
529851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			break;
530851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
531851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		case BTSTAT_SELTIMEO:
532851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			/* Our emulation returns this for non-connected devs */
533851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			cmd->result = (DID_BAD_TARGET << 16);
534851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			break;
535851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
536851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		case BTSTAT_LUNMISMATCH:
537851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		case BTSTAT_TAGREJECT:
538851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		case BTSTAT_BADMSG:
539851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			cmd->result = (DRIVER_INVALID << 24);
540851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			/* fall through */
541851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
542851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		case BTSTAT_HAHARDWARE:
543851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		case BTSTAT_INVPHASE:
544851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		case BTSTAT_HATIMEOUT:
545851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		case BTSTAT_NORESPONSE:
546851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		case BTSTAT_DISCONNECT:
547851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		case BTSTAT_HASOFTWARE:
548851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		case BTSTAT_BUSFREE:
549851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		case BTSTAT_SENSFAILED:
550851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			cmd->result |= (DID_ERROR << 16);
551851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			break;
552851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
553851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		case BTSTAT_SENTRST:
554851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		case BTSTAT_RECVRST:
555851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		case BTSTAT_BUSRESET:
556851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			cmd->result = (DID_RESET << 16);
557851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			break;
558851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
559851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		case BTSTAT_ABORTQUEUE:
560851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			cmd->result = (DID_ABORT << 16);
561851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			break;
562851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
563851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		case BTSTAT_SCSIPARITY:
564851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			cmd->result = (DID_PARITY << 16);
565851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			break;
566851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
567851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		default:
568851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			cmd->result = (DID_ERROR << 16);
569851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			scmd_printk(KERN_DEBUG, cmd,
570851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria				    "Unknown completion status: 0x%x\n",
571851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria				    btstat);
572851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	}
573851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
574851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	dev_dbg(&cmd->device->sdev_gendev,
575851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		"cmd=%p %x ctx=%p result=0x%x status=0x%x,%x\n",
576851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		cmd, cmd->cmnd[0], ctx, cmd->result, btstat, sdstat);
577851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
578851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	cmd->scsi_done(cmd);
579851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
580851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
581851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria/*
582851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * barrier usage : Since the PVSCSI device is emulated, there could be cases
583851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * where we may want to serialize some accesses between the driver and the
584851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * emulation layer. We use compiler barriers instead of the more expensive
585851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * memory barriers because PVSCSI is only supported on X86 which has strong
586851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * memory access ordering.
587851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria */
588851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic void pvscsi_process_completion_ring(struct pvscsi_adapter *adapter)
589851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
590851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct PVSCSIRingsState *s = adapter->rings_state;
591851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct PVSCSIRingCmpDesc *ring = adapter->cmp_ring;
592851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	u32 cmp_entries = s->cmpNumEntriesLog2;
593851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
594851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	while (s->cmpConsIdx != s->cmpProdIdx) {
595851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		struct PVSCSIRingCmpDesc *e = ring + (s->cmpConsIdx &
596851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria						      MASK(cmp_entries));
597851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		/*
598851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		 * This barrier() ensures that *e is not dereferenced while
599851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		 * the device emulation still writes data into the slot.
600851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		 * Since the device emulation advances s->cmpProdIdx only after
601851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		 * updating the slot we want to check it first.
602851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		 */
603851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		barrier();
604851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		pvscsi_complete_request(adapter, e);
605851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		/*
606851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		 * This barrier() ensures that compiler doesn't reorder write
607851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		 * to s->cmpConsIdx before the read of (*e) inside
608851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		 * pvscsi_complete_request. Otherwise, device emulation may
609851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		 * overwrite *e before we had a chance to read it.
610851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		 */
611851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		barrier();
612851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		s->cmpConsIdx++;
613851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	}
614851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
615851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
616851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria/*
617851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * Translate a Linux SCSI request into a request ring entry.
618851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria */
619851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic int pvscsi_queue_ring(struct pvscsi_adapter *adapter,
620851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			     struct pvscsi_ctx *ctx, struct scsi_cmnd *cmd)
621851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
622851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct PVSCSIRingsState *s;
623851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct PVSCSIRingReqDesc *e;
624851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct scsi_device *sdev;
625851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	u32 req_entries;
626851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
627851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	s = adapter->rings_state;
628851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	sdev = cmd->device;
629851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	req_entries = s->reqNumEntriesLog2;
630851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
631851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	/*
632851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 * If this condition holds, we might have room on the request ring, but
633851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 * we might not have room on the completion ring for the response.
634851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 * However, we have already ruled out this possibility - we would not
635851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 * have successfully allocated a context if it were true, since we only
636851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 * have one context per request entry.  Check for it anyway, since it
637851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 * would be a serious bug.
638851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 */
639851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (s->reqProdIdx - s->cmpConsIdx >= 1 << req_entries) {
640851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		scmd_printk(KERN_ERR, cmd, "vmw_pvscsi: "
641851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			    "ring full: reqProdIdx=%d cmpConsIdx=%d\n",
642851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			    s->reqProdIdx, s->cmpConsIdx);
643851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		return -1;
644851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	}
645851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
646851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	e = adapter->req_ring + (s->reqProdIdx & MASK(req_entries));
647851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
648851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	e->bus    = sdev->channel;
649851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	e->target = sdev->id;
650851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	memset(e->lun, 0, sizeof(e->lun));
651851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	e->lun[1] = sdev->lun;
652851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
653851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (cmd->sense_buffer) {
654851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		ctx->sensePA = pci_map_single(adapter->dev, cmd->sense_buffer,
655851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria					      SCSI_SENSE_BUFFERSIZE,
656851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria					      PCI_DMA_FROMDEVICE);
657851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		e->senseAddr = ctx->sensePA;
658851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		e->senseLen = SCSI_SENSE_BUFFERSIZE;
659851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	} else {
660851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		e->senseLen  = 0;
661851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		e->senseAddr = 0;
662851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	}
663851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	e->cdbLen   = cmd->cmd_len;
664851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	e->vcpuHint = smp_processor_id();
665851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	memcpy(e->cdb, cmd->cmnd, e->cdbLen);
666851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
667851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	e->tag = SIMPLE_QUEUE_TAG;
668851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (sdev->tagged_supported &&
669851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	    (cmd->tag == HEAD_OF_QUEUE_TAG ||
670851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	     cmd->tag == ORDERED_QUEUE_TAG))
671851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		e->tag = cmd->tag;
672851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
673851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (cmd->sc_data_direction == DMA_FROM_DEVICE)
674851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		e->flags = PVSCSI_FLAG_CMD_DIR_TOHOST;
675851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	else if (cmd->sc_data_direction == DMA_TO_DEVICE)
676851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		e->flags = PVSCSI_FLAG_CMD_DIR_TODEVICE;
677851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	else if (cmd->sc_data_direction == DMA_NONE)
678851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		e->flags = PVSCSI_FLAG_CMD_DIR_NONE;
679851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	else
680851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		e->flags = 0;
681851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
682851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_map_buffers(adapter, ctx, cmd, e);
683851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
684851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	e->context = pvscsi_map_context(adapter, ctx);
685851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
686851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	barrier();
687851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
688851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	s->reqProdIdx++;
689851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
690851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	return 0;
691851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
692851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
693f281233d3eba15fb225d21ae2e228fd4553d824aJeff Garzikstatic int pvscsi_queue_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
694851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
695851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct Scsi_Host *host = cmd->device->host;
696851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct pvscsi_adapter *adapter = shost_priv(host);
697851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct pvscsi_ctx *ctx;
698851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	unsigned long flags;
699851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
700851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	spin_lock_irqsave(&adapter->hw_lock, flags);
701851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
702851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	ctx = pvscsi_acquire_context(adapter, cmd);
703851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (!ctx || pvscsi_queue_ring(adapter, ctx, cmd) != 0) {
704851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		if (ctx)
705851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			pvscsi_release_context(adapter, ctx);
706851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		spin_unlock_irqrestore(&adapter->hw_lock, flags);
707851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		return SCSI_MLQUEUE_HOST_BUSY;
708851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	}
709851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
710851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	cmd->scsi_done = done;
711851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
712851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	dev_dbg(&cmd->device->sdev_gendev,
713851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		"queued cmd %p, ctx %p, op=%x\n", cmd, ctx, cmd->cmnd[0]);
714851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
715851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	spin_unlock_irqrestore(&adapter->hw_lock, flags);
716851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
717851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_kick_io(adapter, cmd->cmnd[0]);
718851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
719851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	return 0;
720851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
721851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
722f281233d3eba15fb225d21ae2e228fd4553d824aJeff Garzikstatic DEF_SCSI_QCMD(pvscsi_queue)
723f281233d3eba15fb225d21ae2e228fd4553d824aJeff Garzik
724851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic int pvscsi_abort(struct scsi_cmnd *cmd)
725851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
726851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct pvscsi_adapter *adapter = shost_priv(cmd->device->host);
727851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct pvscsi_ctx *ctx;
728851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	unsigned long flags;
729851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
730851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	scmd_printk(KERN_DEBUG, cmd, "task abort on host %u, %p\n",
731851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		    adapter->host->host_no, cmd);
732851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
733851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	spin_lock_irqsave(&adapter->hw_lock, flags);
734851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
735851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	/*
736851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 * Poll the completion ring first - we might be trying to abort
737851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 * a command that is waiting to be dispatched in the completion ring.
738851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 */
739851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_process_completion_ring(adapter);
740851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
741851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	/*
742851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 * If there is no context for the command, it either already succeeded
743851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 * or else was never properly issued.  Not our problem.
744851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 */
745851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	ctx = pvscsi_find_context(adapter, cmd);
746851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (!ctx) {
747851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		scmd_printk(KERN_DEBUG, cmd, "Failed to abort cmd %p\n", cmd);
748851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		goto out;
749851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	}
750851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
751851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_abort_cmd(adapter, ctx);
752851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
753851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_process_completion_ring(adapter);
754851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
755851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariaout:
756851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	spin_unlock_irqrestore(&adapter->hw_lock, flags);
757851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	return SUCCESS;
758851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
759851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
760851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria/*
761851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * Abort all outstanding requests.  This is only safe to use if the completion
762851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * ring will never be walked again or the device has been reset, because it
763851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * destroys the 1-1 mapping between context field passed to emulation and our
764851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * request structure.
765851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria */
766851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic void pvscsi_reset_all(struct pvscsi_adapter *adapter)
767851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
768851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	unsigned i;
769851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
770851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	for (i = 0; i < adapter->req_depth; i++) {
771851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		struct pvscsi_ctx *ctx = &adapter->cmd_map[i];
772851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		struct scsi_cmnd *cmd = ctx->cmd;
773851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		if (cmd) {
774851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			scmd_printk(KERN_ERR, cmd,
775851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria				    "Forced reset on cmd %p\n", cmd);
776851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			pvscsi_unmap_buffers(adapter, ctx);
777851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			pvscsi_release_context(adapter, ctx);
778851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			cmd->result = (DID_RESET << 16);
779851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			cmd->scsi_done(cmd);
780851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		}
781851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	}
782851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
783851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
784851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic int pvscsi_host_reset(struct scsi_cmnd *cmd)
785851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
786851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct Scsi_Host *host = cmd->device->host;
787851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct pvscsi_adapter *adapter = shost_priv(host);
788851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	unsigned long flags;
789851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	bool use_msg;
790851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
791851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	scmd_printk(KERN_INFO, cmd, "SCSI Host reset\n");
792851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
793851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	spin_lock_irqsave(&adapter->hw_lock, flags);
794851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
795851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	use_msg = adapter->use_msg;
796851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
797851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (use_msg) {
798851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		adapter->use_msg = 0;
799851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		spin_unlock_irqrestore(&adapter->hw_lock, flags);
800851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
801851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		/*
802851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		 * Now that we know that the ISR won't add more work on the
803851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		 * workqueue we can safely flush any outstanding work.
804851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		 */
805851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		flush_workqueue(adapter->workqueue);
806851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		spin_lock_irqsave(&adapter->hw_lock, flags);
807851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	}
808851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
809851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	/*
810851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 * We're going to tear down the entire ring structure and set it back
811851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 * up, so stalling new requests until all completions are flushed and
812851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 * the rings are back in place.
813851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 */
814851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
815851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_process_request_ring(adapter);
816851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
817851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	ll_adapter_reset(adapter);
818851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
819851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	/*
820851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 * Now process any completions.  Note we do this AFTER adapter reset,
821851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 * which is strange, but stops races where completions get posted
822851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 * between processing the ring and issuing the reset.  The backend will
823851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 * not touch the ring memory after reset, so the immediately pre-reset
824851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 * completion ring state is still valid.
825851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 */
826851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_process_completion_ring(adapter);
827851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
828851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_reset_all(adapter);
829851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	adapter->use_msg = use_msg;
830851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_setup_all_rings(adapter);
831851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_unmask_intr(adapter);
832851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
833851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	spin_unlock_irqrestore(&adapter->hw_lock, flags);
834851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
835851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	return SUCCESS;
836851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
837851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
838851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic int pvscsi_bus_reset(struct scsi_cmnd *cmd)
839851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
840851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct Scsi_Host *host = cmd->device->host;
841851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct pvscsi_adapter *adapter = shost_priv(host);
842851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	unsigned long flags;
843851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
844851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	scmd_printk(KERN_INFO, cmd, "SCSI Bus reset\n");
845851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
846851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	/*
847851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 * We don't want to queue new requests for this bus after
848851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 * flushing all pending requests to emulation, since new
849851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 * requests could then sneak in during this bus reset phase,
850851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 * so take the lock now.
851851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 */
852851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	spin_lock_irqsave(&adapter->hw_lock, flags);
853851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
854851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_process_request_ring(adapter);
855851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	ll_bus_reset(adapter);
856851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_process_completion_ring(adapter);
857851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
858851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	spin_unlock_irqrestore(&adapter->hw_lock, flags);
859851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
860851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	return SUCCESS;
861851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
862851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
863851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic int pvscsi_device_reset(struct scsi_cmnd *cmd)
864851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
865851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct Scsi_Host *host = cmd->device->host;
866851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct pvscsi_adapter *adapter = shost_priv(host);
867851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	unsigned long flags;
868851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
869851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	scmd_printk(KERN_INFO, cmd, "SCSI device reset on scsi%u:%u\n",
870851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		    host->host_no, cmd->device->id);
871851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
872851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	/*
873851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 * We don't want to queue new requests for this device after flushing
874851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 * all pending requests to emulation, since new requests could then
875851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 * sneak in during this device reset phase, so take the lock now.
876851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 */
877851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	spin_lock_irqsave(&adapter->hw_lock, flags);
878851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
879851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_process_request_ring(adapter);
880851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	ll_device_reset(adapter, cmd->device->id);
881851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_process_completion_ring(adapter);
882851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
883851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	spin_unlock_irqrestore(&adapter->hw_lock, flags);
884851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
885851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	return SUCCESS;
886851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
887851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
888851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic struct scsi_host_template pvscsi_template;
889851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
890851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic const char *pvscsi_info(struct Scsi_Host *host)
891851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
892851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct pvscsi_adapter *adapter = shost_priv(host);
893851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	static char buf[256];
894851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
895851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	sprintf(buf, "VMware PVSCSI storage adapter rev %d, req/cmp/msg rings: "
896851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		"%u/%u/%u pages, cmd_per_lun=%u", adapter->rev,
897851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		adapter->req_pages, adapter->cmp_pages, adapter->msg_pages,
898851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		pvscsi_template.cmd_per_lun);
899851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
900851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	return buf;
901851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
902851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
903851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic struct scsi_host_template pvscsi_template = {
904851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	.module				= THIS_MODULE,
905851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	.name				= "VMware PVSCSI Host Adapter",
906851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	.proc_name			= "vmw_pvscsi",
907851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	.info				= pvscsi_info,
908851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	.queuecommand			= pvscsi_queue,
909851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	.this_id			= -1,
910851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	.sg_tablesize			= PVSCSI_MAX_NUM_SG_ENTRIES_PER_SEGMENT,
911851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	.dma_boundary			= UINT_MAX,
912851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	.max_sectors			= 0xffff,
913851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	.use_clustering			= ENABLE_CLUSTERING,
914851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	.eh_abort_handler		= pvscsi_abort,
915851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	.eh_device_reset_handler	= pvscsi_device_reset,
916851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	.eh_bus_reset_handler		= pvscsi_bus_reset,
917851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	.eh_host_reset_handler		= pvscsi_host_reset,
918851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria};
919851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
920851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic void pvscsi_process_msg(const struct pvscsi_adapter *adapter,
921851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			       const struct PVSCSIRingMsgDesc *e)
922851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
923851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct PVSCSIRingsState *s = adapter->rings_state;
924851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct Scsi_Host *host = adapter->host;
925851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct scsi_device *sdev;
926851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
927851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	printk(KERN_INFO "vmw_pvscsi: msg type: 0x%x - MSG RING: %u/%u (%u) \n",
928851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	       e->type, s->msgProdIdx, s->msgConsIdx, s->msgNumEntriesLog2);
929851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
930851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	BUILD_BUG_ON(PVSCSI_MSG_LAST != 2);
931851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
932851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (e->type == PVSCSI_MSG_DEV_ADDED) {
933851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		struct PVSCSIMsgDescDevStatusChanged *desc;
934851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		desc = (struct PVSCSIMsgDescDevStatusChanged *)e;
935851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
936851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		printk(KERN_INFO
937851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		       "vmw_pvscsi: msg: device added at scsi%u:%u:%u\n",
938851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		       desc->bus, desc->target, desc->lun[1]);
939851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
940851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		if (!scsi_host_get(host))
941851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			return;
942851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
943851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		sdev = scsi_device_lookup(host, desc->bus, desc->target,
944851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria					  desc->lun[1]);
945851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		if (sdev) {
946851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			printk(KERN_INFO "vmw_pvscsi: device already exists\n");
947851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			scsi_device_put(sdev);
948851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		} else
949851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			scsi_add_device(adapter->host, desc->bus,
950851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria					desc->target, desc->lun[1]);
951851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
952851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		scsi_host_put(host);
953851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	} else if (e->type == PVSCSI_MSG_DEV_REMOVED) {
954851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		struct PVSCSIMsgDescDevStatusChanged *desc;
955851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		desc = (struct PVSCSIMsgDescDevStatusChanged *)e;
956851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
957851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		printk(KERN_INFO
958851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		       "vmw_pvscsi: msg: device removed at scsi%u:%u:%u\n",
959851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		       desc->bus, desc->target, desc->lun[1]);
960851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
961851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		if (!scsi_host_get(host))
962851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			return;
963851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
964851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		sdev = scsi_device_lookup(host, desc->bus, desc->target,
965851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria					  desc->lun[1]);
966851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		if (sdev) {
967851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			scsi_remove_device(sdev);
968851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			scsi_device_put(sdev);
969851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		} else
970851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			printk(KERN_INFO
971851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			       "vmw_pvscsi: failed to lookup scsi%u:%u:%u\n",
972851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			       desc->bus, desc->target, desc->lun[1]);
973851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
974851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		scsi_host_put(host);
975851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	}
976851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
977851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
978851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic int pvscsi_msg_pending(const struct pvscsi_adapter *adapter)
979851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
980851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct PVSCSIRingsState *s = adapter->rings_state;
981851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
982851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	return s->msgProdIdx != s->msgConsIdx;
983851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
984851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
985851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic void pvscsi_process_msg_ring(const struct pvscsi_adapter *adapter)
986851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
987851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct PVSCSIRingsState *s = adapter->rings_state;
988851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct PVSCSIRingMsgDesc *ring = adapter->msg_ring;
989851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	u32 msg_entries = s->msgNumEntriesLog2;
990851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
991851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	while (pvscsi_msg_pending(adapter)) {
992851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		struct PVSCSIRingMsgDesc *e = ring + (s->msgConsIdx &
993851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria						      MASK(msg_entries));
994851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
995851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		barrier();
996851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		pvscsi_process_msg(adapter, e);
997851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		barrier();
998851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		s->msgConsIdx++;
999851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	}
1000851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
1001851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1002851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic void pvscsi_msg_workqueue_handler(struct work_struct *data)
1003851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
1004851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct pvscsi_adapter *adapter;
1005851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1006851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	adapter = container_of(data, struct pvscsi_adapter, work);
1007851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1008851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_process_msg_ring(adapter);
1009851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
1010851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1011851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic int pvscsi_setup_msg_workqueue(struct pvscsi_adapter *adapter)
1012851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
1013851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	char name[32];
1014851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1015851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (!pvscsi_use_msg)
1016851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		return 0;
1017851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1018851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_reg_write(adapter, PVSCSI_REG_OFFSET_COMMAND,
1019851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			 PVSCSI_CMD_SETUP_MSG_RING);
1020851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1021851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (pvscsi_reg_read(adapter, PVSCSI_REG_OFFSET_COMMAND_STATUS) == -1)
1022851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		return 0;
1023851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1024851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	snprintf(name, sizeof(name),
1025851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		 "vmw_pvscsi_wq_%u", adapter->host->host_no);
1026851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1027851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	adapter->workqueue = create_singlethread_workqueue(name);
1028851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (!adapter->workqueue) {
1029851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		printk(KERN_ERR "vmw_pvscsi: failed to create work queue\n");
1030851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		return 0;
1031851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	}
1032851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	INIT_WORK(&adapter->work, pvscsi_msg_workqueue_handler);
1033851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1034851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	return 1;
1035851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
1036851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1037851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic irqreturn_t pvscsi_isr(int irq, void *devp)
1038851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
1039851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct pvscsi_adapter *adapter = devp;
1040851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	int handled;
1041851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1042851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (adapter->use_msi || adapter->use_msix)
1043851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		handled = true;
1044851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	else {
1045851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		u32 val = pvscsi_read_intr_status(adapter);
1046851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		handled = (val & PVSCSI_INTR_ALL_SUPPORTED) != 0;
1047851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		if (handled)
1048851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			pvscsi_write_intr_status(devp, val);
1049851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	}
1050851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1051851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (handled) {
1052851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		unsigned long flags;
1053851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1054851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		spin_lock_irqsave(&adapter->hw_lock, flags);
1055851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1056851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		pvscsi_process_completion_ring(adapter);
1057851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		if (adapter->use_msg && pvscsi_msg_pending(adapter))
1058851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			queue_work(adapter->workqueue, &adapter->work);
1059851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1060851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		spin_unlock_irqrestore(&adapter->hw_lock, flags);
1061851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	}
1062851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1063851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	return IRQ_RETVAL(handled);
1064851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
1065851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1066851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic void pvscsi_free_sgls(const struct pvscsi_adapter *adapter)
1067851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
1068851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct pvscsi_ctx *ctx = adapter->cmd_map;
1069851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	unsigned i;
1070851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1071851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	for (i = 0; i < adapter->req_depth; ++i, ++ctx)
1072851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		free_pages((unsigned long)ctx->sgl, get_order(SGL_SIZE));
1073851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
1074851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1075d0e2ddff7c4b493acff50a9000564b67cbe7d676Dmitry Torokhovstatic int pvscsi_setup_msix(const struct pvscsi_adapter *adapter,
1076d0e2ddff7c4b493acff50a9000564b67cbe7d676Dmitry Torokhov			     unsigned int *irq)
1077851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
1078851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct msix_entry entry = { 0, PVSCSI_VECTOR_COMPLETION };
1079851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	int ret;
1080851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1081851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	ret = pci_enable_msix(adapter->dev, &entry, 1);
1082851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (ret)
1083851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		return ret;
1084851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1085851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	*irq = entry.vector;
1086851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1087851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	return 0;
1088851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
1089851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1090851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic void pvscsi_shutdown_intr(struct pvscsi_adapter *adapter)
1091851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
1092851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (adapter->irq) {
1093851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		free_irq(adapter->irq, adapter);
1094851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		adapter->irq = 0;
1095851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	}
1096851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (adapter->use_msi) {
1097851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		pci_disable_msi(adapter->dev);
1098851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		adapter->use_msi = 0;
1099851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	} else if (adapter->use_msix) {
1100851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		pci_disable_msix(adapter->dev);
1101851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		adapter->use_msix = 0;
1102851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	}
1103851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
1104851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1105851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic void pvscsi_release_resources(struct pvscsi_adapter *adapter)
1106851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
1107851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_shutdown_intr(adapter);
1108851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1109851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (adapter->workqueue)
1110851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		destroy_workqueue(adapter->workqueue);
1111851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1112851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (adapter->mmioBase)
1113851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		pci_iounmap(adapter->dev, adapter->mmioBase);
1114851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1115851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pci_release_regions(adapter->dev);
1116851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1117851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (adapter->cmd_map) {
1118851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		pvscsi_free_sgls(adapter);
1119851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		kfree(adapter->cmd_map);
1120851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	}
1121851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1122851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (adapter->rings_state)
1123851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		pci_free_consistent(adapter->dev, PAGE_SIZE,
1124851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria				    adapter->rings_state, adapter->ringStatePA);
1125851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1126851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (adapter->req_ring)
1127851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		pci_free_consistent(adapter->dev,
1128851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria				    adapter->req_pages * PAGE_SIZE,
1129851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria				    adapter->req_ring, adapter->reqRingPA);
1130851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1131851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (adapter->cmp_ring)
1132851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		pci_free_consistent(adapter->dev,
1133851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria				    adapter->cmp_pages * PAGE_SIZE,
1134851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria				    adapter->cmp_ring, adapter->cmpRingPA);
1135851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1136851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (adapter->msg_ring)
1137851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		pci_free_consistent(adapter->dev,
1138851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria				    adapter->msg_pages * PAGE_SIZE,
1139851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria				    adapter->msg_ring, adapter->msgRingPA);
1140851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
1141851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1142851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria/*
1143851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * Allocate scatter gather lists.
1144851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria *
1145851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * These are statically allocated.  Trying to be clever was not worth it.
1146851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria *
114742b2aa86c6670347a2a07e6d7af0e0ecc8fdbff9Justin P. Mattock * Dynamic allocation can fail, and we can't go deep into the memory
1148851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * allocator, since we're a SCSI driver, and trying too hard to allocate
1149851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * memory might generate disk I/O.  We also don't want to fail disk I/O
1150851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * in that case because we can't get an allocation - the I/O could be
1151851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * trying to swap out data to free memory.  Since that is pathological,
1152851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria * just use a statically allocated scatter list.
1153851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria *
1154851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria */
1155851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic int __devinit pvscsi_allocate_sg(struct pvscsi_adapter *adapter)
1156851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
1157851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct pvscsi_ctx *ctx;
1158851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	int i;
1159851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1160851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	ctx = adapter->cmd_map;
1161851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	BUILD_BUG_ON(sizeof(struct pvscsi_sg_list) > SGL_SIZE);
1162851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1163851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	for (i = 0; i < adapter->req_depth; ++i, ++ctx) {
1164851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		ctx->sgl = (void *)__get_free_pages(GFP_KERNEL,
1165851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria						    get_order(SGL_SIZE));
1166851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		ctx->sglPA = 0;
1167851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		BUG_ON(!IS_ALIGNED(((unsigned long)ctx->sgl), PAGE_SIZE));
1168851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		if (!ctx->sgl) {
1169851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			for (; i >= 0; --i, --ctx) {
1170851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria				free_pages((unsigned long)ctx->sgl,
1171851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria					   get_order(SGL_SIZE));
1172851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria				ctx->sgl = NULL;
1173851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			}
1174851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			return -ENOMEM;
1175851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		}
1176851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	}
1177851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1178851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	return 0;
1179851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
1180851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1181a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar/*
1182a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar * Query the device, fetch the config info and return the
1183a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar * maximum number of targets on the adapter. In case of
1184a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar * failure due to any reason return default i.e. 16.
1185a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar */
1186a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumarstatic u32 pvscsi_get_max_targets(struct pvscsi_adapter *adapter)
1187a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar{
1188a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	struct PVSCSICmdDescConfigCmd cmd;
1189a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	struct PVSCSIConfigPageHeader *header;
1190a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	struct device *dev;
1191a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	dma_addr_t configPagePA;
1192a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	void *config_page;
1193a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	u32 numPhys = 16;
1194a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar
1195a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	dev = pvscsi_dev(adapter);
1196a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	config_page = pci_alloc_consistent(adapter->dev, PAGE_SIZE,
1197a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar					   &configPagePA);
1198a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	if (!config_page) {
1199a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar		dev_warn(dev, "vmw_pvscsi: failed to allocate memory for config page\n");
1200a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar		goto exit;
1201a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	}
1202a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	BUG_ON(configPagePA & ~PAGE_MASK);
1203a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar
1204a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	/* Fetch config info from the device. */
1205a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	cmd.configPageAddress = ((u64)PVSCSI_CONFIG_CONTROLLER_ADDRESS) << 32;
1206a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	cmd.configPageNum = PVSCSI_CONFIG_PAGE_CONTROLLER;
1207a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	cmd.cmpAddr = configPagePA;
1208a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	cmd._pad = 0;
1209a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar
1210a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	/*
1211a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	 * Mark the completion page header with error values. If the device
1212a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	 * completes the command successfully, it sets the status values to
1213a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	 * indicate success.
1214a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	 */
1215a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	header = config_page;
1216a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	memset(header, 0, sizeof *header);
1217a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	header->hostStatus = BTSTAT_INVPARAM;
1218a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	header->scsiStatus = SDSTAT_CHECK;
1219a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar
1220a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	pvscsi_write_cmd_desc(adapter, PVSCSI_CMD_CONFIG, &cmd, sizeof cmd);
1221a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar
1222a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	if (header->hostStatus == BTSTAT_SUCCESS &&
1223a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	    header->scsiStatus == SDSTAT_GOOD) {
1224a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar		struct PVSCSIConfigPageController *config;
1225a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar
1226a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar		config = config_page;
1227a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar		numPhys = config->numPhys;
1228a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	} else
1229a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar		dev_warn(dev, "vmw_pvscsi: PVSCSI_CMD_CONFIG failed. hostStatus = 0x%x, scsiStatus = 0x%x\n",
1230a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar			 header->hostStatus, header->scsiStatus);
1231a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	pci_free_consistent(adapter->dev, PAGE_SIZE, config_page, configPagePA);
1232a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumarexit:
1233a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	return numPhys;
1234a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar}
1235a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar
1236851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic int __devinit pvscsi_probe(struct pci_dev *pdev,
1237851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria				  const struct pci_device_id *id)
1238851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
1239851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct pvscsi_adapter *adapter;
1240851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct Scsi_Host *host;
1241a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	struct device *dev;
1242851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	unsigned int i;
1243851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	unsigned long flags = 0;
1244851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	int error;
1245851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1246851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	error = -ENODEV;
1247851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1248851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (pci_enable_device(pdev))
1249851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		return error;
1250851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1251851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) == 0 &&
1252851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	    pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)) == 0) {
1253851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		printk(KERN_INFO "vmw_pvscsi: using 64bit dma\n");
1254851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	} else if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) == 0 &&
1255851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		   pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)) == 0) {
1256851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		printk(KERN_INFO "vmw_pvscsi: using 32bit dma\n");
1257851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	} else {
1258851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		printk(KERN_ERR "vmw_pvscsi: failed to set DMA mask\n");
1259851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		goto out_disable_device;
1260851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	}
1261851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1262851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_template.can_queue =
1263851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		min(PVSCSI_MAX_NUM_PAGES_REQ_RING, pvscsi_ring_pages) *
1264851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE;
1265851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_template.cmd_per_lun =
1266851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		min(pvscsi_template.can_queue, pvscsi_cmd_per_lun);
1267851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	host = scsi_host_alloc(&pvscsi_template, sizeof(struct pvscsi_adapter));
1268851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (!host) {
1269851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		printk(KERN_ERR "vmw_pvscsi: failed to allocate host\n");
1270851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		goto out_disable_device;
1271851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	}
1272851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1273851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	adapter = shost_priv(host);
1274851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	memset(adapter, 0, sizeof(*adapter));
1275851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	adapter->dev  = pdev;
1276851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	adapter->host = host;
1277851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1278851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	spin_lock_init(&adapter->hw_lock);
1279851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1280851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	host->max_channel = 0;
1281851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	host->max_id      = 16;
1282851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	host->max_lun     = 1;
1283851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	host->max_cmd_len = 16;
1284851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1285851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	adapter->rev = pdev->revision;
1286851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1287851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (pci_request_regions(pdev, "vmw_pvscsi")) {
1288851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		printk(KERN_ERR "vmw_pvscsi: pci memory selection failed\n");
1289851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		goto out_free_host;
1290851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	}
1291851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1292851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
1293851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		if ((pci_resource_flags(pdev, i) & PCI_BASE_ADDRESS_SPACE_IO))
1294851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			continue;
1295851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1296851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		if (pci_resource_len(pdev, i) < PVSCSI_MEM_SPACE_SIZE)
1297851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			continue;
1298851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1299851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		break;
1300851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	}
1301851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1302851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (i == DEVICE_COUNT_RESOURCE) {
1303851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		printk(KERN_ERR
1304851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		       "vmw_pvscsi: adapter has no suitable MMIO region\n");
1305851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		goto out_release_resources;
1306851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	}
1307851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1308851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	adapter->mmioBase = pci_iomap(pdev, i, PVSCSI_MEM_SPACE_SIZE);
1309851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1310851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (!adapter->mmioBase) {
1311851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		printk(KERN_ERR
1312851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		       "vmw_pvscsi: can't iomap for BAR %d memsize %lu\n",
1313851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		       i, PVSCSI_MEM_SPACE_SIZE);
1314851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		goto out_release_resources;
1315851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	}
1316851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1317851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pci_set_master(pdev);
1318851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pci_set_drvdata(pdev, host);
1319851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1320851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	ll_adapter_reset(adapter);
1321851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1322851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	adapter->use_msg = pvscsi_setup_msg_workqueue(adapter);
1323851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1324851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	error = pvscsi_allocate_rings(adapter);
1325851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (error) {
1326851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		printk(KERN_ERR "vmw_pvscsi: unable to allocate ring memory\n");
1327851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		goto out_release_resources;
1328851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	}
1329851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1330851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	/*
1331a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	 * Ask the device for max number of targets.
1332a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	 */
1333a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	host->max_id = pvscsi_get_max_targets(adapter);
1334a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	dev = pvscsi_dev(adapter);
1335a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	dev_info(dev, "vmw_pvscsi: host->max_id: %u\n", host->max_id);
1336a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar
1337a93107355d2d4557e7e19ea1724bdb710268cd34Arvind Kumar	/*
1338851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 * From this point on we should reset the adapter if anything goes
1339851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 * wrong.
1340851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	 */
1341851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_setup_all_rings(adapter);
1342851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1343851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	adapter->cmd_map = kcalloc(adapter->req_depth,
1344851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria				   sizeof(struct pvscsi_ctx), GFP_KERNEL);
1345851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (!adapter->cmd_map) {
1346851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		printk(KERN_ERR "vmw_pvscsi: failed to allocate memory.\n");
1347851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		error = -ENOMEM;
1348851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		goto out_reset_adapter;
1349851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	}
1350851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1351851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	INIT_LIST_HEAD(&adapter->cmd_pool);
1352851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	for (i = 0; i < adapter->req_depth; i++) {
1353851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		struct pvscsi_ctx *ctx = adapter->cmd_map + i;
1354851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		list_add(&ctx->list, &adapter->cmd_pool);
1355851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	}
1356851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1357851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	error = pvscsi_allocate_sg(adapter);
1358851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (error) {
1359851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		printk(KERN_ERR "vmw_pvscsi: unable to allocate s/g table\n");
1360851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		goto out_reset_adapter;
1361851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	}
1362851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1363851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (!pvscsi_disable_msix &&
1364851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	    pvscsi_setup_msix(adapter, &adapter->irq) == 0) {
1365851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		printk(KERN_INFO "vmw_pvscsi: using MSI-X\n");
1366851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		adapter->use_msix = 1;
1367851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	} else if (!pvscsi_disable_msi && pci_enable_msi(pdev) == 0) {
1368851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		printk(KERN_INFO "vmw_pvscsi: using MSI\n");
1369851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		adapter->use_msi = 1;
1370851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		adapter->irq = pdev->irq;
1371851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	} else {
1372851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		printk(KERN_INFO "vmw_pvscsi: using INTx\n");
1373851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		adapter->irq = pdev->irq;
1374851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		flags = IRQF_SHARED;
1375851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	}
1376851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1377851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	error = request_irq(adapter->irq, pvscsi_isr, flags,
1378851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria			    "vmw_pvscsi", adapter);
1379851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (error) {
1380851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		printk(KERN_ERR
1381851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		       "vmw_pvscsi: unable to request IRQ: %d\n", error);
1382851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		adapter->irq = 0;
1383851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		goto out_reset_adapter;
1384851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	}
1385851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1386851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	error = scsi_add_host(host, &pdev->dev);
1387851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (error) {
1388851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		printk(KERN_ERR
1389851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		       "vmw_pvscsi: scsi_add_host failed: %d\n", error);
1390851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		goto out_reset_adapter;
1391851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	}
1392851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1393851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	dev_info(&pdev->dev, "VMware PVSCSI rev %d host #%u\n",
1394851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		 adapter->rev, host->host_no);
1395851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1396851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_unmask_intr(adapter);
1397851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1398851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	scsi_scan_host(host);
1399851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1400851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	return 0;
1401851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1402851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariaout_reset_adapter:
1403851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	ll_adapter_reset(adapter);
1404851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariaout_release_resources:
1405851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_release_resources(adapter);
1406851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariaout_free_host:
1407851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	scsi_host_put(host);
1408851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariaout_disable_device:
1409851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pci_set_drvdata(pdev, NULL);
1410851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pci_disable_device(pdev);
1411851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1412851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	return error;
1413851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
1414851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1415851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic void __pvscsi_shutdown(struct pvscsi_adapter *adapter)
1416851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
1417851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_mask_intr(adapter);
1418851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1419851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	if (adapter->workqueue)
1420851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		flush_workqueue(adapter->workqueue);
1421851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1422851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_shutdown_intr(adapter);
1423851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1424851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_process_request_ring(adapter);
1425851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_process_completion_ring(adapter);
1426851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	ll_adapter_reset(adapter);
1427851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
1428851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1429851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic void pvscsi_shutdown(struct pci_dev *dev)
1430851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
1431851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct Scsi_Host *host = pci_get_drvdata(dev);
1432851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct pvscsi_adapter *adapter = shost_priv(host);
1433851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1434851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	__pvscsi_shutdown(adapter);
1435851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
1436851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1437851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic void pvscsi_remove(struct pci_dev *pdev)
1438851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
1439851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct Scsi_Host *host = pci_get_drvdata(pdev);
1440851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	struct pvscsi_adapter *adapter = shost_priv(host);
1441851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1442851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	scsi_remove_host(host);
1443851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1444851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	__pvscsi_shutdown(adapter);
1445851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pvscsi_release_resources(adapter);
1446851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1447851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	scsi_host_put(host);
1448851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1449851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pci_set_drvdata(pdev, NULL);
1450851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pci_disable_device(pdev);
1451851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
1452851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1453851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic struct pci_driver pvscsi_pci_driver = {
1454851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	.name		= "vmw_pvscsi",
1455851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	.id_table	= pvscsi_pci_tbl,
1456851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	.probe		= pvscsi_probe,
1457851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	.remove		= __devexit_p(pvscsi_remove),
1458851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	.shutdown       = pvscsi_shutdown,
1459851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria};
1460851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1461851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic int __init pvscsi_init(void)
1462851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
1463851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pr_info("%s - version %s\n",
1464851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria		PVSCSI_LINUX_DRIVER_DESC, PVSCSI_DRIVER_VERSION_STRING);
1465851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	return pci_register_driver(&pvscsi_pci_driver);
1466851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
1467851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1468851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariastatic void __exit pvscsi_exit(void)
1469851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria{
1470851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria	pci_unregister_driver(&pvscsi_pci_driver);
1471851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria}
1472851b164231d1117673aa44c00c7622e48b7dfcf4Alok Kataria
1473851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariamodule_init(pvscsi_init);
1474851b164231d1117673aa44c00c7622e48b7dfcf4Alok Katariamodule_exit(pvscsi_exit);
1475