fix gcc warning on 64 bit compile of gdth
PATCH 1/1 fix gcc warning on 64 bit compile of gdth
This warning:
drivers/scsi/gdth.c: In function `gdth_fill_raw_cmd':drivers/scsi/gdth.c:2948: warning: cast to pointer from integer of different sizedrivers/scsi/gdth.c:2950: warning: cast to pointer from integer of different sizedrivers/scsi/gdth.c: In function `gdth_sync_event':drivers/scsi/gdth.c:3644: warning: cast from pointer to integer of different sizedrivers/scsi/gdth.c:3646: warning: cast from pointer to integer of different size
can be fixed with the following patch.
James
===== drivers/scsi/gdth.c 1.47 vs edited =====
drivers/scsi/gdth.c +4 -4
@@ -2945,9 +2945,9 @@ offset = (ulong )scp->sense_buffer & ~PAGE_MASK ; sense_paddr =pci_map_page (ha->pdev,page,offset,16 ,PCI_DMA_FROMDEVICE ); - scp->SCp.buffer = (struct scatterlist *)((ulong32 )sense_paddr); + scp->SCp.buffer = (struct scatterlist *)((unsigned long )sense_paddr);/* high part, if 64bit */ - scp->host_scribble = (char *)(ulong32)((ulong64 )sense_paddr >>32 ); + scp->host_scribble = (char *)(unsigned long )((ulong64 )sense_paddr >>32 ); cmdp->OpCode =GDT_WRITE ;/* always */ cmdp->BoardNode =LOCALBOARD ;if (mode64) {
@@ -3641,9 +3641,9 @@ scp->request_bufflen,scp->SCp.Message);if (scp->SCp.buffer) {dma_addr_t addr; - addr = (dma_addr_t )(ulong32 )scp->SCp.buffer; + addr = (dma_addr_t )(unsigned long )scp->SCp.buffer;if (scp->host_scribble) - addr += (dma_addr_t)((ulong64 )(ulong32 )scp->host_scribble <<32 ); + addr += (dma_addr_t)((ulong64 )(unsigned long )scp->host_scribble <<32 );pci_unmap_page (ha->pdev,addr,16 ,PCI_DMA_FROMDEVICE ); }
Quoted 13 lines · James Bottomley
This warning:
drivers/scsi/gdth.c: In function `gdth_fill_raw_cmd':drivers/scsi/gdth.c:2948: warning: cast to pointer from integer of different sizedrivers/scsi/gdth.c:2950: warning: cast to pointer from integer of different sizedrivers/scsi/gdth.c: In function `gdth_sync_event':drivers/scsi/gdth.c:3644: warning: cast from pointer to integer of different sizedrivers/scsi/gdth.c:3646: warning: cast from pointer to integer of different size
Quoted 1 line
can be fixed with the following patch.
*UGH*
Why do you play with shoving dma_addr_t into a pair of pointers and then decoding it when you have ->SCp.dma_handle?
Quoted 4 lines · Al Viro
*UGH*
Why do you play with shoving
dma_addr_tinto a pair of pointers and then decoding it when you have ->SCp.dma_handle?
Well, I don't since it's not my driver.
However, I think the nutcase it's trying to crack is storing dma_addr_t on x86 PAE. There dma_addr_t is wider than a void *.
James
Quoted 10 lines · James Bottomley
Quoted 4 lines · Al Viro
*UGH*
Why do you play with shoving
dma_addr_tinto a pair of pointers and then decoding it when you have ->SCp.dma_handle?Well, I don't since it's not my driver.
However, I think the nutcase it's trying to crack is storing
dma_addr_ton x86 PAE. Theredma_addr_tis wider than a void *.
... and dma_handle *is* dma_addr_t and gets used in exact same driver to store the results of the same function (grep for pci_map_page in there).
Quoted 2 lines · Al Viro
... and
dma_handle*is*dma_addr_tand gets used in exact same driver to store the results of the same function (grep forpci_map_pagein there).
Fine. But I usually observe the rule of tamper minimally ... drivers have a nasty habit of sticking to you if you do more than that.
Indeed, now I look at the cleaned up patch, the think will leak DMA mappings if sense_paddr is zero (which is quite possible, since zero is a valid bus physical address). However, I'm declaring this too minimal to bother with ... unless you want to fix it?
James
===== drivers/scsi/gdth.c 1.47 vs edited =====
drivers/scsi/gdth.c +6 -11
@@ -2945,9 +2945,8 @@ offset = (ulong )scp->sense_buffer & ~PAGE_MASK ; sense_paddr =pci_map_page (ha->pdev,page,offset,16 ,PCI_DMA_FROMDEVICE ); - scp->SCp.buffer = (struct scatterlist *)((ulong32 )sense_paddr); -/* high part, if 64bit */ - scp->host_scribble = (char *)(ulong32)((ulong64 )sense_paddr >>32 ); + scp->SCp.dma_handle = sense_paddr; + cmdp->OpCode =GDT_WRITE ;/* always */ cmdp->BoardNode =LOCALBOARD ;if (mode64) {
@@ -3639,13 +3638,9 @@else if (scp->SCp.Status ==GDTH_MAP_SINGLE )pci_unmap_page (ha->pdev,scp->SCp.dma_handle, scp->request_bufflen,scp->SCp.Message); -if (scp->SCp.buffer) { -dma_addr_t addr; - addr = (dma_addr_t )(ulong32 )scp->SCp.buffer; -if (scp->host_scribble) - addr += (dma_addr_t)((ulong64 )(ulong32 )scp->host_scribble <<32 ); -pci_unmap_page (ha->pdev,addr,16 ,PCI_DMA_FROMDEVICE ); - } +if (scp->SCp.dma_handle) +pci_unmap_page (ha->pdev,scp->SCp.dma_handle,16 ,PCI_DMA_FROMDEVICE ); +if (ha->status ==S_OK ) { scp->SCp.Status =S_OK ;
@@ -4830,7 +4825,7 @@ scp->SCp.phase =-1 ; scp->SCp.sent_command =-1 ; scp->SCp.Status =GDTH_MAP_NONE ; - scp->SCp.buffer = (struct scatterlist *)NULL ; + scp->SCp.dma_handle =0 ; hanum =NUMDATA (scp->device->host)->hanum;#ifdef GDTH_STATISTICS
Quoted 11 lines · James Bottomley
Quoted 2 lines · Al Viro
... and
dma_handle*is*dma_addr_tand gets used in exact same driver to store the results of the same function (grep forpci_map_pagein there).Fine. But I usually observe the rule of tamper minimally ... drivers have a nasty habit of sticking to you if you do more than that.
Indeed, now I look at the cleaned up patch, the think will leak DMA mappings if
sense_paddris zero (which is quite possible, since zero is a valid bus physical address). However, I'm declaring this too minimal to bother with ... unless you want to fix it?
After looking at the source some more... NAK. Turns out that there was a reason to avoid reuse of ->dma_handle here. What happens is that we might map *two* things in gdth_fill_raw_command() - scp->sense_data and possibly scp->request_buffer. So yes, there is a reason for not reusing ->dma_handle - it's used for the latter.
So ->dma_handle is not a solution. However, "shove it into ->Buffer and ->host_scribble" is not a solution either, AFAICS.
a) the problem you've found with code that unmaps stuff. Probably
should be handled by looking at ->SCp.Status instead of ->SCp.Buffer and setting a bit in .Status in the same place where we are currently setting .Buffer.
b) AFAICS, driver blindly assumes that pci_map_page() and friends
never fail. Probably should be checked in gdth_fill_..._cmd() so we could bail out before we feed fsck knows what to the hardware...
c) this "shove dma_address_t into two pointers" is, indeed, fscking
ugly and brittle (note e.g. the bug with checking lower 32 bits first and then adding upper 32 from ->host_scribble only if they were not all 0). What do other drivers do when they want more than one mapping?
Comments?
Quoted 2 lines · Al Viro
... and
dma_handle*is*dma_addr_tand gets used in exact same driver to store the results of the same function (grep forpci_map_pagein there).
But as it looks do me the driver is doing two different dma mappings in here.