summaryrefslogtreecommitdiff
path: root/drivers/scsi/pmcraid.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/pmcraid.c')
-rw-r--r--drivers/scsi/pmcraid.c1441
1 files changed, 374 insertions, 1067 deletions
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c
index 1eb7b0280a45..33f403e307eb 100644
--- a/drivers/scsi/pmcraid.c
+++ b/drivers/scsi/pmcraid.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* pmcraid.c -- driver for PMC Sierra MaxRAID controller adapters
*
@@ -5,22 +6,6 @@
* PMC-Sierra Inc
*
* Copyright (C) 2008, 2009 PMC Sierra Inc
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- * USA
- *
*/
#include <linux/fs.h>
#include <linux/init.h>
@@ -45,6 +30,7 @@
#include <asm/processor.h>
#include <linux/libata.h>
#include <linux/mutex.h>
+#include <linux/ktime.h>
#include <scsi/scsi.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_device.h>
@@ -75,8 +61,10 @@ static atomic_t pmcraid_adapter_count = ATOMIC_INIT(0);
* pmcraid_minor - minor number(s) to use
*/
static unsigned int pmcraid_major;
-static struct class *pmcraid_class;
-DECLARE_BITMAP(pmcraid_minor, PMCRAID_MAX_ADAPTERS);
+static const struct class pmcraid_class = {
+ .name = PMCRAID_DEVFILE,
+};
+static DECLARE_BITMAP(pmcraid_minor, PMCRAID_MAX_ADAPTERS);
/*
* Module parameters
@@ -125,7 +113,7 @@ static struct pmcraid_chip_details pmcraid_chip_cfg[] = {
/*
* PCI device ids supported by pmcraid driver
*/
-static struct pci_device_id pmcraid_pci_table[] = {
+static const struct pci_device_id pmcraid_pci_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_PMC, PCI_DEVICE_ID_PMC_MAXRAID),
0, 0, (kernel_ulong_t)&pmcraid_chip_cfg[0]
},
@@ -137,7 +125,7 @@ MODULE_DEVICE_TABLE(pci, pmcraid_pci_table);
/**
- * pmcraid_slave_alloc - Prepare for commands to a device
+ * pmcraid_sdev_init - Prepare for commands to a device
* @scsi_dev: scsi device struct
*
* This function is called by mid-layer prior to sending any command to the new
@@ -148,7 +136,7 @@ MODULE_DEVICE_TABLE(pci, pmcraid_pci_table);
* Return value:
* 0 on success / -ENXIO if device does not exist
*/
-static int pmcraid_slave_alloc(struct scsi_device *scsi_dev)
+static int pmcraid_sdev_init(struct scsi_device *scsi_dev)
{
struct pmcraid_resource_entry *temp, *res = NULL;
struct pmcraid_instance *pinstance;
@@ -174,7 +162,7 @@ static int pmcraid_slave_alloc(struct scsi_device *scsi_dev)
if (fw_version <= PMCRAID_FW_VERSION_1)
target = temp->cfg_entry.unique_flags1;
else
- target = temp->cfg_entry.array_id & 0xFF;
+ target = le16_to_cpu(temp->cfg_entry.array_id) & 0xFF;
if (target > PMCRAID_MAX_VSET_TARGETS)
continue;
@@ -209,8 +197,9 @@ static int pmcraid_slave_alloc(struct scsi_device *scsi_dev)
}
/**
- * pmcraid_slave_configure - Configures a SCSI device
+ * pmcraid_sdev_configure - Configures a SCSI device
* @scsi_dev: scsi device struct
+ * @lim: queue limits
*
* This function is executed by SCSI mid layer just after a device is first
* scanned (i.e. it has responded to an INQUIRY). For VSET resources, the
@@ -221,7 +210,8 @@ static int pmcraid_slave_alloc(struct scsi_device *scsi_dev)
* Return value:
* 0 on success
*/
-static int pmcraid_slave_configure(struct scsi_device *scsi_dev)
+static int pmcraid_sdev_configure(struct scsi_device *scsi_dev,
+ struct queue_limits *lim)
{
struct pmcraid_resource_entry *res = scsi_dev->hostdata;
@@ -237,7 +227,7 @@ static int pmcraid_slave_configure(struct scsi_device *scsi_dev)
scsi_dev->host->unique_id,
scsi_dev->channel,
scsi_dev->id,
- scsi_dev->lun);
+ (u8)scsi_dev->lun);
if (RES_IS_GSCSI(res->cfg_entry)) {
scsi_dev->allow_restart = 1;
@@ -245,35 +235,30 @@ static int pmcraid_slave_configure(struct scsi_device *scsi_dev)
scsi_dev->allow_restart = 1;
blk_queue_rq_timeout(scsi_dev->request_queue,
PMCRAID_VSET_IO_TIMEOUT);
- blk_queue_max_hw_sectors(scsi_dev->request_queue,
- PMCRAID_VSET_MAX_SECTORS);
+ lim->max_hw_sectors = PMCRAID_VSET_MAX_SECTORS;
}
- if (scsi_dev->tagged_supported &&
- (RES_IS_GSCSI(res->cfg_entry) || RES_IS_VSET(res->cfg_entry))) {
- scsi_activate_tcq(scsi_dev, scsi_dev->queue_depth);
- scsi_adjust_queue_depth(scsi_dev, MSG_SIMPLE_TAG,
- scsi_dev->host->cmd_per_lun);
- } else {
- scsi_adjust_queue_depth(scsi_dev, 0,
- scsi_dev->host->cmd_per_lun);
- }
+ /*
+ * We never want to report TCQ support for these types of devices.
+ */
+ if (!RES_IS_GSCSI(res->cfg_entry) && !RES_IS_VSET(res->cfg_entry))
+ scsi_dev->tagged_supported = 0;
return 0;
}
/**
- * pmcraid_slave_destroy - Unconfigure a SCSI device before removing it
+ * pmcraid_sdev_destroy - Unconfigure a SCSI device before removing it
*
* @scsi_dev: scsi device struct
*
* This is called by mid-layer before removing a device. Pointer assignments
- * done in pmcraid_slave_alloc will be reset to NULL here.
+ * done in pmcraid_sdev_init will be reset to NULL here.
*
* Return value
* none
*/
-static void pmcraid_slave_destroy(struct scsi_device *scsi_dev)
+static void pmcraid_sdev_destroy(struct scsi_device *scsi_dev)
{
struct pmcraid_resource_entry *res;
@@ -289,55 +274,18 @@ static void pmcraid_slave_destroy(struct scsi_device *scsi_dev)
* pmcraid_change_queue_depth - Change the device's queue depth
* @scsi_dev: scsi device struct
* @depth: depth to set
- * @reason: calling context
*
* Return value
* actual depth set
*/
-static int pmcraid_change_queue_depth(struct scsi_device *scsi_dev, int depth,
- int reason)
+static int pmcraid_change_queue_depth(struct scsi_device *scsi_dev, int depth)
{
- if (reason != SCSI_QDEPTH_DEFAULT)
- return -EOPNOTSUPP;
-
if (depth > PMCRAID_MAX_CMD_PER_LUN)
depth = PMCRAID_MAX_CMD_PER_LUN;
-
- scsi_adjust_queue_depth(scsi_dev, scsi_get_tag_type(scsi_dev), depth);
-
- return scsi_dev->queue_depth;
+ return scsi_change_queue_depth(scsi_dev, depth);
}
/**
- * pmcraid_change_queue_type - Change the device's queue type
- * @scsi_dev: scsi device struct
- * @tag: type of tags to use
- *
- * Return value:
- * actual queue type set
- */
-static int pmcraid_change_queue_type(struct scsi_device *scsi_dev, int tag)
-{
- struct pmcraid_resource_entry *res;
-
- res = (struct pmcraid_resource_entry *)scsi_dev->hostdata;
-
- if ((res) && scsi_dev->tagged_supported &&
- (RES_IS_GSCSI(res->cfg_entry) || RES_IS_VSET(res->cfg_entry))) {
- scsi_set_tag_type(scsi_dev, tag);
-
- if (tag)
- scsi_activate_tcq(scsi_dev, scsi_dev->queue_depth);
- else
- scsi_deactivate_tcq(scsi_dev, scsi_dev->queue_depth);
- } else
- tag = 0;
-
- return tag;
-}
-
-
-/**
* pmcraid_init_cmdblk - initializes a command block
*
* @cmd: pointer to struct pmcraid_cmd to be initialized
@@ -346,7 +294,7 @@ static int pmcraid_change_queue_type(struct scsi_device *scsi_dev, int tag)
* Return Value
* None
*/
-void pmcraid_init_cmdblk(struct pmcraid_cmd *cmd, int index)
+static void pmcraid_init_cmdblk(struct pmcraid_cmd *cmd, int index)
{
struct pmcraid_ioarcb *ioarcb = &(cmd->ioa_cb->ioarcb);
dma_addr_t dma_addr = cmd->ioa_cb_bus_addr;
@@ -370,7 +318,7 @@ void pmcraid_init_cmdblk(struct pmcraid_cmd *cmd, int index)
ioarcb->request_flags0 = 0;
ioarcb->request_flags1 = 0;
ioarcb->cmd_timeout = 0;
- ioarcb->ioarcb_bus_addr &= (~0x1FULL);
+ ioarcb->ioarcb_bus_addr &= cpu_to_le64(~0x1FULL);
ioarcb->ioadl_bus_addr = 0;
ioarcb->ioadl_length = 0;
ioarcb->data_transfer_length = 0;
@@ -385,10 +333,10 @@ void pmcraid_init_cmdblk(struct pmcraid_cmd *cmd, int index)
cmd->scsi_cmd = NULL;
cmd->release = 0;
cmd->completion_req = 0;
- cmd->sense_buffer = 0;
+ cmd->sense_buffer = NULL;
cmd->sense_buffer_dma = 0;
cmd->dma_handle = 0;
- init_timer(&cmd->timer);
+ timer_setup(&cmd->timer, NULL, 0);
}
/**
@@ -441,7 +389,7 @@ static struct pmcraid_cmd *pmcraid_get_free_cmd(
* Return Value:
* nothing
*/
-void pmcraid_return_cmd(struct pmcraid_cmd *cmd)
+static void pmcraid_return_cmd(struct pmcraid_cmd *cmd)
{
struct pmcraid_instance *pinstance = cmd->drv_inst;
unsigned long lock_flags;
@@ -498,15 +446,14 @@ static void pmcraid_disable_interrupts(
* pmcraid_enable_interrupts - Enables specified interrupts
*
* @pinstance: pointer to per adapter instance structure
- * @intr: interrupts to enable
+ * @intrs: interrupts to enable
*
* Return Value
* None
*/
static void pmcraid_enable_interrupts(
struct pmcraid_instance *pinstance,
- u32 intrs
-)
+ u32 intrs)
{
u32 gmask = ioread32(pinstance->int_regs.global_interrupt_mask_reg);
u32 nmask = gmask & (~GLOBAL_INTERRUPT_MASK);
@@ -548,7 +495,7 @@ static void pmcraid_clr_trans_op(
}
if (pinstance->reset_cmd != NULL) {
- del_timer(&pinstance->reset_cmd->timer);
+ timer_delete(&pinstance->reset_cmd->timer);
spin_lock_irqsave(
pinstance->host->host_lock, lock_flags);
pinstance->reset_cmd->cmd_done(pinstance->reset_cmd);
@@ -588,17 +535,16 @@ static void pmcraid_reset_type(struct pmcraid_instance *pinstance)
pinstance->ioa_unit_check = 1;
}
+static void pmcraid_ioa_reset(struct pmcraid_cmd *);
/**
* pmcraid_bist_done - completion function for PCI BIST
- * @cmd: pointer to reset command
+ * @t: pointer to reset command
* Return Value
* none
*/
-
-static void pmcraid_ioa_reset(struct pmcraid_cmd *);
-
-static void pmcraid_bist_done(struct pmcraid_cmd *cmd)
+static void pmcraid_bist_done(struct timer_list *t)
{
+ struct pmcraid_cmd *cmd = timer_container_of(cmd, t, timer);
struct pmcraid_instance *pinstance = cmd->drv_inst;
unsigned long lock_flags;
int rc;
@@ -612,9 +558,6 @@ static void pmcraid_bist_done(struct pmcraid_cmd *cmd)
pmcraid_info("BIST not complete, waiting another 2 secs\n");
cmd->timer.expires = jiffies + cmd->time_left;
cmd->time_left = 0;
- cmd->timer.data = (unsigned long)cmd;
- cmd->timer.function =
- (void (*)(unsigned long))pmcraid_bist_done;
add_timer(&cmd->timer);
} else {
cmd->time_left = 0;
@@ -645,20 +588,20 @@ static void pmcraid_start_bist(struct pmcraid_cmd *cmd)
doorbells, intrs);
cmd->time_left = msecs_to_jiffies(PMCRAID_BIST_TIMEOUT);
- cmd->timer.data = (unsigned long)cmd;
cmd->timer.expires = jiffies + msecs_to_jiffies(PMCRAID_BIST_TIMEOUT);
- cmd->timer.function = (void (*)(unsigned long))pmcraid_bist_done;
+ cmd->timer.function = pmcraid_bist_done;
add_timer(&cmd->timer);
}
/**
* pmcraid_reset_alert_done - completion routine for reset_alert
- * @cmd: pointer to command block used in reset sequence
+ * @t: pointer to command block used in reset sequence
* Return value
* None
*/
-static void pmcraid_reset_alert_done(struct pmcraid_cmd *cmd)
+static void pmcraid_reset_alert_done(struct timer_list *t)
{
+ struct pmcraid_cmd *cmd = timer_container_of(cmd, t, timer);
struct pmcraid_instance *pinstance = cmd->drv_inst;
u32 status = ioread32(pinstance->ioa_status);
unsigned long lock_flags;
@@ -677,24 +620,22 @@ static void pmcraid_reset_alert_done(struct pmcraid_cmd *cmd)
pmcraid_info("critical op is not yet reset waiting again\n");
/* restart timer if some more time is available to wait */
cmd->time_left -= PMCRAID_CHECK_FOR_RESET_TIMEOUT;
- cmd->timer.data = (unsigned long)cmd;
cmd->timer.expires = jiffies + PMCRAID_CHECK_FOR_RESET_TIMEOUT;
- cmd->timer.function =
- (void (*)(unsigned long))pmcraid_reset_alert_done;
+ cmd->timer.function = pmcraid_reset_alert_done;
add_timer(&cmd->timer);
}
}
+static void pmcraid_notify_ioastate(struct pmcraid_instance *, u32);
/**
* pmcraid_reset_alert - alerts IOA for a possible reset
- * @cmd : command block to be used for reset sequence.
+ * @cmd: command block to be used for reset sequence.
*
* Return Value
* returns 0 if pci config-space is accessible and RESET_DOORBELL is
* successfully written to IOA. Returns non-zero in case pci_config_space
* is not accessible
*/
-static void pmcraid_notify_ioastate(struct pmcraid_instance *, u32);
static void pmcraid_reset_alert(struct pmcraid_cmd *cmd)
{
struct pmcraid_instance *pinstance = cmd->drv_inst;
@@ -716,10 +657,8 @@ static void pmcraid_reset_alert(struct pmcraid_cmd *cmd)
* bit to be reset.
*/
cmd->time_left = PMCRAID_RESET_TIMEOUT;
- cmd->timer.data = (unsigned long)cmd;
cmd->timer.expires = jiffies + PMCRAID_CHECK_FOR_RESET_TIMEOUT;
- cmd->timer.function =
- (void (*)(unsigned long))pmcraid_reset_alert_done;
+ cmd->timer.function = pmcraid_reset_alert_done;
add_timer(&cmd->timer);
iowrite32(DOORBELL_IOA_RESET_ALERT,
@@ -737,15 +676,16 @@ static void pmcraid_reset_alert(struct pmcraid_cmd *cmd)
/**
* pmcraid_timeout_handler - Timeout handler for internally generated ops
*
- * @cmd : pointer to command structure, that got timedout
+ * @t: pointer to command structure, that got timedout
*
* This function blocks host requests and initiates an adapter reset.
*
* Return value:
* None
*/
-static void pmcraid_timeout_handler(struct pmcraid_cmd *cmd)
+static void pmcraid_timeout_handler(struct timer_list *t)
{
+ struct pmcraid_cmd *cmd = timer_container_of(cmd, t, timer);
struct pmcraid_instance *pinstance = cmd->drv_inst;
unsigned long lock_flags;
@@ -891,27 +831,20 @@ static void pmcraid_erp_done(struct pmcraid_cmd *cmd)
cmd->ioa_cb->ioarcb.cdb[0], ioasc);
}
- /* if we had allocated sense buffers for request sense, copy the sense
- * release the buffers
- */
- if (cmd->sense_buffer != NULL) {
- memcpy(scsi_cmd->sense_buffer,
- cmd->sense_buffer,
- SCSI_SENSE_BUFFERSIZE);
- pci_free_consistent(pinstance->pdev,
- SCSI_SENSE_BUFFERSIZE,
- cmd->sense_buffer, cmd->sense_buffer_dma);
+ if (cmd->sense_buffer) {
+ dma_unmap_single(&pinstance->pdev->dev, cmd->sense_buffer_dma,
+ SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
cmd->sense_buffer = NULL;
cmd->sense_buffer_dma = 0;
}
scsi_dma_unmap(scsi_cmd);
pmcraid_return_cmd(cmd);
- scsi_cmd->scsi_done(scsi_cmd);
+ scsi_done(scsi_cmd);
}
/**
- * pmcraid_fire_command - sends an IOA command to adapter
+ * _pmcraid_fire_command - sends an IOA command to adapter
*
* This function adds the given block into pending command list
* and returns without waiting
@@ -938,8 +871,7 @@ static void _pmcraid_fire_command(struct pmcraid_cmd *cmd)
/* driver writes lower 32-bit value of IOARCB address only */
mb();
- iowrite32(le32_to_cpu(cmd->ioa_cb->ioarcb.ioarcb_bus_addr),
- pinstance->ioarrin);
+ iowrite32(le64_to_cpu(cmd->ioa_cb->ioarcb.ioarcb_bus_addr), pinstance->ioarrin);
}
/**
@@ -960,7 +892,7 @@ static void pmcraid_send_cmd(
struct pmcraid_cmd *cmd,
void (*cmd_done) (struct pmcraid_cmd *),
unsigned long timeout,
- void (*timeout_func) (struct pmcraid_cmd *)
+ void (*timeout_func) (struct timer_list *)
)
{
/* initialize done function */
@@ -968,9 +900,8 @@ static void pmcraid_send_cmd(
if (timeout_func) {
/* setup timeout handler */
- cmd->timer.data = (unsigned long)cmd;
cmd->timer.expires = jiffies + timeout;
- cmd->timer.function = (void (*)(unsigned long))timeout_func;
+ cmd->timer.function = timeout_func;
add_timer(&cmd->timer);
}
@@ -1030,6 +961,7 @@ static void pmcraid_ioa_shutdown(struct pmcraid_cmd *cmd)
pmcraid_timeout_handler);
}
+static void pmcraid_querycfg(struct pmcraid_cmd *);
/**
* pmcraid_get_fwversion_done - completion function for get_fwversion
*
@@ -1038,8 +970,6 @@ static void pmcraid_ioa_shutdown(struct pmcraid_cmd *cmd)
* Return Value
* none
*/
-static void pmcraid_querycfg(struct pmcraid_cmd *);
-
static void pmcraid_get_fwversion_done(struct pmcraid_cmd *cmd)
{
struct pmcraid_instance *pinstance = cmd->drv_inst;
@@ -1072,7 +1002,7 @@ static void pmcraid_get_fwversion_done(struct pmcraid_cmd *cmd)
static void pmcraid_get_fwversion(struct pmcraid_cmd *cmd)
{
struct pmcraid_ioarcb *ioarcb = &cmd->ioa_cb->ioarcb;
- struct pmcraid_ioadl_desc *ioadl = ioarcb->add_data.u.ioadl;
+ struct pmcraid_ioadl_desc *ioadl;
struct pmcraid_instance *pinstance = cmd->drv_inst;
u16 data_size = sizeof(struct pmcraid_inquiry_data);
@@ -1091,7 +1021,7 @@ static void pmcraid_get_fwversion(struct pmcraid_cmd *cmd)
offsetof(struct pmcraid_ioarcb,
add_data.u.ioadl[0]));
ioarcb->ioadl_length = cpu_to_le32(sizeof(struct pmcraid_ioadl_desc));
- ioarcb->ioarcb_bus_addr &= ~(0x1FULL);
+ ioarcb->ioarcb_bus_addr &= cpu_to_le64(~(0x1FULL));
ioarcb->request_flags0 |= NO_LINK_DESCS;
ioarcb->data_transfer_length = cpu_to_le32(data_size);
@@ -1117,7 +1047,7 @@ static void pmcraid_identify_hrrq(struct pmcraid_cmd *cmd)
struct pmcraid_ioarcb *ioarcb = &cmd->ioa_cb->ioarcb;
int index = cmd->hrrq_index;
__be64 hrrq_addr = cpu_to_be64(pinstance->hrrq_start_bus_addr[index]);
- u32 hrrq_size = cpu_to_be32(sizeof(u32) * PMCRAID_MAX_CMD);
+ __be32 hrrq_size = cpu_to_be32(sizeof(u32) * PMCRAID_MAX_CMD);
void (*done_function)(struct pmcraid_cmd *);
pmcraid_reinit_cmdblk(cmd);
@@ -1242,7 +1172,7 @@ static struct pmcraid_cmd *pmcraid_init_hcam
ioadl[0].flags |= IOADL_FLAGS_READ_LAST;
ioadl[0].data_len = cpu_to_le32(rcb_size);
- ioadl[0].address = cpu_to_le32(dma);
+ ioadl[0].address = cpu_to_le64(dma);
cmd->cmd_done = cmd_done;
return cmd;
@@ -1277,7 +1207,13 @@ static void pmcraid_prepare_cancel_cmd(
)
{
struct pmcraid_ioarcb *ioarcb = &cmd->ioa_cb->ioarcb;
- __be64 ioarcb_addr = cmd_to_cancel->ioa_cb->ioarcb.ioarcb_bus_addr;
+ __be64 ioarcb_addr;
+
+ /* IOARCB address of the command to be cancelled is given in
+ * cdb[2]..cdb[9] is Big-Endian format. Note that length bits in
+ * IOARCB address are not masked.
+ */
+ ioarcb_addr = cpu_to_be64(le64_to_cpu(cmd_to_cancel->ioa_cb->ioarcb.ioarcb_bus_addr));
/* Get the resource handle to where the command to be aborted has been
* sent.
@@ -1287,11 +1223,6 @@ static void pmcraid_prepare_cancel_cmd(
memset(ioarcb->cdb, 0, PMCRAID_MAX_CDB_LEN);
ioarcb->cdb[0] = PMCRAID_ABORT_CMD;
- /* IOARCB address of the command to be cancelled is given in
- * cdb[2]..cdb[9] is Big-Endian format. Note that length bits in
- * IOARCB address are not masked.
- */
- ioarcb_addr = cpu_to_be64(ioarcb_addr);
memcpy(&(ioarcb->cdb[2]), &ioarcb_addr, sizeof(ioarcb_addr));
}
@@ -1404,11 +1335,17 @@ enum {
};
#define PMCRAID_AEN_CMD_MAX (__PMCRAID_AEN_CMD_MAX - 1)
-static struct genl_family pmcraid_event_family = {
- .id = GENL_ID_GENERATE,
+static struct genl_multicast_group pmcraid_mcgrps[] = {
+ { .name = "events", /* not really used - see ID discussion below */ },
+};
+
+static struct genl_family pmcraid_event_family __ro_after_init = {
+ .module = THIS_MODULE,
.name = "pmcraid",
.version = 1,
- .maxattr = PMCRAID_AEN_ATTR_MAX
+ .maxattr = PMCRAID_AEN_ATTR_MAX,
+ .mcgrps = pmcraid_mcgrps,
+ .n_mcgrps = ARRAY_SIZE(pmcraid_mcgrps),
};
/**
@@ -1418,7 +1355,7 @@ static struct genl_family pmcraid_event_family = {
* 0 if the pmcraid_event_family is successfully registered
* with netlink generic, non-zero otherwise
*/
-static int pmcraid_netlink_init(void)
+static int __init pmcraid_netlink_init(void)
{
int result;
@@ -1444,10 +1381,9 @@ static void pmcraid_netlink_release(void)
genl_unregister_family(&pmcraid_event_family);
}
-/**
+/*
* pmcraid_notify_aen - sends event msg to user space application
* @pinstance: pointer to adapter instance structure
- * @type: HCAM type
*
* Return value:
* 0 if success, error value in case of any failure.
@@ -1455,8 +1391,7 @@ static void pmcraid_netlink_release(void)
static int pmcraid_notify_aen(
struct pmcraid_instance *pinstance,
struct pmcraid_aen_msg *aen_msg,
- u32 data_size
-)
+ u32 data_size)
{
struct sk_buff *skb;
void *msg_header;
@@ -1502,17 +1437,11 @@ static int pmcraid_notify_aen(
return -EINVAL;
}
- /* send genetlink multicast message to notify appplications */
- result = genlmsg_end(skb, msg_header);
+ /* send genetlink multicast message to notify applications */
+ genlmsg_end(skb, msg_header);
- if (result < 0) {
- pmcraid_err("genlmsg_end failed\n");
- nlmsg_free(skb);
- return result;
- }
-
- result =
- genlmsg_multicast(skb, 0, pmcraid_event_family.id, GFP_ATOMIC);
+ result = genlmsg_multicast(&pmcraid_event_family, skb,
+ 0, 0, GFP_ATOMIC);
/* If there are no listeners, genlmsg_multicast may return non-zero
* value.
@@ -1533,7 +1462,7 @@ static int pmcraid_notify_ccn(struct pmcraid_instance *pinstance)
{
return pmcraid_notify_aen(pinstance,
pinstance->ccn.msg,
- pinstance->ccn.hcam->data_len +
+ le32_to_cpu(pinstance->ccn.hcam->data_len) +
sizeof(struct pmcraid_hcam_hdr));
}
@@ -1548,7 +1477,7 @@ static int pmcraid_notify_ldn(struct pmcraid_instance *pinstance)
{
return pmcraid_notify_aen(pinstance,
pinstance->ldn.msg,
- pinstance->ldn.hcam->data_len +
+ le32_to_cpu(pinstance->ldn.hcam->data_len) +
sizeof(struct pmcraid_hcam_hdr));
}
@@ -1596,10 +1525,10 @@ static void pmcraid_handle_config_change(struct pmcraid_instance *pinstance)
pmcraid_info("CCN(%x): %x timestamp: %llx type: %x lost: %x flags: %x \
res: %x:%x:%x:%x\n",
- pinstance->ccn.hcam->ilid,
+ le32_to_cpu(pinstance->ccn.hcam->ilid),
pinstance->ccn.hcam->op_code,
- ((pinstance->ccn.hcam->timestamp1) |
- ((pinstance->ccn.hcam->timestamp2 & 0xffffffffLL) << 32)),
+ (le32_to_cpu(pinstance->ccn.hcam->timestamp1) |
+ ((le32_to_cpu(pinstance->ccn.hcam->timestamp2) & 0xffffffffLL) << 32)),
pinstance->ccn.hcam->notification_type,
pinstance->ccn.hcam->notification_lost,
pinstance->ccn.hcam->flags,
@@ -1610,7 +1539,7 @@ static void pmcraid_handle_config_change(struct pmcraid_instance *pinstance)
RES_IS_VSET(*cfg_entry) ?
(fw_version <= PMCRAID_FW_VERSION_1 ?
cfg_entry->unique_flags1 :
- cfg_entry->array_id & 0xFF) :
+ le16_to_cpu(cfg_entry->array_id) & 0xFF) :
RES_TARGET(cfg_entry->resource_address),
RES_LUN(cfg_entry->resource_address));
@@ -1635,12 +1564,7 @@ static void pmcraid_handle_config_change(struct pmcraid_instance *pinstance)
if (pinstance->ccn.hcam->notification_type ==
NOTIFICATION_TYPE_ENTRY_CHANGED &&
cfg_entry->resource_type == RES_TYPE_VSET) {
-
- if (fw_version <= PMCRAID_FW_VERSION_1)
- hidden_entry = (cfg_entry->unique_flags1 & 0x80) != 0;
- else
- hidden_entry = (cfg_entry->unique_flags1 & 0x80) != 0;
-
+ hidden_entry = (cfg_entry->unique_flags1 & 0x80) != 0;
} else if (!pmcraid_expose_resource(fw_version, cfg_entry)) {
goto out_notify_apps;
}
@@ -1698,7 +1622,7 @@ static void pmcraid_handle_config_change(struct pmcraid_instance *pinstance)
if (fw_version <= PMCRAID_FW_VERSION_1)
res->cfg_entry.unique_flags1 &= 0x7F;
else
- res->cfg_entry.array_id &= 0xFF;
+ res->cfg_entry.array_id &= cpu_to_le16(0xFF);
res->change_detected = RES_CHANGE_DEL;
res->cfg_entry.resource_handle =
PMCRAID_INVALID_RES_HANDLE;
@@ -1745,7 +1669,7 @@ static struct pmcraid_ioasc_error *pmcraid_get_error_info(u32 ioasc)
* @ioasc: ioasc code
* @cmd: pointer to command that resulted in 'ioasc'
*/
-void pmcraid_ioasc_logger(u32 ioasc, struct pmcraid_cmd *cmd)
+static void pmcraid_ioasc_logger(u32 ioasc, struct pmcraid_cmd *cmd)
{
struct pmcraid_ioasc_error *error_info = pmcraid_get_error_info(ioasc);
@@ -1756,8 +1680,8 @@ void pmcraid_ioasc_logger(u32 ioasc, struct pmcraid_cmd *cmd)
/* log the error string */
pmcraid_err("cmd [%x] for resource %x failed with %x(%s)\n",
cmd->ioa_cb->ioarcb.cdb[0],
- cmd->ioa_cb->ioarcb.resource_handle,
- le32_to_cpu(ioasc), error_info->error_string);
+ le32_to_cpu(cmd->ioa_cb->ioarcb.resource_handle),
+ ioasc, error_info->error_string);
}
/**
@@ -1844,6 +1768,8 @@ static void pmcraid_process_ccn(struct pmcraid_cmd *cmd)
}
}
+static void pmcraid_initiate_reset(struct pmcraid_instance *);
+static void pmcraid_set_timestamp(struct pmcraid_cmd *cmd);
/**
* pmcraid_process_ldn - op done function for an LDN
* @cmd: pointer to command block
@@ -1851,9 +1777,6 @@ static void pmcraid_process_ccn(struct pmcraid_cmd *cmd)
* Return value
* none
*/
-static void pmcraid_initiate_reset(struct pmcraid_instance *);
-static void pmcraid_set_timestamp(struct pmcraid_cmd *cmd);
-
static void pmcraid_process_ldn(struct pmcraid_cmd *cmd)
{
struct pmcraid_instance *pinstance = cmd->drv_inst;
@@ -1951,14 +1874,14 @@ static void pmcraid_unregister_hcams(struct pmcraid_cmd *cmd)
pmcraid_cancel_ldn(cmd);
}
+static void pmcraid_reinit_buffers(struct pmcraid_instance *);
+
/**
* pmcraid_reset_enable_ioa - re-enable IOA after a hard reset
* @pinstance: pointer to adapter instance structure
* Return Value
* 1 if TRANSITION_TO_OPERATIONAL is active, otherwise 0
*/
-static void pmcraid_reinit_buffers(struct pmcraid_instance *);
-
static int pmcraid_reset_enable_ioa(struct pmcraid_instance *pinstance)
{
u32 intrs;
@@ -2000,10 +1923,9 @@ static void pmcraid_soft_reset(struct pmcraid_cmd *cmd)
* would re-initiate a reset
*/
cmd->cmd_done = pmcraid_ioa_reset;
- cmd->timer.data = (unsigned long)cmd;
cmd->timer.expires = jiffies +
msecs_to_jiffies(PMCRAID_TRANSOP_TIMEOUT);
- cmd->timer.function = (void (*)(unsigned long))pmcraid_timeout_handler;
+ cmd->timer.function = pmcraid_timeout_handler;
if (!timer_pending(&cmd->timer))
add_timer(&cmd->timer);
@@ -2024,7 +1946,7 @@ static void pmcraid_soft_reset(struct pmcraid_cmd *cmd)
}
iowrite32(doorbell, pinstance->int_regs.host_ioa_interrupt_reg);
- ioread32(pinstance->int_regs.host_ioa_interrupt_reg),
+ ioread32(pinstance->int_regs.host_ioa_interrupt_reg);
int_reg = ioread32(pinstance->int_regs.ioa_host_interrupt_reg);
pmcraid_info("Waiting for IOA to become operational %x:%x\n",
@@ -2074,10 +1996,10 @@ static void pmcraid_fail_outstanding_cmds(struct pmcraid_instance *pinstance)
cmd->ioa_cb->ioasa.ioasc =
cpu_to_le32(PMCRAID_IOASC_IOA_WAS_RESET);
cmd->ioa_cb->ioasa.ilid =
- cpu_to_be32(PMCRAID_DRIVER_ILID);
+ cpu_to_le32(PMCRAID_DRIVER_ILID);
/* In case the command timer is still running */
- del_timer(&cmd->timer);
+ timer_delete(&cmd->timer);
/* If this is an IO command, complete it by invoking scsi_done
* function. If this is one of the internal commands other
@@ -2098,7 +2020,7 @@ static void pmcraid_fail_outstanding_cmds(struct pmcraid_instance *pinstance)
le32_to_cpu(resp) >> 2,
cmd->ioa_cb->ioarcb.cdb[0],
scsi_cmd->result);
- scsi_cmd->scsi_done(scsi_cmd);
+ scsi_done(scsi_cmd);
} else if (cmd->cmd_done == pmcraid_internal_done ||
cmd->cmd_done == pmcraid_erp_done) {
cmd->cmd_done(cmd);
@@ -2413,46 +2335,43 @@ static int pmcraid_reset_reload(
spin_lock_irqsave(pinstance->host->host_lock, lock_flags);
if (pinstance->ioa_state == IOA_STATE_DEAD) {
- spin_unlock_irqrestore(pinstance->host->host_lock,
- lock_flags);
pmcraid_info("reset_reload: IOA is dead\n");
- return reset;
- } else if (pinstance->ioa_state == target_state) {
+ goto out_unlock;
+ }
+
+ if (pinstance->ioa_state == target_state) {
reset = 0;
+ goto out_unlock;
}
}
- if (reset) {
- pmcraid_info("reset_reload: proceeding with reset\n");
- scsi_block_requests(pinstance->host);
- reset_cmd = pmcraid_get_free_cmd(pinstance);
-
- if (reset_cmd == NULL) {
- pmcraid_err("no free cmnd for reset_reload\n");
- spin_unlock_irqrestore(pinstance->host->host_lock,
- lock_flags);
- return reset;
- }
+ pmcraid_info("reset_reload: proceeding with reset\n");
+ scsi_block_requests(pinstance->host);
+ reset_cmd = pmcraid_get_free_cmd(pinstance);
+ if (reset_cmd == NULL) {
+ pmcraid_err("no free cmnd for reset_reload\n");
+ goto out_unlock;
+ }
- if (shutdown_type == SHUTDOWN_NORMAL)
- pinstance->ioa_bringdown = 1;
+ if (shutdown_type == SHUTDOWN_NORMAL)
+ pinstance->ioa_bringdown = 1;
- pinstance->ioa_shutdown_type = shutdown_type;
- pinstance->reset_cmd = reset_cmd;
- pinstance->force_ioa_reset = reset;
- pmcraid_info("reset_reload: initiating reset\n");
- pmcraid_ioa_reset(reset_cmd);
- spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags);
- pmcraid_info("reset_reload: waiting for reset to complete\n");
- wait_event(pinstance->reset_wait_q,
- !pinstance->ioa_reset_in_progress);
+ pinstance->ioa_shutdown_type = shutdown_type;
+ pinstance->reset_cmd = reset_cmd;
+ pinstance->force_ioa_reset = reset;
+ pmcraid_info("reset_reload: initiating reset\n");
+ pmcraid_ioa_reset(reset_cmd);
+ spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags);
+ pmcraid_info("reset_reload: waiting for reset to complete\n");
+ wait_event(pinstance->reset_wait_q,
+ !pinstance->ioa_reset_in_progress);
- pmcraid_info("reset_reload: reset is complete !!\n");
- scsi_unblock_requests(pinstance->host);
- if (pinstance->ioa_state == target_state)
- reset = 0;
- }
+ pmcraid_info("reset_reload: reset is complete !!\n");
+ scsi_unblock_requests(pinstance->host);
+ return pinstance->ioa_state != target_state;
+out_unlock:
+ spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags);
return reset;
}
@@ -2499,13 +2418,12 @@ static void pmcraid_request_sense(struct pmcraid_cmd *cmd)
{
struct pmcraid_ioarcb *ioarcb = &cmd->ioa_cb->ioarcb;
struct pmcraid_ioadl_desc *ioadl = ioarcb->add_data.u.ioadl;
+ struct device *dev = &cmd->drv_inst->pdev->dev;
- /* allocate DMAable memory for sense buffers */
- cmd->sense_buffer = pci_alloc_consistent(cmd->drv_inst->pdev,
- SCSI_SENSE_BUFFERSIZE,
- &cmd->sense_buffer_dma);
-
- if (cmd->sense_buffer == NULL) {
+ cmd->sense_buffer = cmd->scsi_cmd->sense_buffer;
+ cmd->sense_buffer_dma = dma_map_single(dev, cmd->sense_buffer,
+ SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
+ if (dma_mapping_error(dev, cmd->sense_buffer_dma)) {
pmcraid_err
("couldn't allocate sense buffer for request sense\n");
pmcraid_erp_done(cmd);
@@ -2546,17 +2464,15 @@ static void pmcraid_request_sense(struct pmcraid_cmd *cmd)
/**
* pmcraid_cancel_all - cancel all outstanding IOARCBs as part of error recovery
* @cmd: command that failed
- * @sense: true if request_sense is required after cancel all
+ * @need_sense: true if request_sense is required after cancel all
*
* This function sends a cancel all to a device to clear the queue.
*/
-static void pmcraid_cancel_all(struct pmcraid_cmd *cmd, u32 sense)
+static void pmcraid_cancel_all(struct pmcraid_cmd *cmd, bool need_sense)
{
struct scsi_cmnd *scsi_cmd = cmd->scsi_cmd;
struct pmcraid_ioarcb *ioarcb = &cmd->ioa_cb->ioarcb;
struct pmcraid_resource_entry *res = scsi_cmd->device->hostdata;
- void (*cmd_done) (struct pmcraid_cmd *) = sense ? pmcraid_erp_done
- : pmcraid_request_sense;
memset(ioarcb->cdb, 0, PMCRAID_MAX_CDB_LEN);
ioarcb->request_flags0 = SYNC_OVERRIDE;
@@ -2569,12 +2485,13 @@ static void pmcraid_cancel_all(struct pmcraid_cmd *cmd, u32 sense)
ioarcb->ioadl_bus_addr = 0;
ioarcb->ioadl_length = 0;
ioarcb->data_transfer_length = 0;
- ioarcb->ioarcb_bus_addr &= (~0x1FULL);
+ ioarcb->ioarcb_bus_addr &= cpu_to_le64((~0x1FULL));
/* writing to IOARRIN must be protected by host_lock, as mid-layer
* schedule queuecommand while we are doing this
*/
- pmcraid_send_cmd(cmd, cmd_done,
+ pmcraid_send_cmd(cmd, need_sense ?
+ pmcraid_erp_done : pmcraid_request_sense,
PMCRAID_REQUEST_SENSE_TIMEOUT,
pmcraid_timeout_handler);
}
@@ -2667,7 +2584,7 @@ static int pmcraid_error_handler(struct pmcraid_cmd *cmd)
struct pmcraid_ioasa *ioasa = &cmd->ioa_cb->ioasa;
u32 ioasc = le32_to_cpu(ioasa->ioasc);
u32 masked_ioasc = ioasc & PMCRAID_IOASC_SENSE_MASK;
- u32 sense_copied = 0;
+ bool sense_copied = false;
if (!res) {
pmcraid_info("resource pointer is NULL\n");
@@ -2732,14 +2649,14 @@ static int pmcraid_error_handler(struct pmcraid_cmd *cmd)
* mid-layer
*/
if (ioasa->auto_sense_length != 0) {
- short sense_len = ioasa->auto_sense_length;
- int data_size = min_t(u16, le16_to_cpu(sense_len),
+ short sense_len = le16_to_cpu(ioasa->auto_sense_length);
+ int data_size = min_t(u16, sense_len,
SCSI_SENSE_BUFFERSIZE);
memcpy(scsi_cmd->sense_buffer,
ioasa->sense_data,
data_size);
- sense_copied = 1;
+ sense_copied = true;
}
if (RES_IS_GSCSI(res->cfg_entry))
@@ -2765,7 +2682,8 @@ static int pmcraid_error_handler(struct pmcraid_cmd *cmd)
/**
* pmcraid_reset_device - device reset handler functions
*
- * @scsi_cmd: scsi command struct
+ * @scsi_dev: scsi device struct
+ * @timeout: command timeout
* @modifier: reset modifier indicating the reset sequence to be performed
*
* This function issues a device reset to the affected device.
@@ -2776,10 +2694,9 @@ static int pmcraid_error_handler(struct pmcraid_cmd *cmd)
* SUCCESS / FAILED
*/
static int pmcraid_reset_device(
- struct scsi_cmnd *scsi_cmd,
+ struct scsi_device *scsi_dev,
unsigned long timeout,
- u8 modifier
-)
+ u8 modifier)
{
struct pmcraid_cmd *cmd;
struct pmcraid_instance *pinstance;
@@ -2789,11 +2706,11 @@ static int pmcraid_reset_device(
u32 ioasc;
pinstance =
- (struct pmcraid_instance *)scsi_cmd->device->host->hostdata;
- res = scsi_cmd->device->hostdata;
+ (struct pmcraid_instance *)scsi_dev->host->hostdata;
+ res = scsi_dev->hostdata;
if (!res) {
- sdev_printk(KERN_ERR, scsi_cmd->device,
+ sdev_printk(KERN_ERR, scsi_dev,
"reset_device: NULL resource pointer\n");
return FAILED;
}
@@ -2900,7 +2817,7 @@ static int _pmcraid_io_done(struct pmcraid_cmd *cmd, int reslen, int ioasc)
if (rc == 0) {
scsi_dma_unmap(scsi_cmd);
- scsi_cmd->scsi_done(scsi_cmd);
+ scsi_done(scsi_cmd);
}
return rc;
@@ -2939,10 +2856,8 @@ static struct pmcraid_cmd *pmcraid_abort_cmd(struct pmcraid_cmd *cmd)
{
struct pmcraid_cmd *cancel_cmd;
struct pmcraid_instance *pinstance;
- struct pmcraid_resource_entry *res;
pinstance = (struct pmcraid_instance *)cmd->drv_inst;
- res = cmd->scsi_cmd->device->hostdata;
cancel_cmd = pmcraid_get_free_cmd(pinstance);
@@ -2955,7 +2870,7 @@ static struct pmcraid_cmd *pmcraid_abort_cmd(struct pmcraid_cmd *cmd)
pmcraid_info("aborting command CDB[0]= %x with index = %d\n",
cmd->ioa_cb->ioarcb.cdb[0],
- cmd->ioa_cb->ioarcb.response_handle >> 2);
+ le32_to_cpu(cmd->ioa_cb->ioarcb.response_handle) >> 2);
init_completion(&cancel_cmd->wait_for_completion);
cancel_cmd->completion_req = 1;
@@ -3089,7 +3004,7 @@ static int pmcraid_eh_abort_handler(struct scsi_cmnd *scsi_cmd)
}
/**
- * pmcraid_eh_xxxx_reset_handler - bus/target/device reset handler callbacks
+ * pmcraid_eh_device_reset_handler - bus/target/device reset handler callbacks
*
* @scmd: pointer to scsi_cmd that was sent to the resource to be reset.
*
@@ -3106,27 +3021,72 @@ static int pmcraid_eh_device_reset_handler(struct scsi_cmnd *scmd)
{
scmd_printk(KERN_INFO, scmd,
"resetting device due to an I/O command timeout.\n");
- return pmcraid_reset_device(scmd,
+ return pmcraid_reset_device(scmd->device,
PMCRAID_INTERNAL_TIMEOUT,
RESET_DEVICE_LUN);
}
static int pmcraid_eh_bus_reset_handler(struct scsi_cmnd *scmd)
{
- scmd_printk(KERN_INFO, scmd,
+ struct Scsi_Host *host = scmd->device->host;
+ struct pmcraid_instance *pinstance =
+ (struct pmcraid_instance *)host->hostdata;
+ struct pmcraid_resource_entry *res = NULL;
+ struct pmcraid_resource_entry *temp;
+ struct scsi_device *sdev = NULL;
+ unsigned long lock_flags;
+
+ /*
+ * The reset device code insists on us passing down
+ * a device, so grab the first device on the bus.
+ */
+ spin_lock_irqsave(&pinstance->resource_lock, lock_flags);
+ list_for_each_entry(temp, &pinstance->used_res_q, queue) {
+ if (scmd->device->channel == PMCRAID_VSET_BUS_ID &&
+ RES_IS_VSET(temp->cfg_entry)) {
+ res = temp;
+ break;
+ } else if (scmd->device->channel == PMCRAID_PHYS_BUS_ID &&
+ RES_IS_GSCSI(temp->cfg_entry)) {
+ res = temp;
+ break;
+ }
+ }
+ if (res)
+ sdev = res->scsi_dev;
+ spin_unlock_irqrestore(&pinstance->resource_lock, lock_flags);
+ if (!sdev)
+ return FAILED;
+
+ sdev_printk(KERN_INFO, sdev,
"Doing bus reset due to an I/O command timeout.\n");
- return pmcraid_reset_device(scmd,
+ return pmcraid_reset_device(sdev,
PMCRAID_RESET_BUS_TIMEOUT,
RESET_DEVICE_BUS);
}
static int pmcraid_eh_target_reset_handler(struct scsi_cmnd *scmd)
{
- scmd_printk(KERN_INFO, scmd,
+ struct Scsi_Host *shost = scmd->device->host;
+ struct scsi_device *scsi_dev = NULL, *tmp;
+ int ret;
+
+ shost_for_each_device(tmp, shost) {
+ if ((tmp->channel == scmd->device->channel) &&
+ (tmp->id == scmd->device->id)) {
+ scsi_dev = tmp;
+ break;
+ }
+ }
+ if (!scsi_dev)
+ return FAILED;
+ sdev_printk(KERN_INFO, scsi_dev,
"Doing target reset due to an I/O command timeout.\n");
- return pmcraid_reset_device(scmd,
- PMCRAID_INTERNAL_TIMEOUT,
- RESET_DEVICE_TARGET);
+ ret = pmcraid_reset_device(scsi_dev,
+ PMCRAID_INTERNAL_TIMEOUT,
+ RESET_DEVICE_TARGET);
+ scsi_device_put(scsi_dev);
+ return ret;
}
/**
@@ -3164,36 +3124,6 @@ static int pmcraid_eh_host_reset_handler(struct scsi_cmnd *scmd)
}
/**
- * pmcraid_task_attributes - Translate SPI Q-Tags to task attributes
- * @scsi_cmd: scsi command struct
- *
- * Return value
- * number of tags or 0 if the task is not tagged
- */
-static u8 pmcraid_task_attributes(struct scsi_cmnd *scsi_cmd)
-{
- char tag[2];
- u8 rc = 0;
-
- if (scsi_populate_tag_msg(scsi_cmd, tag)) {
- switch (tag[0]) {
- case MSG_SIMPLE_TAG:
- rc = TASK_TAG_SIMPLE;
- break;
- case MSG_HEAD_TAG:
- rc = TASK_TAG_QUEUE_HEAD;
- break;
- case MSG_ORDERED_TAG:
- rc = TASK_TAG_ORDERED;
- break;
- };
- }
-
- return rc;
-}
-
-
-/**
* pmcraid_init_ioadls - initializes IOADL related fields in IOARCB
* @cmd: pmcraid command struct
* @sgcount: count of scatter-gather elements
@@ -3202,7 +3132,7 @@ static u8 pmcraid_task_attributes(struct scsi_cmnd *scsi_cmd)
* returns pointer pmcraid_ioadl_desc, initialized to point to internal
* or external IOADLs
*/
-struct pmcraid_ioadl_desc *
+static struct pmcraid_ioadl_desc *
pmcraid_init_ioadls(struct pmcraid_cmd *cmd, int sgcount)
{
struct pmcraid_ioadl_desc *ioadl;
@@ -3210,9 +3140,8 @@ pmcraid_init_ioadls(struct pmcraid_cmd *cmd, int sgcount)
int ioadl_count = 0;
if (ioarcb->add_cmd_param_length)
- ioadl_count = DIV_ROUND_UP(ioarcb->add_cmd_param_length, 16);
- ioarcb->ioadl_length =
- sizeof(struct pmcraid_ioadl_desc) * sgcount;
+ ioadl_count = DIV_ROUND_UP(le16_to_cpu(ioarcb->add_cmd_param_length), 16);
+ ioarcb->ioadl_length = cpu_to_le32(sizeof(struct pmcraid_ioadl_desc) * sgcount);
if ((sgcount + ioadl_count) > (ARRAY_SIZE(ioarcb->add_data.u.ioadl))) {
/* external ioadls start at offset 0x80 from control_block
@@ -3220,7 +3149,7 @@ pmcraid_init_ioadls(struct pmcraid_cmd *cmd, int sgcount)
* It is necessary to indicate to firmware that driver is
* using ioadls to be treated as external to IOARCB.
*/
- ioarcb->ioarcb_bus_addr &= ~(0x1FULL);
+ ioarcb->ioarcb_bus_addr &= cpu_to_le64(~(0x1FULL));
ioarcb->ioadl_bus_addr =
cpu_to_le64((cmd->ioa_cb_bus_addr) +
offsetof(struct pmcraid_ioarcb,
@@ -3234,7 +3163,7 @@ pmcraid_init_ioadls(struct pmcraid_cmd *cmd, int sgcount)
ioadl = &ioarcb->add_data.u.ioadl[ioadl_count];
ioarcb->ioarcb_bus_addr |=
- DIV_ROUND_CLOSEST(sgcount + ioadl_count, 8);
+ cpu_to_le64(DIV_ROUND_CLOSEST(sgcount + ioadl_count, 8));
}
return ioadl;
@@ -3261,7 +3190,7 @@ static int pmcraid_build_ioadl(
struct scsi_cmnd *scsi_cmd = cmd->scsi_cmd;
struct pmcraid_ioarcb *ioarcb = &(cmd->ioa_cb->ioarcb);
- struct pmcraid_ioadl_desc *ioadl = ioarcb->add_data.u.ioadl;
+ struct pmcraid_ioadl_desc *ioadl;
u32 length = scsi_bufflen(scsi_cmd);
@@ -3301,168 +3230,8 @@ static int pmcraid_build_ioadl(
}
/**
- * pmcraid_free_sglist - Frees an allocated SG buffer list
- * @sglist: scatter/gather list pointer
- *
- * Free a DMA'able memory previously allocated with pmcraid_alloc_sglist
- *
- * Return value:
- * none
- */
-static void pmcraid_free_sglist(struct pmcraid_sglist *sglist)
-{
- int i;
-
- for (i = 0; i < sglist->num_sg; i++)
- __free_pages(sg_page(&(sglist->scatterlist[i])),
- sglist->order);
-
- kfree(sglist);
-}
-
-/**
- * pmcraid_alloc_sglist - Allocates memory for a SG list
- * @buflen: buffer length
- *
- * Allocates a DMA'able buffer in chunks and assembles a scatter/gather
- * list.
- *
- * Return value
- * pointer to sglist / NULL on failure
- */
-static struct pmcraid_sglist *pmcraid_alloc_sglist(int buflen)
-{
- struct pmcraid_sglist *sglist;
- struct scatterlist *scatterlist;
- struct page *page;
- int num_elem, i, j;
- int sg_size;
- int order;
- int bsize_elem;
-
- sg_size = buflen / (PMCRAID_MAX_IOADLS - 1);
- order = (sg_size > 0) ? get_order(sg_size) : 0;
- bsize_elem = PAGE_SIZE * (1 << order);
-
- /* Determine the actual number of sg entries needed */
- if (buflen % bsize_elem)
- num_elem = (buflen / bsize_elem) + 1;
- else
- num_elem = buflen / bsize_elem;
-
- /* Allocate a scatter/gather list for the DMA */
- sglist = kzalloc(sizeof(struct pmcraid_sglist) +
- (sizeof(struct scatterlist) * (num_elem - 1)),
- GFP_KERNEL);
-
- if (sglist == NULL)
- return NULL;
-
- scatterlist = sglist->scatterlist;
- sg_init_table(scatterlist, num_elem);
- sglist->order = order;
- sglist->num_sg = num_elem;
- sg_size = buflen;
-
- for (i = 0; i < num_elem; i++) {
- page = alloc_pages(GFP_KERNEL|GFP_DMA|__GFP_ZERO, order);
- if (!page) {
- for (j = i - 1; j >= 0; j--)
- __free_pages(sg_page(&scatterlist[j]), order);
- kfree(sglist);
- return NULL;
- }
-
- sg_set_page(&scatterlist[i], page,
- sg_size < bsize_elem ? sg_size : bsize_elem, 0);
- sg_size -= bsize_elem;
- }
-
- return sglist;
-}
-
-/**
- * pmcraid_copy_sglist - Copy user buffer to kernel buffer's SG list
- * @sglist: scatter/gather list pointer
- * @buffer: buffer pointer
- * @len: buffer length
- * @direction: data transfer direction
- *
- * Copy a user buffer into a buffer allocated by pmcraid_alloc_sglist
- *
- * Return value:
- * 0 on success / other on failure
- */
-static int pmcraid_copy_sglist(
- struct pmcraid_sglist *sglist,
- unsigned long buffer,
- u32 len,
- int direction
-)
-{
- struct scatterlist *scatterlist;
- void *kaddr;
- int bsize_elem;
- int i;
- int rc = 0;
-
- /* Determine the actual number of bytes per element */
- bsize_elem = PAGE_SIZE * (1 << sglist->order);
-
- scatterlist = sglist->scatterlist;
-
- for (i = 0; i < (len / bsize_elem); i++, buffer += bsize_elem) {
- struct page *page = sg_page(&scatterlist[i]);
-
- kaddr = kmap(page);
- if (direction == DMA_TO_DEVICE)
- rc = __copy_from_user(kaddr,
- (void *)buffer,
- bsize_elem);
- else
- rc = __copy_to_user((void *)buffer, kaddr, bsize_elem);
-
- kunmap(page);
-
- if (rc) {
- pmcraid_err("failed to copy user data into sg list\n");
- return -EFAULT;
- }
-
- scatterlist[i].length = bsize_elem;
- }
-
- if (len % bsize_elem) {
- struct page *page = sg_page(&scatterlist[i]);
-
- kaddr = kmap(page);
-
- if (direction == DMA_TO_DEVICE)
- rc = __copy_from_user(kaddr,
- (void *)buffer,
- len % bsize_elem);
- else
- rc = __copy_to_user((void *)buffer,
- kaddr,
- len % bsize_elem);
-
- kunmap(page);
-
- scatterlist[i].length = len % bsize_elem;
- }
-
- if (rc) {
- pmcraid_err("failed to copy user data into sg list\n");
- rc = -EFAULT;
- }
-
- return rc;
-}
-
-/**
- * pmcraid_queuecommand - Queue a mid-layer request
+ * pmcraid_queuecommand_lck - Queue a mid-layer request
* @scsi_cmd: scsi command struct
- * @done: done function
*
* This function queues a request generated by the mid-layer. Midlayer calls
* this routine within host->lock. Some of the functions called by queuecommand
@@ -3473,10 +3242,7 @@ static int pmcraid_copy_sglist(
* SCSI_MLQUEUE_DEVICE_BUSY if device is busy
* SCSI_MLQUEUE_HOST_BUSY if host is busy
*/
-static int pmcraid_queuecommand_lck(
- struct scsi_cmnd *scsi_cmd,
- void (*done) (struct scsi_cmnd *)
-)
+static int pmcraid_queuecommand_lck(struct scsi_cmnd *scsi_cmd)
{
struct pmcraid_instance *pinstance;
struct pmcraid_resource_entry *res;
@@ -3488,7 +3254,6 @@ static int pmcraid_queuecommand_lck(
pinstance =
(struct pmcraid_instance *)scsi_cmd->device->host->hostdata;
fw_version = be16_to_cpu(pinstance->inq_data->fw_version);
- scsi_cmd->scsi_done = done;
res = scsi_cmd->device->hostdata;
scsi_cmd->result = (DID_OK << 16);
@@ -3498,7 +3263,7 @@ static int pmcraid_queuecommand_lck(
if (pinstance->ioa_state == IOA_STATE_DEAD) {
pmcraid_info("IOA is dead, but queuecommand is scheduled\n");
scsi_cmd->result = (DID_NO_CONNECT << 16);
- scsi_cmd->scsi_done(scsi_cmd);
+ scsi_done(scsi_cmd);
return 0;
}
@@ -3511,7 +3276,7 @@ static int pmcraid_queuecommand_lck(
*/
if (scsi_cmd->cmnd[0] == SYNCHRONIZE_CACHE) {
pmcraid_info("SYNC_CACHE(0x35), completing in driver itself\n");
- scsi_cmd->scsi_done(scsi_cmd);
+ scsi_done(scsi_cmd);
return 0;
}
@@ -3548,7 +3313,9 @@ static int pmcraid_queuecommand_lck(
}
ioarcb->request_flags0 |= NO_LINK_DESCS;
- ioarcb->request_flags1 |= pmcraid_task_attributes(scsi_cmd);
+
+ if (scsi_cmd->flags & SCMD_TAGGED)
+ ioarcb->request_flags1 |= TASK_TAG_SIMPLE;
if (RES_IS_GSCSI(res->cfg_entry))
ioarcb->request_flags1 |= DELAY_AFTER_RESET;
@@ -3564,7 +3331,7 @@ static int pmcraid_queuecommand_lck(
RES_IS_VSET(res->cfg_entry) ?
(fw_version <= PMCRAID_FW_VERSION_1 ?
res->cfg_entry.unique_flags1 :
- res->cfg_entry.array_id & 0xFF) :
+ le16_to_cpu(res->cfg_entry.array_id) & 0xFF) :
RES_TARGET(res->cfg_entry.resource_address),
RES_LUN(res->cfg_entry.resource_address));
@@ -3581,7 +3348,7 @@ static int pmcraid_queuecommand_lck(
static DEF_SCSI_QCMD(pmcraid_queuecommand)
-/**
+/*
* pmcraid_open -char node "open" entry, allowed only users with admin access
*/
static int pmcraid_chr_open(struct inode *inode, struct file *filep)
@@ -3598,7 +3365,7 @@ static int pmcraid_chr_open(struct inode *inode, struct file *filep)
return 0;
}
-/**
+/*
* pmcraid_fasync - Async notifier registration from applications
*
* This function adds the calling process to a driver global queue. When an
@@ -3617,376 +3384,6 @@ static int pmcraid_chr_fasync(int fd, struct file *filep, int mode)
return rc;
}
-
-/**
- * pmcraid_build_passthrough_ioadls - builds SG elements for passthrough
- * commands sent over IOCTL interface
- *
- * @cmd : pointer to struct pmcraid_cmd
- * @buflen : length of the request buffer
- * @direction : data transfer direction
- *
- * Return value
- * 0 on success, non-zero error code on failure
- */
-static int pmcraid_build_passthrough_ioadls(
- struct pmcraid_cmd *cmd,
- int buflen,
- int direction
-)
-{
- struct pmcraid_sglist *sglist = NULL;
- struct scatterlist *sg = NULL;
- struct pmcraid_ioarcb *ioarcb = &cmd->ioa_cb->ioarcb;
- struct pmcraid_ioadl_desc *ioadl;
- int i;
-
- sglist = pmcraid_alloc_sglist(buflen);
-
- if (!sglist) {
- pmcraid_err("can't allocate memory for passthrough SGls\n");
- return -ENOMEM;
- }
-
- sglist->num_dma_sg = pci_map_sg(cmd->drv_inst->pdev,
- sglist->scatterlist,
- sglist->num_sg, direction);
-
- if (!sglist->num_dma_sg || sglist->num_dma_sg > PMCRAID_MAX_IOADLS) {
- dev_err(&cmd->drv_inst->pdev->dev,
- "Failed to map passthrough buffer!\n");
- pmcraid_free_sglist(sglist);
- return -EIO;
- }
-
- cmd->sglist = sglist;
- ioarcb->request_flags0 |= NO_LINK_DESCS;
-
- ioadl = pmcraid_init_ioadls(cmd, sglist->num_dma_sg);
-
- /* Initialize IOADL descriptor addresses */
- for_each_sg(sglist->scatterlist, sg, sglist->num_dma_sg, i) {
- ioadl[i].data_len = cpu_to_le32(sg_dma_len(sg));
- ioadl[i].address = cpu_to_le64(sg_dma_address(sg));
- ioadl[i].flags = 0;
- }
-
- /* setup the last descriptor */
- ioadl[i - 1].flags = IOADL_FLAGS_LAST_DESC;
-
- return 0;
-}
-
-
-/**
- * pmcraid_release_passthrough_ioadls - release passthrough ioadls
- *
- * @cmd: pointer to struct pmcraid_cmd for which ioadls were allocated
- * @buflen: size of the request buffer
- * @direction: data transfer direction
- *
- * Return value
- * 0 on success, non-zero error code on failure
- */
-static void pmcraid_release_passthrough_ioadls(
- struct pmcraid_cmd *cmd,
- int buflen,
- int direction
-)
-{
- struct pmcraid_sglist *sglist = cmd->sglist;
-
- if (buflen > 0) {
- pci_unmap_sg(cmd->drv_inst->pdev,
- sglist->scatterlist,
- sglist->num_sg,
- direction);
- pmcraid_free_sglist(sglist);
- cmd->sglist = NULL;
- }
-}
-
-/**
- * pmcraid_ioctl_passthrough - handling passthrough IOCTL commands
- *
- * @pinstance: pointer to adapter instance structure
- * @cmd: ioctl code
- * @arg: pointer to pmcraid_passthrough_buffer user buffer
- *
- * Return value
- * 0 on success, non-zero error code on failure
- */
-static long pmcraid_ioctl_passthrough(
- struct pmcraid_instance *pinstance,
- unsigned int ioctl_cmd,
- unsigned int buflen,
- unsigned long arg
-)
-{
- struct pmcraid_passthrough_ioctl_buffer *buffer;
- struct pmcraid_ioarcb *ioarcb;
- struct pmcraid_cmd *cmd;
- struct pmcraid_cmd *cancel_cmd;
- unsigned long request_buffer;
- unsigned long request_offset;
- unsigned long lock_flags;
- void *ioasa;
- u32 ioasc;
- int request_size;
- int buffer_size;
- u8 access, direction;
- int rc = 0;
-
- /* If IOA reset is in progress, wait 10 secs for reset to complete */
- if (pinstance->ioa_reset_in_progress) {
- rc = wait_event_interruptible_timeout(
- pinstance->reset_wait_q,
- !pinstance->ioa_reset_in_progress,
- msecs_to_jiffies(10000));
-
- if (!rc)
- return -ETIMEDOUT;
- else if (rc < 0)
- return -ERESTARTSYS;
- }
-
- /* If adapter is not in operational state, return error */
- if (pinstance->ioa_state != IOA_STATE_OPERATIONAL) {
- pmcraid_err("IOA is not operational\n");
- return -ENOTTY;
- }
-
- buffer_size = sizeof(struct pmcraid_passthrough_ioctl_buffer);
- buffer = kmalloc(buffer_size, GFP_KERNEL);
-
- if (!buffer) {
- pmcraid_err("no memory for passthrough buffer\n");
- return -ENOMEM;
- }
-
- request_offset =
- offsetof(struct pmcraid_passthrough_ioctl_buffer, request_buffer);
-
- request_buffer = arg + request_offset;
-
- rc = __copy_from_user(buffer,
- (struct pmcraid_passthrough_ioctl_buffer *) arg,
- sizeof(struct pmcraid_passthrough_ioctl_buffer));
-
- ioasa =
- (void *)(arg +
- offsetof(struct pmcraid_passthrough_ioctl_buffer, ioasa));
-
- if (rc) {
- pmcraid_err("ioctl: can't copy passthrough buffer\n");
- rc = -EFAULT;
- goto out_free_buffer;
- }
-
- request_size = buffer->ioarcb.data_transfer_length;
-
- if (buffer->ioarcb.request_flags0 & TRANSFER_DIR_WRITE) {
- access = VERIFY_READ;
- direction = DMA_TO_DEVICE;
- } else {
- access = VERIFY_WRITE;
- direction = DMA_FROM_DEVICE;
- }
-
- if (request_size > 0) {
- rc = access_ok(access, arg, request_offset + request_size);
-
- if (!rc) {
- rc = -EFAULT;
- goto out_free_buffer;
- }
- } else if (request_size < 0) {
- rc = -EINVAL;
- goto out_free_buffer;
- }
-
- /* check if we have any additional command parameters */
- if (buffer->ioarcb.add_cmd_param_length > PMCRAID_ADD_CMD_PARAM_LEN) {
- rc = -EINVAL;
- goto out_free_buffer;
- }
-
- cmd = pmcraid_get_free_cmd(pinstance);
-
- if (!cmd) {
- pmcraid_err("free command block is not available\n");
- rc = -ENOMEM;
- goto out_free_buffer;
- }
-
- cmd->scsi_cmd = NULL;
- ioarcb = &(cmd->ioa_cb->ioarcb);
-
- /* Copy the user-provided IOARCB stuff field by field */
- ioarcb->resource_handle = buffer->ioarcb.resource_handle;
- ioarcb->data_transfer_length = buffer->ioarcb.data_transfer_length;
- ioarcb->cmd_timeout = buffer->ioarcb.cmd_timeout;
- ioarcb->request_type = buffer->ioarcb.request_type;
- ioarcb->request_flags0 = buffer->ioarcb.request_flags0;
- ioarcb->request_flags1 = buffer->ioarcb.request_flags1;
- memcpy(ioarcb->cdb, buffer->ioarcb.cdb, PMCRAID_MAX_CDB_LEN);
-
- if (buffer->ioarcb.add_cmd_param_length) {
- ioarcb->add_cmd_param_length =
- buffer->ioarcb.add_cmd_param_length;
- ioarcb->add_cmd_param_offset =
- buffer->ioarcb.add_cmd_param_offset;
- memcpy(ioarcb->add_data.u.add_cmd_params,
- buffer->ioarcb.add_data.u.add_cmd_params,
- buffer->ioarcb.add_cmd_param_length);
- }
-
- /* set hrrq number where the IOA should respond to. Note that all cmds
- * generated internally uses hrrq_id 0, exception to this is the cmd
- * block of scsi_cmd which is re-used (e.g. cancel/abort), which uses
- * hrrq_id assigned here in queuecommand
- */
- ioarcb->hrrq_id = atomic_add_return(1, &(pinstance->last_message_id)) %
- pinstance->num_hrrq;
-
- if (request_size) {
- rc = pmcraid_build_passthrough_ioadls(cmd,
- request_size,
- direction);
- if (rc) {
- pmcraid_err("couldn't build passthrough ioadls\n");
- goto out_free_buffer;
- }
- } else if (request_size < 0) {
- rc = -EINVAL;
- goto out_free_buffer;
- }
-
- /* If data is being written into the device, copy the data from user
- * buffers
- */
- if (direction == DMA_TO_DEVICE && request_size > 0) {
- rc = pmcraid_copy_sglist(cmd->sglist,
- request_buffer,
- request_size,
- direction);
- if (rc) {
- pmcraid_err("failed to copy user buffer\n");
- goto out_free_sglist;
- }
- }
-
- /* passthrough ioctl is a blocking command so, put the user to sleep
- * until timeout. Note that a timeout value of 0 means, do timeout.
- */
- cmd->cmd_done = pmcraid_internal_done;
- init_completion(&cmd->wait_for_completion);
- cmd->completion_req = 1;
-
- pmcraid_info("command(%d) (CDB[0] = %x) for %x\n",
- le32_to_cpu(cmd->ioa_cb->ioarcb.response_handle) >> 2,
- cmd->ioa_cb->ioarcb.cdb[0],
- le32_to_cpu(cmd->ioa_cb->ioarcb.resource_handle));
-
- spin_lock_irqsave(pinstance->host->host_lock, lock_flags);
- _pmcraid_fire_command(cmd);
- spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags);
-
- /* NOTE ! Remove the below line once abort_task is implemented
- * in firmware. This line disables ioctl command timeout handling logic
- * similar to IO command timeout handling, making ioctl commands to wait
- * until the command completion regardless of timeout value specified in
- * ioarcb
- */
- buffer->ioarcb.cmd_timeout = 0;
-
- /* If command timeout is specified put caller to wait till that time,
- * otherwise it would be blocking wait. If command gets timed out, it
- * will be aborted.
- */
- if (buffer->ioarcb.cmd_timeout == 0) {
- wait_for_completion(&cmd->wait_for_completion);
- } else if (!wait_for_completion_timeout(
- &cmd->wait_for_completion,
- msecs_to_jiffies(buffer->ioarcb.cmd_timeout * 1000))) {
-
- pmcraid_info("aborting cmd %d (CDB[0] = %x) due to timeout\n",
- le32_to_cpu(cmd->ioa_cb->ioarcb.response_handle >> 2),
- cmd->ioa_cb->ioarcb.cdb[0]);
-
- spin_lock_irqsave(pinstance->host->host_lock, lock_flags);
- cancel_cmd = pmcraid_abort_cmd(cmd);
- spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags);
-
- if (cancel_cmd) {
- wait_for_completion(&cancel_cmd->wait_for_completion);
- ioasc = cancel_cmd->ioa_cb->ioasa.ioasc;
- pmcraid_return_cmd(cancel_cmd);
-
- /* if abort task couldn't find the command i.e it got
- * completed prior to aborting, return good completion.
- * if command got aborted successfully or there was IOA
- * reset due to abort task itself getting timedout then
- * return -ETIMEDOUT
- */
- if (ioasc == PMCRAID_IOASC_IOA_WAS_RESET ||
- PMCRAID_IOASC_SENSE_KEY(ioasc) == 0x00) {
- if (ioasc != PMCRAID_IOASC_GC_IOARCB_NOTFOUND)
- rc = -ETIMEDOUT;
- goto out_handle_response;
- }
- }
-
- /* no command block for abort task or abort task failed to abort
- * the IOARCB, then wait for 150 more seconds and initiate reset
- * sequence after timeout
- */
- if (!wait_for_completion_timeout(
- &cmd->wait_for_completion,
- msecs_to_jiffies(150 * 1000))) {
- pmcraid_reset_bringup(cmd->drv_inst);
- rc = -ETIMEDOUT;
- }
- }
-
-out_handle_response:
- /* copy entire IOASA buffer and return IOCTL success.
- * If copying IOASA to user-buffer fails, return
- * EFAULT
- */
- if (copy_to_user(ioasa, &cmd->ioa_cb->ioasa,
- sizeof(struct pmcraid_ioasa))) {
- pmcraid_err("failed to copy ioasa buffer to user\n");
- rc = -EFAULT;
- }
-
- /* If the data transfer was from device, copy the data onto user
- * buffers
- */
- else if (direction == DMA_FROM_DEVICE && request_size > 0) {
- rc = pmcraid_copy_sglist(cmd->sglist,
- request_buffer,
- request_size,
- direction);
- if (rc) {
- pmcraid_err("failed to copy user buffer\n");
- rc = -EFAULT;
- }
- }
-
-out_free_sglist:
- pmcraid_release_passthrough_ioadls(cmd, request_size, direction);
- pmcraid_return_cmd(cmd);
-
-out_free_buffer:
- kfree(buffer);
-
- return rc;
-}
-
-
-
-
/**
* pmcraid_ioctl_driver - ioctl handler for commands handled by driver itself
*
@@ -4007,11 +3404,6 @@ static long pmcraid_ioctl_driver(
{
int rc = -ENOSYS;
- if (!access_ok(VERIFY_READ, user_buffer, _IOC_SIZE(cmd))) {
- pmcraid_err("ioctl_driver: access fault in request buffer\n");
- return -EFAULT;
- }
-
switch (cmd) {
case PMCRAID_IOCTL_RESET_ADAPTER:
pmcraid_reset_bringup(pinstance);
@@ -4043,8 +3435,7 @@ static int pmcraid_check_ioctl_buffer(
struct pmcraid_ioctl_header *hdr
)
{
- int rc = 0;
- int access = VERIFY_READ;
+ int rc;
if (copy_from_user(hdr, arg, sizeof(struct pmcraid_ioctl_header))) {
pmcraid_err("couldn't copy ioctl header from user buffer\n");
@@ -4060,23 +3451,10 @@ static int pmcraid_check_ioctl_buffer(
return -EINVAL;
}
- /* check for appropriate buffer access */
- if ((_IOC_DIR(cmd) & _IOC_READ) == _IOC_READ)
- access = VERIFY_WRITE;
-
- rc = access_ok(access,
- (arg + sizeof(struct pmcraid_ioctl_header)),
- hdr->buffer_length);
- if (!rc) {
- pmcraid_err("access failed for user buffer of size %d\n",
- hdr->buffer_length);
- return -EFAULT;
- }
-
return 0;
}
-/**
+/*
* pmcraid_ioctl - char node ioctl entry point
*/
static long pmcraid_chr_ioctl(
@@ -4087,6 +3465,7 @@ static long pmcraid_chr_ioctl(
{
struct pmcraid_instance *pinstance = NULL;
struct pmcraid_ioctl_header *hdr = NULL;
+ void __user *argp = (void __user *)arg;
int retval = -ENOTTY;
hdr = kmalloc(sizeof(struct pmcraid_ioctl_header), GFP_KERNEL);
@@ -4096,7 +3475,7 @@ static long pmcraid_chr_ioctl(
return -ENOMEM;
}
- retval = pmcraid_check_ioctl_buffer(cmd, (void *)arg, hdr);
+ retval = pmcraid_check_ioctl_buffer(cmd, argp, hdr);
if (retval) {
pmcraid_info("chr_ioctl: header check failed\n");
@@ -4114,28 +3493,10 @@ static long pmcraid_chr_ioctl(
switch (_IOC_TYPE(cmd)) {
- case PMCRAID_PASSTHROUGH_IOCTL:
- /* If ioctl code is to download microcode, we need to block
- * mid-layer requests.
- */
- if (cmd == PMCRAID_IOCTL_DOWNLOAD_MICROCODE)
- scsi_block_requests(pinstance->host);
-
- retval = pmcraid_ioctl_passthrough(pinstance,
- cmd,
- hdr->buffer_length,
- arg);
-
- if (cmd == PMCRAID_IOCTL_DOWNLOAD_MICROCODE)
- scsi_unblock_requests(pinstance->host);
- break;
-
case PMCRAID_DRIVER_IOCTL:
arg += sizeof(struct pmcraid_ioctl_header);
- retval = pmcraid_ioctl_driver(pinstance,
- cmd,
- hdr->buffer_length,
- (void __user *)arg);
+ retval = pmcraid_ioctl_driver(pinstance, cmd,
+ hdr->buffer_length, argp);
break;
default:
@@ -4148,7 +3509,7 @@ static long pmcraid_chr_ioctl(
return retval;
}
-/**
+/*
* File operations structure for management interface
*/
static const struct file_operations pmcraid_fops = {
@@ -4156,9 +3517,7 @@ static const struct file_operations pmcraid_fops = {
.open = pmcraid_chr_open,
.fasync = pmcraid_chr_fasync,
.unlocked_ioctl = pmcraid_chr_ioctl,
-#ifdef CONFIG_COMPAT
- .compat_ioctl = pmcraid_chr_ioctl,
-#endif
+ .compat_ioctl = compat_ptr_ioctl,
.llseek = noop_llseek,
};
@@ -4168,6 +3527,7 @@ static const struct file_operations pmcraid_fops = {
/**
* pmcraid_show_log_level - Display adapter's error logging level
* @dev: class device struct
+ * @attr: unused
* @buf: buffer
*
* Return value:
@@ -4187,6 +3547,7 @@ static ssize_t pmcraid_show_log_level(
/**
* pmcraid_store_log_level - Change the adapter's error logging level
* @dev: class device struct
+ * @attr: unused
* @buf: buffer
* @count: not used
*
@@ -4202,9 +3563,9 @@ static ssize_t pmcraid_store_log_level(
{
struct Scsi_Host *shost;
struct pmcraid_instance *pinstance;
- unsigned long val;
+ u8 val;
- if (strict_strtoul(buf, 10, &val))
+ if (kstrtou8(buf, 10, &val))
return -EINVAL;
/* log-level should be from 0 to 2 */
if (val > 2)
@@ -4229,6 +3590,7 @@ static struct device_attribute pmcraid_log_level_attr = {
/**
* pmcraid_show_drv_version - Display driver version
* @dev: class device struct
+ * @attr: unused
* @buf: buffer
*
* Return value:
@@ -4253,8 +3615,9 @@ static struct device_attribute pmcraid_driver_version_attr = {
};
/**
- * pmcraid_show_io_adapter_id - Display driver assigned adapter id
+ * pmcraid_show_adapter_id - Display driver assigned adapter id
* @dev: class device struct
+ * @attr: unused
* @buf: buffer
*
* Return value:
@@ -4269,8 +3632,7 @@ static ssize_t pmcraid_show_adapter_id(
struct Scsi_Host *shost = class_to_shost(dev);
struct pmcraid_instance *pinstance =
(struct pmcraid_instance *)shost->hostdata;
- u32 adapter_id = (pinstance->pdev->bus->number << 8) |
- pinstance->pdev->devfn;
+ u32 adapter_id = pci_dev_id(pinstance->pdev);
u32 aen_group = pmcraid_event_family.id;
return snprintf(buf, PAGE_SIZE,
@@ -4281,21 +3643,22 @@ static ssize_t pmcraid_show_adapter_id(
static struct device_attribute pmcraid_adapter_id_attr = {
.attr = {
.name = "adapter_id",
- .mode = S_IRUGO | S_IWUSR,
+ .mode = S_IRUGO,
},
.show = pmcraid_show_adapter_id,
};
-static struct device_attribute *pmcraid_host_attrs[] = {
- &pmcraid_log_level_attr,
- &pmcraid_driver_version_attr,
- &pmcraid_adapter_id_attr,
+static struct attribute *pmcraid_host_attrs[] = {
+ &pmcraid_log_level_attr.attr,
+ &pmcraid_driver_version_attr.attr,
+ &pmcraid_adapter_id_attr.attr,
NULL,
};
+ATTRIBUTE_GROUPS(pmcraid_host);
/* host template structure for pmcraid driver */
-static struct scsi_host_template pmcraid_host_template = {
+static const struct scsi_host_template pmcraid_host_template = {
.module = THIS_MODULE,
.name = PMCRAID_DRIVER_NAME,
.queuecommand = pmcraid_queuecommand,
@@ -4305,19 +3668,18 @@ static struct scsi_host_template pmcraid_host_template = {
.eh_device_reset_handler = pmcraid_eh_device_reset_handler,
.eh_host_reset_handler = pmcraid_eh_host_reset_handler,
- .slave_alloc = pmcraid_slave_alloc,
- .slave_configure = pmcraid_slave_configure,
- .slave_destroy = pmcraid_slave_destroy,
+ .sdev_init = pmcraid_sdev_init,
+ .sdev_configure = pmcraid_sdev_configure,
+ .sdev_destroy = pmcraid_sdev_destroy,
.change_queue_depth = pmcraid_change_queue_depth,
- .change_queue_type = pmcraid_change_queue_type,
.can_queue = PMCRAID_MAX_IO_CMD,
.this_id = -1,
.sg_tablesize = PMCRAID_MAX_IOADLS,
.max_sectors = PMCRAID_IOA_MAX_SECTORS,
+ .no_write_same = 1,
.cmd_per_lun = PMCRAID_MAX_CMD_PER_LUN,
- .use_clustering = ENABLE_CLUSTERING,
- .shost_attrs = pmcraid_host_attrs,
- .proc_name = PMCRAID_DRIVER_NAME
+ .shost_groups = pmcraid_host_groups,
+ .proc_name = PMCRAID_DRIVER_NAME,
};
/*
@@ -4536,7 +3898,7 @@ static void pmcraid_worker_function(struct work_struct *workp)
if (fw_version <= PMCRAID_FW_VERSION_1)
target = res->cfg_entry.unique_flags1;
else
- target = res->cfg_entry.array_id & 0xFF;
+ target = le16_to_cpu(res->cfg_entry.array_id) & 0xFF;
lun = PMCRAID_VSET_LUN_ID;
} else {
bus = PMCRAID_PHYS_BUS_ID;
@@ -4575,7 +3937,7 @@ static void pmcraid_tasklet_function(unsigned long instance)
unsigned long host_lock_flags;
spinlock_t *lockp; /* hrrq buffer lock */
int id;
- __le32 resp;
+ u32 resp;
hrrq_vector = (struct pmcraid_isr_param *)instance;
pinstance = hrrq_vector->drv_inst;
@@ -4620,7 +3982,7 @@ static void pmcraid_tasklet_function(unsigned long instance)
list_del(&cmd->free_list);
spin_unlock_irqrestore(&pinstance->pending_pool_lock,
pending_lock_flags);
- del_timer(&cmd->timer);
+ timer_delete(&cmd->timer);
atomic_dec(&pinstance->outstanding_cmds);
if (cmd->cmd_done == pmcraid_ioa_reset) {
@@ -4647,22 +4009,20 @@ static void pmcraid_tasklet_function(unsigned long instance)
* This routine un-registers registered interrupt handler and
* also frees irqs/vectors.
*
- * Retun Value
+ * Return Value
* None
*/
static
void pmcraid_unregister_interrupt_handler(struct pmcraid_instance *pinstance)
{
+ struct pci_dev *pdev = pinstance->pdev;
int i;
for (i = 0; i < pinstance->num_hrrq; i++)
- free_irq(pinstance->hrrq_vector[i].vector,
- &(pinstance->hrrq_vector[i]));
+ free_irq(pci_irq_vector(pdev, i), &pinstance->hrrq_vector[i]);
- if (pinstance->interrupt_mode) {
- pci_disable_msix(pinstance->pdev);
- pinstance->interrupt_mode = 0;
- }
+ pinstance->interrupt_mode = 0;
+ pci_free_irq_vectors(pdev);
}
/**
@@ -4675,70 +4035,52 @@ void pmcraid_unregister_interrupt_handler(struct pmcraid_instance *pinstance)
static int
pmcraid_register_interrupt_handler(struct pmcraid_instance *pinstance)
{
- int rc;
struct pci_dev *pdev = pinstance->pdev;
+ unsigned int irq_flag = PCI_IRQ_INTX, flag;
+ int num_hrrq, rc, i;
+ irq_handler_t isr;
- if ((pmcraid_enable_msix) &&
- (pci_find_capability(pdev, PCI_CAP_ID_MSIX))) {
- int num_hrrq = PMCRAID_NUM_MSIX_VECTORS;
- struct msix_entry entries[PMCRAID_NUM_MSIX_VECTORS];
- int i;
- for (i = 0; i < PMCRAID_NUM_MSIX_VECTORS; i++)
- entries[i].entry = i;
+ if (pmcraid_enable_msix)
+ irq_flag |= PCI_IRQ_MSIX;
- rc = pci_enable_msix(pdev, entries, num_hrrq);
- if (rc < 0)
- goto pmcraid_isr_legacy;
+ num_hrrq = pci_alloc_irq_vectors(pdev, 1, PMCRAID_NUM_MSIX_VECTORS,
+ irq_flag);
+ if (num_hrrq < 0)
+ return num_hrrq;
- /* Check how many MSIX vectors are allocated and register
- * msi-x handlers for each of them giving appropriate buffer
- */
- if (rc > 0) {
- num_hrrq = rc;
- if (pci_enable_msix(pdev, entries, num_hrrq))
- goto pmcraid_isr_legacy;
- }
+ if (pdev->msix_enabled) {
+ flag = 0;
+ isr = pmcraid_isr_msix;
+ } else {
+ flag = IRQF_SHARED;
+ isr = pmcraid_isr;
+ }
- for (i = 0; i < num_hrrq; i++) {
- pinstance->hrrq_vector[i].hrrq_id = i;
- pinstance->hrrq_vector[i].drv_inst = pinstance;
- pinstance->hrrq_vector[i].vector = entries[i].vector;
- rc = request_irq(pinstance->hrrq_vector[i].vector,
- pmcraid_isr_msix, 0,
- PMCRAID_DRIVER_NAME,
- &(pinstance->hrrq_vector[i]));
-
- if (rc) {
- int j;
- for (j = 0; j < i; j++)
- free_irq(entries[j].vector,
- &(pinstance->hrrq_vector[j]));
- pci_disable_msix(pdev);
- goto pmcraid_isr_legacy;
- }
- }
+ for (i = 0; i < num_hrrq; i++) {
+ struct pmcraid_isr_param *vec = &pinstance->hrrq_vector[i];
+
+ vec->hrrq_id = i;
+ vec->drv_inst = pinstance;
+ rc = request_irq(pci_irq_vector(pdev, i), isr, flag,
+ PMCRAID_DRIVER_NAME, vec);
+ if (rc)
+ goto out_unwind;
+ }
- pinstance->num_hrrq = num_hrrq;
+ pinstance->num_hrrq = num_hrrq;
+ if (pdev->msix_enabled) {
pinstance->interrupt_mode = 1;
iowrite32(DOORBELL_INTR_MODE_MSIX,
pinstance->int_regs.host_ioa_interrupt_reg);
ioread32(pinstance->int_regs.host_ioa_interrupt_reg);
- goto pmcraid_isr_out;
}
-pmcraid_isr_legacy:
- /* If MSI-X registration failed fallback to legacy mode, where
- * only one hrrq entry will be used
- */
- pinstance->hrrq_vector[0].hrrq_id = 0;
- pinstance->hrrq_vector[0].drv_inst = pinstance;
- pinstance->hrrq_vector[0].vector = pdev->irq;
- pinstance->num_hrrq = 1;
- rc = 0;
-
- rc = request_irq(pdev->irq, pmcraid_isr, IRQF_SHARED,
- PMCRAID_DRIVER_NAME, &pinstance->hrrq_vector[0]);
-pmcraid_isr_out:
+ return 0;
+
+out_unwind:
+ while (--i >= 0)
+ free_irq(pci_irq_vector(pdev, i), &pinstance->hrrq_vector[i]);
+ pci_free_irq_vectors(pdev);
return rc;
}
@@ -4785,19 +4127,19 @@ pmcraid_release_control_blocks(
return;
for (i = 0; i < max_index; i++) {
- pci_pool_free(pinstance->control_pool,
+ dma_pool_free(pinstance->control_pool,
pinstance->cmd_list[i]->ioa_cb,
pinstance->cmd_list[i]->ioa_cb_bus_addr);
pinstance->cmd_list[i]->ioa_cb = NULL;
pinstance->cmd_list[i]->ioa_cb_bus_addr = 0;
}
- pci_pool_destroy(pinstance->control_pool);
+ dma_pool_destroy(pinstance->control_pool);
pinstance->control_pool = NULL;
}
/**
* pmcraid_allocate_cmd_blocks - allocate memory for cmd block structures
- * @pinstance - pointer to per adapter instance structure
+ * @pinstance: pointer to per adapter instance structure
*
* Allocates memory for command blocks using kernel slab allocator.
*
@@ -4848,8 +4190,8 @@ static int pmcraid_allocate_control_blocks(struct pmcraid_instance *pinstance)
pinstance->host->unique_id);
pinstance->control_pool =
- pci_pool_create(pinstance->ctl_pool_name,
- pinstance->pdev,
+ dma_pool_create(pinstance->ctl_pool_name,
+ &pinstance->pdev->dev,
sizeof(struct pmcraid_control_block),
PMCRAID_IOARCB_ALIGNMENT, 0);
@@ -4858,7 +4200,7 @@ static int pmcraid_allocate_control_blocks(struct pmcraid_instance *pinstance)
for (i = 0; i < PMCRAID_MAX_CMD; i++) {
pinstance->cmd_list[i]->ioa_cb =
- pci_pool_alloc(
+ dma_pool_zalloc(
pinstance->control_pool,
GFP_KERNEL,
&(pinstance->cmd_list[i]->ioa_cb_bus_addr));
@@ -4867,8 +4209,6 @@ static int pmcraid_allocate_control_blocks(struct pmcraid_instance *pinstance)
pmcraid_release_control_blocks(pinstance, i);
return -ENOMEM;
}
- memset(pinstance->cmd_list[i]->ioa_cb, 0,
- sizeof(struct pmcraid_control_block));
}
return 0;
}
@@ -4885,9 +4225,9 @@ static void
pmcraid_release_host_rrqs(struct pmcraid_instance *pinstance, int maxindex)
{
int i;
- for (i = 0; i < maxindex; i++) {
- pci_free_consistent(pinstance->pdev,
+ for (i = 0; i < maxindex; i++) {
+ dma_free_coherent(&pinstance->pdev->dev,
HRRQ_ENTRY_SIZE * PMCRAID_MAX_CMD,
pinstance->hrrq_start[i],
pinstance->hrrq_start_bus_addr[i]);
@@ -4914,19 +4254,16 @@ static int pmcraid_allocate_host_rrqs(struct pmcraid_instance *pinstance)
for (i = 0; i < pinstance->num_hrrq; i++) {
pinstance->hrrq_start[i] =
- pci_alloc_consistent(
- pinstance->pdev,
- buffer_size,
- &(pinstance->hrrq_start_bus_addr[i]));
-
- if (pinstance->hrrq_start[i] == 0) {
+ dma_alloc_coherent(&pinstance->pdev->dev, buffer_size,
+ &pinstance->hrrq_start_bus_addr[i],
+ GFP_KERNEL);
+ if (!pinstance->hrrq_start[i]) {
pmcraid_err("pci_alloc failed for hrrq vector : %d\n",
i);
pmcraid_release_host_rrqs(pinstance, i);
return -ENOMEM;
}
- memset(pinstance->hrrq_start[i], 0, buffer_size);
pinstance->hrrq_curr[i] = pinstance->hrrq_start[i];
pinstance->hrrq_end[i] =
pinstance->hrrq_start[i] + PMCRAID_MAX_CMD - 1;
@@ -4947,7 +4284,7 @@ static int pmcraid_allocate_host_rrqs(struct pmcraid_instance *pinstance)
static void pmcraid_release_hcams(struct pmcraid_instance *pinstance)
{
if (pinstance->ccn.msg != NULL) {
- pci_free_consistent(pinstance->pdev,
+ dma_free_coherent(&pinstance->pdev->dev,
PMCRAID_AEN_HDR_SIZE +
sizeof(struct pmcraid_hcam_ccn_ext),
pinstance->ccn.msg,
@@ -4959,7 +4296,7 @@ static void pmcraid_release_hcams(struct pmcraid_instance *pinstance)
}
if (pinstance->ldn.msg != NULL) {
- pci_free_consistent(pinstance->pdev,
+ dma_free_coherent(&pinstance->pdev->dev,
PMCRAID_AEN_HDR_SIZE +
sizeof(struct pmcraid_hcam_ldn),
pinstance->ldn.msg,
@@ -4980,17 +4317,15 @@ static void pmcraid_release_hcams(struct pmcraid_instance *pinstance)
*/
static int pmcraid_allocate_hcams(struct pmcraid_instance *pinstance)
{
- pinstance->ccn.msg = pci_alloc_consistent(
- pinstance->pdev,
+ pinstance->ccn.msg = dma_alloc_coherent(&pinstance->pdev->dev,
PMCRAID_AEN_HDR_SIZE +
sizeof(struct pmcraid_hcam_ccn_ext),
- &(pinstance->ccn.baddr));
+ &pinstance->ccn.baddr, GFP_KERNEL);
- pinstance->ldn.msg = pci_alloc_consistent(
- pinstance->pdev,
+ pinstance->ldn.msg = dma_alloc_coherent(&pinstance->pdev->dev,
PMCRAID_AEN_HDR_SIZE +
sizeof(struct pmcraid_hcam_ldn),
- &(pinstance->ldn.baddr));
+ &pinstance->ldn.baddr, GFP_KERNEL);
if (pinstance->ldn.msg == NULL || pinstance->ccn.msg == NULL) {
pmcraid_release_hcams(pinstance);
@@ -5018,7 +4353,7 @@ static void pmcraid_release_config_buffers(struct pmcraid_instance *pinstance)
{
if (pinstance->cfg_table != NULL &&
pinstance->cfg_table_bus_addr != 0) {
- pci_free_consistent(pinstance->pdev,
+ dma_free_coherent(&pinstance->pdev->dev,
sizeof(struct pmcraid_config_table),
pinstance->cfg_table,
pinstance->cfg_table_bus_addr);
@@ -5050,8 +4385,9 @@ static int pmcraid_allocate_config_buffers(struct pmcraid_instance *pinstance)
int i;
pinstance->res_entries =
- kzalloc(sizeof(struct pmcraid_resource_entry) *
- PMCRAID_MAX_RESOURCES, GFP_KERNEL);
+ kcalloc(PMCRAID_MAX_RESOURCES,
+ sizeof(struct pmcraid_resource_entry),
+ GFP_KERNEL);
if (NULL == pinstance->res_entries) {
pmcraid_err("failed to allocate memory for resource table\n");
@@ -5062,10 +4398,10 @@ static int pmcraid_allocate_config_buffers(struct pmcraid_instance *pinstance)
list_add_tail(&pinstance->res_entries[i].queue,
&pinstance->free_res_q);
- pinstance->cfg_table =
- pci_alloc_consistent(pinstance->pdev,
+ pinstance->cfg_table = dma_alloc_coherent(&pinstance->pdev->dev,
sizeof(struct pmcraid_config_table),
- &pinstance->cfg_table_bus_addr);
+ &pinstance->cfg_table_bus_addr,
+ GFP_KERNEL);
if (NULL == pinstance->cfg_table) {
pmcraid_err("couldn't alloc DMA memory for config table\n");
@@ -5130,7 +4466,7 @@ static void pmcraid_release_buffers(struct pmcraid_instance *pinstance)
pmcraid_release_host_rrqs(pinstance, pinstance->num_hrrq);
if (pinstance->inq_data != NULL) {
- pci_free_consistent(pinstance->pdev,
+ dma_free_coherent(&pinstance->pdev->dev,
sizeof(struct pmcraid_inquiry_data),
pinstance->inq_data,
pinstance->inq_data_baddr);
@@ -5140,7 +4476,7 @@ static void pmcraid_release_buffers(struct pmcraid_instance *pinstance)
}
if (pinstance->timestamp_data != NULL) {
- pci_free_consistent(pinstance->pdev,
+ dma_free_coherent(&pinstance->pdev->dev,
sizeof(struct pmcraid_timestamp_data),
pinstance->timestamp_data,
pinstance->timestamp_data_baddr);
@@ -5157,8 +4493,8 @@ static void pmcraid_release_buffers(struct pmcraid_instance *pinstance)
* This routine pre-allocates memory based on the type of block as below:
* cmdblocks(PMCRAID_MAX_CMD): kernel memory using kernel's slab_allocator,
* IOARCBs(PMCRAID_MAX_CMD) : DMAable memory, using pci pool allocator
- * config-table entries : DMAable memory using pci_alloc_consistent
- * HostRRQs : DMAable memory, using pci_alloc_consistent
+ * config-table entries : DMAable memory using dma_alloc_coherent
+ * HostRRQs : DMAable memory, using dma_alloc_coherent
*
* Return Value
* 0 in case all of the blocks are allocated, -ENOMEM otherwise.
@@ -5195,11 +4531,9 @@ static int pmcraid_init_buffers(struct pmcraid_instance *pinstance)
}
/* allocate DMAable memory for page D0 INQUIRY buffer */
- pinstance->inq_data = pci_alloc_consistent(
- pinstance->pdev,
+ pinstance->inq_data = dma_alloc_coherent(&pinstance->pdev->dev,
sizeof(struct pmcraid_inquiry_data),
- &pinstance->inq_data_baddr);
-
+ &pinstance->inq_data_baddr, GFP_KERNEL);
if (pinstance->inq_data == NULL) {
pmcraid_err("couldn't allocate DMA memory for INQUIRY\n");
pmcraid_release_buffers(pinstance);
@@ -5207,11 +4541,10 @@ static int pmcraid_init_buffers(struct pmcraid_instance *pinstance)
}
/* allocate DMAable memory for set timestamp data buffer */
- pinstance->timestamp_data = pci_alloc_consistent(
- pinstance->pdev,
+ pinstance->timestamp_data = dma_alloc_coherent(&pinstance->pdev->dev,
sizeof(struct pmcraid_timestamp_data),
- &pinstance->timestamp_data_baddr);
-
+ &pinstance->timestamp_data_baddr,
+ GFP_KERNEL);
if (pinstance->timestamp_data == NULL) {
pmcraid_err("couldn't allocate DMA memory for \
set time_stamp \n");
@@ -5304,7 +4637,7 @@ static int pmcraid_init_instance(struct pci_dev *pdev, struct Scsi_Host *host,
mapped_pci_addr + chip_cfg->ioa_host_mask_clr;
pint_regs->global_interrupt_mask_reg =
mapped_pci_addr + chip_cfg->global_intr_mask;
- };
+ }
pinstance->ioa_reset_attempts = 0;
init_waitqueue_head(&pinstance->reset_wait_q);
@@ -5351,19 +4684,19 @@ static void pmcraid_shutdown(struct pci_dev *pdev)
}
-/**
+/*
* pmcraid_get_minor - returns unused minor number from minor number bitmap
*/
static unsigned short pmcraid_get_minor(void)
{
int minor;
- minor = find_first_zero_bit(pmcraid_minor, sizeof(pmcraid_minor));
+ minor = find_first_zero_bit(pmcraid_minor, PMCRAID_MAX_ADAPTERS);
__set_bit(minor, pmcraid_minor);
return minor;
}
-/**
+/*
* pmcraid_release_minor - releases given minor back to minor number bitmap
*/
static void pmcraid_release_minor(unsigned short minor)
@@ -5393,7 +4726,7 @@ static int pmcraid_setup_chrdev(struct pmcraid_instance *pinstance)
if (error)
pmcraid_release_minor(minor);
else
- device_create(pmcraid_class, NULL, MKDEV(pmcraid_major, minor),
+ device_create(&pmcraid_class, NULL, MKDEV(pmcraid_major, minor),
NULL, "%s%u", PMCRAID_DEVFILE, minor);
return error;
}
@@ -5409,7 +4742,7 @@ static int pmcraid_setup_chrdev(struct pmcraid_instance *pinstance)
static void pmcraid_release_chrdev(struct pmcraid_instance *pinstance)
{
pmcraid_release_minor(MINOR(pinstance->cdev.dev));
- device_destroy(pmcraid_class,
+ device_destroy(&pmcraid_class,
MKDEV(pmcraid_major, MINOR(pinstance->cdev.dev)));
cdev_del(&pinstance->cdev);
}
@@ -5451,61 +4784,44 @@ static void pmcraid_remove(struct pci_dev *pdev)
return;
}
-#ifdef CONFIG_PM
/**
* pmcraid_suspend - driver suspend entry point for power management
- * @pdev: PCI device structure
- * @state: PCI power state to suspend routine
+ * @dev: Device structure
*
* Return Value - 0 always
*/
-static int pmcraid_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused pmcraid_suspend(struct device *dev)
{
+ struct pci_dev *pdev = to_pci_dev(dev);
struct pmcraid_instance *pinstance = pci_get_drvdata(pdev);
pmcraid_shutdown(pdev);
pmcraid_disable_interrupts(pinstance, ~0);
pmcraid_kill_tasklets(pinstance);
- pci_set_drvdata(pinstance->pdev, pinstance);
pmcraid_unregister_interrupt_handler(pinstance);
- pci_save_state(pdev);
- pci_disable_device(pdev);
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
return 0;
}
/**
* pmcraid_resume - driver resume entry point PCI power management
- * @pdev: PCI device structure
+ * @dev: Device structure
*
* Return Value - 0 in case of success. Error code in case of any failure
*/
-static int pmcraid_resume(struct pci_dev *pdev)
+static int __maybe_unused pmcraid_resume(struct device *dev)
{
+ struct pci_dev *pdev = to_pci_dev(dev);
struct pmcraid_instance *pinstance = pci_get_drvdata(pdev);
struct Scsi_Host *host = pinstance->host;
- int rc;
-
- pci_set_power_state(pdev, PCI_D0);
- pci_enable_wake(pdev, PCI_D0, 0);
- pci_restore_state(pdev);
-
- rc = pci_enable_device(pdev);
-
- if (rc) {
- dev_err(&pdev->dev, "resume: Enable device failed\n");
- return rc;
- }
-
- pci_set_master(pdev);
+ int rc = 0;
- if ((sizeof(dma_addr_t) == 4) ||
- pci_set_dma_mask(pdev, DMA_BIT_MASK(64)))
- rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+ if (sizeof(dma_addr_t) == 4 ||
+ dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)))
+ rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
if (rc == 0)
- rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+ rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
if (rc != 0) {
dev_err(&pdev->dev, "resume: Failed to set PCI DMA mask\n");
@@ -5551,18 +4867,10 @@ release_host:
scsi_host_put(host);
disable_device:
- pci_disable_device(pdev);
return rc;
}
-#else
-
-#define pmcraid_suspend NULL
-#define pmcraid_resume NULL
-
-#endif /* CONFIG_PM */
-
/**
* pmcraid_complete_ioa_reset - Called by either timer or tasklet during
* completion of the ioa reset
@@ -5634,13 +4942,10 @@ static void pmcraid_set_timestamp(struct pmcraid_cmd *cmd)
struct pmcraid_instance *pinstance = cmd->drv_inst;
struct pmcraid_ioarcb *ioarcb = &cmd->ioa_cb->ioarcb;
__be32 time_stamp_len = cpu_to_be32(PMCRAID_TIMESTAMP_LEN);
- struct pmcraid_ioadl_desc *ioadl = ioarcb->add_data.u.ioadl;
-
- struct timeval tv;
- __le64 timestamp;
+ struct pmcraid_ioadl_desc *ioadl;
+ u64 timestamp;
- do_gettimeofday(&tv);
- timestamp = tv.tv_sec * 1000;
+ timestamp = ktime_get_real_seconds() * 1000;
pinstance->timestamp_data->timestamp[0] = (__u8)(timestamp);
pinstance->timestamp_data->timestamp[1] = (__u8)((timestamp) >> 8);
@@ -5660,7 +4965,7 @@ static void pmcraid_set_timestamp(struct pmcraid_cmd *cmd)
offsetof(struct pmcraid_ioarcb,
add_data.u.ioadl[0]));
ioarcb->ioadl_length = cpu_to_le32(sizeof(struct pmcraid_ioadl_desc));
- ioarcb->ioarcb_bus_addr &= ~(0x1FULL);
+ ioarcb->ioarcb_bus_addr &= cpu_to_le64(~(0x1FULL));
ioarcb->request_flags0 |= NO_LINK_DESCS;
ioarcb->request_flags0 |= TRANSFER_DIR_WRITE;
@@ -5719,7 +5024,7 @@ static void pmcraid_init_res_table(struct pmcraid_cmd *cmd)
list_for_each_entry_safe(res, temp, &pinstance->used_res_q, queue)
list_move_tail(&res->queue, &old_res);
- for (i = 0; i < pinstance->cfg_table->num_entries; i++) {
+ for (i = 0; i < le16_to_cpu(pinstance->cfg_table->num_entries); i++) {
if (be16_to_cpu(pinstance->inq_data->fw_version) <=
PMCRAID_FW_VERSION_1)
cfgte = &pinstance->cfg_table->entries[i];
@@ -5774,7 +5079,7 @@ static void pmcraid_init_res_table(struct pmcraid_cmd *cmd)
res->cfg_entry.resource_type,
(fw_version <= PMCRAID_FW_VERSION_1 ?
res->cfg_entry.unique_flags1 :
- res->cfg_entry.array_id & 0xFF),
+ le16_to_cpu(res->cfg_entry.array_id) & 0xFF),
le32_to_cpu(res->cfg_entry.resource_address));
}
}
@@ -5810,9 +5115,9 @@ static void pmcraid_init_res_table(struct pmcraid_cmd *cmd)
static void pmcraid_querycfg(struct pmcraid_cmd *cmd)
{
struct pmcraid_ioarcb *ioarcb = &cmd->ioa_cb->ioarcb;
- struct pmcraid_ioadl_desc *ioadl = ioarcb->add_data.u.ioadl;
+ struct pmcraid_ioadl_desc *ioadl;
struct pmcraid_instance *pinstance = cmd->drv_inst;
- int cfg_table_size = cpu_to_be32(sizeof(struct pmcraid_config_table));
+ __be32 cfg_table_size = cpu_to_be32(sizeof(struct pmcraid_config_table));
if (be16_to_cpu(pinstance->inq_data->fw_version) <=
PMCRAID_FW_VERSION_1)
@@ -5837,7 +5142,7 @@ static void pmcraid_querycfg(struct pmcraid_cmd *cmd)
offsetof(struct pmcraid_ioarcb,
add_data.u.ioadl[0]));
ioarcb->ioadl_length = cpu_to_le32(sizeof(struct pmcraid_ioadl_desc));
- ioarcb->ioarcb_bus_addr &= ~(0x1FULL);
+ ioarcb->ioarcb_bus_addr &= cpu_to_le64(~0x1FULL);
ioarcb->request_flags0 |= NO_LINK_DESCS;
ioarcb->data_transfer_length =
@@ -5912,19 +5217,19 @@ static int pmcraid_probe(struct pci_dev *pdev,
/* Firmware requires the system bus address of IOARCB to be within
* 32-bit addressable range though it has 64-bit IOARRIN register.
* However, firmware supports 64-bit streaming DMA buffers, whereas
- * coherent buffers are to be 32-bit. Since pci_alloc_consistent always
+ * coherent buffers are to be 32-bit. Since dma_alloc_coherent always
* returns memory within 4GB (if not, change this logic), coherent
* buffers are within firmware acceptable address ranges.
*/
- if ((sizeof(dma_addr_t) == 4) ||
- pci_set_dma_mask(pdev, DMA_BIT_MASK(64)))
- rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+ if (sizeof(dma_addr_t) == 4 ||
+ dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)))
+ rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
/* firmware expects 32-bit DMA addresses for IOARRIN register; set 32
- * bit mask for pci_alloc_consistent to return addresses within 4GB
+ * bit mask for dma_alloc_coherent to return addresses within 4GB
*/
if (rc == 0)
- rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+ rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
if (rc != 0) {
dev_err(&pdev->dev, "Failed to set PCI DMA mask\n");
@@ -6049,21 +5354,21 @@ out_release_regions:
out_disable_device:
atomic_dec(&pmcraid_adapter_count);
- pci_set_drvdata(pdev, NULL);
pci_disable_device(pdev);
return -ENODEV;
}
+static SIMPLE_DEV_PM_OPS(pmcraid_pm_ops, pmcraid_suspend, pmcraid_resume);
+
/*
- * PCI driver structure of pcmraid driver
+ * PCI driver structure of pmcraid driver
*/
static struct pci_driver pmcraid_driver = {
.name = PMCRAID_DRIVER_NAME,
.id_table = pmcraid_pci_table,
.probe = pmcraid_probe,
.remove = pmcraid_remove,
- .suspend = pmcraid_suspend,
- .resume = pmcraid_resume,
+ .driver.pm = &pmcraid_pm_ops,
.shutdown = pmcraid_shutdown
};
@@ -6088,10 +5393,10 @@ static int __init pmcraid_init(void)
}
pmcraid_major = MAJOR(dev);
- pmcraid_class = class_create(THIS_MODULE, PMCRAID_DEVFILE);
- if (IS_ERR(pmcraid_class)) {
- error = PTR_ERR(pmcraid_class);
+ error = class_register(&pmcraid_class);
+
+ if (error) {
pmcraid_err("failed to register with sysfs, error = %x\n",
error);
goto out_unreg_chrdev;
@@ -6099,8 +5404,10 @@ static int __init pmcraid_init(void)
error = pmcraid_netlink_init();
- if (error)
+ if (error) {
+ class_unregister(&pmcraid_class);
goto out_unreg_chrdev;
+ }
error = pci_register_driver(&pmcraid_driver);
@@ -6109,7 +5416,7 @@ static int __init pmcraid_init(void)
pmcraid_err("failed to register pmcraid driver, error = %x\n",
error);
- class_destroy(pmcraid_class);
+ class_unregister(&pmcraid_class);
pmcraid_netlink_release();
out_unreg_chrdev:
@@ -6128,7 +5435,7 @@ static void __exit pmcraid_exit(void)
unregister_chrdev_region(MKDEV(pmcraid_major, 0),
PMCRAID_MAX_ADAPTERS);
pci_unregister_driver(&pmcraid_driver);
- class_destroy(pmcraid_class);
+ class_unregister(&pmcraid_class);
}
module_init(pmcraid_init);