linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / drivers / infiniband / ulp / srp / ib_srp.c
index 9cbdffa..960dae5 100644 (file)
@@ -340,10 +340,7 @@ static void srp_disconnect_target(struct srp_target_port *target)
        /* XXX should send SRP_I_LOGOUT request */
 
        init_completion(&target->done);
-       if (ib_send_cm_dreq(target->cm_id, NULL, 0)) {
-               printk(KERN_DEBUG PFX "Sending CM DREQ failed\n");
-               return;
-       }
+       ib_send_cm_dreq(target->cm_id, NULL, 0);
        wait_for_completion(&target->done);
 }
 
@@ -354,6 +351,7 @@ static void srp_remove_work(void *target_ptr)
        spin_lock_irq(target->scsi_host->host_lock);
        if (target->state != SRP_TARGET_DEAD) {
                spin_unlock_irq(target->scsi_host->host_lock);
+               scsi_host_put(target->scsi_host);
                return;
        }
        target->state = SRP_TARGET_REMOVED;
@@ -367,6 +365,8 @@ static void srp_remove_work(void *target_ptr)
        ib_destroy_cm_id(target->cm_id);
        srp_free_target_ib(target);
        scsi_host_put(target->scsi_host);
+       /* And another put to really free the target port... */
+       scsi_host_put(target->scsi_host);
 }
 
 static int srp_connect_target(struct srp_target_port *target)
@@ -409,34 +409,6 @@ static int srp_connect_target(struct srp_target_port *target)
        }
 }
 
-static void srp_unmap_data(struct scsi_cmnd *scmnd,
-                          struct srp_target_port *target,
-                          struct srp_request *req)
-{
-       struct scatterlist *scat;
-       int nents;
-
-       if (!scmnd->request_buffer ||
-           (scmnd->sc_data_direction != DMA_TO_DEVICE &&
-            scmnd->sc_data_direction != DMA_FROM_DEVICE))
-               return;
-
-       /*
-        * This handling of non-SG commands can be killed when the
-        * SCSI midlayer no longer generates non-SG commands.
-        */
-       if (likely(scmnd->use_sg)) {
-               nents = scmnd->use_sg;
-               scat  = scmnd->request_buffer;
-       } else {
-               nents = 1;
-               scat  = &req->fake_sg;
-       }
-
-       dma_unmap_sg(target->srp_host->dev->dma_device, scat, nents,
-                    scmnd->sc_data_direction);
-}
-
 static int srp_reconnect_target(struct srp_target_port *target)
 {
        struct ib_cm_id *new_cm_id;
@@ -483,16 +455,16 @@ static int srp_reconnect_target(struct srp_target_port *target)
        list_for_each_entry(req, &target->req_queue, list) {
                req->scmnd->result = DID_RESET << 16;
                req->scmnd->scsi_done(req->scmnd);
-               srp_unmap_data(req->scmnd, target, req);
        }
 
        target->rx_head  = 0;
        target->tx_head  = 0;
        target->tx_tail  = 0;
-       INIT_LIST_HEAD(&target->free_reqs);
+       target->req_head = 0;
+       for (i = 0; i < SRP_SQ_SIZE - 1; ++i)
+               target->req_ring[i].next = i + 1;
+       target->req_ring[SRP_SQ_SIZE - 1].next = -1;
        INIT_LIST_HEAD(&target->req_queue);
-       for (i = 0; i < SRP_SQ_SIZE; ++i)
-               list_add_tail(&target->req_ring[i].list, &target->free_reqs);
 
        ret = srp_connect_target(target);
        if (ret)
@@ -531,10 +503,8 @@ err:
 static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target,
                        struct srp_request *req)
 {
-       struct scatterlist *scat;
        struct srp_cmd *cmd = req->cmd->buf;
-       int len, nents, count;
-       int i;
+       int len;
        u8 fmt;
 
        if (!scmnd->request_buffer || scmnd->sc_data_direction == DMA_NONE)
@@ -547,66 +517,82 @@ static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target,
                return -EINVAL;
        }
 
