Re: [PATCH] 3ware scsi_dma_unmap fix

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, May 5, 2009 at 5:12 PM, FUJITA Tomonori
<fujita.tomonori@xxxxxxxxxxxxx> wrote:
> On Tue, 5 May 2009 11:45:37 -0700
> adam radford <aradford@xxxxxxxxx> wrote:
>
>> This patch for the 3w-9xxx driver is for 2.6.30-rc5.
>>
>> This patch fixes the following regression the occurred during the
>> scsi_dma_map()/unmap() changes:
>
> Yeah, sorry about that.
>
>> 3w-9xxx 0001:45:00.0: DMA-API: device driver tries to free DMA memory
>> it has not allocated [device address=0x0000000000000000] [size=36
>> bytes]
>
> Might be better to put the pointer to report this bug?
>
> http://marc.info/?l=linux-kernel&m=124141488730478&w=2
>
>
>> James, could you please apply this?
>>
>> Thanks,
>>
>> -Adam
>>
>> Signed-off-by: Adam Radford <aradford@xxxxxxxxx>
>
> The patch looks correct. Let's add 'Cc: stable@xxxxxxxxxx' here so
> that this patch will be sent to stable trees.
>
>
> btw, can we simplify the dma buffer handling by removing the usage of
> the generi_buffer_virt (always use scatter gather buffers)?
>
> diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
> index 8b7983a..4c7e80e 100644
> --- a/drivers/scsi/3w-9xxx.c
> +++ b/drivers/scsi/3w-9xxx.c
> @@ -1847,29 +1847,19 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id,
>                /* Map sglist from scsi layer to cmd packet */
>
>                if (scsi_sg_count(srb)) {
> -                       if ((scsi_sg_count(srb) == 1) &&
> -                           (scsi_bufflen(srb) < TW_MIN_SGL_LENGTH)) {
> -                               if (srb->sc_data_direction == DMA_TO_DEVICE ||
> -                                   srb->sc_data_direction == DMA_BIDIRECTIONAL)
> -                                       scsi_sg_copy_to_buffer(srb,
> -                                                              tw_dev->generic_buffer_virt[request_id],
> -                                                              TW_SECTOR_SIZE);
> -                               command_packet->sg_list[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]);
> -                               command_packet->sg_list[0].length = cpu_to_le32(TW_MIN_SGL_LENGTH);
> -                       } else {
> -                               sg_count = twa_map_scsi_sg_data(tw_dev, request_id);
> -                               if (sg_count == 0)
> -                                       goto out;
> +                       sg_count = twa_map_scsi_sg_data(tw_dev, request_id);
> +                       if (sg_count == 0)
> +                               goto out;
>
> -                               scsi_for_each_sg(srb, sg, sg_count, i) {
> -                                       command_packet->sg_list[i].address = TW_CPU_TO_SGL(sg_dma_address(sg));
> -                                       command_packet->sg_list[i].length = cpu_to_le32(sg_dma_len(sg));
> -                                       if (command_packet->sg_list[i].address & TW_CPU_TO_SGL(TW_ALIGNMENT_9000_SGL)) {
> -                                               TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2e, "Found unaligned sgl address during execute scsi");
> -                                               goto out;
> -                                       }
> +                       scsi_for_each_sg(srb, sg, sg_count, i) {
> +                               command_packet->sg_list[i].address = TW_CPU_TO_SGL(sg_dma_address(sg));
> +                               command_packet->sg_list[i].length = cpu_to_le32(sg_dma_len(sg));
> +                               if (command_packet->sg_list[i].address & TW_CPU_TO_SGL(TW_ALIGNMENT_9000_SGL)) {
> +                                       TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2e, "Found unaligned sgl address during execute scsi");
> +                                       goto out;
>                                }
>                        }
> +
>                        command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN((srb->device->lun >> 4), scsi_sg_count(tw_dev->srb[request_id])));
>                }
>        } else {
>

I wouldn't do that.  The generic_buffer_virt stuff is there because
the hardware can't DMA < 512 bytes, so we sg_copy_to/from_buffer()
there, then dma from generic_buffer_virt.

-Adam
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux