diff options
Diffstat (limited to 'drivers/scsi/qla4xxx/ql4_iocb.c')
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_iocb.c | 75 |
1 files changed, 69 insertions, 6 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_iocb.c b/drivers/scsi/qla4xxx/ql4_iocb.c index e0c32159749..f89973deac5 100644 --- a/drivers/scsi/qla4xxx/ql4_iocb.c +++ b/drivers/scsi/qla4xxx/ql4_iocb.c @@ -108,8 +108,7 @@ int qla4xxx_send_marker_iocb(struct scsi_qla_host *ha, wmb(); /* Tell ISP it's got a new I/O request */ - writel(ha->request_in, &ha->reg->req_q_in); - readl(&ha->reg->req_q_in); + ha->isp_ops->queue_iocb(ha); exit_send_marker: spin_unlock_irqrestore(&ha->hardware_lock, flags); @@ -194,6 +193,72 @@ static void qla4xxx_build_scsi_iocbs(struct srb *srb, } /** + * qla4_8xxx_queue_iocb - Tell ISP it's got new request(s) + * @ha: pointer to host adapter structure. + * + * This routine notifies the ISP that one or more new request + * queue entries have been placed on the request queue. + **/ +void qla4_8xxx_queue_iocb(struct scsi_qla_host *ha) +{ + uint32_t dbval = 0; + unsigned long wtime; + + dbval = 0x14 | (ha->func_num << 5); + dbval = dbval | (0 << 8) | (ha->request_in << 16); + writel(dbval, (unsigned long __iomem *)ha->nx_db_wr_ptr); + wmb(); + + wtime = jiffies + (2 * HZ); + while (readl((void __iomem *)ha->nx_db_rd_ptr) != dbval && + !time_after_eq(jiffies, wtime)) { + writel(dbval, (unsigned long __iomem *)ha->nx_db_wr_ptr); + wmb(); + } +} + +/** + * qla4_8xxx_complete_iocb - Tell ISP we're done with response(s) + * @ha: pointer to host adapter structure. + * + * This routine notifies the ISP that one or more response/completion + * queue entries have been processed by the driver. + * This also clears the interrupt. + **/ +void qla4_8xxx_complete_iocb(struct scsi_qla_host *ha) +{ + writel(ha->response_out, &ha->qla4_8xxx_reg->rsp_q_out); + readl(&ha->qla4_8xxx_reg->rsp_q_out); +} + +/** + * qla4xxx_queue_iocb - Tell ISP it's got new request(s) + * @ha: pointer to host adapter structure. + * + * This routine is notifies the ISP that one or more new request + * queue entries have been placed on the request queue. + **/ +void qla4xxx_queue_iocb(struct scsi_qla_host *ha) +{ + writel(ha->request_in, &ha->reg->req_q_in); + readl(&ha->reg->req_q_in); +} + +/** + * qla4xxx_complete_iocb - Tell ISP we're done with response(s) + * @ha: pointer to host adapter structure. + * + * This routine is notifies the ISP that one or more response/completion + * queue entries have been processed by the driver. + * This also clears the interrupt. + **/ +void qla4xxx_complete_iocb(struct scsi_qla_host *ha) +{ + writel(ha->response_out, &ha->reg->rsp_q_out); + readl(&ha->reg->rsp_q_out); +} + +/** * qla4xxx_send_command_to_isp - issues command to HBA * @ha: pointer to host adapter structure. * @srb: pointer to SCSI Request Block to be sent to ISP @@ -299,7 +364,7 @@ int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb) qla4xxx_build_scsi_iocbs(srb, cmd_entry, tot_dsds); wmb(); - srb->cmd->host_scribble = (unsigned char *)srb; + srb->cmd->host_scribble = (unsigned char *)(unsigned long)index; /* update counters */ srb->state = SRB_ACTIVE_STATE; @@ -310,9 +375,7 @@ int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb) srb->iocb_cnt = req_cnt; ha->req_q_count -= req_cnt; - /* Debug print statements */ - writel(ha->request_in, &ha->reg->req_q_in); - readl(&ha->reg->req_q_in); + ha->isp_ops->queue_iocb(ha); spin_unlock_irqrestore(&ha->hardware_lock, flags); return QLA_SUCCESS; |