vserver 2.0 rc7
[linux-2.6.git] / drivers / scsi / qla2xxx / qla_iocb.c
index ec06607..af964bb 100644 (file)
@@ -216,18 +216,7 @@ void qla2x00_build_scsi_iocbs_32(srb_t *sp, cmd_entry_t *cmd_pkt,
                        cur_seg++;
                }
        } else {
-               dma_addr_t      req_dma;
-               struct page     *page;
-               unsigned long   offset;
-
-               page = virt_to_page(cmd->request_buffer);
-               offset = ((unsigned long)cmd->request_buffer & ~PAGE_MASK);
-               req_dma = pci_map_page(ha->pdev, page, offset,
-                   cmd->request_bufflen, cmd->sc_data_direction);
-
-               sp->dma_handle = req_dma;
-
-               *cur_dsd++ = cpu_to_le32(req_dma);
+               *cur_dsd++ = cpu_to_le32(sp->dma_handle);
                *cur_dsd++ = cpu_to_le32(cmd->request_bufflen);
        }
 }
@@ -299,19 +288,8 @@ void qla2x00_build_scsi_iocbs_64(srb_t *sp, cmd_entry_t *cmd_pkt,
                        cur_seg++;
                }
        } else {
-               dma_addr_t      req_dma;
-               struct page     *page;
-               unsigned long   offset;
-
-               page = virt_to_page(cmd->request_buffer);
-               offset = ((unsigned long)cmd->request_buffer & ~PAGE_MASK);
-               req_dma = pci_map_page(ha->pdev, page, offset,
-                   cmd->request_bufflen, cmd->sc_data_direction);
-
-               sp->dma_handle = req_dma;
-
-               *cur_dsd++ = cpu_to_le32(LSD(req_dma));
-               *cur_dsd++ = cpu_to_le32(MSD(req_dma));
+               *cur_dsd++ = cpu_to_le32(LSD(sp->dma_handle));
+               *cur_dsd++ = cpu_to_le32(MSD(sp->dma_handle));
                *cur_dsd++ = cpu_to_le32(cmd->request_bufflen);
        }
 }
@@ -328,13 +306,11 @@ qla2x00_start_scsi(srb_t *sp)
        int             ret;
        unsigned long   flags;
        scsi_qla_host_t *ha;
-       fc_lun_t        *fclun;
        struct scsi_cmnd *cmd;
        uint32_t        *clr_ptr;
        uint32_t        index;
        uint32_t        handle;
        cmd_entry_t     *cmd_pkt;
-       uint32_t        timeout;
        struct scatterlist *sg;
        uint16_t        cnt;
        uint16_t        req_cnt;
@@ -344,10 +320,11 @@ qla2x00_start_scsi(srb_t *sp)
 
        /* Setup device pointers. */
        ret = 0;
-       fclun = sp->lun_queue->fclun;
-       ha = fclun->fcport->ha;
+       ha = sp->ha;
        reg = ha->iobase;
        cmd = sp->cmd;