-       /*
-        * This handling of non-SG commands can be killed when the
-        * SCSI midlayer no longer generates non-SG commands.
-        */
-       if (likely(scmnd->use_sg)) {
-               nents = scmnd->use_sg;
-               scat  = scmnd->request_buffer;
-       } else {
-               nents = 1;
-               scat  = &req->fake_sg;
-               sg_init_one(scat, scmnd->request_buffer, scmnd->request_bufflen);
-       }
+       if (scmnd->use_sg) {
+               struct scatterlist *scat = scmnd->request_buffer;
+               int n;
+               int i;
 
-       count = dma_map_sg(target->srp_host->dev->dma_device, scat, nents,
-                          scmnd->sc_data_direction);
+               n = dma_map_sg(target->srp_host->dev->dma_device,
+                              scat, scmnd->use_sg, scmnd->sc_data_direction);
 
-       if (count == 1) {
-               struct srp_direct_buf *buf = (void *) cmd->add_data;
+               if (n == 1) {
+                       struct srp_direct_buf *buf = (void *) cmd->add_data;
 
-               fmt = SRP_DATA_DESC_DIRECT;
+                       fmt = SRP_DATA_DESC_DIRECT;
 
-               buf->va  = cpu_to_be64(sg_dma_address(scat));
-               buf->key = cpu_to_be32(target->srp_host->mr->rkey);
-               buf->len = cpu_to_be32(sg_dma_len(scat));
+                       buf->va  = cpu_to_be64(sg_dma_address(scat));
+                       buf->key = cpu_to_be32(target->srp_host->mr->rkey);
+                       buf->len = cpu_to_be32(sg_dma_len(scat));
 
-               len = sizeof (struct srp_cmd) +
-                       sizeof (struct srp_direct_buf);
-       } else {
-               struct srp_indirect_buf *buf = (void *) cmd->add_data;
-               u32 datalen = 0;
+                       len = sizeof (struct srp_cmd) +
+                               sizeof (struct srp_direct_buf);
+               } else {
+                       struct srp_indirect_buf *buf = (void *) cmd->add_data;
+                       u32 datalen = 0;
 
-               fmt = SRP_DATA_DESC_INDIRECT;
+                       fmt = SRP_DATA_DESC_INDIRECT;
 
-               if (scmnd->sc_data_direction == DMA_TO_DEVICE)
-                       cmd->data_out_desc_cnt = count;
-               else
-                       cmd->data_in_desc_cnt = count;
-
-               buf->table_desc.va  = cpu_to_be64(req->cmd->dma +
-                                                 sizeof *cmd +
-                                                 sizeof *buf);
-               buf->table_desc.key =
-                       cpu_to_be32(target->srp_host->mr->rkey);
-               buf->table_desc.len =
-                       cpu_to_be32(count * sizeof (struct srp_direct_buf));
-
-               for (i = 0; i < count; ++i) {
-                       buf->desc_list[i].va  = cpu_to_be64(sg_dma_address(&scat[i]));
-                       buf->desc_list[i].key =
+                       if (scmnd->sc_data_direction == DMA_TO_DEVICE)
+                               cmd->data_out_desc_cnt = n;
+                       else
+                               cmd->data_in_desc_cnt = n;
+
+                       buf->table_desc.va  = cpu_to_be64(req->cmd->dma +
+                                                         sizeof *cmd +
+                                                         sizeof *buf);
+                       buf->table_desc.key =
                                cpu_to_be32(target->srp_host->mr->rkey);
-                       buf->desc_list[i].len = cpu_to_be32(sg_dma_len(&scat[i]));
+                       buf->table_desc.len =
+                               cpu_to_be32(n * sizeof (struct srp_direct_buf));
+
+                       for (i = 0; i < n; ++i) {
+                               buf->desc_list[i].va  = cpu_to_be64(sg_dma_address(&scat[i]));
+                               buf->desc_list[i].key =
+                                       cpu_to_be32(target->srp_host->mr->rkey);
+                               buf->desc_list[i].len = cpu_to_be32(sg_dma_len(&scat[i]));
+
+                               datalen += sg_dma_len(&scat[i]);
+                       }
+
+                       buf->len = cpu_to_be32(datalen);
 
-                       datalen += sg_dma_len(&scat[i]);
+                       len = sizeof (struct srp_cmd) +
+                               sizeof (struct srp_indirect_buf) +
+                               n * sizeof (struct srp_direct_buf);
                }
+       } else {
+               struct srp_direct_buf *buf = (void *) cmd->add_data;
+               dma_addr_t dma;
+
+               dma = dma_map_single(target->srp_host->dev->dma_device,
+                                    scmnd->request_buffer, scmnd->request_bufflen,
+                                    scmnd->sc_data_direction);
+               if (dma_mapping_error(dma)) {
+                       printk(KERN_WARNING PFX "unable to map %p/%d (dir %d)\n",
+                              scmnd->request_buffer, (int) scmnd->request_bufflen,
+                              scmnd->sc_data_direction);
+                       return -EINVAL;
+               }
+
+               pci_unmap_addr_set(req, direct_mapping, dma);
+
+               buf->va  = cpu_to_be64(dma);
+               buf->key = cpu_to_be32(target->srp_host->mr->rkey);
+               buf->len = cpu_to_be32(scmnd->request_bufflen);
 
-               buf->len = cpu_to_be32(datalen);
+               fmt = SRP_DATA_DESC_DIRECT;
 
-               len = sizeof (struct srp_cmd) +
-                       sizeof (struct srp_indirect_buf) +
-                       count * sizeof (struct srp_direct_buf);
+               len = sizeof (struct srp_cmd) + sizeof (struct srp_direct_buf);
        }
 
        if (scmnd->sc_data_direction == DMA_TO_DEVICE)
@@ -614,13 +600,28 @@ static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target,
        else
                cmd->buf_fmt = fmt;
 
+
        return len;
 }
 
-static void srp_remove_req(struct srp_target_port *target, struct srp_request *req)
+static void srp_unmap_data(struct scsi_cmnd *scmnd,
+                          struct srp_target_port *target,
+                          struct srp_request *req)
 {
-       srp_unmap_data(req->scmnd, target, req);
-       list_move_tail(&req->list, &target->free_reqs);
+       if (!scmnd->request_buffer ||
+           (scmnd->sc_data_direction != DMA_TO_DEVICE &&
+            scmnd->sc_data_direction != DMA_FROM_DEVICE))
+           return;
+
+       if (scmnd->use_sg)
+               dma_unmap_sg(target->srp_host->dev->dma_device,
+                            (struct scatterlist *) scmnd->request_buffer,
+                            scmnd->use_sg, scmnd->sc_data_direction);
+       else
+               dma_unmap_single(target->srp_host->dev->dma_device,
+                                pci_unmap_addr(req, direct_mapping),
+                                scmnd->request_bufflen,
+                                scmnd->sc_data_direction);
 }
 
 static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp)
