diff options
author | Jayamohan Kallickal <jayamohan.kallickal@emulex.com> | 2012-04-04 00:41:36 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-04-25 03:52:50 -0400 |
commit | dc63aac62de5851ad11e8bc5fa1cf8a7f4e586fb (patch) | |
tree | 375e00095d8a389eaf2b10d96f173bc65f6878e7 /drivers/scsi/be2iscsi | |
parent | 0fc9fd4016ae03b0f5da5d7156644755c94783c4 (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.c | 86 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_main.h | 7 |
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!! |