1afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu/* 2afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * QLogic iSCSI HBA Driver 37d01d0698f450ed8cc9fd4557f88a3309c868d44Vikas Chaudhary * Copyright (c) 2003-2010 QLogic Corporation 4afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * 5afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * See LICENSE.qla4xxx for copyright and licensing details. 6afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu */ 7afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 8afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu#include "ql4_def.h" 9e08c182cba87180d7c1e7530dd690a5f6894c412David C Somayajulu#include "ql4_glbl.h" 10e08c182cba87180d7c1e7530dd690a5f6894c412David C Somayajulu#include "ql4_dbg.h" 11e08c182cba87180d7c1e7530dd690a5f6894c412David C Somayajulu#include "ql4_inline.h" 12e08c182cba87180d7c1e7530dd690a5f6894c412David C Somayajulu 13afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu#include <scsi/scsi_tcq.h> 14afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 1516ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higginsstatic int 1616ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higginsqla4xxx_space_in_req_ring(struct scsi_qla_host *ha, uint16_t req_cnt) 1716ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins{ 1816ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins uint16_t cnt; 1916ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins 2016ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins /* Calculate number of free request entries. */ 2116ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins if ((req_cnt + 2) >= ha->req_q_count) { 22b173a132cbf0a4a48b2f341716e20a6d8b24957eVikas Chaudhary cnt = (uint16_t) ha->isp_ops->rd_shdw_req_q_out(ha); 2316ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins if (ha->request_in < cnt) 2416ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins ha->req_q_count = cnt - ha->request_in; 2516ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins else 2616ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins ha->req_q_count = REQUEST_QUEUE_DEPTH - 2716ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins (ha->request_in - cnt); 2816ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins } 2916ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins 3016ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins /* Check if room for request in request ring. */ 3116ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins if ((req_cnt + 2) < ha->req_q_count) 3216ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins return 1; 3316ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins else 3416ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins return 0; 3516ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins} 3616ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins 3716ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higginsstatic void qla4xxx_advance_req_ring_ptr(struct scsi_qla_host *ha) 3816ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins{ 3916ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins /* Advance request queue pointer */ 4016ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins if (ha->request_in == (REQUEST_QUEUE_DEPTH - 1)) { 4116ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins ha->request_in = 0; 4216ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins ha->request_ptr = ha->request_ring; 4316ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins } else { 4416ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins ha->request_in++; 4516ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins ha->request_ptr++; 4616ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins } 4716ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins} 4816ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins 49afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu/** 50afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * qla4xxx_get_req_pkt - returns a valid entry in request queue. 51afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * @ha: Pointer to host adapter structure. 52afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * @queue_entry: Pointer to pointer to queue entry structure 53afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * 54afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * This routine performs the following tasks: 55afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * - returns the current request_in pointer (if queue not full) 56afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * - advances the request_in pointer 57afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * - checks for queue full 58afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu **/ 594797547778fd51e6ee929c5dd67ab3807898eb82Adrian Bunkstatic int qla4xxx_get_req_pkt(struct scsi_qla_host *ha, 604797547778fd51e6ee929c5dd67ab3807898eb82Adrian Bunk struct queue_entry **queue_entry) 61afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu{ 6216ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins uint16_t req_cnt = 1; 63afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 6416ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins if (qla4xxx_space_in_req_ring(ha, req_cnt)) { 6516ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins *queue_entry = ha->request_ptr; 66afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu memset(*queue_entry, 0, sizeof(**queue_entry)); 6716ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins 6816ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins qla4xxx_advance_req_ring_ptr(ha); 6916ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins ha->req_q_count -= req_cnt; 7016ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins return QLA_SUCCESS; 71afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 72afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 7316ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins return QLA_ERROR; 74afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu} 75afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 76afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu/** 77afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * qla4xxx_send_marker_iocb - issues marker iocb to HBA 78afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * @ha: Pointer to host adapter structure. 79afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * @ddb_entry: Pointer to device database entry 80afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * @lun: SCSI LUN 81afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * @marker_type: marker identifier 82afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * 83afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * This routine issues a marker IOCB. 84afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu **/ 859d56291366cd6ab156be722e42cf487bef20f5fdDavid C Somayajuluint qla4xxx_send_marker_iocb(struct scsi_qla_host *ha, 869d56291366cd6ab156be722e42cf487bef20f5fdDavid C Somayajulu struct ddb_entry *ddb_entry, int lun, uint16_t mrkr_mod) 87afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu{ 881c3f0b8e07de78a86f2dce911f5e245845ce40a8Mathieu Desnoyers struct qla4_marker_entry *marker_entry; 89afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu unsigned long flags = 0; 90afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu uint8_t status = QLA_SUCCESS; 91afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 92afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Acquire hardware specific lock */ 93afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu spin_lock_irqsave(&ha->hardware_lock, flags); 94afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 95afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Get pointer to the queue entry for the marker */ 96afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (qla4xxx_get_req_pkt(ha, (struct queue_entry **) &marker_entry) != 97afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu QLA_SUCCESS) { 98afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu status = QLA_ERROR; 99afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu goto exit_send_marker; 100afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 101afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 102afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Put the marker in the request queue */ 103afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu marker_entry->hdr.entryType = ET_MARKER; 104afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu marker_entry->hdr.entryCount = 1; 105afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu marker_entry->target = cpu_to_le16(ddb_entry->fw_ddb_index); 1069d56291366cd6ab156be722e42cf487bef20f5fdDavid C Somayajulu marker_entry->modifier = cpu_to_le16(mrkr_mod); 107afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu int_to_scsilun(lun, &marker_entry->lun); 108afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu wmb(); 109afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 110afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Tell ISP it's got a new I/O request */ 111f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ha->isp_ops->queue_iocb(ha); 112afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 113afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajuluexit_send_marker: 114afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu spin_unlock_irqrestore(&ha->hardware_lock, flags); 115afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu return status; 116afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu} 117afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 11816ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higginsstatic struct continuation_t1_entry * 11916ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higginsqla4xxx_alloc_cont_entry(struct scsi_qla_host *ha) 120afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu{ 121afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu struct continuation_t1_entry *cont_entry; 122afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 123afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cont_entry = (struct continuation_t1_entry *)ha->request_ptr; 124afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 12516ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins qla4xxx_advance_req_ring_ptr(ha); 126afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 127afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Load packet defaults */ 128afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cont_entry->hdr.entryType = ET_CONTINUE; 129afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cont_entry->hdr.entryCount = 1; 130afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cont_entry->hdr.systemDefined = (uint8_t) cpu_to_le16(ha->request_in); 131afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 132afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu return cont_entry; 133afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu} 134afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 1354797547778fd51e6ee929c5dd67ab3807898eb82Adrian Bunkstatic uint16_t qla4xxx_calc_request_entries(uint16_t dsds) 136afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu{ 137afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu uint16_t iocbs; 138afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 139afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu iocbs = 1; 140afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (dsds > COMMAND_SEG) { 141afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu iocbs += (dsds - COMMAND_SEG) / CONTINUE_SEG; 142afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if ((dsds - COMMAND_SEG) % CONTINUE_SEG) 143afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu iocbs++; 144afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 145afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu return iocbs; 146afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu} 147afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 1484797547778fd51e6ee929c5dd67ab3807898eb82Adrian Bunkstatic void qla4xxx_build_scsi_iocbs(struct srb *srb, 1494797547778fd51e6ee929c5dd67ab3807898eb82Adrian Bunk struct command_t3_entry *cmd_entry, 1504797547778fd51e6ee929c5dd67ab3807898eb82Adrian Bunk uint16_t tot_dsds) 151afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu{ 152afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu struct scsi_qla_host *ha; 153afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu uint16_t avail_dsds; 154afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu struct data_seg_a64 *cur_dsd; 155afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu struct scsi_cmnd *cmd; 1565f7186c841a13abff0bf81ee93754b4f46e19141FUJITA Tomonori struct scatterlist *sg; 1575f7186c841a13abff0bf81ee93754b4f46e19141FUJITA Tomonori int i; 158afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 159afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd = srb->cmd; 160afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha = srb->ha; 161afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 1625f7186c841a13abff0bf81ee93754b4f46e19141FUJITA Tomonori if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) { 163afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* No data being transferred */ 164afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd_entry->ttlByteCnt = __constant_cpu_to_le32(0); 165afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu return; 166afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 167afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 168afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu avail_dsds = COMMAND_SEG; 169afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cur_dsd = (struct data_seg_a64 *) & (cmd_entry->dataseg[0]); 170afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 1715f7186c841a13abff0bf81ee93754b4f46e19141FUJITA Tomonori scsi_for_each_sg(cmd, sg, tot_dsds, i) { 1725f7186c841a13abff0bf81ee93754b4f46e19141FUJITA Tomonori dma_addr_t sle_dma; 1735f7186c841a13abff0bf81ee93754b4f46e19141FUJITA Tomonori 1745f7186c841a13abff0bf81ee93754b4f46e19141FUJITA Tomonori /* Allocate additional continuation packets? */ 1755f7186c841a13abff0bf81ee93754b4f46e19141FUJITA Tomonori if (avail_dsds == 0) { 1765f7186c841a13abff0bf81ee93754b4f46e19141FUJITA Tomonori struct continuation_t1_entry *cont_entry; 1775f7186c841a13abff0bf81ee93754b4f46e19141FUJITA Tomonori 1785f7186c841a13abff0bf81ee93754b4f46e19141FUJITA Tomonori cont_entry = qla4xxx_alloc_cont_entry(ha); 1795f7186c841a13abff0bf81ee93754b4f46e19141FUJITA Tomonori cur_dsd = 1805f7186c841a13abff0bf81ee93754b4f46e19141FUJITA Tomonori (struct data_seg_a64 *) 1815f7186c841a13abff0bf81ee93754b4f46e19141FUJITA Tomonori &cont_entry->dataseg[0]; 1825f7186c841a13abff0bf81ee93754b4f46e19141FUJITA Tomonori avail_dsds = CONTINUE_SEG; 183afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 1845f7186c841a13abff0bf81ee93754b4f46e19141FUJITA Tomonori 1855f7186c841a13abff0bf81ee93754b4f46e19141FUJITA Tomonori sle_dma = sg_dma_address(sg); 1865f7186c841a13abff0bf81ee93754b4f46e19141FUJITA Tomonori cur_dsd->base.addrLow = cpu_to_le32(LSDW(sle_dma)); 1875f7186c841a13abff0bf81ee93754b4f46e19141FUJITA Tomonori cur_dsd->base.addrHigh = cpu_to_le32(MSDW(sle_dma)); 1885f7186c841a13abff0bf81ee93754b4f46e19141FUJITA Tomonori cur_dsd->count = cpu_to_le32(sg_dma_len(sg)); 1895f7186c841a13abff0bf81ee93754b4f46e19141FUJITA Tomonori avail_dsds--; 1905f7186c841a13abff0bf81ee93754b4f46e19141FUJITA Tomonori 1915f7186c841a13abff0bf81ee93754b4f46e19141FUJITA Tomonori cur_dsd++; 192afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 193afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu} 194afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 195afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu/** 196f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * qla4_8xxx_queue_iocb - Tell ISP it's got new request(s) 197f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * @ha: pointer to host adapter structure. 198f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * 199f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * This routine notifies the ISP that one or more new request 200f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * queue entries have been placed on the request queue. 201f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary **/ 202f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudharyvoid qla4_8xxx_queue_iocb(struct scsi_qla_host *ha) 203f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary{ 204f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary uint32_t dbval = 0; 205f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 206f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary dbval = 0x14 | (ha->func_num << 5); 207f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary dbval = dbval | (0 << 8) | (ha->request_in << 16); 208f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 2092657c800dbb24761097ef341dfa43672c08a7a9eShyam Sundar qla4_8xxx_wr_32(ha, ha->nx_db_wr_ptr, ha->request_in); 210f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary} 211f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 212f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary/** 213f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * qla4_8xxx_complete_iocb - Tell ISP we're done with response(s) 214f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * @ha: pointer to host adapter structure. 215f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * 216f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * This routine notifies the ISP that one or more response/completion 217f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * queue entries have been processed by the driver. 218f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * This also clears the interrupt. 219f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary **/ 220f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudharyvoid qla4_8xxx_complete_iocb(struct scsi_qla_host *ha) 221f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary{ 222f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary writel(ha->response_out, &ha->qla4_8xxx_reg->rsp_q_out); 223f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary readl(&ha->qla4_8xxx_reg->rsp_q_out); 224f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary} 225f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 226f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary/** 227f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * qla4xxx_queue_iocb - Tell ISP it's got new request(s) 228f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * @ha: pointer to host adapter structure. 229f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * 230f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * This routine is notifies the ISP that one or more new request 231f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * queue entries have been placed on the request queue. 232f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary **/ 233f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudharyvoid qla4xxx_queue_iocb(struct scsi_qla_host *ha) 234f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary{ 235f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary writel(ha->request_in, &ha->reg->req_q_in); 236f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary readl(&ha->reg->req_q_in); 237f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary} 238f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 239f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary/** 240f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * qla4xxx_complete_iocb - Tell ISP we're done with response(s) 241f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * @ha: pointer to host adapter structure. 242f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * 243f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * This routine is notifies the ISP that one or more response/completion 244f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * queue entries have been processed by the driver. 245f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * This also clears the interrupt. 246f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary **/ 247f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudharyvoid qla4xxx_complete_iocb(struct scsi_qla_host *ha) 248f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary{ 249f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary writel(ha->response_out, &ha->reg->rsp_q_out); 250f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary readl(&ha->reg->rsp_q_out); 251f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary} 252f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 253f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary/** 254afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * qla4xxx_send_command_to_isp - issues command to HBA 255afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * @ha: pointer to host adapter structure. 256afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * @srb: pointer to SCSI Request Block to be sent to ISP 257afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * 258afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * This routine is called by qla4xxx_queuecommand to build an ISP 259afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * command and pass it to the ISP for execution. 260afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu **/ 261afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajuluint qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb) 262afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu{ 263afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu struct scsi_cmnd *cmd = srb->cmd; 264afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu struct ddb_entry *ddb_entry; 265afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu struct command_t3_entry *cmd_entry; 2665f7186c841a13abff0bf81ee93754b4f46e19141FUJITA Tomonori int nseg; 267afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu uint16_t tot_dsds; 268afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu uint16_t req_cnt; 269afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu unsigned long flags; 270afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu uint32_t index; 271afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu char tag[2]; 272afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 273afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Get real lun and adapter */ 274afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ddb_entry = srb->ddb; 275afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 276afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu tot_dsds = 0; 277afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 278afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Acquire hardware specific lock */ 279afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu spin_lock_irqsave(&ha->hardware_lock, flags); 280afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 281afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu index = (uint32_t)cmd->request->tag; 282afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 28316ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins /* 28416ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins * Check to see if adapter is online before placing request on 28516ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins * request queue. If a reset occurs and a request is in the queue, 28616ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins * the firmware will still attempt to process the request, retrieving 28716ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins * garbage for pointers. 28816ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins */ 28916ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins if (!test_bit(AF_ONLINE, &ha->flags)) { 29016ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins DEBUG2(printk("scsi%ld: %s: Adapter OFFLINE! " 29116ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins "Do not issue command.\n", 29216ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins ha->host_no, __func__)); 29316ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins goto queuing_error; 29416ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins } 29516ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins 296afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Calculate the number of request entries needed. */ 2975f7186c841a13abff0bf81ee93754b4f46e19141FUJITA Tomonori nseg = scsi_dma_map(cmd); 2985f7186c841a13abff0bf81ee93754b4f46e19141FUJITA Tomonori if (nseg < 0) 2995f7186c841a13abff0bf81ee93754b4f46e19141FUJITA Tomonori goto queuing_error; 3005f7186c841a13abff0bf81ee93754b4f46e19141FUJITA Tomonori tot_dsds = nseg; 3015f7186c841a13abff0bf81ee93754b4f46e19141FUJITA Tomonori 302afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu req_cnt = qla4xxx_calc_request_entries(tot_dsds); 30316ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins if (!qla4xxx_space_in_req_ring(ha, req_cnt)) 304afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu goto queuing_error; 305afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 306afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* total iocbs active */ 307afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if ((ha->iocb_cnt + req_cnt) >= REQUEST_QUEUE_DEPTH) 308afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu goto queuing_error; 309afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 310afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Build command packet */ 311afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd_entry = (struct command_t3_entry *) ha->request_ptr; 312afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu memset(cmd_entry, 0, sizeof(struct command_t3_entry)); 313afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd_entry->hdr.entryType = ET_COMMAND; 314afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd_entry->handle = cpu_to_le32(index); 315afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd_entry->target = cpu_to_le16(ddb_entry->fw_ddb_index); 316afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 317afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu int_to_scsilun(cmd->device->lun, &cmd_entry->lun); 3185f7186c841a13abff0bf81ee93754b4f46e19141FUJITA Tomonori cmd_entry->ttlByteCnt = cpu_to_le32(scsi_bufflen(cmd)); 319afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu memcpy(cmd_entry->cdb, cmd->cmnd, cmd->cmd_len); 320afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd_entry->dataSegCnt = cpu_to_le16(tot_dsds); 321afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd_entry->hdr.entryCount = req_cnt; 322afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 323afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Set data transfer direction control flags 324afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * NOTE: Look at data_direction bits iff there is data to be 325afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * transferred, as the data direction bit is sometimed filled 326afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * in when there is no data to be transferred */ 327afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd_entry->control_flags = CF_NO_DATA; 3285f7186c841a13abff0bf81ee93754b4f46e19141FUJITA Tomonori if (scsi_bufflen(cmd)) { 329afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (cmd->sc_data_direction == DMA_TO_DEVICE) 330afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd_entry->control_flags = CF_WRITE; 331afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu else if (cmd->sc_data_direction == DMA_FROM_DEVICE) 332afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd_entry->control_flags = CF_READ; 333d915058f48745c0d5c4582566e5aa63867264f81David C Somayajulu 3345f7186c841a13abff0bf81ee93754b4f46e19141FUJITA Tomonori ha->bytes_xfered += scsi_bufflen(cmd); 335d915058f48745c0d5c4582566e5aa63867264f81David C Somayajulu if (ha->bytes_xfered & ~0xFFFFF){ 336d915058f48745c0d5c4582566e5aa63867264f81David C Somayajulu ha->total_mbytes_xferred += ha->bytes_xfered >> 20; 337d915058f48745c0d5c4582566e5aa63867264f81David C Somayajulu ha->bytes_xfered &= 0xFFFFF; 338d915058f48745c0d5c4582566e5aa63867264f81David C Somayajulu } 339afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 340afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 341afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Set tagged queueing control flags */ 342afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd_entry->control_flags |= CF_SIMPLE_TAG; 343afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (scsi_populate_tag_msg(cmd, tag)) 344afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu switch (tag[0]) { 345afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MSG_HEAD_TAG: 346afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd_entry->control_flags |= CF_HEAD_TAG; 347afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 348afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MSG_ORDERED_TAG: 349afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd_entry->control_flags |= CF_ORDERED_TAG; 350afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 351afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 352afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 35316ed55f9de6743ceece9bf528362cadff10f1c5cKaren Higgins qla4xxx_advance_req_ring_ptr(ha); 354afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu qla4xxx_build_scsi_iocbs(srb, cmd_entry, tot_dsds); 355afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu wmb(); 356afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 3575369887a95da9509163931b21f61a94da09dac15Vikas Chaudhary srb->cmd->host_scribble = (unsigned char *)(unsigned long)index; 358afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 359afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* update counters */ 360afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu srb->state = SRB_ACTIVE_STATE; 361afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu srb->flags |= SRB_DMA_VALID; 362afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 363afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Track IOCB used */ 364afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->iocb_cnt += req_cnt; 365afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu srb->iocb_cnt = req_cnt; 366afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->req_q_count -= req_cnt; 367afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 368f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ha->isp_ops->queue_iocb(ha); 369afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu spin_unlock_irqrestore(&ha->hardware_lock, flags); 370afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 371afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu return QLA_SUCCESS; 372afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 373afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajuluqueuing_error: 3745f7186c841a13abff0bf81ee93754b4f46e19141FUJITA Tomonori if (tot_dsds) 3755f7186c841a13abff0bf81ee93754b4f46e19141FUJITA Tomonori scsi_dma_unmap(cmd); 376afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 377afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu spin_unlock_irqrestore(&ha->hardware_lock, flags); 378afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 379afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu return QLA_ERROR; 380afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu} 381afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 382b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankarint qla4xxx_send_passthru0(struct iscsi_task *task) 383b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar{ 384b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar struct passthru0 *passthru_iocb; 385b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar struct iscsi_session *sess = task->conn->session; 386b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar struct ddb_entry *ddb_entry = sess->dd_data; 387b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar struct scsi_qla_host *ha = ddb_entry->ha; 388b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar struct ql4_task_data *task_data = task->dd_data; 389b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar uint16_t ctrl_flags = 0; 390b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar unsigned long flags; 391b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar int ret = QLA_ERROR; 392b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar 393b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar spin_lock_irqsave(&ha->hardware_lock, flags); 394b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar task_data->iocb_req_cnt = 1; 395b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar /* Put the IOCB on the request queue */ 396b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar if (!qla4xxx_space_in_req_ring(ha, task_data->iocb_req_cnt)) 397b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar goto queuing_error; 398b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar 399b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar passthru_iocb = (struct passthru0 *) ha->request_ptr; 400b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar 401b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar memset(passthru_iocb, 0, sizeof(struct passthru0)); 402b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar passthru_iocb->hdr.entryType = ET_PASSTHRU0; 403b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar passthru_iocb->hdr.systemDefined = SD_ISCSI_PDU; 404b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar passthru_iocb->hdr.entryCount = task_data->iocb_req_cnt; 405b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar passthru_iocb->handle = task->itt; 406b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar passthru_iocb->target = cpu_to_le16(ddb_entry->fw_ddb_index); 407b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar passthru_iocb->timeout = cpu_to_le16(PT_DEFAULT_TIMEOUT); 408b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar 409b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar /* Setup the out & in DSDs */ 41069ca216e9bbbe2baf7f441ab57c5d791f439f775Manish Rangankar if (task_data->req_len) { 411b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar memcpy((uint8_t *)task_data->req_buffer + 412b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar sizeof(struct iscsi_hdr), task->data, task->data_count); 413b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar ctrl_flags |= PT_FLAG_SEND_BUFFER; 414b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar passthru_iocb->out_dsd.base.addrLow = 415b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar cpu_to_le32(LSDW(task_data->req_dma)); 416b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar passthru_iocb->out_dsd.base.addrHigh = 417b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar cpu_to_le32(MSDW(task_data->req_dma)); 418b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar passthru_iocb->out_dsd.count = 419b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar cpu_to_le32(task->data_count + 420b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar sizeof(struct iscsi_hdr)); 421b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar } 422b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar if (task_data->resp_len) { 423b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar passthru_iocb->in_dsd.base.addrLow = 424b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar cpu_to_le32(LSDW(task_data->resp_dma)); 425b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar passthru_iocb->in_dsd.base.addrHigh = 426b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar cpu_to_le32(MSDW(task_data->resp_dma)); 427b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar passthru_iocb->in_dsd.count = 428b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar cpu_to_le32(task_data->resp_len); 429b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar } 430b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar 431b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar ctrl_flags |= (PT_FLAG_ISCSI_PDU | PT_FLAG_WAIT_4_RESPONSE); 432b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar passthru_iocb->control_flags = cpu_to_le16(ctrl_flags); 433b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar 434b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar /* Update the request pointer */ 435b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar qla4xxx_advance_req_ring_ptr(ha); 436b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar wmb(); 437b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar 438b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar /* Track IOCB used */ 439b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar ha->iocb_cnt += task_data->iocb_req_cnt; 440b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar ha->req_q_count -= task_data->iocb_req_cnt; 441b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar ha->isp_ops->queue_iocb(ha); 442b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar ret = QLA_SUCCESS; 443b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar 444b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankarqueuing_error: 445b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar spin_unlock_irqrestore(&ha->hardware_lock, flags); 446b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar return ret; 447b3a271a94d0034dd3bab10b8d8cd432843be629eManish Rangankar} 448