diff options
| author | Roland Dreier <rolandd@cisco.com> | 2006-05-09 13:50:28 -0400 |
|---|---|---|
| committer | Roland Dreier <rolandd@cisco.com> | 2006-05-09 13:50:28 -0400 |
| commit | d945e1df28ca07642b3e1a9b9d07074ba5f76be0 (patch) | |
| tree | ff392416f1339dd222b9470c24db1ec4defc1bf5 | |
| parent | d8b9f23b23e080d820e3c0aa5ccd7834c26ebf96 (diff) | |
IB/srp: Fix tracking of pending requests during error handling
If a SCSI abort completes, or the command completes successfully, then
the driver must remove the command from its queue of pending
commands. Similarly, if a device reset succeeds, then all commands
queued for the given device must be removed from the queue.
Signed-off-by: Roland Dreier <rolandd@cisco.com>
| -rw-r--r-- | drivers/infiniband/ulp/srp/ib_srp.c | 195 | ||||
| -rw-r--r-- | drivers/infiniband/ulp/srp/ib_srp.h | 4 |
2 files changed, 115 insertions, 84 deletions
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 5bb55742ada6..c32ce4348e1b 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c | |||
| @@ -409,6 +409,34 @@ static int srp_connect_target(struct srp_target_port *target) | |||
| 409 | } | 409 | } |
| 410 | } | 410 | } |
| 411 | 411 | ||
| 412 | static void srp_unmap_data(struct scsi_cmnd *scmnd, | ||
| 413 | struct srp_target_port *target, | ||
| 414 | struct srp_request *req) | ||
| 415 | { | ||
| 416 | struct scatterlist *scat; | ||
| 417 | int nents; | ||
| 418 | |||
| 419 | if (!scmnd->request_buffer || | ||
| 420 | (scmnd->sc_data_direction != DMA_TO_DEVICE && | ||
| 421 | scmnd->sc_data_direction != DMA_FROM_DEVICE)) | ||
| 422 | return; | ||
| 423 | |||
| 424 | /* | ||
| 425 | * This handling of non-SG commands can be killed when the | ||
| 426 | * SCSI midlayer no longer generates non-SG commands. | ||
| 427 | */ | ||
| 428 | if (likely(scmnd->use_sg)) { | ||
| 429 | nents = scmnd->use_sg; | ||
| 430 | scat = scmnd->request_buffer; | ||
| 431 | } else { | ||
| 432 | nents = 1; | ||
| 433 | scat = &req->fake_sg; | ||
| 434 | } | ||
| 435 | |||
| 436 | dma_unmap_sg(target->srp_host->dev->dma_device, scat, nents, | ||
| 437 | scmnd->sc_data_direction); | ||
| 438 | } | ||
| 439 | |||
| 412 | static int srp_reconnect_target(struct srp_target_port *target) | 440 | static int srp_reconnect_target(struct srp_target_port *target) |
| 413 | { | 441 | { |
| 414 | struct ib_cm_id *new_cm_id; | 442 | struct ib_cm_id *new_cm_id; |
| @@ -455,16 +483,16 @@ static int srp_reconnect_target(struct srp_target_port *target) | |||
| 455 | list_for_each_entry(req, &target->req_queue, list) { | 483 | list_for_each_entry(req, &target->req_queue, list) { |
| 456 | req->scmnd->result = DID_RESET << 16; | 484 | req->scmnd->result = DID_RESET << 16; |
| 457 | req->scmnd->scsi_done(req->scmnd); | 485 | req->scmnd->scsi_done(req->scmnd); |
| 486 | srp_unmap_data(req->scmnd, target, req); | ||
| 458 | } | 487 | } |
| 459 | 488 | ||
| 460 | target->rx_head = 0; | 489 | target->rx_head = 0; |
| 461 | target->tx_head = 0; | 490 | target->tx_head = 0; |
| 462 | target->tx_tail = 0; | 491 | target->tx_tail = 0; |
| 463 | target->req_head = 0; | 492 | INIT_LIST_HEAD(&target->free_reqs); |
| 464 | for (i = 0; i < SRP_SQ_SIZE - 1; ++i) | ||
| 465 | target->req_ring[i].next = i + 1; | ||
| 466 | target->req_ring[SRP_SQ_SIZE - 1].next = -1; | ||
| 467 | INIT_LIST_HEAD(&target->req_queue); | 493 | INIT_LIST_HEAD(&target->req_queue); |
| 494 | for (i = 0; i < SRP_SQ_SIZE; ++i) | ||
| 495 | list_add_tail(&target->req_ring[i].list, &target->free_reqs); | ||
| 468 | 496 | ||
| 469 | ret = srp_connect_target(target); | 497 | ret = srp_connect_target(target); |
| 470 | if (ret) | 498 | if (ret) |
| @@ -589,40 +617,10 @@ static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target, | |||
| 589 | return len; | 617 | return len; |
| 590 | } | 618 | } |
| 591 | 619 | ||
| 592 | static void srp_unmap_data(struct scsi_cmnd *scmnd, | 620 | static void srp_remove_req(struct srp_target_port *target, struct srp_request *req) |
| 593 | struct srp_target_port *target, | ||
| 594 | struct srp_request *req) | ||
| 595 | { | ||
| 596 | struct scatterlist *scat; | ||
| 597 | int nents; | ||
| 598 | |||
| 599 | if (!scmnd->request_buffer || | ||
| 600 | (scmnd->sc_data_direction != DMA_TO_DEVICE && | ||
| 601 | scmnd->sc_data_direction != DMA_FROM_DEVICE)) | ||
| 602 | return; | ||
| 603 | |||
| 604 | /* | ||
| 605 | * This handling of non-SG commands can be killed when the | ||
| 606 | * SCSI midlayer no longer generates non-SG commands. | ||
| 607 | */ | ||
| 608 | if (likely(scmnd->use_sg)) { | ||
| 609 | nents = scmnd->use_sg; | ||
| 610 | scat = scmnd->request_buffer; | ||
| 611 | } else { | ||
| 612 | nents = 1; | ||
| 613 | scat = &req->fake_sg; | ||
| 614 | } | ||
| 615 | |||
| 616 | dma_unmap_sg(target->srp_host->dev->dma_device, scat, nents, | ||
| 617 | scmnd->sc_data_direction); | ||
| 618 | } | ||
| 619 | |||
| 620 | static void srp_remove_req(struct srp_target_port *target, struct srp_request *req, | ||
| 621 | int index) | ||
| 622 | { | 621 | { |
| 623 | list_del(&req->list); | 622 | srp_unmap_data(req->scmnd, target, req); |
| 624 | req->next = target->req_head; | 623 | list_move_tail(&req->list, &target->free_reqs); |
| 625 | target->req_head = index; | ||
| 626 | } | 624 | } |
| 627 | 625 | ||
| 628 | static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp) | 626 | static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp) |
| @@ -647,7 +645,7 @@ static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp) | |||
| 647 | req->tsk_status = rsp->data[3]; | 645 | req->tsk_status = rsp->data[3]; |
| 648 | complete(&req->done); | 646 | complete(&req->done); |
| 649 | } else { | 647 | } else { |
| 650 | scmnd = req->scmnd; | 648 | scmnd = req->scmnd; |
| 651 | if (!scmnd) | 649 | if (!scmnd) |
| 652 | printk(KERN_ERR "Null scmnd for RSP w/tag %016llx\n", | 650 | printk(KERN_ERR "Null scmnd for RSP w/tag %016llx\n", |
| 653 | (unsigned long long) rsp->tag); | 651 | (unsigned long long) rsp->tag); |
| @@ -665,14 +663,11 @@ static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp) | |||
| 665 | else if (rsp->flags & (SRP_RSP_FLAG_DIOVER | SRP_RSP_FLAG_DIUNDER)) | 663 | else if (rsp->flags & (SRP_RSP_FLAG_DIOVER | SRP_RSP_FLAG_DIUNDER)) |
| 666 | scmnd->resid = be32_to_cpu(rsp->data_in_res_cnt); | 664 | scmnd->resid = be32_to_cpu(rsp->data_in_res_cnt); |
| 667 | 665 | ||
| 668 | srp_unmap_data(scmnd, target, req); | ||
| 669 | |||
| 670 | if (!req->tsk_mgmt) { | 666 | if (!req->tsk_mgmt) { |
| 671 | req->scmnd = NULL; | ||
| 672 | scmnd->host_scribble = (void *) -1L; | 667 | scmnd->host_scribble = (void *) -1L; |
| 673 | scmnd->scsi_done(scmnd); | 668 | scmnd->scsi_done(scmnd); |
| 674 | 669 | ||
| 675 | srp_remove_req(target, req, rsp->tag & ~SRP_TAG_TSK_MGMT); | 670 | srp_remove_req(target, req); |
| 676 | } else | 671 | } else |
| 677 | req->cmd_done = 1; | 672 | req->cmd_done = 1; |
| 678 | } | 673 | } |
| @@ -859,7 +854,6 @@ static int srp_queuecommand(struct scsi_cmnd *scmnd, | |||
| 859 | struct srp_request *req; | 854 | struct srp_request *req; |
| 860 | struct srp_iu *iu; | 855 | struct srp_iu *iu; |
| 861 | struct srp_cmd *cmd; | 856 | struct srp_cmd *cmd; |
| 862 | long req_index; | ||
| 863 | int len; | 857 | int len; |
| 864 | 858 | ||
| 865 | if (target->state == SRP_TARGET_CONNECTING) | 859 | if (target->state == SRP_TARGET_CONNECTING) |
| @@ -879,22 +873,20 @@ static int srp_queuecommand(struct scsi_cmnd *scmnd, | |||
| 879 | dma_sync_single_for_cpu(target->srp_host->dev->dma_device, iu->dma, | 873 | dma_sync_single_for_cpu(target->srp_host->dev->dma_device, iu->dma, |
| 880 | SRP_MAX_IU_LEN, DMA_TO_DEVICE); | 874 | SRP_MAX_IU_LEN, DMA_TO_DEVICE); |
| 881 | 875 | ||
| 882 | req_index = target->req_head; | 876 | req = list_entry(target->free_reqs.next, struct srp_request, list); |
| 883 | 877 | ||
| 884 | scmnd->scsi_done = done; | 878 | scmnd->scsi_done = done; |
| 885 | scmnd->result = 0; | 879 | scmnd->result = 0; |
| 886 | scmnd->host_scribble = (void *) req_index; | 880 | scmnd->host_scribble = (void *) (long) req->index; |
| 887 | 881 | ||
| 888 | cmd = iu->buf; | 882 | cmd = iu->buf; |
| 889 | memset(cmd, 0, sizeof *cmd); | 883 | memset(cmd, 0, sizeof *cmd); |
| 890 | 884 | ||
| 891 | cmd->opcode = SRP_CMD; | 885 | cmd->opcode = SRP_CMD; |
| 892 | cmd->lun = cpu_to_be64((u64) scmnd->device->lun << 48); | 886 | cmd->lun = cpu_to_be64((u64) scmnd->device->lun << 48); |
| 893 | cmd->tag = req_index; | 887 | cmd->tag = req->index; |
| 894 | memcpy(cmd->cdb, scmnd->cmnd, scmnd->cmd_len); | 888 | memcpy(cmd->cdb, scmnd->cmnd, scmnd->cmd_len); |
| 895 | 889 | ||
| 896 | req = &target->req_ring[req_index]; | ||
| 897 | |||
| 898 | req->scmnd = scmnd; | 890 | req->scmnd = scmnd; |
| 899 | req->cmd = iu; | 891 | req->cmd = iu; |
| 900 | req->cmd_done = 0; | 892 | req->cmd_done = 0; |
| @@ -919,8 +911,7 @@ static int srp_queuecommand(struct scsi_cmnd *scmnd, | |||
| 919 | goto err_unmap; | 911 | goto err_unmap; |
| 920 | } | 912 | } |
| 921 | 913 | ||
| 922 | target->req_head = req->next; | 914 | list_move_tail(&req->list, &target->req_queue); |
| 923 | list_add_tail(&req->list, &target->req_queue); | ||
| 924 | 915 | ||
| 925 | return 0; | 916 | return 0; |
| 926 | 917 | ||
| @@ -1143,30 +1134,20 @@ static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event) | |||
| 1143 | return 0; | 1134 | return 0; |
| 1144 | } | 1135 | } |
| 1145 | 1136 | ||
| 1146 | static int srp_send_tsk_mgmt(struct scsi_cmnd *scmnd, u8 func) | 1137 | static int srp_send_tsk_mgmt(struct srp_target_port *target, |
| 1138 | struct srp_request *req, u8 func) | ||
| 1147 | { | 1139 | { |
| 1148 | struct srp_target_port *target = host_to_target(scmnd->device->host); | ||
| 1149 | struct srp_request *req; | ||
| 1150 | struct srp_iu *iu; | 1140 | struct srp_iu *iu; |
| 1151 | struct srp_tsk_mgmt *tsk_mgmt; | 1141 | struct srp_tsk_mgmt *tsk_mgmt; |
| 1152 | int req_index; | ||
| 1153 | int ret = FAILED; | ||
| 1154 | 1142 | ||
| 1155 | spin_lock_irq(target->scsi_host->host_lock); | 1143 | spin_lock_irq(target->scsi_host->host_lock); |
| 1156 | 1144 | ||
| 1157 | if (target->state == SRP_TARGET_DEAD || | 1145 | if (target->state == SRP_TARGET_DEAD || |
| 1158 | target->state == SRP_TARGET_REMOVED) { | 1146 | target->state == SRP_TARGET_REMOVED) { |
| 1159 | scmnd->result = DID_BAD_TARGET << 16; | 1147 | req->scmnd->result = DID_BAD_TARGET << 16; |
| 1160 | goto out; | 1148 | goto out; |
| 1161 | } | 1149 | } |
| 1162 | 1150 | ||
| 1163 | if (scmnd->host_scribble == (void *) -1L) | ||
| 1164 | goto out; | ||
| 1165 | |||
| 1166 | req_index = (long) scmnd->host_scribble; | ||
| 1167 | printk(KERN_ERR "Abort for req_index %d\n", req_index); | ||
| 1168 | |||
| 1169 | req = &target->req_ring[req_index]; | ||
| 1170 | init_completion(&req->done); | 1151 | init_completion(&req->done); |
| 1171 | 1152 | ||
| 1172 | iu = __srp_get_tx_iu(target); | 1153 | iu = __srp_get_tx_iu(target); |
| @@ -1177,10 +1158,10 @@ static int srp_send_tsk_mgmt(struct scsi_cmnd *scmnd, u8 func) | |||
| 1177 | memset(tsk_mgmt, 0, sizeof *tsk_mgmt); | 1158 | memset(tsk_mgmt, 0, sizeof *tsk_mgmt); |
| 1178 | 1159 | ||
| 1179 | tsk_mgmt->opcode = SRP_TSK_MGMT; | 1160 | tsk_mgmt->opcode = SRP_TSK_MGMT; |
| 1180 | tsk_mgmt->lun = cpu_to_be64((u64) scmnd->device->lun << 48); | 1161 | tsk_mgmt->lun = cpu_to_be64((u64) req->scmnd->device->lun << 48); |
| 1181 | tsk_mgmt->tag = req_index | SRP_TAG_TSK_MGMT; | 1162 | tsk_mgmt->tag = req->index | SRP_TAG_TSK_MGMT; |
| 1182 | tsk_mgmt->tsk_mgmt_func = func; | 1163 | tsk_mgmt->tsk_mgmt_func = func; |
| 1183 | tsk_mgmt->task_tag = req_index; | 1164 | tsk_mgmt->task_tag = req->index; |
| 1184 | 1165 | ||
| 1185 | if (__srp_post_send(target, iu, sizeof *tsk_mgmt)) | 1166 | if (__srp_post_send(target, iu, sizeof *tsk_mgmt)) |
| 1186 | goto out; | 1167 | goto out; |
| @@ -1188,37 +1169,85 @@ static int srp_send_tsk_mgmt(struct scsi_cmnd *scmnd, u8 func) | |||
| 1188 | req->tsk_mgmt = iu; | 1169 | req->tsk_mgmt = iu; |
| 1189 | 1170 | ||
| 1190 | spin_unlock_irq(target->scsi_host->host_lock); | 1171 | spin_unlock_irq(target->scsi_host->host_lock); |
| 1172 | |||
| 1191 | if (!wait_for_completion_timeout(&req->done, | 1173 | if (!wait_for_completion_timeout(&req->done, |
| 1192 | msecs_to_jiffies(SRP_ABORT_TIMEOUT_MS))) | 1174 | msecs_to_jiffies(SRP_ABORT_TIMEOUT_MS))) |
| 1193 | return FAILED; | 1175 | return -1; |
| 1194 | spin_lock_irq(target->scsi_host->host_lock); | ||
| 1195 | 1176 | ||
| 1196 | if (req->cmd_done) { | 1177 | return 0; |
| 1197 | srp_remove_req(target, req, req_index); | ||
| 1198 | scmnd->scsi_done(scmnd); | ||
| 1199 | } else if (!req->tsk_status) { | ||
| 1200 | srp_remove_req(target, req, req_index); | ||
| 1201 | scmnd->result = DID_ABORT << 16; | ||
| 1202 | ret = SUCCESS; | ||
| 1203 | } | ||
| 1204 | 1178 | ||
| 1205 | out: | 1179 | out: |
| 1206 | spin_unlock_irq(target->scsi_host->host_lock); | 1180 | spin_unlock_irq(target->scsi_host->host_lock); |
| 1207 | return ret; | 1181 | return -1; |
| 1182 | } | ||
| 1183 | |||
| 1184 | static int srp_find_req(struct srp_target_port *target, | ||
| 1185 | struct scsi_cmnd *scmnd, | ||
| 1186 | struct srp_request **req) | ||
| 1187 | { | ||
| 1188 | if (scmnd->host_scribble == (void *) -1L) | ||
| 1189 | return -1; | ||
| 1190 | |||
| 1191 | *req = &target->req_ring[(long) scmnd->host_scribble]; | ||
| 1192 | |||
| 1193 | return 0; | ||
| 1208 | } | 1194 | } |
| 1209 | 1195 | ||
| 1210 | static int srp_abort(struct scsi_cmnd *scmnd) | 1196 | static int srp_abort(struct scsi_cmnd *scmnd) |
| 1211 | { | 1197 | { |
| 1198 | struct srp_target_port *target = host_to_target(scmnd->device->host); | ||
| 1199 | struct srp_request *req; | ||
| 1200 | int ret = SUCCESS; | ||
| 1201 | |||
| 1212 | printk(KERN_ERR "SRP abort called\n"); | 1202 | printk(KERN_ERR "SRP abort called\n"); |
| 1213 | 1203 | ||
| 1214 | return srp_send_tsk_mgmt(scmnd, SRP_TSK_ABORT_TASK); | 1204 | if (srp_find_req(target, scmnd, &req)) |
| 1205 | return FAILED; | ||
| 1206 | if (srp_send_tsk_mgmt(target, req, SRP_TSK_ABORT_TASK)) | ||
| 1207 | return FAILED; | ||
| 1208 | |||
| 1209 | spin_lock_irq(target->scsi_host->host_lock); | ||
| 1210 | |||
| 1211 | if (req->cmd_done) { | ||
| 1212 | srp_remove_req(target, req); | ||
| 1213 | scmnd->scsi_done(scmnd); | ||
| 1214 | } else if (!req->tsk_status) { | ||
| 1215 | srp_remove_req(target, req); | ||
| 1216 | scmnd->result = DID_ABORT << 16; | ||
| 1217 | } else | ||
| 1218 | ret = FAILED; | ||
| 1219 | |||
| 1220 | spin_unlock_irq(target->scsi_host->host_lock); | ||
| 1221 | |||
| 1222 | return ret; | ||
| 1215 | } | 1223 | } |
| 1216 | 1224 | ||
| 1217 | static int srp_reset_device(struct scsi_cmnd *scmnd) | 1225 | static int srp_reset_device(struct scsi_cmnd *scmnd) |
| 1218 | { | 1226 | { |
| 1227 | struct srp_target_port *target = host_to_target(scmnd->device->host); | ||
| 1228 | struct srp_request *req, *tmp; | ||
| 1229 | |||
| 1219 | printk(KERN_ERR "SRP reset_device called\n"); | 1230 | printk(KERN_ERR "SRP reset_device called\n"); |
| 1220 | 1231 | ||
| 1221 | return srp_send_tsk_mgmt(scmnd, SRP_TSK_LUN_RESET); | 1232 | if (srp_find_req(target, scmnd, &req)) |
| 1233 | return FAILED; | ||
| 1234 | if (srp_send_tsk_mgmt(target, req, SRP_TSK_LUN_RESET)) | ||
| 1235 | return FAILED; | ||
| 1236 | if (req->tsk_status) | ||
| 1237 | return FAILED; | ||
| 1238 | |||
| 1239 | spin_lock_irq(target->scsi_host->host_lock); | ||
| 1240 | |||
| 1241 | list_for_each_entry_safe(req, tmp, &target->req_queue, list) | ||
| 1242 | if (req->scmnd->device == scmnd->device) { | ||
| 1243 | req->scmnd->result = DID_RESET << 16; | ||
| 1244 | scmnd->scsi_done(scmnd); | ||
| 1245 | srp_remove_req(target, req); | ||
| 1246 | } | ||
| 1247 | |||
| 1248 | spin_unlock_irq(target->scsi_host->host_lock); | ||
| 1249 | |||
| 1250 | return SUCCESS; | ||
| 1222 | } | 1251 | } |
| 1223 | 1252 | ||
| 1224 | static int srp_reset_host(struct scsi_cmnd *scmnd) | 1253 | static int srp_reset_host(struct scsi_cmnd *scmnd) |
| @@ -1518,10 +1547,12 @@ static ssize_t srp_create_target(struct class_device *class_dev, | |||
| 1518 | 1547 | ||
| 1519 | INIT_WORK(&target->work, srp_reconnect_work, target); | 1548 | INIT_WORK(&target->work, srp_reconnect_work, target); |
| 1520 | 1549 | ||
| 1521 | for (i = 0; i < SRP_SQ_SIZE - 1; ++i) | 1550 | INIT_LIST_HEAD(&target->free_reqs); |
| 1522 | target->req_ring[i].next = i + 1; | ||
| 1523 | target->req_ring[SRP_SQ_SIZE - 1].next = -1; | ||
| 1524 | INIT_LIST_HEAD(&target->req_queue); | 1551 | INIT_LIST_HEAD(&target->req_queue); |
| 1552 | for (i = 0; i < SRP_SQ_SIZE; ++i) { | ||
| 1553 | target->req_ring[i].index = i; | ||
| 1554 | list_add_tail(&target->req_ring[i].list, &target->free_reqs); | ||
| 1555 | } | ||
| 1525 | 1556 | ||
| 1526 | ret = srp_parse_options(buf, target); | 1557 | ret = srp_parse_options(buf, target); |
| 1527 | if (ret) | 1558 | if (ret) |
diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h index bd7f7c3115de..c5cd43aae860 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.h +++ b/drivers/infiniband/ulp/srp/ib_srp.h | |||
| @@ -101,7 +101,7 @@ struct srp_request { | |||
| 101 | */ | 101 | */ |
| 102 | struct scatterlist fake_sg; | 102 | struct scatterlist fake_sg; |
| 103 | struct completion done; | 103 | struct completion done; |
| 104 | short next; | 104 | short index; |
| 105 | u8 cmd_done; | 105 | u8 cmd_done; |
| 106 | u8 tsk_status; | 106 | u8 tsk_status; |
| 107 | }; | 107 | }; |
| @@ -133,7 +133,7 @@ struct srp_target_port { | |||
| 133 | unsigned tx_tail; | 133 | unsigned tx_tail; |
| 134 | struct srp_iu *tx_ring[SRP_SQ_SIZE + 1]; | 134 | struct srp_iu *tx_ring[SRP_SQ_SIZE + 1]; |
| 135 | 135 | ||
| 136 | int req_head; | 136 | struct list_head free_reqs; |
| 137 | struct list_head req_queue; | 137 | struct list_head req_queue; |
| 138 | struct srp_request req_ring[SRP_SQ_SIZE]; | 138 | struct srp_request req_ring[SRP_SQ_SIZE]; |
| 139 | 139 | ||
