]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/infiniband/ulp/srp/ib_srp.c
Merge branch 'upstream' into upstream-jgarzik
[linux-2.6-omap-h63xx.git] / drivers / infiniband / ulp / srp / ib_srp.c
index 64ab5fc7cca38db98ad503dbf4e8cf2a5fbd7eb3..5e8ac577f0ad1c33dd9cf65a71d18dd149848822 100644 (file)
@@ -122,9 +122,8 @@ static struct srp_iu *srp_alloc_iu(struct srp_host *host, size_t size,
        if (!iu->buf)
                goto out_free_iu;
 
-       iu->dma = dma_map_single(host->dev->dev->dma_device,
-                                iu->buf, size, direction);
-       if (dma_mapping_error(iu->dma))
+       iu->dma = ib_dma_map_single(host->dev->dev, iu->buf, size, direction);
+       if (ib_dma_mapping_error(host->dev->dev, iu->dma))
                goto out_free_buf;
 
        iu->size      = size;
@@ -145,8 +144,7 @@ static void srp_free_iu(struct srp_host *host, struct srp_iu *iu)
        if (!iu)
                return;
 
-       dma_unmap_single(host->dev->dev->dma_device,
-                        iu->dma, iu->size, iu->direction);
+       ib_dma_unmap_single(host->dev->dev, iu->dma, iu->size, iu->direction);
        kfree(iu->buf);
        kfree(iu);
 }
@@ -390,9 +388,10 @@ static void srp_disconnect_target(struct srp_target_port *target)
        wait_for_completion(&target->done);
 }
 
