summaryrefslogtreecommitdiff
path: root/drivers/scsi/vmw_pvscsi.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2012-04-14 13:18:27 +0200
committerIngo Molnar <mingo@kernel.org>2012-04-14 13:19:04 +0200
commit6ac1ef482d7ae0c690f1640bf6eb818ff9a2d91e (patch)
tree021cc9f6b477146fcebe6f3be4752abfa2ba18a9 /drivers/scsi/vmw_pvscsi.c
parent682968e0c425c60f0dde37977e5beb2b12ddc4cc (diff)
parenta385ec4f11bdcf81af094c03e2444ee9b7fad2e5 (diff)
Merge branch 'perf/core' into perf/uprobes
Merge in latest upstream (and the latest perf development tree), to prepare for tooling changes, and also to pick up v3.4 MM changes that the uprobes code needs to take care of. Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'drivers/scsi/vmw_pvscsi.c')
-rw-r--r--drivers/scsi/vmw_pvscsi.c65
1 files changed, 64 insertions, 1 deletions
diff --git a/drivers/scsi/vmw_pvscsi.c b/drivers/scsi/vmw_pvscsi.c
index 7264116185d5..4411d4224401 100644
--- a/drivers/scsi/vmw_pvscsi.c
+++ b/drivers/scsi/vmw_pvscsi.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * Maintained by: Alok N Kataria <akataria@vmware.com>
+ * Maintained by: Arvind Kumar <arvindkumar@vmware.com>
*
*/
@@ -1178,11 +1178,67 @@ static int __devinit pvscsi_allocate_sg(struct pvscsi_adapter *adapter)
return 0;
}
+/*
+ * Query the device, fetch the config info and return the
+ * maximum number of targets on the adapter. In case of
+ * failure due to any reason return default i.e. 16.
+ */
+static u32 pvscsi_get_max_targets(struct pvscsi_adapter *adapter)
+{
+ struct PVSCSICmdDescConfigCmd cmd;
+ struct PVSCSIConfigPageHeader *header;
+ struct device *dev;
+ dma_addr_t configPagePA;
+ void *config_page;
+ u32 numPhys = 16;
+
+ dev = pvscsi_dev(adapter);
+ config_page = pci_alloc_consistent(adapter->dev, PAGE_SIZE,
+ &configPagePA);
+ if (!config_page) {
+ dev_warn(dev, "vmw_pvscsi: failed to allocate memory for config page\n");
+ goto exit;
+ }
+ BUG_ON(configPagePA & ~PAGE_MASK);
+
+ /* Fetch config info from the device. */
+ cmd.configPageAddress = ((u64)PVSCSI_CONFIG_CONTROLLER_ADDRESS) << 32;
+ cmd.configPageNum = PVSCSI_CONFIG_PAGE_CONTROLLER;
+ cmd.cmpAddr = configPagePA;
+ cmd._pad = 0;
+
+ /*
+ * Mark the completion page header with error values. If the device
+ * completes the command successfully, it sets the status values to
+ * indicate success.
+ */
+ header = config_page;
+ memset(header, 0, sizeof *header);
+ header->hostStatus = BTSTAT_INVPARAM;
+ header->scsiStatus = SDSTAT_CHECK;
+
+ pvscsi_write_cmd_desc(adapter, PVSCSI_CMD_CONFIG, &cmd, sizeof cmd);
+
+ if (header->hostStatus == BTSTAT_SUCCESS &&
+ header->scsiStatus == SDSTAT_GOOD) {
+ struct PVSCSIConfigPageController *config;
+
+ config = config_page;
+ numPhys = config->numPhys;
+ } else
+ dev_warn(dev, "vmw_pvscsi: PVSCSI_CMD_CONFIG failed. hostStatus = 0x%x, scsiStatus = 0x%x\n",
+ header->hostStatus, header->scsiStatus);
+ pci_free_consistent(adapter->dev, PAGE_SIZE, config_page, configPagePA);
+exit:
+ return numPhys;
+}
+
static int __devinit pvscsi_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
struct pvscsi_adapter *adapter;
struct Scsi_Host *host;
+ struct device *dev;
unsigned int i;
unsigned long flags = 0;
int error;
@@ -1272,6 +1328,13 @@ static int __devinit pvscsi_probe(struct pci_dev *pdev,
}
/*
+ * Ask the device for max number of targets.
+ */
+ host->max_id = pvscsi_get_max_targets(adapter);
+ dev = pvscsi_dev(adapter);
+ dev_info(dev, "vmw_pvscsi: host->max_id: %u\n", host->max_id);
+
+ /*
* From this point on we should reset the adapter if anything goes
* wrong.
*/