diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_iocb.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_iocb.c | 134 |
1 files changed, 16 insertions, 118 deletions
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 5d0e99c2b522..370646f7b3ff 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c | |||
@@ -11,8 +11,6 @@ | |||
11 | 11 | ||
12 | #include <scsi/scsi_tcq.h> | 12 | #include <scsi/scsi_tcq.h> |
13 | 13 | ||
14 | static request_t *qla2x00_req_pkt(struct scsi_qla_host *, struct req_que *, | ||
15 | struct rsp_que *rsp); | ||
16 | static void qla2x00_isp_cmd(struct scsi_qla_host *, struct req_que *); | 14 | static void qla2x00_isp_cmd(struct scsi_qla_host *, struct req_que *); |
17 | 15 | ||
18 | static void qla25xx_set_que(srb_t *, struct rsp_que **); | 16 | static void qla25xx_set_que(srb_t *, struct rsp_que **); |
@@ -474,7 +472,7 @@ __qla2x00_marker(struct scsi_qla_host *vha, struct req_que *req, | |||
474 | scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); | 472 | scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); |
475 | 473 | ||
476 | mrk24 = NULL; | 474 | mrk24 = NULL; |
477 | mrk = (mrk_entry_t *)qla2x00_req_pkt(vha, req, rsp); | 475 | mrk = (mrk_entry_t *)qla2x00_alloc_iocbs(vha, 0); |
478 | if (mrk == NULL) { | 476 | if (mrk == NULL) { |
479 | DEBUG2_3(printk("%s(%ld): failed to allocate Marker IOCB.\n", | 477 | DEBUG2_3(printk("%s(%ld): failed to allocate Marker IOCB.\n", |
480 | __func__, base_vha->host_no)); | 478 | __func__, base_vha->host_no)); |
@@ -521,84 +519,6 @@ qla2x00_marker(struct scsi_qla_host *vha, struct req_que *req, | |||
521 | } | 519 | } |
522 | 520 | ||
523 | /** | 521 | /** |
524 | * qla2x00_req_pkt() - Retrieve a request packet from the request ring. | ||
525 | * @ha: HA context | ||
526 | * | ||
527 | * Note: The caller must hold the hardware lock before calling this routine. | ||
528 | * | ||
529 | * Returns NULL if function failed, else, a pointer to the request packet. | ||
530 | */ | ||
531 | static request_t * | ||
532 | qla2x00_req_pkt(struct scsi_qla_host *vha, struct req_que *req, | ||
533 | struct rsp_que *rsp) | ||
534 | { | ||
535 | struct qla_hw_data *ha = vha->hw; | ||
536 | device_reg_t __iomem *reg = ISP_QUE_REG(ha, req->id); | ||
537 | request_t *pkt = NULL; | ||
538 | uint16_t cnt; | ||
539 | uint32_t *dword_ptr; | ||
540 | uint32_t timer; | ||
541 | uint16_t req_cnt = 1; | ||
542 | |||
543 | /* Wait 1 second for slot. */ | ||
544 | for (timer = HZ; timer; timer--) { | ||
545 | if ((req_cnt + 2) >= req->cnt) { | ||
546 | /* Calculate number of free request entries. */ | ||
547 | if (ha->mqenable) | ||
548 | cnt = (uint16_t) | ||
549 | RD_REG_DWORD(®->isp25mq.req_q_out); | ||
550 | else { | ||
551 | if (IS_QLA82XX(ha)) | ||
552 | cnt = (uint16_t)RD_REG_DWORD( | ||
553 | ®->isp82.req_q_out); | ||
554 | else if (IS_FWI2_CAPABLE(ha)) | ||
555 | cnt = (uint16_t)RD_REG_DWORD( | ||
556 | ®->isp24.req_q_out); | ||
557 | else | ||
558 | cnt = qla2x00_debounce_register( | ||
559 | ISP_REQ_Q_OUT(ha, ®->isp)); | ||
560 | } | ||
561 | if (req->ring_index < cnt) | ||
562 | req->cnt = cnt - req->ring_index; | ||
563 | else | ||
564 | req->cnt = req->length - | ||
565 | (req->ring_index - cnt); | ||
566 | } | ||
567 | /* If room for request in request ring. */ | ||
568 | if ((req_cnt + 2) < req->cnt) { | ||
569 | req->cnt--; | ||
570 | pkt = req->ring_ptr; | ||
571 | |||
572 | /* Zero out packet. */ | ||
573 | dword_ptr = (uint32_t *)pkt; | ||
574 | for (cnt = 0; cnt < REQUEST_ENTRY_SIZE / 4; cnt++) | ||
575 | *dword_ptr++ = 0; | ||
576 | |||
577 | /* Set entry count. */ | ||
578 | pkt->entry_count = 1; | ||
579 | |||
580 | break; | ||
581 | } | ||
582 | |||
583 | /* Release ring specific lock */ | ||
584 | spin_unlock_irq(&ha->hardware_lock); | ||
585 | |||
586 | udelay(2); /* 2 us */ | ||
587 | |||
588 | /* Check for pending interrupts. */ | ||
589 | /* During init we issue marker directly */ | ||
590 | if (!vha->marker_needed && !vha->flags.init_done) | ||
591 | qla2x00_poll(rsp); | ||
592 | spin_lock_irq(&ha->hardware_lock); | ||
593 | } | ||
594 | if (!pkt) { | ||
595 | DEBUG2_3(printk("%s(): **** FAILED ****\n", __func__)); | ||
596 | } | ||
597 | |||
598 | return (pkt); | ||
599 | } | ||
600 | |||
601 | /** | ||
602 | * qla2x00_isp_cmd() - Modify the request ring pointer. | 522 | * qla2x00_isp_cmd() - Modify the request ring pointer. |
603 | * @ha: HA context | 523 | * @ha: HA context |
604 | * | 524 | * |
@@ -1559,11 +1479,9 @@ static void qla25xx_set_que(srb_t *sp, struct rsp_que **rsp) | |||
1559 | } | 1479 | } |
1560 | 1480 | ||
1561 | /* Generic Control-SRB manipulation functions. */ | 1481 | /* Generic Control-SRB manipulation functions. */ |
1562 | 1482 | void * | |
1563 | static void * | 1483 | qla2x00_alloc_iocbs(scsi_qla_host_t *vha, srb_t *sp) |
1564 | qla2x00_alloc_iocbs(srb_t *sp) | ||
1565 | { | 1484 | { |
1566 | scsi_qla_host_t *vha = sp->fcport->vha; | ||
1567 | struct qla_hw_data *ha = vha->hw; | 1485 | struct qla_hw_data *ha = vha->hw; |
1568 | struct req_que *req = ha->req_q_map[0]; | 1486 | struct req_que *req = ha->req_q_map[0]; |
1569 | device_reg_t __iomem *reg = ISP_QUE_REG(ha, req->id); | 1487 | device_reg_t __iomem *reg = ISP_QUE_REG(ha, req->id); |
@@ -1573,6 +1491,10 @@ qla2x00_alloc_iocbs(srb_t *sp) | |||
1573 | 1491 | ||
1574 | pkt = NULL; | 1492 | pkt = NULL; |
1575 | req_cnt = 1; | 1493 | req_cnt = 1; |
1494 | handle = 0; | ||
1495 | |||
1496 | if (!sp) | ||
1497 | goto skip_cmd_array; | ||
1576 | 1498 | ||
1577 | /* Check for room in outstanding command list. */ | 1499 | /* Check for room in outstanding command list. */ |
1578 | handle = req->current_outstanding_cmd; | 1500 | handle = req->current_outstanding_cmd; |
@@ -1586,10 +1508,18 @@ qla2x00_alloc_iocbs(srb_t *sp) | |||
1586 | if (index == MAX_OUTSTANDING_COMMANDS) | 1508 | if (index == MAX_OUTSTANDING_COMMANDS) |
1587 | goto queuing_error; | 1509 | goto queuing_error; |
1588 | 1510 | ||
1511 | /* Prep command array. */ | ||
1512 | req->current_outstanding_cmd = handle; | ||
1513 | req->outstanding_cmds[handle] = sp; | ||
1514 | sp->handle = handle; | ||
1515 | |||
1516 | skip_cmd_array: | ||
1589 | /* Check for room on request queue. */ | 1517 | /* Check for room on request queue. */ |
1590 | if (req->cnt < req_cnt) { | 1518 | if (req->cnt < req_cnt) { |
1591 | if (ha->mqenable) | 1519 | if (ha->mqenable) |
1592 | cnt = RD_REG_DWORD(®->isp25mq.req_q_out); | 1520 | cnt = RD_REG_DWORD(®->isp25mq.req_q_out); |
1521 | else if (IS_QLA82XX(ha)) | ||
1522 | cnt = RD_REG_DWORD(®->isp82.req_q_out); | ||
1593 | else if (IS_FWI2_CAPABLE(ha)) | 1523 | else if (IS_FWI2_CAPABLE(ha)) |
1594 | cnt = RD_REG_DWORD(®->isp24.req_q_out); | 1524 | cnt = RD_REG_DWORD(®->isp24.req_q_out); |
1595 | else | 1525 | else |
@@ -1606,15 +1536,11 @@ qla2x00_alloc_iocbs(srb_t *sp) | |||
1606 | goto queuing_error; | 1536 | goto queuing_error; |
1607 | 1537 | ||
1608 | /* Prep packet */ | 1538 | /* Prep packet */ |
1609 | req->current_outstanding_cmd = handle; | ||
1610 | req->outstanding_cmds[handle] = sp; | ||
1611 | req->cnt -= req_cnt; | 1539 | req->cnt -= req_cnt; |
1612 | |||
1613 | pkt = req->ring_ptr; | 1540 | pkt = req->ring_ptr; |
1614 | memset(pkt, 0, REQUEST_ENTRY_SIZE); | 1541 | memset(pkt, 0, REQUEST_ENTRY_SIZE); |
1615 | pkt->entry_count = req_cnt; | 1542 | pkt->entry_count = req_cnt; |
1616 | pkt->handle = handle; | 1543 | pkt->handle = handle; |
1617 | sp->handle = handle; | ||
1618 | 1544 | ||
1619 | queuing_error: | 1545 | queuing_error: |
1620 | return pkt; | 1546 | return pkt; |
@@ -1795,31 +1721,6 @@ qla24xx_tm_iocb(srb_t *sp, struct tsk_mgmt_entry *tsk) | |||
1795 | } | 1721 | } |
1796 | 1722 | ||
1797 | static void | 1723 | static void |
1798 | qla24xx_marker_iocb(srb_t *sp, struct mrk_entry_24xx *mrk) | ||
1799 | { | ||
1800 | uint16_t lun; | ||
1801 | uint8_t modif; | ||
1802 | struct fc_port *fcport = sp->fcport; | ||
1803 | scsi_qla_host_t *vha = fcport->vha; | ||
1804 | struct srb_ctx *ctx = sp->ctx; | ||
1805 | struct srb_iocb *iocb = ctx->u.iocb_cmd; | ||
1806 | struct req_que *req = vha->req; | ||
1807 | |||
1808 | lun = iocb->u.marker.lun; | ||
1809 | modif = iocb->u.marker.modif; | ||
1810 | mrk->entry_type = MARKER_TYPE; | ||
1811 | mrk->modifier = modif; | ||
1812 | if (modif != MK_SYNC_ALL) { | ||
1813 | mrk->nport_handle = cpu_to_le16(fcport->loop_id); | ||
1814 | mrk->lun[1] = LSB(lun); | ||
1815 | mrk->lun[2] = MSB(lun); | ||
1816 | host_to_fcp_swap(mrk->lun, sizeof(mrk->lun)); | ||
1817 | mrk->vp_index = vha->vp_idx; | ||
1818 | mrk->handle = MAKE_HANDLE(req->id, mrk->handle); | ||
1819 | } | ||
1820 | } | ||
1821 | |||
1822 | static void | ||
1823 | qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb) | 1724 | qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb) |
1824 | { | 1725 | { |
1825 | struct fc_bsg_job *bsg_job = ((struct srb_ctx *)sp->ctx)->u.bsg_job; | 1726 | struct fc_bsg_job *bsg_job = ((struct srb_ctx *)sp->ctx)->u.bsg_job; |
@@ -1945,7 +1846,7 @@ qla2x00_start_sp(srb_t *sp) | |||
1945 | 1846 | ||
1946 | rval = QLA_FUNCTION_FAILED; | 1847 | rval = QLA_FUNCTION_FAILED; |
1947 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1848 | spin_lock_irqsave(&ha->hardware_lock, flags); |
1948 | pkt = qla2x00_alloc_iocbs(sp); | 1849 | pkt = qla2x00_alloc_iocbs(sp->fcport->vha, sp); |
1949 | if (!pkt) | 1850 | if (!pkt) |
1950 | goto done; | 1851 | goto done; |
1951 | 1852 | ||
@@ -1976,9 +1877,6 @@ qla2x00_start_sp(srb_t *sp) | |||
1976 | case SRB_TM_CMD: | 1877 | case SRB_TM_CMD: |
1977 | qla24xx_tm_iocb(sp, pkt); | 1878 | qla24xx_tm_iocb(sp, pkt); |
1978 | break; | 1879 | break; |
1979 | case SRB_MARKER_CMD: | ||
1980 | qla24xx_marker_iocb(sp, pkt); | ||
1981 | break; | ||
1982 | default: | 1880 | default: |
1983 | break; | 1881 | break; |
1984 | } | 1882 | } |