-static void srp_remove_work(void *target_ptr)
+static void srp_remove_work(struct work_struct *work)
 {
-       struct srp_target_port *target = target_ptr;
+       struct srp_target_port *target =
+               container_of(work, struct srp_target_port, work);
 
        spin_lock_irq(target->scsi_host->host_lock);
        if (target->state != SRP_TARGET_DEAD) {
@@ -481,8 +480,8 @@ static void srp_unmap_data(struct scsi_cmnd *scmnd,
                scat  = &req->fake_sg;
        }
 
-       dma_unmap_sg(target->srp_host->dev->dev->dma_device, scat, nents,
-                    scmnd->sc_data_direction);
+       ib_dma_unmap_sg(target->srp_host->dev->dev, scat, nents,
+                       scmnd->sc_data_direction);
 }
 
 static void srp_remove_req(struct srp_target_port *target, struct srp_request *req)
@@ -549,6 +548,7 @@ static int srp_reconnect_target(struct srp_target_port *target)
        target->tx_head  = 0;
        target->tx_tail  = 0;
 
+       target->qp_in_error = 0;
        ret = srp_connect_target(target);
        if (ret)
                goto err;
@@ -575,7 +575,7 @@ err:
        spin_lock_irq(target->scsi_host->host_lock);
        if (target->state == SRP_TARGET_CONNECTING) {
                target->state = SRP_TARGET_DEAD;
-               INIT_WORK(&target->work, srp_remove_work, target);
+               INIT_WORK(&target->work, srp_remove_work);
                schedule_work(&target->work);
        }
        spin_unlock_irq(target->scsi_host->host_lock);
@@ -594,23 +594,26 @@ static int srp_map_fmr(struct srp_target_port *target, struct scatterlist *scat,
        int i, j;
        int ret;
        struct srp_device *dev = target->srp_host->dev;
+       struct ib_device *ibdev = dev->dev;
 
        if (!dev->fmr_pool)
                return -ENODEV;
 
-       if ((sg_dma_address(&scat[0]) & ~dev->fmr_page_mask) &&
+       if ((ib_sg_dma_address(ibdev, &scat[0]) & ~dev->fmr_page_mask) &&
            mellanox_workarounds && !memcmp(&target->ioc_guid, mellanox_oui, 3))
                return -EINVAL;
 
        len = page_cnt = 0;
        for (i = 0; i < sg_cnt; ++i) {
-               if (sg_dma_address(&scat[i]) & ~dev->fmr_page_mask) {
+               unsigned int dma_len = ib_sg_dma_len(ibdev, &scat[i]);
+
+               if (ib_sg_dma_address(ibdev, &scat[i]) & ~dev->fmr_page_mask) {
                        if (i > 0)
                                return -EINVAL;
                        else
                                ++page_cnt;
                }
-               if ((sg_dma_address(&scat[i]) + sg_dma_len(&scat[i])) &
+               if ((ib_sg_dma_address(ibdev, &scat[i]) + dma_len) &
                    ~dev->fmr_page_mask) {
                        if (i < sg_cnt - 1)
                                return -EINVAL;
@@ -618,7 +621,7 @@ static int srp_map_fmr(struct srp_target_port *target, struct scatterlist *scat,
                                ++page_cnt;
                }
 
-               len += sg_dma_len(&scat[i]);
+               len += dma_len;
        }
 
        page_cnt += len >> dev->fmr_page_shift;
@@ -630,10 +633,14 @@ static int srp_map_fmr(struct srp_target_port *target, struct scatterlist *scat,
                return -ENOMEM;
 
        page_cnt = 0;
-       for (i = 0; i < sg_cnt; ++i)
-               for (j = 0; j < sg_dma_len(&scat[i]); j += dev->fmr_page_size)
+       for (i = 0; i < sg_cnt; ++i) {
+               unsigned int dma_len = ib_sg_dma_len(ibdev, &scat[i]);
+
+               for (j = 0; j < dma_len; j += dev->fmr_page_size)
                        dma_pages[page_cnt++] =
-                               (sg_dma_address(&scat[i]) & dev->fmr_page_mask) + j;
+                               (ib_sg_dma_address(ibdev, &scat[i]) &
+                                dev->fmr_page_mask) + j;
+       }
 
        req->fmr = ib_fmr_pool_map_phys(dev->fmr_pool,
                                        dma_pages, page_cnt, io_addr);
@@ -643,7 +650,8 @@ static int srp_map_fmr(struct srp_target_port *target, struct scatterlist *scat,
                goto out;
        }
 
-       buf->va  = cpu_to_be64(sg_dma_address(&scat[0]) & ~dev->fmr_page_mask);
+       buf->va  = cpu_to_be64(ib_sg_dma_address(ibdev, &scat[0]) &
+                              ~dev->fmr_page_mask);
        buf->key = cpu_to_be32(req->fmr->fmr->rkey);
        buf->len = cpu_to_be32(len);
 
@@ -662,6 +670,8 @@ static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target,
        struct srp_cmd *cmd = req->cmd->buf;
        int len, nents, count;
        u8 fmt = SRP_DATA_DESC_DIRECT;
+       struct srp_device *dev;
+       struct ib_device *ibdev;
 
        if (!scmnd->request_buffer || scmnd->sc_data_direction == DMA_NONE)
                return sizeof (struct srp_cmd);
@@ -686,8 +696,10 @@ static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target,
                sg_init_one(scat, scmnd->request_buffer, scmnd->request_bufflen);
        }
 
-       count = dma_map_sg(target->srp_host->dev->dev->dma_device,
-                          scat, nents, scmnd->sc_data_direction);
+       dev = target->srp_host->dev;
+       ibdev = dev->dev;
+
+       count = ib_dma_map_sg(ibdev, scat, nents, scmnd->sc_data_direction);
 
        fmt = SRP_DATA_DESC_DIRECT;
        len = sizeof (struct srp_cmd) + sizeof (struct srp_direct_buf);
@@ -701,9 +713,9 @@ static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target,
                 */
                struct srp_direct_buf *buf = (void *) cmd->add_data;
 
-               buf->va  = cpu_to_be64(sg_dma_address(scat));
-               buf->key = cpu_to_be32(target->srp_host->dev->mr->rkey);
-               buf->len = cpu_to_be32(sg_dma_len(scat));
+               buf->va  = cpu_to_be64(ib_sg_dma_address(ibdev, scat));
+               buf->key = cpu_to_be32(dev->mr->rkey);
+               buf->len = cpu_to_be32(ib_sg_dma_len(ibdev, scat));
        } else if (srp_map_fmr(target, scat, count, req,
                               (void *) cmd->add_data)) {
                /*
@@ -721,13 +733,14 @@ static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target,
                        count * sizeof (struct srp_direct_buf);
 
                for (i = 0; i < count; ++i) {
+                       unsigned int dma_len = ib_sg_dma_len(ibdev, &scat[i]);
+
                        buf->desc_list[i].va  =
-                               cpu_to_be64(sg_dma_address(&scat[i]));
+                               cpu_to_be64(ib_sg_dma_address(ibdev, &scat[i]));
                        buf->desc_list[i].key =
-                               cpu_to_be32(target->srp_host->dev->mr->rkey);
-                       buf->desc_list[i].len =
-                               cpu_to_be32(sg_dma_len(&scat[i]));
-                       datalen += sg_dma_len(&scat[i]);
+                               cpu_to_be32(dev->mr->rkey);
+                       buf->desc_list[i].len = cpu_to_be32(dma_len);
+                       datalen += dma_len;
                }
 
                if (scmnd->sc_data_direction == DMA_TO_DEVICE)
@@ -807,13 +820,15 @@ static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp)
 
 static void srp_handle_recv(struct srp_target_port *target, struct ib_wc *wc)
 {
+       struct ib_device *dev;
        struct srp_iu *iu;
        u8 opcode;
 
        iu = target->rx_ring[wc->wr_id & ~SRP_OP_RECV];
 
-       dma_sync_single_for_cpu(target->srp_host->dev->dev->dma_device, iu->dma,
-                               target->max_ti_iu_len, DMA_FROM_DEVICE);
+       dev = target->srp_host->dev->dev;
+       ib_dma_sync_single_for_cpu(dev, iu->dma, target->max_ti_iu_len,
+                                  DMA_FROM_DEVICE);
 
        opcode = *(u8 *) iu->buf;
 
@@ -849,8 +864,8 @@ static void srp_handle_recv(struct srp_target_port *target, struct ib_wc *wc)
                break;
        }
 
-       dma_sync_single_for_device(target->srp_host->dev->dev->dma_device, iu->dma,
-                                  target->max_ti_iu_len, DMA_FROM_DEVICE);
+       ib_dma_sync_single_for_device(dev, iu->dma, target->max_ti_iu_len,
+                                     DMA_FROM_DEVICE);
 }
 
 static void srp_completion(struct ib_cq *cq, void *target_ptr)
@@ -864,6 +879,7 @@ static void srp_completion(struct ib_cq *cq, void *target_ptr)
                        printk(KERN_ERR PFX "failed %s status %d\n",
                               wc.wr_id & SRP_OP_RECV ? "receive" : "send",
                               wc.status);
+                       target->qp_in_error = 1;
                        break;
                }
 
@@ -968,6 +984,7 @@ static int srp_queuecommand(struct scsi_cmnd *scmnd,
        struct srp_request *req;
        struct srp_iu *iu;
        struct srp_cmd *cmd;
+       struct ib_device *dev;
        int len;
 
        if (target->state == SRP_TARGET_CONNECTING)
@@ -984,8 +1001,9 @@ static int srp_queuecommand(struct scsi_cmnd *scmnd,
        if (!iu)
                goto err;
 
-       dma_sync_single_for_cpu(target->srp_host->dev->dev->dma_device, iu->dma,
-                               srp_max_iu_len, DMA_TO_DEVICE);
+       dev = target->srp_host->dev->dev;
+       ib_dma_sync_single_for_cpu(dev, iu->dma, srp_max_iu_len,
+                                  DMA_TO_DEVICE);
 
        req = list_entry(target->free_reqs.next, struct srp_request, list);
 
@@ -1017,8 +1035,8 @@ static int srp_queuecommand(struct scsi_cmnd *scmnd,
                goto err_unmap;
        }
 
-       dma_sync_single_for_device(target->srp_host->dev->dev->dma_device, iu->dma,
-                                  srp_max_iu_len, DMA_TO_DEVICE);
+       ib_dma_sync_single_for_device(dev, iu->dma, srp_max_iu_len,
+                                     DMA_TO_DEVICE);
 
        if (__srp_post_send(target, iu, len)) {
                printk(KERN_ERR PFX "Send failed\n");
@@ -1321,6 +1339,8 @@ static int srp_abort(struct scsi_cmnd *scmnd)
 
        printk(KERN_ERR "SRP abort called\n");
 
+       if (target->qp_in_error)
+               return FAILED;
        if (srp_find_req(target, scmnd, &req))
                return FAILED;
        if (srp_send_tsk_mgmt(target, req, SRP_TSK_ABORT_TASK))
@@ -1349,6 +1369,8 @@ static int srp_reset_device(struct scsi_cmnd *scmnd)
 
        printk(KERN_ERR "SRP reset_device called\n");
 
+       if (target->qp_in_error)
+               return FAILED;
        if (srp_find_req(target, scmnd, &req))
                return FAILED;
        if (srp_send_tsk_mgmt(target, req, SRP_TSK_LUN_RESET))
@@ -1605,18 +1627,30 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target)
                switch (token) {
                case SRP_OPT_ID_EXT:
                        p = match_strdup(args);
+                       if (!p) {
+                               ret = -ENOMEM;
+                               goto out;
+                       }
                        target->id_ext = cpu_to_be64(simple_strtoull(p, NULL, 16));
                        kfree(p);
                        break;
 
                case SRP_OPT_IOC_GUID:
                        p = match_strdup(args);
+                       if (!p) {
+                               ret = -ENOMEM;
+                               goto out;
+                       }
                        target->ioc_guid = cpu_to_be64(simple_strtoull(p, NULL, 16));
                        kfree(p);
                        break;
 
                case SRP_OPT_DGID:
                        p = match_strdup(args);
+                       if (!p) {
+                               ret = -ENOMEM;
+                               goto out;
+                       }
                        if (strlen(p) != 32) {
                                printk(KERN_WARNING PFX "bad dest GID parameter '%s'\n", p);
                                kfree(p);
@@ -1640,6 +1674,10 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target)
 
                case SRP_OPT_SERVICE_ID:
                        p = match_strdup(args);
+                       if (!p) {
+                               ret = -ENOMEM;
+                               goto out;
+                       }
                        target->service_id = cpu_to_be64(simple_strtoull(p, NULL, 16));
                        kfree(p);
                        break;
@@ -1677,6 +1715,10 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target)
 
                case SRP_OPT_INITIATOR_EXT:
                        p = match_strdup(args);
+                       if (!p) {
+                               ret = -ENOMEM;
+                               goto out;
+                       }
                        target->initiator_ext = cpu_to_be64(simple_strtoull(p, NULL, 16));
                        kfree(p);
                        break;
@@ -1765,6 +1807,7 @@ static ssize_t srp_create_target(struct class_device *class_dev,
                goto err_free;
        }
 
+       target->qp_in_error = 0;
        ret = srp_connect_target(target);
        if (ret) {
                printk(KERN_ERR PFX "Connection failed\n");
@@ -1882,7 +1925,7 @@ static void srp_add_one(struct ib_device *device)
         */
        srp_dev->fmr_page_shift = max(9, ffs(dev_attr->page_size_cap) - 1);
        srp_dev->fmr_page_size  = 1 << srp_dev->fmr_page_shift;
-       srp_dev->fmr_page_mask  = ~((unsigned long) srp_dev->fmr_page_size - 1);
+       srp_dev->fmr_page_mask  = ~((u64) srp_dev->fmr_page_size - 1);
 
        INIT_LIST_HEAD(&srp_dev->dev_list);