X-Git-Url: http://git.onelab.eu/?p=linux-2.6.git;a=blobdiff_plain;f=drivers%2Fscsi%2Fqla2xxx%2Fqla_iocb.c;h=af964bb3d87052c3f61807344f79135339471b9d;hp=ec066074c72297baa28e1c81804269a09149e06c;hb=f7f1b0f1e2fbadeab12d24236000e778aa9b1ead;hpb=e3f6fb6212a7102bdb56ba38fa1e98fe72950475 diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index ec066074c..af964bb3d 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -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);