ibmvscsi: driver enablement for CMO
Enable the driver to function in a Cooperative Memory Overcommitment (CMO) environment. The following changes are made to enable the driver for CMO: * DMA mapping errors will not result in error messages if entitlement has been exceeded and resources were not available. * The driver has a get_desired_dma function defined to function in a CMO environment. It will indicate how much IO memory it would like to function. Signed-off-by: Robert Jennings <rcj@linux.vnet.ibm.com> Acked by: Brian King <brking@linux.vnet.ibm.com> Acked-by: Paul Mackerras <paulus@samba.org> Acked-by: James Bottomley <James.Bottomley@HansenPartnership.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
This commit is contained in:
committed by
Benjamin Herrenschmidt
parent
1096d63d8e
commit
7912a0ac59
@@ -72,6 +72,7 @@
|
|||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <asm/firmware.h>
|
#include <asm/firmware.h>
|
||||||
#include <asm/vio.h>
|
#include <asm/vio.h>
|
||||||
|
#include <asm/firmware.h>
|
||||||
#include <scsi/scsi.h>
|
#include <scsi/scsi.h>
|
||||||
#include <scsi/scsi_cmnd.h>
|
#include <scsi/scsi_cmnd.h>
|
||||||
#include <scsi/scsi_host.h>
|
#include <scsi/scsi_host.h>
|
||||||
@@ -426,8 +427,10 @@ static int map_sg_data(struct scsi_cmnd *cmd,
|
|||||||
SG_ALL * sizeof(struct srp_direct_buf),
|
SG_ALL * sizeof(struct srp_direct_buf),
|
||||||
&evt_struct->ext_list_token, 0);
|
&evt_struct->ext_list_token, 0);
|
||||||
if (!evt_struct->ext_list) {
|
if (!evt_struct->ext_list) {
|
||||||
sdev_printk(KERN_ERR, cmd->device,
|
if (!firmware_has_feature(FW_FEATURE_CMO))
|
||||||
"Can't allocate memory for indirect table\n");
|
sdev_printk(KERN_ERR, cmd->device,
|
||||||
|
"Can't allocate memory "
|
||||||
|
"for indirect table\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -743,7 +746,9 @@ static int ibmvscsi_queuecommand(struct scsi_cmnd *cmnd,
|
|||||||
srp_cmd->lun = ((u64) lun) << 48;
|
srp_cmd->lun = ((u64) lun) << 48;
|
||||||
|
|
||||||
if (!map_data_for_srp_cmd(cmnd, evt_struct, srp_cmd, hostdata->dev)) {
|
if (!map_data_for_srp_cmd(cmnd, evt_struct, srp_cmd, hostdata->dev)) {
|
||||||
sdev_printk(KERN_ERR, cmnd->device, "couldn't convert cmd to srp_cmd\n");
|
if (!firmware_has_feature(FW_FEATURE_CMO))
|
||||||
|
sdev_printk(KERN_ERR, cmnd->device,
|
||||||
|
"couldn't convert cmd to srp_cmd\n");
|
||||||
free_event_struct(&hostdata->pool, evt_struct);
|
free_event_struct(&hostdata->pool, evt_struct);
|
||||||
return SCSI_MLQUEUE_HOST_BUSY;
|
return SCSI_MLQUEUE_HOST_BUSY;
|
||||||
}
|
}
|
||||||
@@ -855,7 +860,10 @@ static void send_mad_adapter_info(struct ibmvscsi_host_data *hostdata)
|
|||||||
DMA_BIDIRECTIONAL);
|
DMA_BIDIRECTIONAL);
|
||||||
|
|
||||||
if (dma_mapping_error(req->buffer)) {
|
if (dma_mapping_error(req->buffer)) {
|
||||||
dev_err(hostdata->dev, "Unable to map request_buffer for adapter_info!\n");
|
if (!firmware_has_feature(FW_FEATURE_CMO))
|
||||||
|
dev_err(hostdata->dev,
|
||||||
|
"Unable to map request_buffer for "
|
||||||
|
"adapter_info!\n");
|
||||||
free_event_struct(&hostdata->pool, evt_struct);
|
free_event_struct(&hostdata->pool, evt_struct);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1400,7 +1408,9 @@ static int ibmvscsi_do_host_config(struct ibmvscsi_host_data *hostdata,
|
|||||||
DMA_BIDIRECTIONAL);
|
DMA_BIDIRECTIONAL);
|
||||||
|
|
||||||
if (dma_mapping_error(host_config->buffer)) {
|
if (dma_mapping_error(host_config->buffer)) {
|
||||||
dev_err(hostdata->dev, "dma_mapping error getting host config\n");
|
if (!firmware_has_feature(FW_FEATURE_CMO))
|
||||||
|
dev_err(hostdata->dev,
|
||||||
|
"dma_mapping error getting host config\n");
|
||||||
free_event_struct(&hostdata->pool, evt_struct);
|
free_event_struct(&hostdata->pool, evt_struct);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -1604,7 +1614,7 @@ static struct scsi_host_template driver_template = {
|
|||||||
.eh_host_reset_handler = ibmvscsi_eh_host_reset_handler,
|
.eh_host_reset_handler = ibmvscsi_eh_host_reset_handler,
|
||||||
.slave_configure = ibmvscsi_slave_configure,
|
.slave_configure = ibmvscsi_slave_configure,
|
||||||
.change_queue_depth = ibmvscsi_change_queue_depth,
|
.change_queue_depth = ibmvscsi_change_queue_depth,
|
||||||
.cmd_per_lun = 16,
|
.cmd_per_lun = IBMVSCSI_CMDS_PER_LUN_DEFAULT,
|
||||||
.can_queue = IBMVSCSI_MAX_REQUESTS_DEFAULT,
|
.can_queue = IBMVSCSI_MAX_REQUESTS_DEFAULT,
|
||||||
.this_id = -1,
|
.this_id = -1,
|
||||||
.sg_tablesize = SG_ALL,
|
.sg_tablesize = SG_ALL,
|
||||||
@@ -1612,6 +1622,26 @@ static struct scsi_host_template driver_template = {
|
|||||||
.shost_attrs = ibmvscsi_attrs,
|
.shost_attrs = ibmvscsi_attrs,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ibmvscsi_get_desired_dma - Calculate IO memory desired by the driver
|
||||||
|
*
|
||||||
|
* @vdev: struct vio_dev for the device whose desired IO mem is to be returned
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
* Number of bytes of IO data the driver will need to perform well.
|
||||||
|
*/
|
||||||
|
static unsigned long ibmvscsi_get_desired_dma(struct vio_dev *vdev)
|
||||||
|
{
|
||||||
|
/* iu_storage data allocated in initialize_event_pool */
|
||||||
|
unsigned long desired_io = max_requests * sizeof(union viosrp_iu);
|
||||||
|
|
||||||
|
/* add io space for sg data */
|
||||||
|
desired_io += (IBMVSCSI_MAX_SECTORS_DEFAULT *
|
||||||
|
IBMVSCSI_CMDS_PER_LUN_DEFAULT);
|
||||||
|
|
||||||
|
return desired_io;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by bus code for each adapter
|
* Called by bus code for each adapter
|
||||||
*/
|
*/
|
||||||
@@ -1641,7 +1671,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id)
|
|||||||
hostdata->host = host;
|
hostdata->host = host;
|
||||||
hostdata->dev = dev;
|
hostdata->dev = dev;
|
||||||
atomic_set(&hostdata->request_limit, -1);
|
atomic_set(&hostdata->request_limit, -1);
|
||||||
hostdata->host->max_sectors = 32 * 8; /* default max I/O 32 pages */
|
hostdata->host->max_sectors = IBMVSCSI_MAX_SECTORS_DEFAULT;
|
||||||
|
|
||||||
rc = ibmvscsi_ops->init_crq_queue(&hostdata->queue, hostdata, max_requests);
|
rc = ibmvscsi_ops->init_crq_queue(&hostdata->queue, hostdata, max_requests);
|
||||||
if (rc != 0 && rc != H_RESOURCE) {
|
if (rc != 0 && rc != H_RESOURCE) {
|
||||||
@@ -1735,6 +1765,7 @@ static struct vio_driver ibmvscsi_driver = {
|
|||||||
.id_table = ibmvscsi_device_table,
|
.id_table = ibmvscsi_device_table,
|
||||||
.probe = ibmvscsi_probe,
|
.probe = ibmvscsi_probe,
|
||||||
.remove = ibmvscsi_remove,
|
.remove = ibmvscsi_remove,
|
||||||
|
.get_desired_dma = ibmvscsi_get_desired_dma,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "ibmvscsi",
|
.name = "ibmvscsi",
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
|
@@ -45,6 +45,8 @@ struct Scsi_Host;
|
|||||||
#define MAX_INDIRECT_BUFS 10
|
#define MAX_INDIRECT_BUFS 10
|
||||||
|
|
||||||
#define IBMVSCSI_MAX_REQUESTS_DEFAULT 100
|
#define IBMVSCSI_MAX_REQUESTS_DEFAULT 100
|
||||||
|
#define IBMVSCSI_CMDS_PER_LUN_DEFAULT 16
|
||||||
|
#define IBMVSCSI_MAX_SECTORS_DEFAULT 256 /* 32 * 8 = default max I/O 32 pages */
|
||||||
#define IBMVSCSI_MAX_CMDS_PER_LUN 64
|
#define IBMVSCSI_MAX_CMDS_PER_LUN 64
|
||||||
|
|
||||||
/* ------------------------------------------------------------
|
/* ------------------------------------------------------------
|
||||||
|
Reference in New Issue
Block a user