Re: dma related cleanups for wd719x v2
Christoph, > Various dma relates cleanups Applied to 4.21/scsi-queue, thanks! -- Martin K. Petersen Oracle Linux Engineering
dma related cleanups for wd719x v2
Various dma relates cleanups Changes since v1: - include important fixes from Ondrej
Re: dma related cleanups for wd719x
On Thursday 18 October 2018 15:01:14 Christoph Hellwig wrote: > Hi Ondrej, > > can you look over this series, which cleans up a few dma-related > bits in the wd719x driver? Hello, this patch is needed to make it work: diff --git a/drivers/scsi/wd719x.c b/drivers/scsi/wd719x.c index d47190f08ed6..b73e7f24a1c4 100644 --- a/drivers/scsi/wd719x.c +++ b/drivers/scsi/wd719x.c @@ -183,7 +183,7 @@ static void wd719x_finish_cmd(struct wd719x_scb *scb, int result) list_del(&scb->list); dma_unmap_single(&wd->pdev->dev, scb->phys, - sizeof(struct wd719x_scb), DMA_TO_DEVICE); + sizeof(struct wd719x_scb), DMA_BIDIRECTIONAL); scsi_dma_unmap(cmd); dma_unmap_single(&wd->pdev->dev, cmd->SCp.dma_handle, SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE); @@ -209,12 +209,19 @@ static int wd719x_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *cmd) /* copy the command */ memcpy(scb->CDB, cmd->cmnd, cmd->cmd_len); + /* map SCB */ + scb->phys = dma_map_single(&wd->pdev->dev, scb, sizeof(*scb), + DMA_BIDIRECTIONAL); + + if (dma_mapping_error(&wd->pdev->dev, scb->phys)) + goto out_error; + /* map sense buffer */ scb->sense_buf_length = SCSI_SENSE_BUFFERSIZE; cmd->SCp.dma_handle = dma_map_single(&wd->pdev->dev, cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE); if (dma_mapping_error(&wd->pdev->dev, cmd->SCp.dma_handle)) - goto out_error; + goto out_unmap_scb; scb->sense_buf = cpu_to_le32(cmd->SCp.dma_handle); /* request autosense */ @@ -246,11 +253,6 @@ static int wd719x_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *cmd) scb->sg_list[i].length = cpu_to_le32(sg_dma_len(sg)); } scb->SCB_options |= WD719X_SCB_FLAGS_DO_SCATTER_GATHER; - - scb->phys = dma_map_single(&wd->pdev->dev, scb, sizeof(*scb), - DMA_TO_DEVICE); - if (dma_mapping_error(&wd->pdev->dev, scb->phys)) - goto out_unmap_scsi_cmd; } else { /* zero length */ scb->data_length = 0; scb->data_p = 0; @@ -274,11 +276,12 @@ static int wd719x_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *cmd) spin_unlock_irqrestore(wd->sh->host_lock, flags); return 0; -out_unmap_scsi_cmd: - scsi_dma_unmap(cmd); out_unmap_sense: dma_unmap_single(&wd->pdev->dev, cmd->SCp.dma_handle, SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE); +out_unmap_scb: + dma_unmap_single(&wd->pdev->dev, scb->phys, sizeof(*scb), +DMA_BIDIRECTIONAL); out_error: cmd->result = DID_ERROR << 16; cmd->scsi_done(cmd); -- Ondrej Zary
Re: dma related cleanups for wd719x
On Thursday 18 October 2018 15:01:14 Christoph Hellwig wrote: > Hi Ondrej, > > can you look over this series, which cleans up a few dma-related > bits in the wd719x driver? > This makes it work a bit (can detect drive and read partitions) but it hangs completely after hdparm -t. diff --git a/drivers/scsi/wd719x.c b/drivers/scsi/wd719x.c index d47190f08ed6..55a7a542e653 100644 --- a/drivers/scsi/wd719x.c +++ b/drivers/scsi/wd719x.c @@ -183,7 +183,7 @@ static void wd719x_finish_cmd(struct wd719x_scb *scb, int result) list_del(&scb->list); dma_unmap_single(&wd->pdev->dev, scb->phys, - sizeof(struct wd719x_scb), DMA_TO_DEVICE); + sizeof(struct wd719x_scb), DMA_BIDIRECTIONAL); scsi_dma_unmap(cmd); dma_unmap_single(&wd->pdev->dev, cmd->SCp.dma_handle, SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE); @@ -236,6 +236,12 @@ static int wd719x_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *cmd) if (count_sg) { struct scatterlist *sg; + scb->phys = dma_map_single(&wd->pdev->dev, scb, sizeof(*scb), + DMA_BIDIRECTIONAL); + + if (dma_mapping_error(&wd->pdev->dev, scb->phys)) + goto out_unmap_scsi_cmd; + scb->data_length = cpu_to_le32(count_sg * sizeof(struct wd719x_sglist)); scb->data_p = cpu_to_le32(scb->phys + @@ -246,11 +252,6 @@ static int wd719x_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *cmd) scb->sg_list[i].length = cpu_to_le32(sg_dma_len(sg)); } scb->SCB_options |= WD719X_SCB_FLAGS_DO_SCATTER_GATHER; - - scb->phys = dma_map_single(&wd->pdev->dev, scb, sizeof(*scb), - DMA_TO_DEVICE); - if (dma_mapping_error(&wd->pdev->dev, scb->phys)) - goto out_unmap_scsi_cmd; } else { /* zero length */ scb->data_length = 0; scb->data_p = 0; -- Ondrej Zary
Re: dma related cleanups for wd719x
On Thursday 18 October 2018 15:01:14 Christoph Hellwig wrote: > Hi Ondrej, > > can you look over this series, which cleans up a few dma-related > bits in the wd719x driver? > Looks nice but does not work. The first patch works, but the 2nd one causes hang on modprobe: [ 408.350359] wd719x :00:0c.0: RISC initialized with firmware version 03.10 [ 408.949225] wd719x :00:0c.0: WD7193 at I/O 0xe800, IRQ 5, SCSI ID 7 [ 408.954450] scsi host2: Western Digital 719x [ 409.263961] wd719x :00:0c.0: invalid SCSI phase [ 409.297203] wd719x :00:0c.0: invalid SCSI phase [ 409.325714] scsi 2:0:1:0: Direct-Access QUANTUM LP240S GM240S01X 4.6 PQ: 0 ANSI: 2 CCS [ 409.346106] wd719x :00:0c.0: invalid SCSI phase [ 409.380731] wd719x :00:0c.0: invalid SCSI phase [ 410.748579] sd 2:0:1:0: Attached scsi generic sg1 type 0 -- Ondrej Zary
dma related cleanups for wd719x
Hi Ondrej, can you look over this series, which cleans up a few dma-related bits in the wd719x driver?