@@ -645,7 +646,7 @@ static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp)
                        req->tsk_status = rsp->data[3];
                complete(&req->done);
        } else {
-               scmnd = req->scmnd;
+               scmnd         = req->scmnd;
                if (!scmnd)
                        printk(KERN_ERR "Null scmnd for RSP w/tag %016llx\n",
                               (unsigned long long) rsp->tag);
@@ -663,11 +664,16 @@ static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp)
                else if (rsp->flags & (SRP_RSP_FLAG_DIOVER | SRP_RSP_FLAG_DIUNDER))
                        scmnd->resid = be32_to_cpu(rsp->data_in_res_cnt);
 
+               srp_unmap_data(scmnd, target, req);
+
                if (!req->tsk_mgmt) {
+                       req->scmnd = NULL;
                        scmnd->host_scribble = (void *) -1L;
                        scmnd->scsi_done(scmnd);
 
-                       srp_remove_req(target, req);
+                       list_del(&req->list);
+                       req->next = target->req_head;
+                       target->req_head = rsp->tag & ~SRP_TAG_TSK_MGMT;
                } else
                        req->cmd_done = 1;
        }
@@ -854,6 +860,7 @@ static int srp_queuecommand(struct scsi_cmnd *scmnd,
        struct srp_request *req;
        struct srp_iu *iu;
        struct srp_cmd *cmd;
+       long req_index;
        int len;
 
        if (target->state == SRP_TARGET_CONNECTING)
@@ -873,20 +880,22 @@ static int srp_queuecommand(struct scsi_cmnd *scmnd,
        dma_sync_single_for_cpu(target->srp_host->dev->dma_device, iu->dma,
                                SRP_MAX_IU_LEN, DMA_TO_DEVICE);
 
-       req = list_entry(target->free_reqs.next, struct srp_request, list);
+       req_index = target->req_head;
 
        scmnd->scsi_done     = done;
        scmnd->result        = 0;
-       scmnd->host_scribble = (void *) (long) req->index;
+       scmnd->host_scribble = (void *) req_index;
 
        cmd = iu->buf;
        memset(cmd, 0, sizeof *cmd);
 
        cmd->opcode = SRP_CMD;
        cmd->lun    = cpu_to_be64((u64) scmnd->device->lun << 48);
-       cmd->tag    = req->index;
+       cmd->tag    = req_index;
        memcpy(cmd->cdb, scmnd->cmnd, scmnd->cmd_len);
 
+       req = &target->req_ring[req_index];
+
        req->scmnd    = scmnd;
        req->cmd      = iu;
        req->cmd_done = 0;
@@ -911,7 +920,8 @@ static int srp_queuecommand(struct scsi_cmnd *scmnd,
                goto err_unmap;
        }
 
-       list_move_tail(&req->list, &target->req_queue);
+       target->req_head = req->next;
+       list_add_tail(&req->list, &target->req_queue);
 
        return 0;
 
@@ -1134,20 +1144,30 @@ static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event)
        return 0;
 }
 
