aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2008-02-22 09:11:03 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-02-22 18:20:39 -0500
commit26106e3ca379e30790c41d8835e79395437152ec (patch)
treec3f7825595819d4d607b642499616d3e5055bcb4
parenteafe1df9e311034cce204e43c0e45c91723b802f (diff)
[SCSI] stex: stex_direct_copy shouldn't call dma_map_sg
stex_direct_copy copies an in-kernel buffer to a sg list in order to spoof some SCSI commands. stex_direct_copy calls dma_map_sg and then stex_internal_copy with the value that dma_map_sg returned. It calls scsi_kmap_atomic_sg to copy data. scsi_kmap_atomic_sg doesn't see sg->dma_length so if dma_map_sg merges sg entries, stex_internal_copy gets the smaller number of sg entries than the acutual number, which means it wrongly think that the data length in the sg list is shorter than the actual length. stex_direct_copy shouldn't call dma_map_sg and it doesn't need since this code path doesn't involve dma transfers. This patch removes stex_direct_copy and simply calls stex_internal_copy with the actual number of sg entries. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Acked-by: Ed Lin <ed.lin@promise.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r--drivers/scsi/stex.c34
1 files changed, 12 insertions, 22 deletions
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c
index 72f6d8015358..4b6861cf0417 100644
--- a/drivers/scsi/stex.c
+++ b/drivers/scsi/stex.c
@@ -461,23 +461,6 @@ static void stex_internal_copy(struct scsi_cmnd *cmd,
461 } 461 }
462} 462}
463 463
464static int stex_direct_copy(struct scsi_cmnd *cmd,
465 const void *src, size_t count)
466{
467 size_t cp_len = count;
468 int n_elem = 0;
469
470 n_elem = scsi_dma_map(cmd);
471 if (n_elem < 0)
472 return 0;
473
474 stex_internal_copy(cmd, src, &cp_len, n_elem, ST_TO_CMD);
475
476 scsi_dma_unmap(cmd);
477
478 return cp_len == count;
479}
480
481static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb) 464static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb)
482{ 465{
483 struct st_frame *p; 466 struct st_frame *p;
@@ -569,8 +552,10 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
569 unsigned char page; 552 unsigned char page;
570 page = cmd->cmnd[2] & 0x3f; 553 page = cmd->cmnd[2] & 0x3f;
571 if (page == 0x8 || page == 0x3f) { 554 if (page == 0x8 || page == 0x3f) {
572 stex_direct_copy(cmd, ms10_caching_page, 555 size_t cp_len = sizeof(ms10_caching_page);
573 sizeof(ms10_caching_page)); 556 stex_internal_copy(cmd, ms10_caching_page,
557 &cp_len, scsi_sg_count(cmd),
558 ST_TO_CMD);
574 cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; 559 cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
575 done(cmd); 560 done(cmd);
576 } else 561 } else
@@ -599,8 +584,10 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
599 if (id != host->max_id - 1) 584 if (id != host->max_id - 1)
600 break; 585 break;
601 if (lun == 0 && (cmd->cmnd[1] & INQUIRY_EVPD) == 0) { 586 if (lun == 0 && (cmd->cmnd[1] & INQUIRY_EVPD) == 0) {
602 stex_direct_copy(cmd, console_inq_page, 587 size_t cp_len = sizeof(console_inq_page);
603 sizeof(console_inq_page)); 588 stex_internal_copy(cmd, console_inq_page,
589 &cp_len, scsi_sg_count(cmd),
590 ST_TO_CMD);
604 cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; 591 cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
605 done(cmd); 592 done(cmd);
606 } else 593 } else
@@ -609,6 +596,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
609 case PASSTHRU_CMD: 596 case PASSTHRU_CMD:
610 if (cmd->cmnd[1] == PASSTHRU_GET_DRVVER) { 597 if (cmd->cmnd[1] == PASSTHRU_GET_DRVVER) {
611 struct st_drvver ver; 598 struct st_drvver ver;
599 size_t cp_len = sizeof(ver);
612 ver.major = ST_VER_MAJOR; 600 ver.major = ST_VER_MAJOR;
613 ver.minor = ST_VER_MINOR; 601 ver.minor = ST_VER_MINOR;
614 ver.oem = ST_OEM; 602 ver.oem = ST_OEM;
@@ -616,7 +604,9 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
616 ver.signature[0] = PASSTHRU_SIGNATURE; 604 ver.signature[0] = PASSTHRU_SIGNATURE;
617 ver.console_id = host->max_id - 1; 605 ver.console_id = host->max_id - 1;
618 ver.host_no = hba->host->host_no; 606 ver.host_no = hba->host->host_no;
619 cmd->result = stex_direct_copy(cmd, &ver, sizeof(ver)) ? 607 stex_internal_copy(cmd, &ver, &cp_len,
608 scsi_sg_count(cmd), ST_TO_CMD);
609 cmd->result = sizeof(ver) == cp_len ?
620 DID_OK << 16 | COMMAND_COMPLETE << 8 : 610 DID_OK << 16 | COMMAND_COMPLETE << 8 :
621 DID_ERROR << 16 | COMMAND_COMPLETE << 8; 611 DID_ERROR << 16 | COMMAND_COMPLETE << 8;
622 done(cmd); 612 done(cmd);