Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target...
[firefly-linux-kernel-4.4.55.git] / drivers / xen / xen-scsiback.c
index f8a1bd741b5dce08f5fde1af76dbce5e15752af5..b7f51504f85adc1b5d19d33e48d066bdd60684c5 100644 (file)
@@ -31,6 +31,8 @@
  * IN THE SOFTWARE.
  */
 
+#define pr_fmt(fmt) "xen-pvscsi: " fmt
+
 #include <stdarg.h>
 
 #include <linux/module.h>
@@ -69,9 +71,6 @@
 #include <xen/interface/grant_table.h>
 #include <xen/interface/io/vscsiif.h>
 
-#define DPRINTK(_f, _a...)                     \
-       pr_debug("(file=%s, line=%d) " _f, __FILE__ , __LINE__ , ## _a)
-
 #define VSCSI_VERSION  "v0.1"
 #define VSCSI_NAMELEN  32
 
@@ -270,7 +269,7 @@ static void scsiback_print_status(char *sense_buffer, int errors,
 {
        struct scsiback_tpg *tpg = pending_req->v2p->tpg;
 
-       pr_err("xen-pvscsi[%s:%d] cmnd[0]=%02x -> st=%02x msg=%02x host=%02x drv=%02x\n",
+       pr_err("[%s:%d] cmnd[0]=%02x -> st=%02x msg=%02x host=%02x drv=%02x\n",
               tpg->tport->tport_name, pending_req->v2p->lun,
               pending_req->cmnd[0], status_byte(errors), msg_byte(errors),
               host_byte(errors), driver_byte(errors));
@@ -426,7 +425,7 @@ static int scsiback_gnttab_data_map_batch(struct gnttab_map_grant_ref *map,
        BUG_ON(err);
        for (i = 0; i < cnt; i++) {
                if (unlikely(map[i].status != GNTST_okay)) {
-                       pr_err("xen-pvscsi: invalid buffer -- could not remap it\n");
+                       pr_err("invalid buffer -- could not remap it\n");
                        map[i].handle = SCSIBACK_INVALID_HANDLE;
                        err = -ENOMEM;
                } else {
@@ -448,7 +447,7 @@ static int scsiback_gnttab_data_map_list(struct vscsibk_pend *pending_req,
        for (i = 0; i < cnt; i++) {
                if (get_free_page(pg + mapcount)) {
                        put_free_pages(pg, mapcount);
-                       pr_err("xen-pvscsi: no grant page\n");
+                       pr_err("no grant page\n");
                        return -ENOMEM;
                }
                gnttab_set_map_op(&map[mapcount], vaddr_page(pg[mapcount]),
@@ -491,7 +490,7 @@ static int scsiback_gnttab_data_map(struct vscsiif_request *ring_req,
                return 0;
 
        if (nr_segments > VSCSIIF_SG_TABLESIZE) {
-               DPRINTK("xen-pvscsi: invalid parameter nr_seg = %d\n",
+               pr_debug("invalid parameter nr_seg = %d\n",
                        ring_req->nr_segments);
                return -EINVAL;
        }
@@ -515,13 +514,12 @@ static int scsiback_gnttab_data_map(struct vscsiif_request *ring_req,
                        nr_segments += n_segs;
                }
                if (nr_segments > SG_ALL) {
-                       DPRINTK("xen-pvscsi: invalid nr_seg = %d\n",
-                               nr_segments);
+                       pr_debug("invalid nr_seg = %d\n", nr_segments);
                        return -EINVAL;
                }
        }
 
-       /* free of (sgl) in fast_flush_area()*/
+       /* free of (sgl) in fast_flush_area() */
        pending_req->sgl = kmalloc_array(nr_segments,
                                        sizeof(struct scatterlist), GFP_KERNEL);
        if (!pending_req->sgl)
@@ -678,7 +676,8 @@ static int prepare_pending_reqs(struct vscsibk_info *info,
        v2p = scsiback_do_translation(info, &vir);
        if (!v2p) {
                pending_req->v2p = NULL;
-               DPRINTK("xen-pvscsi: doesn't exist.\n");
+               pr_debug("the v2p of (chn:%d, tgt:%d, lun:%d) doesn't exist.\n",
+                       vir.chn, vir.tgt, vir.lun);
                return -ENODEV;
        }
        pending_req->v2p = v2p;
@@ -689,14 +688,14 @@ static int prepare_pending_reqs(struct vscsibk_info *info,
                (pending_req->sc_data_direction != DMA_TO_DEVICE) &&
                (pending_req->sc_data_direction != DMA_FROM_DEVICE) &&
                (pending_req->sc_data_direction != DMA_NONE)) {
-               DPRINTK("xen-pvscsi: invalid parameter data_dir = %d\n",
+               pr_debug("invalid parameter data_dir = %d\n",
                        pending_req->sc_data_direction);
                return -EINVAL;
        }
 
        pending_req->cmd_len = ring_req->cmd_len;
        if (pending_req->cmd_len > VSCSIIF_MAX_COMMAND_SIZE) {
-               DPRINTK("xen-pvscsi: invalid parameter cmd_len = %d\n",
+               pr_debug("invalid parameter cmd_len = %d\n",
                        pending_req->cmd_len);
                return -EINVAL;
        }
@@ -708,12 +707,11 @@ static int prepare_pending_reqs(struct vscsibk_info *info,
 static int scsiback_do_cmd_fn(struct vscsibk_info *info)
 {
        struct vscsiif_back_ring *ring = &info->ring;
-       struct vscsiif_request *ring_req;
+       struct vscsiif_request ring_req;
        struct vscsibk_pend *pending_req;
        RING_IDX rc, rp;
        int err, more_to_do;
        uint32_t result;
-       uint8_t act;
 
        rc = ring->req_cons;
        rp = ring->sring->req_prod;
@@ -721,7 +719,7 @@ static int scsiback_do_cmd_fn(struct vscsibk_info *info)
 
        if (RING_REQUEST_PROD_OVERFLOW(ring, rp)) {
                rc = ring->rsp_prod_pvt;
-               pr_warn("xen-pvscsi: Dom%d provided bogus ring requests (%#x - %#x = %u). Halting ring processing\n",
+               pr_warn("Dom%d provided bogus ring requests (%#x - %#x = %u). Halting ring processing\n",
                           info->domid, rp, rc, rp - rc);
                info->ring_error = 1;
                return 0;
@@ -734,11 +732,10 @@ static int scsiback_do_cmd_fn(struct vscsibk_info *info)
                if (!pending_req)
                        return 1;
 
-               ring_req = RING_GET_REQUEST(ring, rc);
+               ring_req = *RING_GET_REQUEST(ring, rc);
                ring->req_cons = ++rc;
 
-               act = ring_req->act;
-               err = prepare_pending_reqs(info, ring_req, pending_req);
+               err = prepare_pending_reqs(info, &ring_req, pending_req);
                if (err) {
                        switch (err) {
                        case -ENODEV:
@@ -754,9 +751,9 @@ static int scsiback_do_cmd_fn(struct vscsibk_info *info)
                        return 1;
                }
 
-               switch (act) {
+               switch (ring_req.act) {
                case VSCSIIF_ACT_SCSI_CDB:
-                       if (scsiback_gnttab_data_map(ring_req, pending_req)) {
+                       if (scsiback_gnttab_data_map(&ring_req, pending_req)) {
                                scsiback_fast_flush_area(pending_req);
                                scsiback_do_resp_with_sense(NULL,
                                        DRIVER_ERROR << 24, 0, pending_req);
@@ -767,13 +764,13 @@ static int scsiback_do_cmd_fn(struct vscsibk_info *info)
                        break;
                case VSCSIIF_ACT_SCSI_ABORT:
                        scsiback_device_action(pending_req, TMR_ABORT_TASK,
-                               ring_req->ref_rqid);
+                               ring_req.ref_rqid);
                        break;
                case VSCSIIF_ACT_SCSI_RESET:
                        scsiback_device_action(pending_req, TMR_LUN_RESET, 0);
                        break;
                default:
-                       pr_err_ratelimited("xen-pvscsi: invalid request\n");
+                       pr_err_ratelimited("invalid request\n");
                        scsiback_do_resp_with_sense(NULL, DRIVER_ERROR << 24,
                                                    0, pending_req);
                        kmem_cache_free(scsiback_cachep, pending_req);
@@ -811,7 +808,7 @@ static int scsiback_init_sring(struct vscsibk_info *info, grant_ref_t ring_ref,
        if (info->irq)
                return -1;
 
-       err = xenbus_map_ring_valloc(info->dev, ring_ref, &area);
+       err = xenbus_map_ring_valloc(info->dev, &ring_ref, 1, &area);
        if (err)
                return err;
 
@@ -875,14 +872,13 @@ static int scsiback_add_translation_entry(struct vscsibk_info *info,
 
        lunp = strrchr(phy, ':');
        if (!lunp) {
-               pr_err("xen-pvscsi: illegal format of physical device %s\n",
-                       phy);
+               pr_err("illegal format of physical device %s\n", phy);
                return -EINVAL;
        }
        *lunp = 0;
        lunp++;
        if (kstrtouint(lunp, 10, &lun) || lun >= TRANSPORT_MAX_LUNS_PER_TPG) {
-               pr_err("xen-pvscsi: lun number not valid: %s\n", lunp);
+               pr_err("lun number not valid: %s\n", lunp);
                return -EINVAL;
        }
 
@@ -910,7 +906,7 @@ static int scsiback_add_translation_entry(struct vscsibk_info *info,
        mutex_unlock(&scsiback_mutex);
 
        if (!tpg) {
-               pr_err("xen-pvscsi: %s:%d %s\n", phy, lun, error);
+               pr_err("%s:%d %s\n", phy, lun, error);
                return -ENODEV;
        }
 
@@ -927,7 +923,7 @@ static int scsiback_add_translation_entry(struct vscsibk_info *info,
                if ((entry->v.chn == v->chn) &&
                    (entry->v.tgt == v->tgt) &&
                    (entry->v.lun == v->lun)) {
-                       pr_warn("xen-pvscsi: Virtual ID is already used. Assignment was not performed.\n");
+                       pr_warn("Virtual ID is already used. Assignment was not performed.\n");
                        err = -EEXIST;
                        goto out;
                }
@@ -993,15 +989,15 @@ found:
 }
 
 static void scsiback_do_add_lun(struct vscsibk_info *info, const char *state,
-                               char *phy, struct ids_tuple *vir)
+                               char *phy, struct ids_tuple *vir, int try)
 {
        if (!scsiback_add_translation_entry(info, phy, vir)) {
                if (xenbus_printf(XBT_NIL, info->dev->nodename, state,
                                  "%d", XenbusStateInitialised)) {
-                       pr_err("xen-pvscsi: xenbus_printf error %s\n", state);
+                       pr_err("xenbus_printf error %s\n", state);
                        scsiback_del_translation_entry(info, vir);
                }
-       } else {
+       } else if (!try) {
                xenbus_printf(XBT_NIL, info->dev->nodename, state,
                              "%d", XenbusStateClosed);
        }
@@ -1013,7 +1009,7 @@ static void scsiback_do_del_lun(struct vscsibk_info *info, const char *state,
        if (!scsiback_del_translation_entry(info, vir)) {
                if (xenbus_printf(XBT_NIL, info->dev->nodename, state,
                                  "%d", XenbusStateClosed))
-                       pr_err("xen-pvscsi: xenbus_printf error %s\n", state);
+                       pr_err("xenbus_printf error %s\n", state);
        }
 }
 
@@ -1061,10 +1057,19 @@ static void scsiback_do_1lun_hotplug(struct vscsibk_info *info, int op,
 
        switch (op) {
        case VSCSIBACK_OP_ADD_OR_DEL_LUN:
-               if (device_state == XenbusStateInitialising)
-                       scsiback_do_add_lun(info, state, phy, &vir);
-               if (device_state == XenbusStateClosing)
+               switch (device_state) {
+               case XenbusStateInitialising:
+                       scsiback_do_add_lun(info, state, phy, &vir, 0);
+                       break;
+               case XenbusStateConnected:
+                       scsiback_do_add_lun(info, state, phy, &vir, 1);
+                       break;
+               case XenbusStateClosing:
                        scsiback_do_del_lun(info, state, &vir);
+                       break;
+               default:
+                       break;
+               }
                break;
 
        case VSCSIBACK_OP_UPDATEDEV_STATE:
@@ -1072,15 +1077,14 @@ static void scsiback_do_1lun_hotplug(struct vscsibk_info *info, int op,
                        /* modify vscsi-devs/dev-x/state */
                        if (xenbus_printf(XBT_NIL, dev->nodename, state,
                                          "%d", XenbusStateConnected)) {
-                               pr_err("xen-pvscsi: xenbus_printf error %s\n",
-                                      str);
+                               pr_err("xenbus_printf error %s\n", str);
                                scsiback_del_translation_entry(info, &vir);
                                xenbus_printf(XBT_NIL, dev->nodename, state,
                                              "%d", XenbusStateClosed);
                        }
                }
                break;
-       /*When it is necessary, processing is added here.*/
+       /* When it is necessary, processing is added here. */
        default:
                break;
        }
@@ -1197,7 +1201,7 @@ static int scsiback_probe(struct xenbus_device *dev,
        struct vscsibk_info *info = kzalloc(sizeof(struct vscsibk_info),
                                            GFP_KERNEL);
 
-       DPRINTK("%p %d\n", dev, dev->otherend_id);
+       pr_debug("%s %p %d\n", __func__, dev, dev->otherend_id);
 
        if (!info) {
                xenbus_dev_fatal(dev, -ENOMEM, "allocating backend structure");
@@ -1228,7 +1232,7 @@ static int scsiback_probe(struct xenbus_device *dev,
        return 0;
 
 fail:
-       pr_warn("xen-pvscsi: %s failed\n", __func__);
+       pr_warn("%s failed\n", __func__);
        scsiback_remove(dev);
 
        return err;
@@ -1433,7 +1437,7 @@ check_len:
        }
        snprintf(&tport->tport_name[0], VSCSI_NAMELEN, "%s", &name[off]);
 
-       pr_debug("xen-pvscsi: Allocated emulated Target %s Address: %s\n",
+       pr_debug("Allocated emulated Target %s Address: %s\n",
                 scsiback_dump_proto_id(tport), name);
 
        return &tport->tport_wwn;
@@ -1444,7 +1448,7 @@ static void scsiback_drop_tport(struct se_wwn *wwn)
        struct scsiback_tport *tport = container_of(wwn,
                                struct scsiback_tport, tport_wwn);
 
-       pr_debug("xen-pvscsi: Deallocating emulated Target %s Address: %s\n",
+       pr_debug("Deallocating emulated Target %s Address: %s\n",
                 scsiback_dump_proto_id(tport), tport->tport_name);
 
        kfree(tport);
@@ -1471,8 +1475,8 @@ static u32 scsiback_tpg_get_inst_index(struct se_portal_group *se_tpg)
 static int scsiback_check_stop_free(struct se_cmd *se_cmd)
 {
        /*
-        * Do not release struct se_cmd's containing a valid TMR
-        * pointer.  These will be released directly in scsiback_device_action()
+        * Do not release struct se_cmd's containing a valid TMR pointer.
+        * These will be released directly in scsiback_device_action()
         * with transport_generic_free_cmd().
         */
        if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)
@@ -1638,7 +1642,7 @@ static int scsiback_make_nexus(struct scsiback_tpg *tpg,
                return -ENOMEM;
        }
        /*
-        *  Initialize the struct se_session pointer
+        * Initialize the struct se_session pointer
         */
        tv_nexus->tvn_se_sess = transport_init_session(TARGET_PROT_NORMAL);
        if (IS_ERR(tv_nexus->tvn_se_sess)) {
@@ -1660,11 +1664,8 @@ static int scsiback_make_nexus(struct scsiback_tpg *tpg,
                         name);
                goto out;
        }
-       /*
-        * Now register the TCM pvscsi virtual I_T Nexus as active with the
-        * call to __transport_register_session()
-        */
-       __transport_register_session(se_tpg, tv_nexus->tvn_se_sess->se_node_acl,
+       /* Now register the TCM pvscsi virtual I_T Nexus as active. */
+       transport_register_session(se_tpg, tv_nexus->tvn_se_sess->se_node_acl,
                        tv_nexus->tvn_se_sess, tv_nexus);
        tpg->tpg_nexus = tv_nexus;
 
@@ -1709,7 +1710,7 @@ static int scsiback_drop_nexus(struct scsiback_tpg *tpg)
                return -EBUSY;
        }
 
-       pr_debug("xen-pvscsi: Removing I_T Nexus to emulated %s Initiator Port: %s\n",
+       pr_debug("Removing I_T Nexus to emulated %s Initiator Port: %s\n",
                scsiback_dump_proto_id(tpg->tport),
                tv_nexus->tvn_se_sess->se_node_acl->initiatorname);
 
@@ -1755,7 +1756,7 @@ static ssize_t scsiback_tpg_store_nexus(struct se_portal_group *se_tpg,
        unsigned char i_port[VSCSI_NAMELEN], *ptr, *port_ptr;
        int ret;
        /*
-        * Shutdown the active I_T nexus if 'NULL' is passed..
+        * Shutdown the active I_T nexus if 'NULL' is passed.
         */
        if (!strncmp(page, "NULL", 4)) {
                ret = scsiback_drop_nexus(tpg);
@@ -1926,7 +1927,7 @@ static void scsiback_drop_tpg(struct se_portal_group *se_tpg)
         */
        scsiback_drop_nexus(tpg);
        /*
-        * Deregister the se_tpg from TCM..
+        * Deregister the se_tpg from TCM.
         */
        core_tpg_deregister(se_tpg);
        kfree(tpg);
@@ -2048,7 +2049,7 @@ out_unregister_xenbus:
        xenbus_unregister_driver(&scsiback_driver);
 out_cache_destroy:
        kmem_cache_destroy(scsiback_cachep);
-       pr_err("xen-pvscsi: %s: error %d\n", __func__, ret);
+       pr_err("%s: error %d\n", __func__, ret);
        return ret;
 }