Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[SCSI] atp870u: fix memory addressing bug

From: Alan Cox <alan@redhat.com>

The virt_to_bus() wasn't correctly taken out of this driver. It needs
to be able to track both physical and virtual addresses for its prd table.
Update the driver to do this with separate tracking entries.

Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>

+7 -4
+4 -2
drivers/scsi/atp870u.c
··· 996 996 #ifdef ED_DBGP 997 997 printk("send_s870: prdaddr_2 0x%8x tmpcip %x target_id %d\n", dev->id[c][target_id].prdaddr,tmpcip,target_id); 998 998 #endif 999 + dev->id[c][target_id].prdaddr = dev->id[c][target_id].prd_bus; 999 1000 outl(dev->id[c][target_id].prdaddr, tmpcip); 1000 1001 tmpcip = tmpcip - 2; 1001 1002 outb(0x06, tmpcip); ··· 2573 2572 for (k = 0; k < 16; k++) { 2574 2573 if (!atp_dev->id[j][k].prd_table) 2575 2574 continue; 2576 - pci_free_consistent(atp_dev->pdev, 1024, atp_dev->id[j][k].prd_table, atp_dev->id[j][k].prdaddr); 2575 + pci_free_consistent(atp_dev->pdev, 1024, atp_dev->id[j][k].prd_table, atp_dev->id[j][k].prd_bus); 2577 2576 atp_dev->id[j][k].prd_table = NULL; 2578 2577 } 2579 2578 } ··· 2585 2584 int c,k; 2586 2585 for(c=0;c < 2;c++) { 2587 2586 for(k=0;k<16;k++) { 2588 - atp_dev->id[c][k].prd_table = pci_alloc_consistent(atp_dev->pdev, 1024, &(atp_dev->id[c][k].prdaddr)); 2587 + atp_dev->id[c][k].prd_table = pci_alloc_consistent(atp_dev->pdev, 1024, &(atp_dev->id[c][k].prd_bus)); 2589 2588 if (!atp_dev->id[c][k].prd_table) { 2590 2589 printk("atp870u_init_tables fail\n"); 2591 2590 atp870u_free_tables(host); 2592 2591 return -ENOMEM; 2593 2592 } 2593 + atp_dev->id[c][k].prdaddr = atp_dev->id[c][k].prd_bus; 2594 2594 atp_dev->id[c][k].devsp=0x20; 2595 2595 atp_dev->id[c][k].devtype = 0x7f; 2596 2596 atp_dev->id[c][k].curr_req = NULL;
+3 -2
drivers/scsi/atp870u.h
··· 54 54 unsigned long tran_len; 55 55 unsigned long last_len; 56 56 unsigned char *prd_pos; 57 - unsigned char *prd_table; 58 - dma_addr_t prdaddr; 57 + unsigned char *prd_table; /* Kernel address of PRD table */ 58 + dma_addr_t prd_bus; /* Bus address of PRD */ 59 + dma_addr_t prdaddr; /* Dynamically updated in driver */ 59 60 struct scsi_cmnd *curr_req; 60 61 } id[2][16]; 61 62 struct Scsi_Host *host;