diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-15 08:19:33 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-15 08:19:33 -0700 |
commit | df3d80f5a5c74168be42788364d13cf6c83c7b9c (patch) | |
tree | 892a964c2fd28d028f2fb7471e8543d3f4006a58 /drivers/scsi/ibmvscsi | |
parent | 3d06f7a5f74a813cee817c4b30b5e6f0398da0be (diff) | |
parent | c8e91b0a8fc8493e3bf3efcb3c8f866e9453cf1c (diff) | |
download | op-kernel-dev-df3d80f5a5c74168be42788364d13cf6c83c7b9c.zip op-kernel-dev-df3d80f5a5c74168be42788364d13cf6c83c7b9c.tar.gz |
Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (207 commits)
[SCSI] gdth: fix CONFIG_ISA build failure
[SCSI] esp_scsi: remove __dev{init,exit}
[SCSI] gdth: !use_sg cleanup and use of scsi accessors
[SCSI] gdth: Move members from SCp to gdth_cmndinfo, stage 2
[SCSI] gdth: Setup proper per-command private data
[SCSI] gdth: Remove gdth_ctr_tab[]
[SCSI] gdth: switch to modern scsi host registration
[SCSI] gdth: gdth_interrupt() gdth_get_status() & gdth_wait() fixes
[SCSI] gdth: clean up host private data
[SCSI] gdth: Remove virt hosts
[SCSI] gdth: Reorder scsi_host_template intitializers
[SCSI] gdth: kill gdth_{read,write}[bwl] wrappers
[SCSI] gdth: Remove 2.4.x support, in-kernel changelog
[SCSI] gdth: split out pci probing
[SCSI] gdth: split out eisa probing
[SCSI] gdth: split out isa probing
gdth: Make one abuse of scsi_cmnd less obvious
[SCSI] NCR5380: Use scsi_eh API for REQUEST_SENSE invocation
[SCSI] usb storage: use scsi_eh API in REQUEST_SENSE execution
[SCSI] scsi_error: Refactoring scsi_error to facilitate in synchronous REQUEST_SENSE
...
Diffstat (limited to 'drivers/scsi/ibmvscsi')
-rw-r--r-- | drivers/scsi/ibmvscsi/Makefile | 2 | ||||
-rw-r--r-- | drivers/scsi/ibmvscsi/ibmvscsi.c | 81 | ||||
-rw-r--r-- | drivers/scsi/ibmvscsi/ibmvscsi.h | 32 | ||||
-rw-r--r-- | drivers/scsi/ibmvscsi/ibmvstgt.c | 61 | ||||
-rw-r--r-- | drivers/scsi/ibmvscsi/iseries_vscsi.c | 37 | ||||
-rw-r--r-- | drivers/scsi/ibmvscsi/rpa_vscsi.c | 113 |
6 files changed, 217 insertions, 109 deletions
diff --git a/drivers/scsi/ibmvscsi/Makefile b/drivers/scsi/ibmvscsi/Makefile index f67d9ef..6ac0633 100644 --- a/drivers/scsi/ibmvscsi/Makefile +++ b/drivers/scsi/ibmvscsi/Makefile @@ -1,9 +1,7 @@ obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsic.o ibmvscsic-y += ibmvscsi.o -ifndef CONFIG_PPC_PSERIES ibmvscsic-$(CONFIG_PPC_ISERIES) += iseries_vscsi.o -endif ibmvscsic-$(CONFIG_PPC_PSERIES) += rpa_vscsi.o obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvstgt.o diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 5ecc63d..cda0cc3 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -70,11 +70,13 @@ #include <linux/moduleparam.h> #include <linux/dma-mapping.h> #include <linux/delay.h> +#include <asm/firmware.h> #include <asm/vio.h> #include <scsi/scsi.h> #include <scsi/scsi_cmnd.h> #include <scsi/scsi_host.h> #include <scsi/scsi_device.h> +#include <scsi/scsi_transport_srp.h> #include "ibmvscsi.h" /* The values below are somewhat arbitrary default values, but @@ -87,8 +89,12 @@ static int max_channel = 3; static int init_timeout = 5; static int max_requests = IBMVSCSI_MAX_REQUESTS_DEFAULT; +static struct scsi_transport_template *ibmvscsi_transport_template; + #define IBMVSCSI_VERSION "1.5.8" +static struct ibmvscsi_ops *ibmvscsi_ops; + MODULE_DESCRIPTION("IBM Virtual SCSI"); MODULE_AUTHOR("Dave Boutcher"); MODULE_LICENSE("GPL"); @@ -506,8 +512,8 @@ static void ibmvscsi_reset_host(struct ibmvscsi_host_data *hostdata) atomic_set(&hostdata->request_limit, 0); purge_requests(hostdata, DID_ERROR); - if ((ibmvscsi_reset_crq_queue(&hostdata->queue, hostdata)) || - (ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0)) || + if ((ibmvscsi_ops->reset_crq_queue(&hostdata->queue, hostdata)) || + (ibmvscsi_ops->send_crq(hostdata, 0xC001000000000000LL, 0)) || (vio_enable_interrupts(to_vio_dev(hostdata->dev)))) { atomic_set(&hostdata->request_limit, -1); dev_err(hostdata->dev, "error after reset\n"); @@ -612,7 +618,7 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct, } 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); del_timer(&evt_struct->timer); @@ -1211,8 +1217,8 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq, case 0x01: /* Initialization message */ dev_info(hostdata->dev, "partner initialized\n"); /* Send back a response */ - if ((rc = ibmvscsi_send_crq(hostdata, - 0xC002000000000000LL, 0)) == 0) { + if ((rc = ibmvscsi_ops->send_crq(hostdata, + 0xC002000000000000LL, 0)) == 0) { /* Now login */ send_srp_login(hostdata); } else { @@ -1237,10 +1243,10 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq, /* We need to re-setup the interpartition connection */ dev_info(hostdata->dev, "Re-enabling adapter!\n"); purge_requests(hostdata, DID_REQUEUE); - if ((ibmvscsi_reenable_crq_queue(&hostdata->queue, - hostdata)) || - (ibmvscsi_send_crq(hostdata, - 0xC001000000000000LL, 0))) { + if ((ibmvscsi_ops->reenable_crq_queue(&hostdata->queue, + hostdata)) || + (ibmvscsi_ops->send_crq(hostdata, + 0xC001000000000000LL, 0))) { atomic_set(&hostdata->request_limit, -1); dev_err(hostdata->dev, "error after enable\n"); @@ -1250,10 +1256,10 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq, crq->format); purge_requests(hostdata, DID_ERROR); - if ((ibmvscsi_reset_crq_queue(&hostdata->queue, - hostdata)) || - (ibmvscsi_send_crq(hostdata, - 0xC001000000000000LL, 0))) { + if ((ibmvscsi_ops->reset_crq_queue(&hostdata->queue, + hostdata)) || + (ibmvscsi_ops->send_crq(hostdata, + 0xC001000000000000LL, 0))) { atomic_set(&hostdata->request_limit, -1); dev_err(hostdata->dev, "error after reset\n"); @@ -1553,6 +1559,8 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) struct ibmvscsi_host_data *hostdata; struct Scsi_Host *host; struct device *dev = &vdev->dev; + struct srp_rport_identifiers ids; + struct srp_rport *rport; unsigned long wait_switch = 0; int rc; @@ -1565,6 +1573,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) goto scsi_host_alloc_failed; } + host->transportt = ibmvscsi_transport_template; hostdata = shost_priv(host); memset(hostdata, 0x00, sizeof(*hostdata)); INIT_LIST_HEAD(&hostdata->sent); @@ -1573,7 +1582,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) atomic_set(&hostdata->request_limit, -1); 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) { dev_err(&vdev->dev, "couldn't initialize crq. rc=%d\n", rc); goto init_crq_failed; @@ -1590,11 +1599,19 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) if (scsi_add_host(hostdata->host, hostdata->dev)) goto add_host_failed; + /* we don't have a proper target_port_id so let's use the fake one */ + memcpy(ids.port_id, hostdata->madapter_info.partition_name, + sizeof(ids.port_id)); + ids.roles = SRP_RPORT_ROLE_TARGET; + rport = srp_rport_add(host, &ids); + if (IS_ERR(rport)) + goto add_srp_port_failed; + /* Try to send an initialization message. Note that this is allowed * to fail if the other end is not acive. In that case we don't * want to scan */ - if (ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0) == 0 + if (ibmvscsi_ops->send_crq(hostdata, 0xC001000000000000LL, 0) == 0 || rc == H_RESOURCE) { /* * Wait around max init_timeout secs for the adapter to finish @@ -1617,10 +1634,12 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) vdev->dev.driver_data = hostdata; return 0; + add_srp_port_failed: + scsi_remove_host(hostdata->host); add_host_failed: release_event_pool(&hostdata->pool, hostdata); 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: scsi_host_put(host); scsi_host_alloc_failed: @@ -1631,9 +1650,10 @@ static int ibmvscsi_remove(struct vio_dev *vdev) { struct ibmvscsi_host_data *hostdata = vdev->dev.driver_data; release_event_pool(&hostdata->pool, hostdata); - ibmvscsi_release_crq_queue(&hostdata->queue, hostdata, - max_requests); - + ibmvscsi_ops->release_crq_queue(&hostdata->queue, hostdata, + max_requests); + + srp_remove_host(hostdata->host); scsi_remove_host(hostdata->host); scsi_host_put(hostdata->host); @@ -1660,14 +1680,35 @@ static struct vio_driver ibmvscsi_driver = { } }; +static struct srp_function_template ibmvscsi_transport_functions = { +}; + int __init ibmvscsi_module_init(void) { - return vio_register_driver(&ibmvscsi_driver); + 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 = + srp_attach_transport(&ibmvscsi_transport_functions); + if (!ibmvscsi_transport_template) + return -ENOMEM; + + ret = vio_register_driver(&ibmvscsi_driver); + if (ret) + srp_release_transport(ibmvscsi_transport_template); + return ret; } void __exit ibmvscsi_module_exit(void) { vio_unregister_driver(&ibmvscsi_driver); + srp_release_transport(ibmvscsi_transport_template); } module_init(ibmvscsi_module_init); diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.h b/drivers/scsi/ibmvscsi/ibmvscsi.h index b19c2e2..46e850e 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.h +++ b/drivers/scsi/ibmvscsi/ibmvscsi.h @@ -98,21 +98,25 @@ struct ibmvscsi_host_data { }; /* 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, 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 */ diff --git a/drivers/scsi/ibmvscsi/ibmvstgt.c b/drivers/scsi/ibmvscsi/ibmvstgt.c index 8ba7dd0..82bcab6 100644 --- a/drivers/scsi/ibmvscsi/ibmvstgt.c +++ b/drivers/scsi/ibmvscsi/ibmvstgt.c @@ -25,6 +25,7 @@ #include <linux/module.h> #include <scsi/scsi.h> #include <scsi/scsi_host.h> +#include <scsi/scsi_transport_srp.h> #include <scsi/scsi_tgt.h> #include <scsi/libsrp.h> #include <asm/hvcall.h> @@ -68,9 +69,12 @@ struct vio_port { unsigned long liobn; unsigned long riobn; struct srp_target *target; + + struct srp_rport *rport; }; static struct workqueue_struct *vtgtd; +static struct scsi_transport_template *ibmvstgt_transport_template; /* * These are fixed for the system and come from the Open Firmware device tree. @@ -188,6 +192,7 @@ static int send_rsp(struct iu_entry *iue, struct scsi_cmnd *sc, static void handle_cmd_queue(struct srp_target *target) { struct Scsi_Host *shost = target->shost; + struct srp_rport *rport = target_to_port(target)->rport; struct iu_entry *iue; struct srp_cmd *cmd; unsigned long flags; @@ -200,7 +205,8 @@ retry: if (!test_and_set_bit(V_FLYING, &iue->flags)) { spin_unlock_irqrestore(&target->lock, flags); cmd = iue->sbuf->buf; - err = srp_cmd_queue(shost, cmd, iue, 0); + err = srp_cmd_queue(shost, cmd, iue, + (unsigned long)rport, 0); if (err) { eprintk("cannot queue cmd %p %d\n", cmd, err); srp_iu_put(iue); @@ -359,6 +365,16 @@ static void process_login(struct iu_entry *iue) union viosrp_iu *iu = vio_iu(iue); struct srp_login_rsp *rsp = &iu->srp.login_rsp; uint64_t tag = iu->srp.rsp.tag; + struct Scsi_Host *shost = iue->target->shost; + struct srp_target *target = host_to_srp_target(shost); + struct vio_port *vport = target_to_port(target); + struct srp_rport_identifiers ids; + + memset(&ids, 0, sizeof(ids)); + sprintf(ids.port_id, "%x", vport->dma_dev->unit_address); + ids.roles = SRP_RPORT_ROLE_INITIATOR; + if (!vport->rport) + vport->rport = srp_rport_add(shost, &ids); /* TODO handle case that requested size is wrong and * buffer format is wrong @@ -412,7 +428,9 @@ static int process_tsk_mgmt(struct iu_entry *iue) fn = 0; } if (fn) - scsi_tgt_tsk_mgmt_request(iue->target->shost, fn, + scsi_tgt_tsk_mgmt_request(iue->target->shost, + (unsigned long)iue->target->shost, + fn, iu->srp.tsk_mgmt.task_tag, (struct scsi_lun *) &iu->srp.tsk_mgmt.lun, iue); @@ -721,7 +739,8 @@ static int ibmvstgt_eh_abort_handler(struct scsi_cmnd *sc) return 0; } -static int ibmvstgt_tsk_mgmt_response(u64 mid, int result) +static int ibmvstgt_tsk_mgmt_response(struct Scsi_Host *shost, + u64 itn_id, u64 mid, int result) { struct iu_entry *iue = (struct iu_entry *) ((void *) mid); union viosrp_iu *iu = vio_iu(iue); @@ -747,6 +766,20 @@ static int ibmvstgt_tsk_mgmt_response(u64 mid, int result) return 0; } +static int ibmvstgt_it_nexus_response(struct Scsi_Host *shost, u64 itn_id, + int result) +{ + struct srp_target *target = host_to_srp_target(shost); + struct vio_port *vport = target_to_port(target); + + if (result) { + eprintk("%p %d\n", shost, result); + srp_rport_del(vport->rport); + vport->rport = NULL; + } + return 0; +} + static ssize_t system_id_show(struct class_device *cdev, char *buf) { return snprintf(buf, PAGE_SIZE, "%s\n", system_id); @@ -785,9 +818,9 @@ static struct scsi_host_template ibmvstgt_sht = { .max_sectors = DEFAULT_MAX_SECTORS, .transfer_response = ibmvstgt_cmd_done, .eh_abort_handler = ibmvstgt_eh_abort_handler, - .tsk_mgmt_response = ibmvstgt_tsk_mgmt_response, .shost_attrs = ibmvstgt_attrs, .proc_name = TGT_NAME, + .supported_mode = MODE_TARGET, }; static int ibmvstgt_probe(struct vio_dev *dev, const struct vio_device_id *id) @@ -804,6 +837,7 @@ static int ibmvstgt_probe(struct vio_dev *dev, const struct vio_device_id *id) shost = scsi_host_alloc(&ibmvstgt_sht, sizeof(struct srp_target)); if (!shost) goto free_vport; + shost->transportt = ibmvstgt_transport_template; err = scsi_tgt_alloc_queue(shost); if (err) goto put_host; @@ -837,8 +871,8 @@ static int ibmvstgt_probe(struct vio_dev *dev, const struct vio_device_id *id) err = scsi_add_host(shost, target->dev); if (err) goto destroy_queue; - return 0; + return 0; destroy_queue: crq_queue_destroy(target); free_srp_target: @@ -857,6 +891,7 @@ static int ibmvstgt_remove(struct vio_dev *dev) struct vio_port *vport = target->ldata; crq_queue_destroy(target); + srp_remove_host(shost); scsi_remove_host(shost); scsi_tgt_free_queue(shost); srp_target_free(target); @@ -909,15 +944,25 @@ static int get_system_info(void) return 0; } +static struct srp_function_template ibmvstgt_transport_functions = { + .tsk_mgmt_response = ibmvstgt_tsk_mgmt_response, + .it_nexus_response = ibmvstgt_it_nexus_response, +}; + static int ibmvstgt_init(void) { int err = -ENOMEM; printk("IBM eServer i/pSeries Virtual SCSI Target Driver\n"); + ibmvstgt_transport_template = + srp_attach_transport(&ibmvstgt_transport_functions); + if (!ibmvstgt_transport_template) + return err; + vtgtd = create_workqueue("ibmvtgtd"); if (!vtgtd) - return err; + goto release_transport; err = get_system_info(); if (err) @@ -928,9 +973,10 @@ static int ibmvstgt_init(void) goto destroy_wq; return 0; - destroy_wq: destroy_workqueue(vtgtd); +release_transport: + srp_release_transport(ibmvstgt_transport_template); return err; } @@ -940,6 +986,7 @@ static void ibmvstgt_exit(void) destroy_workqueue(vtgtd); vio_unregister_driver(&ibmvstgt_driver); + srp_release_transport(ibmvstgt_transport_template); } MODULE_DESCRIPTION("IBM Virtual SCSI Target"); diff --git a/drivers/scsi/ibmvscsi/iseries_vscsi.c b/drivers/scsi/ibmvscsi/iseries_vscsi.c index 6aeb5f0..0775fde 100644 --- a/drivers/scsi/ibmvscsi/iseries_vscsi.c +++ b/drivers/scsi/ibmvscsi/iseries_vscsi.c @@ -53,7 +53,7 @@ struct srp_lp_event { /** * 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; @@ -74,9 +74,9 @@ static void ibmvscsi_handle_event(struct HvLpEvent *lpevt) /* ------------------------------------------------------------ * Routines for driver initialization */ -int ibmvscsi_init_crq_queue(struct crq_queue *queue, - struct ibmvscsi_host_data *hostdata, - int max_requests) +static int iseriesvscsi_init_crq_queue(struct crq_queue *queue, + struct ibmvscsi_host_data *hostdata, + int max_requests) { int rc; @@ -88,7 +88,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, goto viopath_open_failed; } - rc = vio_setHandler(viomajorsubtype_scsi, ibmvscsi_handle_event); + rc = vio_setHandler(viomajorsubtype_scsi, iseriesvscsi_handle_event); if (rc < 0) { printk("vio_setHandler failed with rc %d in open_event_path\n", rc); @@ -102,9 +102,9 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, return -1; } -void ibmvscsi_release_crq_queue(struct crq_queue *queue, - struct ibmvscsi_host_data *hostdata, - int max_requests) +static void iseriesvscsi_release_crq_queue(struct crq_queue *queue, + struct ibmvscsi_host_data *hostdata, + int max_requests) { vio_clearHandler(viomajorsubtype_scsi); viopath_close(viopath_hostLp, viomajorsubtype_scsi, max_requests); @@ -117,8 +117,8 @@ void ibmvscsi_release_crq_queue(struct crq_queue *queue, * * no-op for iSeries */ -int ibmvscsi_reset_crq_queue(struct crq_queue *queue, - struct ibmvscsi_host_data *hostdata) +static int iseriesvscsi_reset_crq_queue(struct crq_queue *queue, + struct ibmvscsi_host_data *hostdata) { return 0; } @@ -130,19 +130,20 @@ int ibmvscsi_reset_crq_queue(struct crq_queue *queue, * * no-op for iSeries */ -int ibmvscsi_reenable_crq_queue(struct crq_queue *queue, - struct ibmvscsi_host_data *hostdata) +static int iseriesvscsi_reenable_crq_queue(struct crq_queue *queue, + struct ibmvscsi_host_data *hostdata) { return 0; } /** - * ibmvscsi_send_crq: - Send a CRQ + * iseriesvscsi_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 iseriesvscsi_send_crq(struct ibmvscsi_host_data *hostdata, + u64 word1, u64 word2) { single_host_data = hostdata; return HvCallEvent_signalLpEventFast(viopath_hostLp, @@ -156,3 +157,11 @@ int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata, u64 word1, u64 word2) VIOVERSION << 16, word1, word2, 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, +}; diff --git a/drivers/scsi/ibmvscsi/rpa_vscsi.c b/drivers/scsi/ibmvscsi/rpa_vscsi.c index 9c14e78..1821461 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); @@ -190,6 +191,42 @@ static void set_adapter_info(struct ibmvscsi_host_data *hostdata) } /** + * 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 * @hostdata: ibmvscsi_host_data of host @@ -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, +}; |