From 4908c258cea4876100a9de34d37f6ce63f06b6f5 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 12 Sep 2010 10:02:36 +0000 Subject: [PATCH] Further conversion towards SCST. Fixed sparse errors and warnings. Restored struct srp_target_port in libsrp to the upstream definition / moved several members to struct vio_port. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@2105 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- ibmvstgt/src/Makefile | 8 +-- ibmvstgt/src/ibmvstgt.c | 149 +++++++++++++++++++++++++++++---------- ibmvstgt/src/libsrpnew.c | 34 +++++---- ibmvstgt/src/libsrpnew.h | 9 +-- 4 files changed, 137 insertions(+), 63 deletions(-) diff --git a/ibmvstgt/src/Makefile b/ibmvstgt/src/Makefile index b9ed8bc0d..19a2e5edb 100644 --- a/ibmvstgt/src/Makefile +++ b/ibmvstgt/src/Makefile @@ -1,11 +1,11 @@ IBMVSTGT_INC_DIR := $(SUBDIRS)/../../scst/include EXTRA_CFLAGS += -I$(IBMVSTGT_INC_DIR) -#EXTRA_CFLAGS += -DCONFIG_SCST_TRACING -#EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG +EXTRA_CFLAGS += -DCONFIG_SCST_TRACING +EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG #EXTRA_CFLAGS += -g -fno-inline -fno-inline-functions -#EXTRA_CFLAGS += -DCONFIG_SCST_EXTRACHECKS -#EXTRA_CFLAGS += -Wextra -Wno-unused-parameter +EXTRA_CFLAGS += -DCONFIG_SCST_EXTRACHECKS +EXTRA_CFLAGS += -Wextra -Wno-unused-parameter obj-m += ibmvstgt.o obj-m += libsrpnew.o diff --git a/ibmvstgt/src/ibmvstgt.c b/ibmvstgt/src/ibmvstgt.c index c8a1c7d79..7aeba39a7 100644 --- a/ibmvstgt/src/ibmvstgt.c +++ b/ibmvstgt/src/ibmvstgt.c @@ -1,3 +1,4 @@ +/* -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8; -*- */ /* * IBM eServer i/pSeries Virtual SCSI Target Driver * Copyright (C) 2003-2005 Dave Boutcher (boutcher@us.ibm.com) IBM Corp. @@ -5,6 +6,7 @@ * Linda Xie (lxie@us.ibm.com) IBM Corp. * * Copyright (C) 2005-2006 FUJITA Tomonori + * Copyright (C) 2010 Bart Van Assche * * 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 @@ -79,11 +81,23 @@ struct vio_port { unsigned long liobn; unsigned long riobn; struct srp_target *target; + struct scst_session *sess; + struct device dev; + bool releasing; + bool enabled; }; static atomic_t ibmvstgt_device_count; static struct workqueue_struct *vtgtd; +#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING) +#define DEFAULT_IBMVSTGT_TRACE_FLAGS \ + (TRACE_OUT_OF_MEM | TRACE_MINOR | TRACE_MGMT | TRACE_SPECIAL) +static unsigned long trace_flag = DEFAULT_IBMVSTGT_TRACE_FLAGS; +module_param(trace_flag, long, 0644); +MODULE_PARM_DESC(trace_flag, "SCST trace flags."); +#endif + /* * These are fixed for the system and come from the Open Firmware device tree. * We just store them here to save getting them every time. @@ -155,7 +169,7 @@ static int send_rsp(struct iu_entry *iue, struct scst_cmd *sc, memset(iu, 0, sizeof(struct srp_rsp)); iu->srp.rsp.opcode = SRP_RSP; - iu->srp.rsp.req_lim_delta = 1; + iu->srp.rsp.req_lim_delta = __constant_cpu_to_be32(1); iu->srp.rsp.tag = tag; if (test_bit(V_DIOVER, &iue->flags)) @@ -185,7 +199,8 @@ static int send_rsp(struct iu_entry *iue, struct scst_cmd *sc, } else { iu->srp.rsp.status = SAM_STAT_CHECK_CONDITION; iu->srp.rsp.flags |= SRP_RSP_FLAG_SNSVALID; - iu->srp.rsp.sense_data_len = SRP_RSP_SENSE_DATA_LEN; + iu->srp.rsp.sense_data_len + = __constant_cpu_to_be32(SRP_RSP_SENSE_DATA_LEN); /* Valid bit and 'current errors' */ sense[0] = (0x1 << 7 | 0x70); @@ -206,7 +221,8 @@ static int send_rsp(struct iu_entry *iue, struct scst_cmd *sc, static void handle_cmd_queue(struct srp_target *target) { - struct scst_session *sess = target->sess; + struct vio_port *vport = target_to_port(target); + struct scst_session *sess = vport->sess; struct iu_entry *iue; struct srp_cmd *cmd; unsigned long flags; @@ -250,14 +266,14 @@ static int ibmvstgt_rdma(struct scst_cmd *sc, struct scatterlist *sg, int nsg, for (i = 0; i < nmd && rest; i++) { unsigned int mdone, mlen; - mlen = min(rest, md[i].len); + mlen = min(rest, be32_to_cpu(md[i].len)); for (mdone = 0; mlen;) { int slen = min(sg_dma_len(sg + sidx) - soff, mlen); if (dir == DMA_TO_DEVICE) err = h_copy_rdma(slen, vport->riobn, - md[i].va + mdone, + be64_to_cpu(md[i].va) + mdone, vport->liobn, token + soff); else @@ -265,7 +281,8 @@ static int ibmvstgt_rdma(struct scst_cmd *sc, struct scatterlist *sg, int nsg, vport->liobn, token + soff, vport->riobn, - md[i].va + mdone); + be64_to_cpu(md[i].va) + + mdone); if (err != H_SUCCESS) { eprintk("rdma error %d %d %ld\n", dir, slen, err); @@ -302,13 +319,17 @@ static int ibmvstgt_rdma(struct scst_cmd *sc, struct scatterlist *sg, int nsg, static int ibmvstgt_enable_target(struct scst_tgt *scst_tgt, bool enable) { struct srp_target *target = scst_tgt_get_tgt_priv(scst_tgt); + struct vio_port *vport = target_to_port(target); + unsigned long flags; EXTRACHECKS_WARN_ON_ONCE(irqs_disabled()); - TRACE_DBG("%s target %s", enable ? "Enabling" : "Disabling", - target->sess ? target->sess->name : "???"); + TRACE_DBG("%s target %d", enable ? "Enabling" : "Disabling", + vport->dma_dev->unit_address); - target->enabled = enable; + spin_lock_irqsave(&target->lock, flags); + vport->enabled = enable; + spin_unlock_irqrestore(&target->lock, flags); return 0; } @@ -319,10 +340,16 @@ static int ibmvstgt_enable_target(struct scst_tgt *scst_tgt, bool enable) static bool ibmvstgt_is_target_enabled(struct scst_tgt *scst_tgt) { struct srp_target *target = scst_tgt_get_tgt_priv(scst_tgt); + struct vio_port *vport = target_to_port(target); + unsigned long flags; + bool res; EXTRACHECKS_WARN_ON_ONCE(irqs_disabled()); - return target->enabled; + spin_lock_irqsave(&target->lock, flags); + res = vport->enabled; + spin_unlock_irqrestore(&target->lock, flags); + return res; } #endif @@ -343,7 +370,17 @@ static int ibmvstgt_detect(struct scst_tgt_template *tp) */ static int ibmvstgt_release(struct scst_tgt *scst_tgt) { - /* To do: implement this function. */ + unsigned long flags; + struct srp_target *target = scst_tgt_get_tgt_priv(scst_tgt); + struct vio_port *vport = target_to_port(target); + struct scst_session *sess = vport->sess; + + spin_lock_irqsave(&target->lock, flags); + vport->releasing = true; + spin_unlock_irqrestore(&target->lock, flags); + + scst_unregister_session(sess, 0, NULL); + return 0; } @@ -437,7 +474,7 @@ static void ibmvstgt_on_free_cmd(struct scst_cmd *sc) srp_iu_put(iue); } -int send_adapter_info(struct iu_entry *iue, +static int send_adapter_info(struct iu_entry *iue, dma_addr_t remote_buffer, uint16_t length) { struct srp_target *target = iue->target; @@ -496,7 +533,7 @@ static void process_login(struct iu_entry *iue) struct vio_port *vport = target_to_port(target); char name[16]; - BUG_ON(target->sess); + BUG_ON(vport->sess); memset(iu, 0, max(sizeof *rsp, sizeof *rej)); @@ -505,21 +542,22 @@ static void process_login(struct iu_entry *iue) BUG_ON(!target); sess = scst_register_session(target->tgt, 0, name, target, NULL, NULL); if (!sess) { - rej->reason = cpu_to_be32(SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES); + rej->reason + = __constant_cpu_to_be32(SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES); TRACE_DBG("%s", "Failed to create SCST session"); goto reject; } - target->sess = sess; + vport->sess = sess; /* TODO handle case that requested size is wrong and * buffer format is wrong */ rsp->opcode = SRP_LOGIN_RSP; - rsp->req_lim_delta = INITIAL_SRP_LIMIT; + rsp->req_lim_delta = __constant_cpu_to_be32(INITIAL_SRP_LIMIT); rsp->tag = tag; - rsp->max_it_iu_len = sizeof(union srp_iu); - rsp->max_ti_iu_len = sizeof(union srp_iu); + rsp->max_it_iu_len = __constant_cpu_to_be32(sizeof(union srp_iu)); + rsp->max_ti_iu_len = __constant_cpu_to_be32(sizeof(union srp_iu)); /* direct and indirect */ rsp->buf_fmt = cpu_to_be16(SRP_BUF_FORMAT_DIRECT | SRP_BUF_FORMAT_INDIRECT); @@ -561,7 +599,9 @@ struct mgmt_ctx { static int process_tsk_mgmt(struct iu_entry *iue) { union viosrp_iu *iu = vio_iu(iue); - struct scst_session *sess = iue->target->sess; + struct srp_target *target = iue->target; + struct vio_port *vport = target_to_port(target); + struct scst_session *sess = vport->sess; struct srp_tsk_mgmt *srp_tsk; struct mgmt_ctx *mgmt_ctx; int ret = 0; @@ -664,8 +704,8 @@ static void ibmvstgt_tsk_mgmt_done(struct scst_mgmt_cmd *mcmnd) iu = vio_iu(iue); - TRACE_DBG("%s: tsk_mgmt_done for tag= %lld status=%d", - __func__, mgmt_ctx->tag, scst_mgmt_cmd_get_status(mcmnd)); + TRACE_DBG("%s: tag %lld status %d", + __func__, iu->srp.rsp.tag, scst_mgmt_cmd_get_status(mcmnd)); send_rsp(iue, NULL, scst_to_srp_tsk_mgmt_status(scst_mgmt_cmd_get_status(mcmnd)), @@ -709,10 +749,20 @@ static int process_mad_iu(struct iu_entry *iue) static bool process_srp_iu(struct iu_entry *iue) { + unsigned long flags; union viosrp_iu *iu = vio_iu(iue); + struct srp_target *target = iue->target; + struct vio_port *vport = target_to_port(target); bool done = true; u8 opcode = iu->srp.rsp.opcode; + spin_lock_irqsave(&target->lock, flags); + if (vport->releasing) { + spin_unlock_irqrestore(&target->lock, flags); + return done; + } + spin_unlock_irqrestore(&target->lock, flags); + switch (opcode) { case SRP_LOGIN_REQ: process_login(iue); @@ -828,7 +878,7 @@ static int crq_queue_create(struct crq_queue *queue, struct srp_target *target) vio_enable_interrupts(vport->dma_dev); - h_send_crq(vport->dma_dev->unit_address, 0xC001000000000000, 0); + h_send_crq(vport->dma_dev->unit_address, 0xC001000000000000UL, 0); queue->cur = 0; spin_lock_init(&queue->lock); @@ -878,7 +928,7 @@ static void process_crq(struct viosrp_crq *crq, struct srp_target *target) switch (crq->format) { case 0x01: h_send_crq(vport->dma_dev->unit_address, - 0xC002000000000000, 0); + 0xC002000000000000UL, 0); break; case 0x02: break; @@ -970,8 +1020,7 @@ static ssize_t partition_number_show(struct device *dev, static ssize_t unit_address_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct srp_target *target = container_of(dev, struct srp_target, dev2); - struct vio_port *vport = target_to_port(target); + struct vio_port *vport = container_of(dev, struct vio_port, dev); return snprintf(buf, PAGE_SIZE, "%x\n", vport->dma_dev->unit_address); } @@ -1061,17 +1110,19 @@ static int ibmvstgt_probe(struct vio_dev *dev, const struct vio_device_id *id) if (err) goto free_srp_target; - target->dev2.class = &ibmvstgt_class; - target->dev2.parent = &dev->dev; - dev_set_name(&target->dev2, "ibmvstgt-%d", + vport->dev.class = &ibmvstgt_class; + vport->dev.parent = &dev->dev; + dev_set_name(&vport->dev, "ibmvstgt-%d", vport->dma_dev->unit_address); - if (device_register(&target->dev2)) - /* to do: handle failure */; + if (device_register(&vport->dev)) + goto destroy_crq_queue; atomic_inc(&ibmvstgt_device_count); return 0; +destroy_crq_queue: + crq_queue_destroy(target); free_srp_target: srp_target_free(target); unregister_target: @@ -1106,9 +1157,9 @@ static struct vio_device_id ibmvstgt_device_table[] __devinitdata = { MODULE_DEVICE_TABLE(vio, ibmvstgt_device_table); static struct vio_driver ibmvstgt_driver = { - .id_table = ibmvstgt_device_table, - .probe = ibmvstgt_probe, - .remove = ibmvstgt_remove, + .id_table = ibmvstgt_device_table, + .probe = ibmvstgt_probe, + .remove = ibmvstgt_remove, .driver = { .name = "ibmvscsis", .owner = THIS_MODULE, @@ -1142,15 +1193,31 @@ static int get_system_info(void) return 0; } -static int ibmvstgt_init(void) +/** + * ibmvstgt_init() - Kernel module initialization. + * + * Note: Since vio_register_driver() registers callback functions, and since + * at least one of these callback functions (ibmvstgt_probe()) calls SCST + * functions, the SCST target template must be registered before + * vio_register_driver() is called. + */ +static int __init ibmvstgt_init(void) { int err = -ENOMEM; printk("IBM eServer i/pSeries Virtual SCSI Target Driver\n"); + err = class_register(&ibmvstgt_class); + if (err) + goto out; + + err = scst_register_target_template(&ibmvstgt_template); + if (err) + goto unregister_class; + vtgtd = create_workqueue("ibmvtgtd"); if (!vtgtd) - return err; + goto unregister_tgt; err = get_system_info(); if (err) @@ -1161,17 +1228,25 @@ static int ibmvstgt_init(void) goto destroy_wq; return 0; + destroy_wq: destroy_workqueue(vtgtd); +unregister_tgt: + scst_unregister_target_template(&ibmvstgt_template); +unregister_class: + class_unregister(&ibmvstgt_class); +out: return err; } -static void ibmvstgt_exit(void) +static void __exit ibmvstgt_exit(void) { printk("Unregister IBM virtual SCSI driver\n"); - destroy_workqueue(vtgtd); vio_unregister_driver(&ibmvstgt_driver); + destroy_workqueue(vtgtd); + scst_unregister_target_template(&ibmvstgt_template); + class_unregister(&ibmvstgt_class); } MODULE_DESCRIPTION("IBM Virtual SCSI Target"); diff --git a/ibmvstgt/src/libsrpnew.c b/ibmvstgt/src/libsrpnew.c index 668771afc..78a6dee48 100644 --- a/ibmvstgt/src/libsrpnew.c +++ b/ibmvstgt/src/libsrpnew.c @@ -1,7 +1,9 @@ +/* -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8; -*- */ /* * SCSI RDMA Protocol lib functions * * Copyright (C) 2006 FUJITA Tomonori + * Copyright (C) 2010 Bart Van Assche * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -203,10 +205,10 @@ static int srp_direct_data(struct scst_cmd *sc, struct srp_direct_buf *md, scst_cmd_get_sg_cnt(sc)); return 0; } - len = min_t(int, scst_cmd_get_expected_transfer_len(sc), - md->len); + len = min_t(unsigned, scst_cmd_get_expected_transfer_len(sc), + be32_to_cpu(md->len)); } else - len = md->len; + len = be32_to_cpu(md->len); err = rdma_io(sc, sg, nsg, md, 1, dir, len); @@ -237,7 +239,7 @@ static int srp_indirect_data(struct scst_cmd *sc, struct srp_cmd *cmd, cmd->data_in_desc_cnt, cmd->data_out_desc_cnt); } - nmd = id->table_desc.len / sizeof(struct srp_direct_buf); + nmd = be32_to_cpu(id->table_desc.len) / sizeof(struct srp_direct_buf); if ((dir == DMA_FROM_DEVICE && nmd == cmd->data_in_desc_cnt) || (dir == DMA_TO_DEVICE && nmd == cmd->data_out_desc_cnt)) { @@ -246,18 +248,19 @@ static int srp_indirect_data(struct scst_cmd *sc, struct srp_cmd *cmd, } if (ext_desc && dma_map) { - md = dma_alloc_coherent(iue->target->dev, id->table_desc.len, - &token, GFP_KERNEL); + md = dma_alloc_coherent(iue->target->dev, + be32_to_cpu(id->table_desc.len), + &token, GFP_KERNEL); if (!md) { eprintk("Can't get dma memory %u\n", id->table_desc.len); return -ENOMEM; } - sg_init_one(&dummy, md, id->table_desc.len); + sg_init_one(&dummy, md, be32_to_cpu(id->table_desc.len)); sg_dma_address(&dummy) = token; - sg_dma_len(&dummy) = id->table_desc.len; + sg_dma_len(&dummy) = be32_to_cpu(id->table_desc.len); err = rdma_io(sc, &dummy, 1, &id->table_desc, 1, DMA_TO_DEVICE, - id->table_desc.len); + be32_to_cpu(id->table_desc.len)); if (err) { eprintk("Error copying indirect table %d\n", err); goto free_mem; @@ -277,10 +280,10 @@ rdma: err = -EIO; goto free_mem; } - len = min_t(int, scst_cmd_get_expected_transfer_len(sc), - id->len); + len = min_t(unsigned, scst_cmd_get_expected_transfer_len(sc), + be32_to_cpu(id->len)); } else - len = id->len; + len = be32_to_cpu(id->len); err = rdma_io(sc, sg, nsg, md, nmd, dir, len); @@ -289,7 +292,8 @@ rdma: free_mem: if (token && dma_map) - dma_free_coherent(iue->target->dev, id->table_desc.len, md, token); + dma_free_coherent(iue->target->dev, + be32_to_cpu(id->table_desc.len), md, token); return err; } @@ -382,11 +386,11 @@ static int vscsis_data_length(struct srp_cmd *cmd, enum dma_data_direction dir) break; case SRP_DATA_DESC_DIRECT: md = (struct srp_direct_buf *) (cmd->add_data + offset); - len = md->len; + len = be32_to_cpu(md->len); break; case SRP_DATA_DESC_INDIRECT: id = (struct srp_indirect_buf *) (cmd->add_data + offset); - len = id->len; + len = be32_to_cpu(id->len); break; default: eprintk("invalid data format %x\n", fmt); diff --git a/ibmvstgt/src/libsrpnew.h b/ibmvstgt/src/libsrpnew.h index 7a35b9283..9fa97b498 100644 --- a/ibmvstgt/src/libsrpnew.h +++ b/ibmvstgt/src/libsrpnew.h @@ -1,3 +1,4 @@ +/* -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8; -*- */ #ifndef __LIBSRP_H__ #define __LIBSRP_H__ @@ -17,8 +18,6 @@ enum iue_flags { V_FLYING, }; -struct scst_session; - struct srp_buf { dma_addr_t dma; void *buf; @@ -33,9 +32,7 @@ struct srp_queue { struct srp_target { struct scst_tgt *tgt; - struct scst_session *sess; - struct device *dev; /* to do: invent a better name */ - struct device dev2; /* to do: invent a better name */ + struct device *dev; spinlock_t lock; struct list_head cmd_queue; @@ -46,8 +43,6 @@ struct srp_target { struct srp_buf **rx_ring; void *ldata; - - bool enabled; }; struct iu_entry {