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