Merge git://www.linux-watchdog.org/linux-watchdog
[pandora-kernel.git] / drivers / scsi / qla4xxx / ql4_iocb.c
index 75fcd82..4106693 100644 (file)
@@ -313,10 +313,8 @@ int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb)
        cmd_entry->hdr.entryType = ET_COMMAND;
        cmd_entry->handle = cpu_to_le32(index);
        cmd_entry->target = cpu_to_le16(ddb_entry->fw_ddb_index);
-       cmd_entry->connection_id = cpu_to_le16(ddb_entry->connection_id);
 
        int_to_scsilun(cmd->device->lun, &cmd_entry->lun);
-       cmd_entry->cmdSeqNum = cpu_to_le32(ddb_entry->CmdSn);
        cmd_entry->ttlByteCnt = cpu_to_le32(scsi_bufflen(cmd));
        memcpy(cmd_entry->cdb, cmd->cmnd, cmd->cmd_len);
        cmd_entry->dataSegCnt = cpu_to_le16(tot_dsds);
@@ -381,3 +379,69 @@ queuing_error:
        return QLA_ERROR;
 }
 
+int qla4xxx_send_passthru0(struct iscsi_task *task)
+{
+       struct passthru0 *passthru_iocb;
+       struct iscsi_session *sess = task->conn->session;
+       struct ddb_entry *ddb_entry = sess->dd_data;
+       struct scsi_qla_host *ha = ddb_entry->ha;
+       struct ql4_task_data *task_data = task->dd_data;
+       uint16_t ctrl_flags = 0;
+       unsigned long flags;
+       int ret = QLA_ERROR;
+
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       task_data->iocb_req_cnt = 1;
+       /* Put the IOCB on the request queue */
+       if (!qla4xxx_space_in_req_ring(ha, task_data->iocb_req_cnt))
+               goto queuing_error;
+
+       passthru_iocb = (struct passthru0 *) ha->request_ptr;
+
+       memset(passthru_iocb, 0, sizeof(struct passthru0));
+       passthru_iocb->hdr.entryType = ET_PASSTHRU0;
+       passthru_iocb->hdr.systemDefined = SD_ISCSI_PDU;
+       passthru_iocb->hdr.entryCount = task_data->iocb_req_cnt;
+       passthru_iocb->handle = task->itt;
+       passthru_iocb->target = cpu_to_le16(ddb_entry->fw_ddb_index);
+       passthru_iocb->timeout = cpu_to_le16(PT_DEFAULT_TIMEOUT);
+
+       /* Setup the out & in DSDs */
+       if (task_data->req_len) {
+               memcpy((uint8_t *)task_data->req_buffer +
+                      sizeof(struct iscsi_hdr), task->data, task->data_count);
+               ctrl_flags |= PT_FLAG_SEND_BUFFER;
+               passthru_iocb->out_dsd.base.addrLow =
+                                       cpu_to_le32(LSDW(task_data->req_dma));
+               passthru_iocb->out_dsd.base.addrHigh =
+                                       cpu_to_le32(MSDW(task_data->req_dma));
+               passthru_iocb->out_dsd.count =
+                                       cpu_to_le32(task->data_count +
+                                                   sizeof(struct iscsi_hdr));
+       }
+       if (task_data->resp_len) {
+               passthru_iocb->in_dsd.base.addrLow =
+                                       cpu_to_le32(LSDW(task_data->resp_dma));
+               passthru_iocb->in_dsd.base.addrHigh =
+                                       cpu_to_le32(MSDW(task_data->resp_dma));
+               passthru_iocb->in_dsd.count =
+                       cpu_to_le32(task_data->resp_len);
+       }
+
+       ctrl_flags |= (PT_FLAG_ISCSI_PDU | PT_FLAG_WAIT_4_RESPONSE);
+       passthru_iocb->control_flags = cpu_to_le16(ctrl_flags);
+
+       /* Update the request pointer */
+       qla4xxx_advance_req_ring_ptr(ha);
+       wmb();
+
+       /* Track IOCB used */
+       ha->iocb_cnt += task_data->iocb_req_cnt;
+       ha->req_q_count -= task_data->iocb_req_cnt;
+       ha->isp_ops->queue_iocb(ha);
+       ret = QLA_SUCCESS;
+
+queuing_error:
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+       return ret;
+}