From d3849d512fb0ca1e369e3efcaec910a949f55f62 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 22 Sep 2007 08:29:36 +1000 Subject: [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: David Woodhouse Acked by: Brian King Signed-off-by: Paul Mackerras Signed-off-by: James Bottomley --- drivers/scsi/ibmvscsi/rpa_vscsi.c | 113 ++++++++++++++++++++------------------ 1 file changed, 61 insertions(+), 52 deletions(-) (limited to 'drivers/scsi/ibmvscsi/rpa_vscsi.c') diff --git a/drivers/scsi/ibmvscsi/rpa_vscsi.c b/drivers/scsi/ibmvscsi/rpa_vscsi.c index 9c14e789df5..182146100dc 100644 --- a/drivers/scsi/ibmvscsi/rpa_vscsi.c +++ b/drivers/scsi/ibmvscsi/rpa_vscsi.c @@ -42,14 +42,14 @@ static unsigned int partition_number = -1; * 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 * @dev_instance: ibmvscsi_host_data of host that received interrupt * * Disables interrupts and schedules srp_task * 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 *)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 * the crq with the hypervisor. */ -void ibmvscsi_release_crq_queue(struct crq_queue *queue, - struct ibmvscsi_host_data *hostdata, - int max_requests) +static void rpavscsi_release_crq_queue(struct crq_queue *queue, + struct ibmvscsi_host_data *hostdata, + int max_requests) { long rc; 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) } /** - * ibmvscsi_send_crq: - Send a CRQ + * rpavscsi_send_crq: - Send a CRQ * @hostdata: the adapter * @word1: the first 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); @@ -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 */ -static void ibmvscsi_task(void *data) +static void rpavscsi_task(void *data) { struct ibmvscsi_host_data *hostdata = (struct ibmvscsi_host_data *)data; struct vio_dev *vdev = to_vio_dev(hostdata->dev); @@ -189,6 +190,42 @@ static void set_adapter_info(struct ibmvscsi_host_data *hostdata) 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 * @queue: crq_queue to initialize and register @@ -198,9 +235,9 @@ static void set_adapter_info(struct ibmvscsi_host_data *hostdata) * the crq with the hypervisor. * Returns zero on success. */ -int ibmvscsi_init_crq_queue(struct crq_queue *queue, - struct ibmvscsi_host_data *hostdata, - int max_requests) +static int rpavscsi_init_crq_queue(struct crq_queue *queue, + struct ibmvscsi_host_data *hostdata, + int max_requests) { int rc; int retrc; @@ -227,7 +264,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, queue->msg_token, PAGE_SIZE); if (rc == H_RESOURCE) /* maybe kexecing and resource is busy. try a reset */ - rc = ibmvscsi_reset_crq_queue(queue, + rc = rpavscsi_reset_crq_queue(queue, hostdata); if (rc == 2) { @@ -240,7 +277,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, } if (request_irq(vdev->irq, - ibmvscsi_handle_event, + rpavscsi_handle_event, 0, "ibmvscsi", (void *)hostdata) != 0) { dev_err(hostdata->dev, "couldn't register irq 0x%x\n", vdev->irq); @@ -256,7 +293,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, queue->cur = 0; spin_lock_init(&queue->lock); - tasklet_init(&hostdata->srp_task, (void *)ibmvscsi_task, + tasklet_init(&hostdata->srp_task, (void *)rpavscsi_task, (unsigned long)hostdata); return retrc; @@ -281,8 +318,8 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, * @hostdata: ibmvscsi_host_data of host * */ -int ibmvscsi_reenable_crq_queue(struct crq_queue *queue, - struct ibmvscsi_host_data *hostdata) +static int rpavscsi_reenable_crq_queue(struct crq_queue *queue, + struct ibmvscsi_host_data *hostdata) { int rc; struct vio_dev *vdev = to_vio_dev(hostdata->dev); @@ -297,38 +334,10 @@ int ibmvscsi_reenable_crq_queue(struct crq_queue *queue, return rc; } -/** - * reset_crq_queue: - resets a crq after a failure - * @queue: crq_queue to initialize and register - * @hostdata: ibmvscsi_host_data of host - * - */ -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; -} +struct ibmvscsi_ops rpavscsi_ops = { + .init_crq_queue = rpavscsi_init_crq_queue, + .release_crq_queue = rpavscsi_release_crq_queue, + .reset_crq_queue = rpavscsi_reset_crq_queue, + .reenable_crq_queue = rpavscsi_reenable_crq_queue, + .send_crq = rpavscsi_send_crq, +}; -- cgit v1.2.3