Commit d3849d51 authored by David Woodhouse's avatar David Woodhouse Committed by James Bottomley

[SCSI] Fix ibmvscsi client for multiplatform iSeries+pSeries kernel

If you build a multiplatform kernel for iSeries and pSeries, with
ibmvscsic support, the resulting client doesn't work on iSeries.

This fixes that, using the appropriate low-level operations
for the machine detected at runtime.

[jejb: fixed up rejections around the srp transport patch]
Signed-off-by: default avatarDavid Woodhouse <dwmw2@infradead.org>
Acked by: Brian King <brking@linux.vnet.ibm.com>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 5307b1e8
obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsic.o obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsic.o
ibmvscsic-y += ibmvscsi.o ibmvscsic-y += ibmvscsi.o
ifndef CONFIG_PPC_PSERIES
ibmvscsic-$(CONFIG_PPC_ISERIES) += iseries_vscsi.o ibmvscsic-$(CONFIG_PPC_ISERIES) += iseries_vscsi.o
endif
ibmvscsic-$(CONFIG_PPC_PSERIES) += rpa_vscsi.o ibmvscsic-$(CONFIG_PPC_PSERIES) += rpa_vscsi.o
obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvstgt.o obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvstgt.o
...@@ -70,6 +70,7 @@ ...@@ -70,6 +70,7 @@
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <asm/firmware.h>
#include <asm/vio.h> #include <asm/vio.h>
#include <scsi/scsi.h> #include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h> #include <scsi/scsi_cmnd.h>
...@@ -92,6 +93,8 @@ static struct scsi_transport_template *ibmvscsi_transport_template; ...@@ -92,6 +93,8 @@ static struct scsi_transport_template *ibmvscsi_transport_template;
#define IBMVSCSI_VERSION "1.5.8" #define IBMVSCSI_VERSION "1.5.8"
static struct ibmvscsi_ops *ibmvscsi_ops;
MODULE_DESCRIPTION("IBM Virtual SCSI"); MODULE_DESCRIPTION("IBM Virtual SCSI");
MODULE_AUTHOR("Dave Boutcher"); MODULE_AUTHOR("Dave Boutcher");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -509,8 +512,8 @@ static void ibmvscsi_reset_host(struct ibmvscsi_host_data *hostdata) ...@@ -509,8 +512,8 @@ static void ibmvscsi_reset_host(struct ibmvscsi_host_data *hostdata)
atomic_set(&hostdata->request_limit, 0); atomic_set(&hostdata->request_limit, 0);
purge_requests(hostdata, DID_ERROR); purge_requests(hostdata, DID_ERROR);
if ((ibmvscsi_reset_crq_queue(&hostdata->queue, hostdata)) || if ((ibmvscsi_ops->reset_crq_queue(&hostdata->queue, hostdata)) ||
(ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0)) || (ibmvscsi_ops->send_crq(hostdata, 0xC001000000000000LL, 0)) ||
(vio_enable_interrupts(to_vio_dev(hostdata->dev)))) { (vio_enable_interrupts(to_vio_dev(hostdata->dev)))) {
atomic_set(&hostdata->request_limit, -1); atomic_set(&hostdata->request_limit, -1);
dev_err(hostdata->dev, "error after reset\n"); dev_err(hostdata->dev, "error after reset\n");
...@@ -615,7 +618,7 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct, ...@@ -615,7 +618,7 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct,
} }
if ((rc = if ((rc =
ibmvscsi_send_crq(hostdata, crq_as_u64[0], crq_as_u64[1])) != 0) { ibmvscsi_ops->send_crq(hostdata, crq_as_u64[0], crq_as_u64[1])) != 0) {
list_del(&evt_struct->list); list_del(&evt_struct->list);
del_timer(&evt_struct->timer); del_timer(&evt_struct->timer);
...@@ -1214,8 +1217,8 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq, ...@@ -1214,8 +1217,8 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq,
case 0x01: /* Initialization message */ case 0x01: /* Initialization message */
dev_info(hostdata->dev, "partner initialized\n"); dev_info(hostdata->dev, "partner initialized\n");
/* Send back a response */ /* Send back a response */
if ((rc = ibmvscsi_send_crq(hostdata, if ((rc = ibmvscsi_ops->send_crq(hostdata,
0xC002000000000000LL, 0)) == 0) { 0xC002000000000000LL, 0)) == 0) {
/* Now login */ /* Now login */
send_srp_login(hostdata); send_srp_login(hostdata);
} else { } else {
...@@ -1240,10 +1243,10 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq, ...@@ -1240,10 +1243,10 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq,
/* We need to re-setup the interpartition connection */ /* We need to re-setup the interpartition connection */
dev_info(hostdata->dev, "Re-enabling adapter!\n"); dev_info(hostdata->dev, "Re-enabling adapter!\n");
purge_requests(hostdata, DID_REQUEUE); purge_requests(hostdata, DID_REQUEUE);
if ((ibmvscsi_reenable_crq_queue(&hostdata->queue, if ((ibmvscsi_ops->reenable_crq_queue(&hostdata->queue,
hostdata)) || hostdata)) ||
(ibmvscsi_send_crq(hostdata, (ibmvscsi_ops->send_crq(hostdata,
0xC001000000000000LL, 0))) { 0xC001000000000000LL, 0))) {
atomic_set(&hostdata->request_limit, atomic_set(&hostdata->request_limit,
-1); -1);
dev_err(hostdata->dev, "error after enable\n"); dev_err(hostdata->dev, "error after enable\n");
...@@ -1253,10 +1256,10 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq, ...@@ -1253,10 +1256,10 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq,
crq->format); crq->format);
purge_requests(hostdata, DID_ERROR); purge_requests(hostdata, DID_ERROR);
if ((ibmvscsi_reset_crq_queue(&hostdata->queue, if ((ibmvscsi_ops->reset_crq_queue(&hostdata->queue,
hostdata)) || hostdata)) ||
(ibmvscsi_send_crq(hostdata, (ibmvscsi_ops->send_crq(hostdata,
0xC001000000000000LL, 0))) { 0xC001000000000000LL, 0))) {
atomic_set(&hostdata->request_limit, atomic_set(&hostdata->request_limit,
-1); -1);
dev_err(hostdata->dev, "error after reset\n"); dev_err(hostdata->dev, "error after reset\n");
...@@ -1579,7 +1582,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) ...@@ -1579,7 +1582,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id)
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 = 32 * 8; /* default max I/O 32 pages */
rc = ibmvscsi_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) {
dev_err(&vdev->dev, "couldn't initialize crq. rc=%d\n", rc); dev_err(&vdev->dev, "couldn't initialize crq. rc=%d\n", rc);
goto init_crq_failed; goto init_crq_failed;
...@@ -1608,7 +1611,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) ...@@ -1608,7 +1611,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id)
* to fail if the other end is not acive. In that case we don't * to fail if the other end is not acive. In that case we don't
* want to scan * want to scan
*/ */
if (ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0) == 0 if (ibmvscsi_ops->send_crq(hostdata, 0xC001000000000000LL, 0) == 0
|| rc == H_RESOURCE) { || rc == H_RESOURCE) {
/* /*
* Wait around max init_timeout secs for the adapter to finish * Wait around max init_timeout secs for the adapter to finish
...@@ -1636,7 +1639,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) ...@@ -1636,7 +1639,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id)
add_host_failed: add_host_failed:
release_event_pool(&hostdata->pool, hostdata); release_event_pool(&hostdata->pool, hostdata);
init_pool_failed: init_pool_failed:
ibmvscsi_release_crq_queue(&hostdata->queue, hostdata, max_requests); ibmvscsi_ops->release_crq_queue(&hostdata->queue, hostdata, max_requests);
init_crq_failed: init_crq_failed:
scsi_host_put(host); scsi_host_put(host);
scsi_host_alloc_failed: scsi_host_alloc_failed:
...@@ -1647,8 +1650,8 @@ static int ibmvscsi_remove(struct vio_dev *vdev) ...@@ -1647,8 +1650,8 @@ static int ibmvscsi_remove(struct vio_dev *vdev)
{ {
struct ibmvscsi_host_data *hostdata = vdev->dev.driver_data; struct ibmvscsi_host_data *hostdata = vdev->dev.driver_data;
release_event_pool(&hostdata->pool, hostdata); release_event_pool(&hostdata->pool, hostdata);
ibmvscsi_release_crq_queue(&hostdata->queue, hostdata, ibmvscsi_ops->release_crq_queue(&hostdata->queue, hostdata,
max_requests); max_requests);
srp_remove_host(hostdata->host); srp_remove_host(hostdata->host);
scsi_remove_host(hostdata->host); scsi_remove_host(hostdata->host);
...@@ -1684,6 +1687,13 @@ int __init ibmvscsi_module_init(void) ...@@ -1684,6 +1687,13 @@ int __init ibmvscsi_module_init(void)
{ {
int ret; int ret;
if (firmware_has_feature(FW_FEATURE_ISERIES))
ibmvscsi_ops = &iseriesvscsi_ops;
else if (firmware_has_feature(FW_FEATURE_VIO))
ibmvscsi_ops = &rpavscsi_ops;
else
return -ENODEV;
ibmvscsi_transport_template = ibmvscsi_transport_template =
srp_attach_transport(&ibmvscsi_transport_functions); srp_attach_transport(&ibmvscsi_transport_functions);
if (!ibmvscsi_transport_template) if (!ibmvscsi_transport_template)
......
...@@ -98,21 +98,25 @@ struct ibmvscsi_host_data { ...@@ -98,21 +98,25 @@ struct ibmvscsi_host_data {
}; };
/* routines for managing a command/response queue */ /* routines for managing a command/response queue */
int ibmvscsi_init_crq_queue(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata,
int max_requests);
void ibmvscsi_release_crq_queue(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata,
int max_requests);
int ibmvscsi_reset_crq_queue(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata);
int ibmvscsi_reenable_crq_queue(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata);
void ibmvscsi_handle_crq(struct viosrp_crq *crq, void ibmvscsi_handle_crq(struct viosrp_crq *crq,
struct ibmvscsi_host_data *hostdata); struct ibmvscsi_host_data *hostdata);
int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata,
u64 word1, u64 word2); struct ibmvscsi_ops {
int (*init_crq_queue)(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata,
int max_requests);
void (*release_crq_queue)(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata,
int max_requests);
int (*reset_crq_queue)(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata);
int (*reenable_crq_queue)(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata);
int (*send_crq)(struct ibmvscsi_host_data *hostdata,
u64 word1, u64 word2);
};
extern struct ibmvscsi_ops iseriesvscsi_ops;
extern struct ibmvscsi_ops rpavscsi_ops;
#endif /* IBMVSCSI_H */ #endif /* IBMVSCSI_H */
...@@ -53,7 +53,7 @@ struct srp_lp_event { ...@@ -53,7 +53,7 @@ struct srp_lp_event {
/** /**
* standard interface for handling logical partition events. * standard interface for handling logical partition events.
*/ */
static void ibmvscsi_handle_event(struct HvLpEvent *lpevt) static void iseriesvscsi_handle_event(struct HvLpEvent *lpevt)
{ {
struct srp_lp_event *evt = (struct srp_lp_event *)lpevt; struct srp_lp_event *evt = (struct srp_lp_event *)lpevt;
...@@ -74,9 +74,9 @@ static void ibmvscsi_handle_event(struct HvLpEvent *lpevt) ...@@ -74,9 +74,9 @@ static void ibmvscsi_handle_event(struct HvLpEvent *lpevt)
/* ------------------------------------------------------------ /* ------------------------------------------------------------
* Routines for driver initialization * Routines for driver initialization
*/ */
int ibmvscsi_init_crq_queue(struct crq_queue *queue, static int iseriesvscsi_init_crq_queue(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata, struct ibmvscsi_host_data *hostdata,
int max_requests) int max_requests)
{ {
int rc; int rc;
...@@ -88,7 +88,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, ...@@ -88,7 +88,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue,
goto viopath_open_failed; goto viopath_open_failed;
} }
rc = vio_setHandler(viomajorsubtype_scsi, ibmvscsi_handle_event); rc = vio_setHandler(viomajorsubtype_scsi, iseriesvscsi_handle_event);
if (rc < 0) { if (rc < 0) {
printk("vio_setHandler failed with rc %d in open_event_path\n", printk("vio_setHandler failed with rc %d in open_event_path\n",
rc); rc);
...@@ -102,9 +102,9 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, ...@@ -102,9 +102,9 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue,
return -1; return -1;
} }
void ibmvscsi_release_crq_queue(struct crq_queue *queue, static void iseriesvscsi_release_crq_queue(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata, struct ibmvscsi_host_data *hostdata,
int max_requests) int max_requests)
{ {
vio_clearHandler(viomajorsubtype_scsi); vio_clearHandler(viomajorsubtype_scsi);
viopath_close(viopath_hostLp, viomajorsubtype_scsi, max_requests); viopath_close(viopath_hostLp, viomajorsubtype_scsi, max_requests);
...@@ -117,8 +117,8 @@ void ibmvscsi_release_crq_queue(struct crq_queue *queue, ...@@ -117,8 +117,8 @@ void ibmvscsi_release_crq_queue(struct crq_queue *queue,
* *
* no-op for iSeries * no-op for iSeries
*/ */
int ibmvscsi_reset_crq_queue(struct crq_queue *queue, static int iseriesvscsi_reset_crq_queue(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata) struct ibmvscsi_host_data *hostdata)
{ {
return 0; return 0;
} }
...@@ -130,19 +130,20 @@ int ibmvscsi_reset_crq_queue(struct crq_queue *queue, ...@@ -130,19 +130,20 @@ int ibmvscsi_reset_crq_queue(struct crq_queue *queue,
* *
* no-op for iSeries * no-op for iSeries
*/ */
int ibmvscsi_reenable_crq_queue(struct crq_queue *queue, static int iseriesvscsi_reenable_crq_queue(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata) struct ibmvscsi_host_data *hostdata)
{ {
return 0; return 0;
} }
/** /**
* ibmvscsi_send_crq: - Send a CRQ * iseriesvscsi_send_crq: - Send a CRQ
* @hostdata: the adapter * @hostdata: the adapter
* @word1: the first 64 bits of the data * @word1: the first 64 bits of the data
* @word2: the second 64 bits of the data * @word2: the second 64 bits of the data
*/ */
int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata, u64 word1, u64 word2) static int iseriesvscsi_send_crq(struct ibmvscsi_host_data *hostdata,
u64 word1, u64 word2)
{ {
single_host_data = hostdata; single_host_data = hostdata;
return HvCallEvent_signalLpEventFast(viopath_hostLp, return HvCallEvent_signalLpEventFast(viopath_hostLp,
...@@ -156,3 +157,11 @@ int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata, u64 word1, u64 word2) ...@@ -156,3 +157,11 @@ int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata, u64 word1, u64 word2)
VIOVERSION << 16, word1, word2, 0, VIOVERSION << 16, word1, word2, 0,
0); 0);
} }
struct ibmvscsi_ops iseriesvscsi_ops = {
.init_crq_queue = iseriesvscsi_init_crq_queue,
.release_crq_queue = iseriesvscsi_release_crq_queue,
.reset_crq_queue = iseriesvscsi_reset_crq_queue,
.reenable_crq_queue = iseriesvscsi_reenable_crq_queue,
.send_crq = iseriesvscsi_send_crq,
};
...@@ -42,14 +42,14 @@ static unsigned int partition_number = -1; ...@@ -42,14 +42,14 @@ static unsigned int partition_number = -1;
* Routines for managing the command/response queue * Routines for managing the command/response queue
*/ */
/** /**
* ibmvscsi_handle_event: - Interrupt handler for crq events * rpavscsi_handle_event: - Interrupt handler for crq events
* @irq: number of irq to handle, not used * @irq: number of irq to handle, not used
* @dev_instance: ibmvscsi_host_data of host that received interrupt * @dev_instance: ibmvscsi_host_data of host that received interrupt
* *
* Disables interrupts and schedules srp_task * Disables interrupts and schedules srp_task
* Always returns IRQ_HANDLED * Always returns IRQ_HANDLED
*/ */
static irqreturn_t ibmvscsi_handle_event(int irq, void *dev_instance) static irqreturn_t rpavscsi_handle_event(int irq, void *dev_instance)
{ {
struct ibmvscsi_host_data *hostdata = struct ibmvscsi_host_data *hostdata =
(struct ibmvscsi_host_data *)dev_instance; (struct ibmvscsi_host_data *)dev_instance;
...@@ -66,9 +66,9 @@ static irqreturn_t ibmvscsi_handle_event(int irq, void *dev_instance) ...@@ -66,9 +66,9 @@ static irqreturn_t ibmvscsi_handle_event(int irq, void *dev_instance)
* Frees irq, deallocates a page for messages, unmaps dma, and unregisters * Frees irq, deallocates a page for messages, unmaps dma, and unregisters
* the crq with the hypervisor. * the crq with the hypervisor.
*/ */
void ibmvscsi_release_crq_queue(struct crq_queue *queue, static void rpavscsi_release_crq_queue(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata, struct ibmvscsi_host_data *hostdata,
int max_requests) int max_requests)
{ {
long rc; long rc;
struct vio_dev *vdev = to_vio_dev(hostdata->dev); struct vio_dev *vdev = to_vio_dev(hostdata->dev);
...@@ -108,12 +108,13 @@ static struct viosrp_crq *crq_queue_next_crq(struct crq_queue *queue) ...@@ -108,12 +108,13 @@ static struct viosrp_crq *crq_queue_next_crq(struct crq_queue *queue)
} }
/** /**
* ibmvscsi_send_crq: - Send a CRQ * rpavscsi_send_crq: - Send a CRQ
* @hostdata: the adapter * @hostdata: the adapter
* @word1: the first 64 bits of the data * @word1: the first 64 bits of the data
* @word2: the second 64 bits of the data * @word2: the second 64 bits of the data
*/ */
int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata, u64 word1, u64 word2) static int rpavscsi_send_crq(struct ibmvscsi_host_data *hostdata,
u64 word1, u64 word2)
{ {
struct vio_dev *vdev = to_vio_dev(hostdata->dev); struct vio_dev *vdev = to_vio_dev(hostdata->dev);
...@@ -121,10 +122,10 @@ int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata, u64 word1, u64 word2) ...@@ -121,10 +122,10 @@ int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata, u64 word1, u64 word2)
} }
/** /**
* ibmvscsi_task: - Process srps asynchronously * rpavscsi_task: - Process srps asynchronously
* @data: ibmvscsi_host_data of host * @data: ibmvscsi_host_data of host
*/ */
static void ibmvscsi_task(void *data) static void rpavscsi_task(void *data)
{ {
struct ibmvscsi_host_data *hostdata = (struct ibmvscsi_host_data *)data; struct ibmvscsi_host_data *hostdata = (struct ibmvscsi_host_data *)data;
struct vio_dev *vdev = to_vio_dev(hostdata->dev); struct vio_dev *vdev = to_vio_dev(hostdata->dev);
...@@ -189,6 +190,42 @@ static void set_adapter_info(struct ibmvscsi_host_data *hostdata) ...@@ -189,6 +190,42 @@ static void set_adapter_info(struct ibmvscsi_host_data *hostdata)
hostdata->madapter_info.os_type = 2; hostdata->madapter_info.os_type = 2;
} }
/**
* reset_crq_queue: - resets a crq after a failure
* @queue: crq_queue to initialize and register
* @hostdata: ibmvscsi_host_data of host
*
*/
static int rpavscsi_reset_crq_queue(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata)
{
int rc;
struct vio_dev *vdev = to_vio_dev(hostdata->dev);
/* Close the CRQ */
do {
rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address);
} while ((rc == H_BUSY) || (H_IS_LONG_BUSY(rc)));
/* Clean out the queue */
memset(queue->msgs, 0x00, PAGE_SIZE);
queue->cur = 0;
set_adapter_info(hostdata);
/* And re-open it again */
rc = plpar_hcall_norets(H_REG_CRQ,
vdev->unit_address,
queue->msg_token, PAGE_SIZE);
if (rc == 2) {
/* Adapter is good, but other end is not ready */
dev_warn(hostdata->dev, "Partner adapter not ready\n");
} else if (rc != 0) {
dev_warn(hostdata->dev, "couldn't register crq--rc 0x%x\n", rc);
}
return rc;
}
/** /**
* initialize_crq_queue: - Initializes and registers CRQ with hypervisor * initialize_crq_queue: - Initializes and registers CRQ with hypervisor
* @queue: crq_queue to initialize and register * @queue: crq_queue to initialize and register
...@@ -198,9 +235,9 @@ static void set_adapter_info(struct ibmvscsi_host_data *hostdata) ...@@ -198,9 +235,9 @@ static void set_adapter_info(struct ibmvscsi_host_data *hostdata)
* the crq with the hypervisor. * the crq with the hypervisor.
* Returns zero on success. * Returns zero on success.
*/ */
int ibmvscsi_init_crq_queue(struct crq_queue *queue, static int rpavscsi_init_crq_queue(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata, struct ibmvscsi_host_data *hostdata,
int max_requests) int max_requests)
{ {
int rc; int rc;
int retrc; int retrc;
...@@ -227,7 +264,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, ...@@ -227,7 +264,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue,
queue->msg_token, PAGE_SIZE); queue->msg_token, PAGE_SIZE);
if (rc == H_RESOURCE) if (rc == H_RESOURCE)
/* maybe kexecing and resource is busy. try a reset */ /* maybe kexecing and resource is busy. try a reset */
rc = ibmvscsi_reset_crq_queue(queue, rc = rpavscsi_reset_crq_queue(queue,
hostdata); hostdata);
if (rc == 2) { if (rc == 2) {
...@@ -240,7 +277,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, ...@@ -240,7 +277,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue,
} }
if (request_irq(vdev->irq, if (request_irq(vdev->irq,
ibmvscsi_handle_event, rpavscsi_handle_event,
0, "ibmvscsi", (void *)hostdata) != 0) { 0, "ibmvscsi", (void *)hostdata) != 0) {
dev_err(hostdata->dev, "couldn't register irq 0x%x\n", dev_err(hostdata->dev, "couldn't register irq 0x%x\n",
vdev->irq); vdev->irq);
...@@ -256,7 +293,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, ...@@ -256,7 +293,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue,
queue->cur = 0; queue->cur = 0;
spin_lock_init(&queue->lock); spin_lock_init(&queue->lock);
tasklet_init(&hostdata->srp_task, (void *)ibmvscsi_task, tasklet_init(&hostdata->srp_task, (void *)rpavscsi_task,
(unsigned long)hostdata); (unsigned long)hostdata);
return retrc; return retrc;
...@@ -281,8 +318,8 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, ...@@ -281,8 +318,8 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue,
* @hostdata: ibmvscsi_host_data of host * @hostdata: ibmvscsi_host_data of host
* *
*/ */
int ibmvscsi_reenable_crq_queue(struct crq_queue *queue, static int rpavscsi_reenable_crq_queue(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata) struct ibmvscsi_host_data *hostdata)
{ {
int rc; int rc;
struct vio_dev *vdev = to_vio_dev(hostdata->dev); struct vio_dev *vdev = to_vio_dev(hostdata->dev);
...@@ -297,38 +334,10 @@ int ibmvscsi_reenable_crq_queue(struct crq_queue *queue, ...@@ -297,38 +334,10 @@ int ibmvscsi_reenable_crq_queue(struct crq_queue *queue,
return rc; return rc;
} }
/** struct ibmvscsi_ops rpavscsi_ops = {
* reset_crq_queue: - resets a crq after a failure .init_crq_queue = rpavscsi_init_crq_queue,
* @queue: crq_queue to initialize and register .release_crq_queue = rpavscsi_release_crq_queue,
* @hostdata: ibmvscsi_host_data of host .reset_crq_queue = rpavscsi_reset_crq_queue,
* .reenable_crq_queue = rpavscsi_reenable_crq_queue,
*/ .send_crq = rpavscsi_send_crq,
int ibmvscsi_reset_crq_queue(struct crq_queue *queue, };
struct ibmvscsi_host_data *hostdata)
{
int rc;
struct vio_dev *vdev = to_vio_dev(hostdata->dev);
/* Close the CRQ */
do {
rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address);
} while ((rc == H_BUSY) || (H_IS_LONG_BUSY(rc)));
/* Clean out the queue */
memset(queue->msgs, 0x00, PAGE_SIZE);
queue->cur = 0;
set_adapter_info(hostdata);
/* And re-open it again */
rc = plpar_hcall_norets(H_REG_CRQ,
vdev->unit_address,
queue->msg_token, PAGE_SIZE);
if (rc == 2) {
/* Adapter is good, but other end is not ready */
dev_warn(hostdata->dev, "Partner adapter not ready\n");
} else if (rc != 0) {
dev_warn(hostdata->dev, "couldn't register crq--rc 0x%x\n", rc);
}
return rc;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment