diff options
-rw-r--r-- | drivers/scsi/stex.c | 109 |
1 files changed, 36 insertions, 73 deletions
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c index 69be1324b114..baf516d09d79 100644 --- a/drivers/scsi/stex.c +++ b/drivers/scsi/stex.c | |||
@@ -398,53 +398,34 @@ static struct req_msg *stex_alloc_req(struct st_hba *hba) | |||
398 | static int stex_map_sg(struct st_hba *hba, | 398 | static int stex_map_sg(struct st_hba *hba, |
399 | struct req_msg *req, struct st_ccb *ccb) | 399 | struct req_msg *req, struct st_ccb *ccb) |
400 | { | 400 | { |
401 | struct pci_dev *pdev = hba->pdev; | ||
402 | struct scsi_cmnd *cmd; | 401 | struct scsi_cmnd *cmd; |
403 | dma_addr_t dma_handle; | 402 | struct scatterlist *sg; |
404 | struct scatterlist *src; | ||
405 | struct st_sgtable *dst; | 403 | struct st_sgtable *dst; |
406 | int i; | 404 | int i, nseg; |
407 | 405 | ||
408 | cmd = ccb->cmd; | 406 | cmd = ccb->cmd; |
409 | dst = (struct st_sgtable *)req->variable; | 407 | dst = (struct st_sgtable *)req->variable; |
410 | dst->max_sg_count = cpu_to_le16(ST_MAX_SG); | 408 | dst->max_sg_count = cpu_to_le16(ST_MAX_SG); |
411 | dst->sz_in_byte = cpu_to_le32(cmd->request_bufflen); | 409 | dst->sz_in_byte = cpu_to_le32(scsi_bufflen(cmd)); |
412 | |||
413 | if (cmd->use_sg) { | ||
414 | int n_elem; | ||
415 | 410 | ||
416 | src = (struct scatterlist *) cmd->request_buffer; | 411 | nseg = scsi_dma_map(cmd); |
417 | n_elem = pci_map_sg(pdev, src, | 412 | if (nseg < 0) |
418 | cmd->use_sg, cmd->sc_data_direction); | 413 | return -EIO; |
419 | if (n_elem <= 0) | 414 | if (nseg) { |
420 | return -EIO; | 415 | ccb->sg_count = nseg; |
416 | dst->sg_count = cpu_to_le16((u16)nseg); | ||
421 | 417 | ||
422 | ccb->sg_count = n_elem; | 418 | scsi_for_each_sg(cmd, sg, nseg, i) { |
423 | dst->sg_count = cpu_to_le16((u16)n_elem); | 419 | dst->table[i].count = cpu_to_le32((u32)sg_dma_len(sg)); |
424 | |||
425 | for (i = 0; i < n_elem; i++, src++) { | ||
426 | dst->table[i].count = cpu_to_le32((u32)sg_dma_len(src)); | ||
427 | dst->table[i].addr = | 420 | dst->table[i].addr = |
428 | cpu_to_le32(sg_dma_address(src) & 0xffffffff); | 421 | cpu_to_le32(sg_dma_address(sg) & 0xffffffff); |
429 | dst->table[i].addr_hi = | 422 | dst->table[i].addr_hi = |
430 | cpu_to_le32((sg_dma_address(src) >> 16) >> 16); | 423 | cpu_to_le32((sg_dma_address(sg) >> 16) >> 16); |
431 | dst->table[i].ctrl = SG_CF_64B | SG_CF_HOST; | 424 | dst->table[i].ctrl = SG_CF_64B | SG_CF_HOST; |
432 | } | 425 | } |
433 | dst->table[--i].ctrl |= SG_CF_EOT; | 426 | dst->table[--i].ctrl |= SG_CF_EOT; |
434 | return 0; | ||
435 | } | 427 | } |
436 | 428 | ||
437 | dma_handle = pci_map_single(pdev, cmd->request_buffer, | ||
438 | cmd->request_bufflen, cmd->sc_data_direction); | ||
439 | cmd->SCp.dma_handle = dma_handle; | ||
440 | |||
441 | ccb->sg_count = 1; | ||
442 | dst->sg_count = cpu_to_le16(1); | ||
443 | dst->table[0].addr = cpu_to_le32(dma_handle & 0xffffffff); | ||
444 | dst->table[0].addr_hi = cpu_to_le32((dma_handle >> 16) >> 16); | ||
445 | dst->table[0].count = cpu_to_le32((u32)cmd->request_bufflen); | ||
446 | dst->table[0].ctrl = SG_CF_EOT | SG_CF_64B | SG_CF_HOST; | ||
447 | |||
448 | return 0; | 429 | return 0; |
449 | } | 430 | } |
450 | 431 | ||
@@ -454,24 +435,24 @@ static void stex_internal_copy(struct scsi_cmnd *cmd, | |||
454 | size_t lcount; | 435 | size_t lcount; |
455 | size_t len; | 436 | size_t len; |
456 | void *s, *d, *base = NULL; | 437 | void *s, *d, *base = NULL; |
457 | if (*count > cmd->request_bufflen) | 438 | size_t offset; |
458 | *count = cmd->request_bufflen; | 439 | |
440 | if (*count > scsi_bufflen(cmd)) | ||
441 | *count = scsi_bufflen(cmd); | ||
459 | lcount = *count; | 442 | lcount = *count; |
460 | while (lcount) { | 443 | while (lcount) { |
461 | len = lcount; | 444 | len = lcount; |
462 | s = (void *)src; | 445 | s = (void *)src; |
463 | if (cmd->use_sg) { | 446 | |
464 | size_t offset = *count - lcount; | 447 | offset = *count - lcount; |
465 | s += offset; | 448 | s += offset; |
466 | base = scsi_kmap_atomic_sg(cmd->request_buffer, | 449 | base = scsi_kmap_atomic_sg(scsi_sglist(cmd), |
467 | sg_count, &offset, &len); | 450 | sg_count, &offset, &len); |
468 | if (base == NULL) { | 451 | if (!base) { |
469 | *count -= lcount; | 452 | *count -= lcount; |
470 | return; | 453 | return; |
471 | } | 454 | } |
472 | d = base + offset; | 455 | d = base + offset; |
473 | } else | ||
474 | d = cmd->request_buffer; | ||
475 | 456 | ||
476 | if (direction == ST_TO_CMD) | 457 | if (direction == ST_TO_CMD) |
477 | memcpy(d, s, len); | 458 | memcpy(d, s, len); |
@@ -479,30 +460,24 @@ static void stex_internal_copy(struct scsi_cmnd *cmd, | |||
479 | memcpy(s, d, len); | 460 | memcpy(s, d, len); |
480 | 461 | ||
481 | lcount -= len; | 462 | lcount -= len; |
482 | if (cmd->use_sg) | 463 | scsi_kunmap_atomic_sg(base); |
483 | scsi_kunmap_atomic_sg(base); | ||
484 | } | 464 | } |
485 | } | 465 | } |
486 | 466 | ||
487 | static int stex_direct_copy(struct scsi_cmnd *cmd, | 467 | static int stex_direct_copy(struct scsi_cmnd *cmd, |
488 | const void *src, size_t count) | 468 | const void *src, size_t count) |
489 | { | 469 | { |
490 | struct st_hba *hba = (struct st_hba *) &cmd->device->host->hostdata[0]; | ||
491 | size_t cp_len = count; | 470 | size_t cp_len = count; |
492 | int n_elem = 0; | 471 | int n_elem = 0; |
493 | 472 | ||
494 | if (cmd->use_sg) { | 473 | n_elem = scsi_dma_map(cmd); |
495 | n_elem = pci_map_sg(hba->pdev, cmd->request_buffer, | 474 | if (n_elem < 0) |
496 | cmd->use_sg, cmd->sc_data_direction); | 475 | return 0; |
497 | if (n_elem <= 0) | ||
498 | return 0; | ||
499 | } | ||
500 | 476 | ||
501 | stex_internal_copy(cmd, src, &cp_len, n_elem, ST_TO_CMD); | 477 | stex_internal_copy(cmd, src, &cp_len, n_elem, ST_TO_CMD); |
502 | 478 | ||
503 | if (cmd->use_sg) | 479 | scsi_dma_unmap(cmd); |
504 | pci_unmap_sg(hba->pdev, cmd->request_buffer, | 480 | |
505 | cmd->use_sg, cmd->sc_data_direction); | ||
506 | return cp_len == count; | 481 | return cp_len == count; |
507 | } | 482 | } |
508 | 483 | ||
@@ -668,18 +643,6 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) | |||
668 | return 0; | 643 | return 0; |
669 | } | 644 | } |
670 | 645 | ||
671 | static void stex_unmap_sg(struct st_hba *hba, struct scsi_cmnd *cmd) | ||
672 | { | ||
673 | if (cmd->sc_data_direction != DMA_NONE) { | ||
674 | if (cmd->use_sg) | ||
675 | pci_unmap_sg(hba->pdev, cmd->request_buffer, | ||
676 | cmd->use_sg, cmd->sc_data_direction); | ||
677 | else | ||
678 | pci_unmap_single(hba->pdev, cmd->SCp.dma_handle, | ||
679 | cmd->request_bufflen, cmd->sc_data_direction); | ||
680 | } | ||
681 | } | ||
682 | |||
683 | static void stex_scsi_done(struct st_ccb *ccb) | 646 | static void stex_scsi_done(struct st_ccb *ccb) |
684 | { | 647 | { |
685 | struct scsi_cmnd *cmd = ccb->cmd; | 648 | struct scsi_cmnd *cmd = ccb->cmd; |
@@ -746,7 +709,7 @@ static void stex_ys_commands(struct st_hba *hba, | |||
746 | 709 | ||
747 | if (ccb->cmd->cmnd[0] == MGT_CMD && | 710 | if (ccb->cmd->cmnd[0] == MGT_CMD && |
748 | resp->scsi_status != SAM_STAT_CHECK_CONDITION) { | 711 | resp->scsi_status != SAM_STAT_CHECK_CONDITION) { |
749 | ccb->cmd->request_bufflen = | 712 | scsi_bufflen(ccb->cmd) = |
750 | le32_to_cpu(*(__le32 *)&resp->variable[0]); | 713 | le32_to_cpu(*(__le32 *)&resp->variable[0]); |
751 | return; | 714 | return; |
752 | } | 715 | } |
@@ -857,7 +820,7 @@ static void stex_mu_intr(struct st_hba *hba, u32 doorbell) | |||
857 | ccb->cmd->cmnd[1] == PASSTHRU_GET_ADAPTER)) | 820 | ccb->cmd->cmnd[1] == PASSTHRU_GET_ADAPTER)) |
858 | stex_controller_info(hba, ccb); | 821 | stex_controller_info(hba, ccb); |
859 | 822 | ||
860 | stex_unmap_sg(hba, ccb->cmd); | 823 | scsi_dma_unmap(ccb->cmd); |
861 | stex_scsi_done(ccb); | 824 | stex_scsi_done(ccb); |
862 | hba->out_req_cnt--; | 825 | hba->out_req_cnt--; |
863 | } else if (ccb->req_type & PASSTHRU_REQ_TYPE) { | 826 | } else if (ccb->req_type & PASSTHRU_REQ_TYPE) { |
@@ -1025,7 +988,7 @@ static int stex_abort(struct scsi_cmnd *cmd) | |||
1025 | } | 988 | } |
1026 | 989 | ||
1027 | fail_out: | 990 | fail_out: |
1028 | stex_unmap_sg(hba, cmd); | 991 | scsi_dma_unmap(cmd); |
1029 | hba->wait_ccb->req = NULL; /* nullify the req's future return */ | 992 | hba->wait_ccb->req = NULL; /* nullify the req's future return */ |
1030 | hba->wait_ccb = NULL; | 993 | hba->wait_ccb = NULL; |
1031 | result = FAILED; | 994 | result = FAILED; |