-static int srp_send_tsk_mgmt(struct srp_target_port *target,
-                            struct srp_request *req, u8 func)
+static int srp_send_tsk_mgmt(struct scsi_cmnd *scmnd, u8 func)
 {
+       struct srp_target_port *target = host_to_target(scmnd->device->host);
+       struct srp_request *req;
        struct srp_iu *iu;
        struct srp_tsk_mgmt *tsk_mgmt;
+       int req_index;
+       int ret = FAILED;
 
        spin_lock_irq(target->scsi_host->host_lock);
 
        if (target->state == SRP_TARGET_DEAD ||
            target->state == SRP_TARGET_REMOVED) {
-               req->scmnd->result = DID_BAD_TARGET << 16;
+               scmnd->result = DID_BAD_TARGET << 16;
                goto out;
        }
 
+       if (scmnd->host_scribble == (void *) -1L)
+               goto out;
+
+       req_index = (long) scmnd->host_scribble;
+       printk(KERN_ERR "Abort for req_index %d\n", req_index);
+
+       req = &target->req_ring[req_index];
        init_completion(&req->done);
 
        iu = __srp_get_tx_iu(target);
@@ -1158,10 +1178,10 @@ static int srp_send_tsk_mgmt(struct srp_target_port *target,
        memset(tsk_mgmt, 0, sizeof *tsk_mgmt);
 
        tsk_mgmt->opcode        = SRP_TSK_MGMT;
-       tsk_mgmt->lun           = cpu_to_be64((u64) req->scmnd->device->lun << 48);
-       tsk_mgmt->tag           = req->index | SRP_TAG_TSK_MGMT;
+       tsk_mgmt->lun           = cpu_to_be64((u64) scmnd->device->lun << 48);
+       tsk_mgmt->tag           = req_index | SRP_TAG_TSK_MGMT;
        tsk_mgmt->tsk_mgmt_func = func;
-       tsk_mgmt->task_tag      = req->index;
+       tsk_mgmt->task_tag      = req_index;
 
        if (__srp_post_send(target, iu, sizeof *tsk_mgmt))
                goto out;
@@ -1169,85 +1189,39 @@ static int srp_send_tsk_mgmt(struct srp_target_port *target,
        req->tsk_mgmt = iu;
 
        spin_unlock_irq(target->scsi_host->host_lock);
-
        if (!wait_for_completion_timeout(&req->done,
                                         msecs_to_jiffies(SRP_ABORT_TIMEOUT_MS)))
-               return -1;
-
-       return 0;
-
-out:
-       spin_unlock_irq(target->scsi_host->host_lock);
-       return -1;
-}
-
-static int srp_find_req(struct srp_target_port *target,
-                       struct scsi_cmnd *scmnd,
-                       struct srp_request **req)
-{
-       if (scmnd->host_scribble == (void *) -1L)
-               return -1;
-
-       *req = &target->req_ring[(long) scmnd->host_scribble];
-
-       return 0;
-}
-
-static int srp_abort(struct scsi_cmnd *scmnd)
-{
-       struct srp_target_port *target = host_to_target(scmnd->device->host);
-       struct srp_request *req;
-       int ret = SUCCESS;
-
-       printk(KERN_ERR "SRP abort called\n");
-
-       if (srp_find_req(target, scmnd, &req))
                return FAILED;
-       if (srp_send_tsk_mgmt(target, req, SRP_TSK_ABORT_TASK))
-               return FAILED;
-
        spin_lock_irq(target->scsi_host->host_lock);
 
        if (req->cmd_done) {
-               srp_remove_req(target, req);
+               list_del(&req->list);
+               req->next = target->req_head;
+               target->req_head = req_index;
+
                scmnd->scsi_done(scmnd);
        } else if (!req->tsk_status) {
-               srp_remove_req(target, req);
                scmnd->result = DID_ABORT << 16;
-       } else
-               ret = FAILED;
+               ret = SUCCESS;
+       }
 
+out:
        spin_unlock_irq(target->scsi_host->host_lock);
-
        return ret;
 }
 
-static int srp_reset_device(struct scsi_cmnd *scmnd)
+static int srp_abort(struct scsi_cmnd *scmnd)
 {
-       struct srp_target_port *target = host_to_target(scmnd->device->host);
-       struct srp_request *req, *tmp;
-
-       printk(KERN_ERR "SRP reset_device called\n");
-
-       if (srp_find_req(target, scmnd, &req))
-               return FAILED;
-       if (srp_send_tsk_mgmt(target, req, SRP_TSK_LUN_RESET))
-               return FAILED;
-       if (req->tsk_status)
-               return FAILED;
-
-       spin_lock_irq(target->scsi_host->host_lock);
+       printk(KERN_ERR "SRP abort called\n");
 
-       list_for_each_entry_safe(req, tmp, &target->req_queue, list)
-               if (req->scmnd->device == scmnd->device) {
-                       req->scmnd->result = DID_RESET << 16;
-                       req->scmnd->scsi_done(req->scmnd);
-                       srp_remove_req(target, req);
-               }
+       return srp_send_tsk_mgmt(scmnd, SRP_TSK_ABORT_TASK);
+}
 
-       spin_unlock_irq(target->scsi_host->host_lock);
+static int srp_reset_device(struct scsi_cmnd *scmnd)
+{
+       printk(KERN_ERR "SRP reset_device called\n");
 
-       return SUCCESS;
+       return srp_send_tsk_mgmt(scmnd, SRP_TSK_LUN_RESET);
 }
 
 static int srp_reset_host(struct scsi_cmnd *scmnd)
@@ -1263,87 +1237,6 @@ static int srp_reset_host(struct scsi_cmnd *scmnd)
        return ret;
 }
 