+       /* So we know we haven't pci_map'ed anything yet */
+       tot_dsds = 0;
 
        /* Send marker if required */
        if (ha->marker_needed != 0) {
@@ -372,8 +349,27 @@ qla2x00_start_scsi(srb_t *sp)
        if (index == MAX_OUTSTANDING_COMMANDS)
                goto queuing_error;
 
+       /* Map the sg table so we have an accurate count of sg entries needed */
+       if (cmd->use_sg) {
+               sg = (struct scatterlist *) cmd->request_buffer;
+               tot_dsds = pci_map_sg(ha->pdev, sg, cmd->use_sg,
+                   cmd->sc_data_direction);
+               if (tot_dsds == 0)
+                       goto queuing_error;
+       } else if (cmd->request_bufflen) {
+               dma_addr_t      req_dma;
+
+               req_dma = pci_map_single(ha->pdev, cmd->request_buffer,
+                   cmd->request_bufflen, cmd->sc_data_direction);
+               if (dma_mapping_error(req_dma))
+                       goto queuing_error;
+
+               sp->dma_handle = req_dma;
+               tot_dsds = 1;
+       }
+
        /* Calculate the number of request entries needed. */
-       req_cnt = (ha->calc_request_entries)(cmd->request->nr_hw_segments);
+       req_cnt = (ha->calc_request_entries)(tot_dsds);
        if (ha->req_q_cnt < (req_cnt + 2)) {
                cnt = RD_REG_WORD_RELAXED(ISP_REQ_Q_OUT(ha, reg));
                if (ha->req_ring_index < cnt)
@@ -385,19 +381,6 @@ qla2x00_start_scsi(srb_t *sp)
        if (ha->req_q_cnt < (req_cnt + 2))
                goto queuing_error;
 
-       /* Finally, we have enough space, now perform mappings. */
-       tot_dsds = 0;
-       if (cmd->use_sg) {
-               sg = (struct scatterlist *) cmd->request_buffer;
-               tot_dsds = pci_map_sg(ha->pdev, sg, cmd->use_sg,
-                   cmd->sc_data_direction);
-               if (tot_dsds == 0)
-                       goto queuing_error;
-       } else if (cmd->request_bufflen) {
-           tot_dsds++;
-       }
-       req_cnt = (ha->calc_request_entries)(tot_dsds);
-
        /* Build command packet */
        ha->current_outstanding_cmd = handle;
        ha->outstanding_cmds[handle] = sp;
@@ -412,11 +395,9 @@ qla2x00_start_scsi(srb_t *sp)
        memset(clr_ptr, 0, REQUEST_ENTRY_SIZE - 8);
        cmd_pkt->dseg_count = cpu_to_le16(tot_dsds);
 
-       /* Set target ID */
-       SET_TARGET_ID(ha, cmd_pkt->target, fclun->fcport->loop_id);
-
-       /* Set LUN number*/
-       cmd_pkt->lun = cpu_to_le16(fclun->lun);
+       /* Set target ID and LUN number*/
+       SET_TARGET_ID(ha, cmd_pkt->target, sp->fcport->loop_id);
+       cmd_pkt->lun = cpu_to_le16(sp->cmd->device->lun);
 
        /* Update tagged queuing modifier */
        cmd_pkt->control_flags = __constant_cpu_to_le16(CF_SIMPLE_TAG);
@@ -433,18 +414,6 @@ qla2x00_start_scsi(srb_t *sp)
                }
        }
 
-       /*
-        * Allocate at least 5 (+ QLA_CMD_TIMER_DELTA) seconds for RISC timeout.
-        */
-       timeout = (uint32_t)(cmd->timeout_per_command / HZ);
-       if (timeout > 65535)
-               cmd_pkt->timeout = __constant_cpu_to_le16(0);
-       else if (timeout > 25)
-               cmd_pkt->timeout = cpu_to_le16((uint16_t)timeout -
-                   (5 + QLA_CMD_TIMER_DELTA));
-       else
-               cmd_pkt->timeout = cpu_to_le16((uint16_t)timeout);
-
        /* Load SCSI command packet. */
        memcpy(cmd_pkt->scsi_cdb, cmd->cmnd, cmd->cmd_len);
        cmd_pkt->byte_count = cpu_to_le32((uint32_t)cmd->request_bufflen);
@@ -466,7 +435,6 @@ qla2x00_start_scsi(srb_t *sp)
 
        ha->actthreads++;
        ha->total_ios++;
-       sp->lun_queue->out_cnt++;
        sp->flags |= SRB_DMA_VALID;
        sp->state = SRB_ACTIVE_STATE;
        sp->u_start = jiffies;
@@ -479,6 +447,14 @@ qla2x00_start_scsi(srb_t *sp)
        return (QLA_SUCCESS);
 
 queuing_error:
+       if (cmd->use_sg && tot_dsds) {
+               sg = (struct scatterlist *) cmd->request_buffer;
+               pci_unmap_sg(ha->pdev, sg, cmd->use_sg,
+                   cmd->sc_data_direction);
+       } else if (tot_dsds) {
+               pci_unmap_single(ha->pdev, sp->dma_handle,
+                   cmd->request_bufflen, cmd->sc_data_direction);
+       }
        spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
        return (QLA_FUNCTION_FAILED);