aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/be2iscsi
diff options
context:
space:
mode:
authorJayamohan Kallickal <jayamohan.kallickal@emulex.com>2012-04-04 00:41:36 -0400
committerJames Bottomley <JBottomley@Parallels.com>2012-04-25 03:52:50 -0400
commitdc63aac62de5851ad11e8bc5fa1cf8a7f4e586fb (patch)
tree375e00095d8a389eaf2b10d96f173bc65f6878e7 /drivers/scsi/be2iscsi
parent0fc9fd4016ae03b0f5da5d7156644755c94783c4 (diff)
[SCSI] be2iscsi: Fix in the Asynchronous Code Path
Set the ASYNC PDU Handle pBuffer for Data ring with the VA/PA of the allocated memory for it. To get the correct ASYNC PDY Handle iterate the list and compare the PA set during initialization with the passed PHY Address. The buffer_size and num_enteries are common for HDR and Data ring Signed-off-by: Jayamohan Kallickal <jayamohan.kallickal@emulex.com> Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/be2iscsi')
-rw-r--r--drivers/scsi/be2iscsi/be_main.c86
-rw-r--r--drivers/scsi/be2iscsi/be_main.h7
2 files changed, 47 insertions, 46 deletions
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 375756fa95cf..4765f47b612a 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -1370,8 +1370,6 @@ hwi_get_async_handle(struct beiscsi_hba *phba,
1370 struct be_bus_address phys_addr; 1370 struct be_bus_address phys_addr;
1371 struct list_head *pbusy_list; 1371 struct list_head *pbusy_list;
1372 struct async_pdu_handle *pasync_handle = NULL; 1372 struct async_pdu_handle *pasync_handle = NULL;
1373 int buffer_len = 0;
1374 unsigned char buffer_index = -1;
1375 unsigned char is_header = 0; 1373 unsigned char is_header = 0;
1376 1374
1377 phys_addr.u.a32.address_lo = 1375 phys_addr.u.a32.address_lo =
@@ -1392,22 +1390,11 @@ hwi_get_async_handle(struct beiscsi_hba *phba,
1392 pbusy_list = hwi_get_async_busy_list(pasync_ctx, 1, 1390 pbusy_list = hwi_get_async_busy_list(pasync_ctx, 1,
1393 (pdpdu_cqe->dw[offsetof(struct amap_i_t_dpdu_cqe, 1391 (pdpdu_cqe->dw[offsetof(struct amap_i_t_dpdu_cqe,
1394 index) / 32] & PDUCQE_INDEX_MASK)); 1392 index) / 32] & PDUCQE_INDEX_MASK));
1395
1396 buffer_len = (unsigned int)(phys_addr.u.a64.address -
1397 pasync_ctx->async_header.pa_base.u.a64.address);
1398
1399 buffer_index = buffer_len /
1400 pasync_ctx->async_header.buffer_size;
1401
1402 break; 1393 break;
1403 case UNSOL_DATA_NOTIFY: 1394 case UNSOL_DATA_NOTIFY:
1404 pbusy_list = hwi_get_async_busy_list(pasync_ctx, 0, (pdpdu_cqe-> 1395 pbusy_list = hwi_get_async_busy_list(pasync_ctx, 0, (pdpdu_cqe->
1405 dw[offsetof(struct amap_i_t_dpdu_cqe, 1396 dw[offsetof(struct amap_i_t_dpdu_cqe,
1406 index) / 32] & PDUCQE_INDEX_MASK)); 1397 index) / 32] & PDUCQE_INDEX_MASK));
1407 buffer_len = (unsigned long)(phys_addr.u.a64.address -
1408 pasync_ctx->async_data.pa_base.u.
1409 a64.address);
1410 buffer_index = buffer_len / pasync_ctx->async_data.buffer_size;
1411 break; 1398 break;
1412 default: 1399 default:
1413 pbusy_list = NULL; 1400 pbusy_list = NULL;
@@ -1418,11 +1405,9 @@ hwi_get_async_handle(struct beiscsi_hba *phba,
1418 return NULL; 1405 return NULL;
1419 } 1406 }
1420 1407
1421 WARN_ON(!(buffer_index <= pasync_ctx->async_data.num_entries));
1422 WARN_ON(list_empty(pbusy_list)); 1408 WARN_ON(list_empty(pbusy_list));
1423 list_for_each_entry(pasync_handle, pbusy_list, link) { 1409 list_for_each_entry(pasync_handle, pbusy_list, link) {
1424 WARN_ON(pasync_handle->consumed); 1410 if (pasync_handle->pa.u.a64.address == phys_addr.u.a64.address)
1425 if (pasync_handle->index == buffer_index)
1426 break; 1411 break;
1427 } 1412 }
1428 1413
@@ -1449,15 +1434,13 @@ hwi_update_async_writables(struct hwi_async_pdu_context *pasync_ctx,
1449 unsigned int num_entries, writables = 0; 1434 unsigned int num_entries, writables = 0;
1450 unsigned int *pep_read_ptr, *pwritables; 1435 unsigned int *pep_read_ptr, *pwritables;
1451 1436
1452 1437 num_entries = pasync_ctx->num_entries;
1453 if (is_header) { 1438 if (is_header) {
1454 pep_read_ptr = &pasync_ctx->async_header.ep_read_ptr; 1439 pep_read_ptr = &pasync_ctx->async_header.ep_read_ptr;
1455 pwritables = &pasync_ctx->async_header.writables; 1440 pwritables = &pasync_ctx->async_header.writables;
1456 num_entries = pasync_ctx->async_header.num_entries;
1457 } else { 1441 } else {
1458 pep_read_ptr = &pasync_ctx->async_data.ep_read_ptr; 1442 pep_read_ptr = &pasync_ctx->async_data.ep_read_ptr;
1459 pwritables = &pasync_ctx->async_data.writables; 1443 pwritables = &pasync_ctx->async_data.writables;
1460 num_entries = pasync_ctx->async_data.num_entries;
1461 } 1444 }
1462 1445
1463 while ((*pep_read_ptr) != cq_index) { 1446 while ((*pep_read_ptr) != cq_index) {
@@ -1557,16 +1540,15 @@ static void hwi_post_async_buffers(struct beiscsi_hba *phba,
1557 1540
1558 phwi_ctrlr = phba->phwi_ctrlr; 1541 phwi_ctrlr = phba->phwi_ctrlr;
1559 pasync_ctx = HWI_GET_ASYNC_PDU_CTX(phwi_ctrlr); 1542 pasync_ctx = HWI_GET_ASYNC_PDU_CTX(phwi_ctrlr);
1543 num_entries = pasync_ctx->num_entries;
1560 1544
1561 if (is_header) { 1545 if (is_header) {
1562 num_entries = pasync_ctx->async_header.num_entries;
1563 writables = min(pasync_ctx->async_header.writables, 1546 writables = min(pasync_ctx->async_header.writables,
1564 pasync_ctx->async_header.free_entries); 1547 pasync_ctx->async_header.free_entries);
1565 pfree_link = pasync_ctx->async_header.free_list.next; 1548 pfree_link = pasync_ctx->async_header.free_list.next;
1566 host_write_num = pasync_ctx->async_header.host_write_ptr; 1549 host_write_num = pasync_ctx->async_header.host_write_ptr;
1567 ring_id = phwi_ctrlr->default_pdu_hdr.id; 1550 ring_id = phwi_ctrlr->default_pdu_hdr.id;
1568 } else { 1551 } else {
1569 num_entries = pasync_ctx->async_data.num_entries;
1570 writables = min(pasync_ctx->async_data.writables, 1552 writables = min(pasync_ctx->async_data.writables,
1571 pasync_ctx->async_data.free_entries); 1553 pasync_ctx->async_data.free_entries);
1572 pfree_link = pasync_ctx->async_data.free_list.next; 1554 pfree_link = pasync_ctx->async_data.free_list.next;
@@ -2450,7 +2432,7 @@ static void hwi_init_async_pdu_ctx(struct beiscsi_hba *phba)
2450 struct hba_parameters *p = &phba->params; 2432 struct hba_parameters *p = &phba->params;
2451 struct hwi_async_pdu_context *pasync_ctx; 2433 struct hwi_async_pdu_context *pasync_ctx;
2452 struct async_pdu_handle *pasync_header_h, *pasync_data_h; 2434 struct async_pdu_handle *pasync_header_h, *pasync_data_h;
2453 unsigned int index; 2435 unsigned int index, idx, num_per_mem, num_async_data;
2454 struct be_mem_descriptor *mem_descr; 2436 struct be_mem_descriptor *mem_descr;
2455 2437
2456 mem_descr = (struct be_mem_descriptor *)phba->init_mem; 2438 mem_descr = (struct be_mem_descriptor *)phba->init_mem;
@@ -2462,10 +2444,8 @@ static void hwi_init_async_pdu_ctx(struct beiscsi_hba *phba)
2462 pasync_ctx = phwi_ctrlr->phwi_ctxt->pasync_ctx; 2444 pasync_ctx = phwi_ctrlr->phwi_ctxt->pasync_ctx;
2463 memset(pasync_ctx, 0, sizeof(*pasync_ctx)); 2445 memset(pasync_ctx, 0, sizeof(*pasync_ctx));
2464 2446
2465 pasync_ctx->async_header.num_entries = p->asyncpdus_per_ctrl; 2447 pasync_ctx->num_entries = p->asyncpdus_per_ctrl;
2466 pasync_ctx->async_header.buffer_size = p->defpdu_hdr_sz; 2448 pasync_ctx->buffer_size = p->defpdu_hdr_sz;
2467 pasync_ctx->async_data.buffer_size = p->defpdu_data_sz;
2468 pasync_ctx->async_data.num_entries = p->asyncpdus_per_ctrl;
2469 2449
2470 mem_descr = (struct be_mem_descriptor *)phba->init_mem; 2450 mem_descr = (struct be_mem_descriptor *)phba->init_mem;
2471 mem_descr += HWI_MEM_ASYNC_HEADER_BUF; 2451 mem_descr += HWI_MEM_ASYNC_HEADER_BUF;
@@ -2510,19 +2490,6 @@ static void hwi_init_async_pdu_ctx(struct beiscsi_hba *phba)
2510 pasync_ctx->async_header.writables = 0; 2490 pasync_ctx->async_header.writables = 0;
2511 INIT_LIST_HEAD(&pasync_ctx->async_header.free_list); 2491 INIT_LIST_HEAD(&pasync_ctx->async_header.free_list);
2512 2492
2513 mem_descr = (struct be_mem_descriptor *)phba->init_mem;
2514 mem_descr += HWI_MEM_ASYNC_DATA_BUF;
2515 if (mem_descr->mem_array[0].virtual_address) {
2516 SE_DEBUG(DBG_LVL_8,
2517 "hwi_init_async_pdu_ctx HWI_MEM_ASYNC_DATA_BUF"
2518 "va=%p\n", mem_descr->mem_array[0].virtual_address);
2519 } else
2520 shost_printk(KERN_WARNING, phba->shost,
2521 "No Virtual address\n");
2522 pasync_ctx->async_data.va_base =
2523 mem_descr->mem_array[0].virtual_address;
2524 pasync_ctx->async_data.pa_base.u.a64.address =
2525 mem_descr->mem_array[0].bus_address.u.a64.address;
2526 2493
2527 mem_descr = (struct be_mem_descriptor *)phba->init_mem; 2494 mem_descr = (struct be_mem_descriptor *)phba->init_mem;
2528 mem_descr += HWI_MEM_ASYNC_DATA_RING; 2495 mem_descr += HWI_MEM_ASYNC_DATA_RING;
@@ -2553,6 +2520,25 @@ static void hwi_init_async_pdu_ctx(struct beiscsi_hba *phba)
2553 pasync_data_h = 2520 pasync_data_h =
2554 (struct async_pdu_handle *)pasync_ctx->async_data.handle_base; 2521 (struct async_pdu_handle *)pasync_ctx->async_data.handle_base;
2555 2522
2523 mem_descr = (struct be_mem_descriptor *)phba->init_mem;
2524 mem_descr += HWI_MEM_ASYNC_DATA_BUF;
2525 if (mem_descr->mem_array[0].virtual_address) {
2526 SE_DEBUG(DBG_LVL_8,
2527 "hwi_init_async_pdu_ctx HWI_MEM_ASYNC_DATA_BUF"
2528 "va=%p\n", mem_descr->mem_array[0].virtual_address);
2529 } else
2530 shost_printk(KERN_WARNING, phba->shost,
2531 "No Virtual address\n");
2532 idx = 0;
2533 pasync_ctx->async_data.va_base =
2534 mem_descr->mem_array[idx].virtual_address;
2535 pasync_ctx->async_data.pa_base.u.a64.address =
2536 mem_descr->mem_array[idx].bus_address.u.a64.address;
2537
2538 num_async_data = ((mem_descr->mem_array[idx].size) /
2539 phba->params.defpdu_data_sz);
2540 num_per_mem = 0;
2541
2556 for (index = 0; index < p->asyncpdus_per_ctrl; index++) { 2542 for (index = 0; index < p->asyncpdus_per_ctrl; index++) {
2557 pasync_header_h->cri = -1; 2543 pasync_header_h->cri = -1;
2558 pasync_header_h->index = (char)index; 2544 pasync_header_h->index = (char)index;
@@ -2578,14 +2564,29 @@ static void hwi_init_async_pdu_ctx(struct beiscsi_hba *phba)
2578 pasync_data_h->cri = -1; 2564 pasync_data_h->cri = -1;
2579 pasync_data_h->index = (char)index; 2565 pasync_data_h->index = (char)index;
2580 INIT_LIST_HEAD(&pasync_data_h->link); 2566 INIT_LIST_HEAD(&pasync_data_h->link);
2567
2568 if (!num_async_data) {
2569 num_per_mem = 0;
2570 idx++;
2571 pasync_ctx->async_data.va_base =
2572 mem_descr->mem_array[idx].virtual_address;
2573 pasync_ctx->async_data.pa_base.u.a64.address =
2574 mem_descr->mem_array[idx].
2575 bus_address.u.a64.address;
2576
2577 num_async_data = ((mem_descr->mem_array[idx].size) /
2578 phba->params.defpdu_data_sz);
2579 }
2581 pasync_data_h->pbuffer = 2580 pasync_data_h->pbuffer =
2582 (void *)((unsigned long) 2581 (void *)((unsigned long)
2583 (pasync_ctx->async_data.va_base) + 2582 (pasync_ctx->async_data.va_base) +
2584 (p->defpdu_data_sz * index)); 2583 (p->defpdu_data_sz * num_per_mem));
2585 2584
2586 pasync_data_h->pa.u.a64.address = 2585 pasync_data_h->pa.u.a64.address =
2587 pasync_ctx->async_data.pa_base.u.a64.address + 2586 pasync_ctx->async_data.pa_base.u.a64.address +
2588 (p->defpdu_data_sz * index); 2587 (p->defpdu_data_sz * num_per_mem);
2588 num_per_mem++;
2589 num_async_data--;
2589 2590
2590 list_add_tail(&pasync_data_h->link, 2591 list_add_tail(&pasync_data_h->link,
2591 &pasync_ctx->async_data.free_list); 2592 &pasync_ctx->async_data.free_list);
@@ -3993,7 +3994,8 @@ static int beiscsi_iotask(struct iscsi_task *task, struct scatterlist *sg,
3993 &io_task->cmd_bhs->iscsi_hdr.lun, sizeof(struct scsi_lun)); 3994 &io_task->cmd_bhs->iscsi_hdr.lun, sizeof(struct scsi_lun));
3994 3995
3995 AMAP_SET_BITS(struct amap_iscsi_wrb, lun, pwrb, 3996 AMAP_SET_BITS(struct amap_iscsi_wrb, lun, pwrb,
3996 cpu_to_be16(*(unsigned short *)&io_task->cmd_bhs->iscsi_hdr.lun)); 3997 cpu_to_be16(*(unsigned short *)
3998 &io_task->cmd_bhs->iscsi_hdr.lun));
3997 AMAP_SET_BITS(struct amap_iscsi_wrb, r2t_exp_dtl, pwrb, xferlen); 3999 AMAP_SET_BITS(struct amap_iscsi_wrb, r2t_exp_dtl, pwrb, xferlen);
3998 AMAP_SET_BITS(struct amap_iscsi_wrb, wrb_idx, pwrb, 4000 AMAP_SET_BITS(struct amap_iscsi_wrb, wrb_idx, pwrb,
3999 io_task->pwrb_handle->wrb_index); 4001 io_task->pwrb_handle->wrb_index);
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
index b4a06d5e5f9e..50f231f3dd08 100644
--- a/drivers/scsi/be2iscsi/be_main.h
+++ b/drivers/scsi/be2iscsi/be_main.h
@@ -525,8 +525,6 @@ struct hwi_async_pdu_context {
525 525
526 unsigned int free_entries; 526 unsigned int free_entries;
527 unsigned int busy_entries; 527 unsigned int busy_entries;
528 unsigned int buffer_size;
529 unsigned int num_entries;
530 528
531 struct list_head free_list; 529 struct list_head free_list;
532 } async_header; 530 } async_header;
@@ -543,11 +541,12 @@ struct hwi_async_pdu_context {
543 541
544 unsigned int free_entries; 542 unsigned int free_entries;
545 unsigned int busy_entries; 543 unsigned int busy_entries;
546 unsigned int buffer_size;
547 struct list_head free_list; 544 struct list_head free_list;
548 unsigned int num_entries;
549 } async_data; 545 } async_data;
550 546
547 unsigned int buffer_size;
548 unsigned int num_entries;
549
551 /** 550 /**
552 * This is a varying size list! Do not add anything 551 * This is a varying size list! Do not add anything
553 * after this entry!! 552 * after this entry!!