-static ssize_t show_id_ext(struct class_device *cdev, char *buf)
-{
-       struct srp_target_port *target = host_to_target(class_to_shost(cdev));
-
-       if (target->state == SRP_TARGET_DEAD ||
-           target->state == SRP_TARGET_REMOVED)
-               return -ENODEV;
-
-       return sprintf(buf, "0x%016llx\n",
-                      (unsigned long long) be64_to_cpu(target->id_ext));
-}
-
-static ssize_t show_ioc_guid(struct class_device *cdev, char *buf)
-{
-       struct srp_target_port *target = host_to_target(class_to_shost(cdev));
-
-       if (target->state == SRP_TARGET_DEAD ||
-           target->state == SRP_TARGET_REMOVED)
-               return -ENODEV;
-
-       return sprintf(buf, "0x%016llx\n",
-                      (unsigned long long) be64_to_cpu(target->ioc_guid));
-}
-
-static ssize_t show_service_id(struct class_device *cdev, char *buf)
-{
-       struct srp_target_port *target = host_to_target(class_to_shost(cdev));
-
-       if (target->state == SRP_TARGET_DEAD ||
-           target->state == SRP_TARGET_REMOVED)
-               return -ENODEV;
-
-       return sprintf(buf, "0x%016llx\n",
-                      (unsigned long long) be64_to_cpu(target->service_id));
-}
-
-static ssize_t show_pkey(struct class_device *cdev, char *buf)
-{
-       struct srp_target_port *target = host_to_target(class_to_shost(cdev));
-
-       if (target->state == SRP_TARGET_DEAD ||
-           target->state == SRP_TARGET_REMOVED)
-               return -ENODEV;
-
-       return sprintf(buf, "0x%04x\n", be16_to_cpu(target->path.pkey));
-}
-
-static ssize_t show_dgid(struct class_device *cdev, char *buf)
-{
-       struct srp_target_port *target = host_to_target(class_to_shost(cdev));
-
-       if (target->state == SRP_TARGET_DEAD ||
-           target->state == SRP_TARGET_REMOVED)
-               return -ENODEV;
-
-       return sprintf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
-                      be16_to_cpu(((__be16 *) target->path.dgid.raw)[0]),
-                      be16_to_cpu(((__be16 *) target->path.dgid.raw)[1]),
-                      be16_to_cpu(((__be16 *) target->path.dgid.raw)[2]),
-                      be16_to_cpu(((__be16 *) target->path.dgid.raw)[3]),
-                      be16_to_cpu(((__be16 *) target->path.dgid.raw)[4]),
-                      be16_to_cpu(((__be16 *) target->path.dgid.raw)[5]),
-                      be16_to_cpu(((__be16 *) target->path.dgid.raw)[6]),
-                      be16_to_cpu(((__be16 *) target->path.dgid.raw)[7]));
-}
-
-static CLASS_DEVICE_ATTR(id_ext,       S_IRUGO, show_id_ext,           NULL);
-static CLASS_DEVICE_ATTR(ioc_guid,     S_IRUGO, show_ioc_guid,         NULL);
-static CLASS_DEVICE_ATTR(service_id,   S_IRUGO, show_service_id,       NULL);
-static CLASS_DEVICE_ATTR(pkey,         S_IRUGO, show_pkey,             NULL);
-static CLASS_DEVICE_ATTR(dgid,         S_IRUGO, show_dgid,             NULL);
-
-static struct class_device_attribute *srp_host_attrs[] = {
-       &class_device_attr_id_ext,
-       &class_device_attr_ioc_guid,
-       &class_device_attr_service_id,
-       &class_device_attr_pkey,
-       &class_device_attr_dgid,
-       NULL
-};
-
 static struct scsi_host_template srp_template = {
        .module                         = THIS_MODULE,
        .name                           = DRV_NAME,
@@ -1356,8 +1249,7 @@ static struct scsi_host_template srp_template = {
        .this_id                        = -1,
        .sg_tablesize                   = SRP_MAX_INDIRECT,
        .cmd_per_lun                    = SRP_SQ_SIZE,
-       .use_clustering                 = ENABLE_CLUSTERING,
-       .shost_attrs                    = srp_host_attrs
+       .use_clustering                 = ENABLE_CLUSTERING
 };
 
 static int srp_add_target(struct srp_host *host, struct srp_target_port *target)
@@ -1467,7 +1359,6 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target)
                        p = match_strdup(args);
                        if (strlen(p) != 32) {
                                printk(KERN_WARNING PFX "bad dest GID parameter '%s'\n", p);
-                               kfree(p);
                                goto out;
                        }
 
@@ -1475,7 +1366,6 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target)
                                strlcpy(dgid, p + i * 2, 3);
                                target->path.dgid.raw[i] = simple_strtoul(dgid, NULL, 16);
                        }
-                       kfree(p);
                        break;
 
                case SRP_OPT_PKEY:
@@ -1547,12 +1437,10 @@ static ssize_t srp_create_target(struct class_device *class_dev,
 
        INIT_WORK(&target->work, srp_reconnect_work, target);
 
-       INIT_LIST_HEAD(&target->free_reqs);
+       for (i = 0; i < SRP_SQ_SIZE - 1; ++i)
+               target->req_ring[i].next = i + 1;
+       target->req_ring[SRP_SQ_SIZE - 1].next = -1;
        INIT_LIST_HEAD(&target->req_queue);
-       for (i = 0; i < SRP_SQ_SIZE; ++i) {
-               target->req_ring[i].index = i;
-               list_add_tail(&target->req_ring[i].list, &target->free_reqs);
-       }
 
        ret = srp_parse_options(buf, target);
        if (ret)