diff options
author | Christoph Hellwig <hch@lst.de> | 2018-10-13 09:26:27 +0200 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2018-10-15 23:00:38 -0400 |
commit | 3f9295b65ea44194252d60376036a3618d822152 (patch) | |
tree | c08aa217d9c95b10fec4d1b788360cfcfc360afb /drivers/scsi | |
parent | 44b1b4d24b2d65134efeccb3cc2341c61227f0f9 (diff) | |
download | lwn-3f9295b65ea44194252d60376036a3618d822152.tar.gz lwn-3f9295b65ea44194252d60376036a3618d822152.zip |
scsi: esp_scsi: move dma mapping into the core code
Except for the mac_esp driver, which uses PIO or pseudo DMA, all drivers
share the same dma mapping calls. Move the dma mapping into the core
code using the scsi_dma_map / scsi_dma_unmap helpers, with a special
identify mapping variant triggered off a new ESP_FLAG_NO_DMA_MAP flag
for mac_esp.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Tested-by: Finn Thain <fthain@telegraphics.com.au>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/am53c974.c | 28 | ||||
-rw-r--r-- | drivers/scsi/esp_scsi.c | 77 | ||||
-rw-r--r-- | drivers/scsi/esp_scsi.h | 14 | ||||
-rw-r--r-- | drivers/scsi/jazz_esp.c | 28 | ||||
-rw-r--r-- | drivers/scsi/mac_esp.c | 39 | ||||
-rw-r--r-- | drivers/scsi/sun3x_esp.c | 28 | ||||
-rw-r--r-- | drivers/scsi/sun_esp.c | 28 | ||||
-rw-r--r-- | drivers/scsi/zorro_esp.c | 48 |
8 files changed, 47 insertions, 243 deletions
diff --git a/drivers/scsi/am53c974.c b/drivers/scsi/am53c974.c index 75ac065ef49e..27c0a4a937d9 100644 --- a/drivers/scsi/am53c974.c +++ b/drivers/scsi/am53c974.c @@ -114,30 +114,6 @@ static void pci_esp_write32(struct esp *esp, u32 val, unsigned long reg) return iowrite32(val, esp->regs + (reg * 4UL)); } -static dma_addr_t pci_esp_map_single(struct esp *esp, void *buf, - size_t sz, int dir) -{ - return dma_map_single(esp->dev, buf, sz, dir); -} - -static int pci_esp_map_sg(struct esp *esp, struct scatterlist *sg, - int num_sg, int dir) -{ - return dma_map_sg(esp->dev, sg, num_sg, dir); -} - -static void pci_esp_unmap_single(struct esp *esp, dma_addr_t addr, - size_t sz, int dir) -{ - dma_unmap_single(esp->dev, addr, sz, dir); -} - -static void pci_esp_unmap_sg(struct esp *esp, struct scatterlist *sg, - int num_sg, int dir) -{ - dma_unmap_sg(esp->dev, sg, num_sg, dir); -} - static int pci_esp_irq_pending(struct esp *esp) { struct pci_esp_priv *pep = pci_esp_get_priv(esp); @@ -293,10 +269,6 @@ static u32 pci_esp_dma_length_limit(struct esp *esp, u32 dma_addr, u32 dma_len) static const struct esp_driver_ops pci_esp_ops = { .esp_write8 = pci_esp_write8, .esp_read8 = pci_esp_read8, - .map_single = pci_esp_map_single, - .map_sg = pci_esp_map_sg, - .unmap_single = pci_esp_unmap_single, - .unmap_sg = pci_esp_unmap_sg, .irq_pending = pci_esp_irq_pending, .reset_dma = pci_esp_reset_dma, .dma_drain = pci_esp_dma_drain, diff --git a/drivers/scsi/esp_scsi.c b/drivers/scsi/esp_scsi.c index 90604bff8dd2..c88d0cbe5d1f 100644 --- a/drivers/scsi/esp_scsi.c +++ b/drivers/scsi/esp_scsi.c @@ -369,19 +369,28 @@ static void esp_map_dma(struct esp *esp, struct scsi_cmnd *cmd) { struct esp_cmd_priv *spriv = ESP_CMD_PRIV(cmd); struct scatterlist *sg = scsi_sglist(cmd); - int dir = cmd->sc_data_direction; - int total, i; + int total = 0, i; - if (dir == DMA_NONE) + if (cmd->sc_data_direction == DMA_NONE) return; - spriv->u.num_sg = esp->ops->map_sg(esp, sg, scsi_sg_count(cmd), dir); + if (esp->flags & ESP_FLAG_NO_DMA_MAP) { + /* + * For pseudo DMA and PIO we need the virtual address instead of + * a dma address, so perform an identity mapping. + */ + spriv->u.num_sg = scsi_sg_count(cmd); + for (i = 0; i < spriv->u.num_sg; i++) { + sg[i].dma_address = (uintptr_t)sg_virt(&sg[i]); + total += sg_dma_len(&sg[i]); + } + } else { + spriv->u.num_sg = scsi_dma_map(cmd); + for (i = 0; i < spriv->u.num_sg; i++) + total += sg_dma_len(&sg[i]); + } spriv->cur_residue = sg_dma_len(sg); spriv->cur_sg = sg; - - total = 0; - for (i = 0; i < spriv->u.num_sg; i++) - total += sg_dma_len(&sg[i]); spriv->tot_residue = total; } @@ -441,13 +450,8 @@ static void esp_advance_dma(struct esp *esp, struct esp_cmd_entry *ent, static void esp_unmap_dma(struct esp *esp, struct scsi_cmnd *cmd) { - struct esp_cmd_priv *spriv = ESP_CMD_PRIV(cmd); - int dir = cmd->sc_data_direction; - - if (dir == DMA_NONE) - return; - - esp->ops->unmap_sg(esp, scsi_sglist(cmd), spriv->u.num_sg, dir); + if (!(esp->flags & ESP_FLAG_NO_DMA_MAP)) + scsi_dma_unmap(cmd); } static void esp_save_pointers(struct esp *esp, struct esp_cmd_entry *ent) @@ -624,6 +628,26 @@ static void esp_free_lun_tag(struct esp_cmd_entry *ent, } } +static void esp_map_sense(struct esp *esp, struct esp_cmd_entry *ent) +{ + ent->sense_ptr = ent->cmd->sense_buffer; + if (esp->flags & ESP_FLAG_NO_DMA_MAP) { + ent->sense_dma = (uintptr_t)ent->sense_ptr; + return; + } + + ent->sense_dma = dma_map_single(esp->dev, ent->sense_ptr, + SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE); +} + +static void esp_unmap_sense(struct esp *esp, struct esp_cmd_entry *ent) +{ + if (!(esp->flags & ESP_FLAG_NO_DMA_MAP)) + dma_unmap_single(esp->dev, ent->sense_dma, + SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE); + ent->sense_ptr = NULL; +} + /* When a contingent allegiance conditon is created, we force feed a * REQUEST_SENSE command to the device to fetch the sense data. I * tried many other schemes, relying on the scsi error handling layer @@ -645,12 +669,7 @@ static void esp_autosense(struct esp *esp, struct esp_cmd_entry *ent) if (!ent->sense_ptr) { esp_log_autosense("Doing auto-sense for tgt[%d] lun[%d]\n", tgt, lun); - - ent->sense_ptr = cmd->sense_buffer; - ent->sense_dma = esp->ops->map_single(esp, - ent->sense_ptr, - SCSI_SENSE_BUFFERSIZE, - DMA_FROM_DEVICE); + esp_map_sense(esp, ent); } ent->saved_sense_ptr = ent->sense_ptr; @@ -902,9 +921,7 @@ static void esp_cmd_is_done(struct esp *esp, struct esp_cmd_entry *ent, } if (ent->flags & ESP_CMD_FLAG_AUTOSENSE) { - esp->ops->unmap_single(esp, ent->sense_dma, - SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE); - ent->sense_ptr = NULL; + esp_unmap_sense(esp, ent); /* Restore the message/status bytes to what we actually * saw originally. Also, report that we are providing @@ -1256,10 +1273,7 @@ static int esp_finish_select(struct esp *esp) esp->cmd_bytes_ptr = NULL; esp->cmd_bytes_left = 0; } else { - esp->ops->unmap_single(esp, ent->sense_dma, - SCSI_SENSE_BUFFERSIZE, - DMA_FROM_DEVICE); - ent->sense_ptr = NULL; + esp_unmap_sense(esp, ent); } /* Now that the state is unwound properly, put back onto @@ -2039,11 +2053,8 @@ static void esp_reset_cleanup_one(struct esp *esp, struct esp_cmd_entry *ent) esp_free_lun_tag(ent, cmd->device->hostdata); cmd->result = DID_RESET << 16; - if (ent->flags & ESP_CMD_FLAG_AUTOSENSE) { - esp->ops->unmap_single(esp, ent->sense_dma, - SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE); - ent->sense_ptr = NULL; - } + if (ent->flags & ESP_CMD_FLAG_AUTOSENSE) + esp_unmap_sense(esp, ent); cmd->scsi_done(cmd); list_del(&ent->list); diff --git a/drivers/scsi/esp_scsi.h b/drivers/scsi/esp_scsi.h index b27cf5e2b4b6..4ce2b8dc148b 100644 --- a/drivers/scsi/esp_scsi.h +++ b/drivers/scsi/esp_scsi.h @@ -363,19 +363,6 @@ struct esp_driver_ops { void (*esp_write8)(struct esp *esp, u8 val, unsigned long reg); u8 (*esp_read8)(struct esp *esp, unsigned long reg); - /* Map and unmap DMA memory. Eventually the driver will be - * converted to the generic DMA API as soon as SBUS is able to - * cope with that. At such time we can remove this. - */ - dma_addr_t (*map_single)(struct esp *esp, void *buf, - size_t sz, int dir); - int (*map_sg)(struct esp *esp, struct scatterlist *sg, - int num_sg, int dir); - void (*unmap_single)(struct esp *esp, dma_addr_t addr, - size_t sz, int dir); - void (*unmap_sg)(struct esp *esp, struct scatterlist *sg, - int num_sg, int dir); - /* Return non-zero if there is an IRQ pending. Usually this * status bit lives in the DMA controller sitting in front of * the ESP. This has to be accurate or else the ESP interrupt @@ -495,6 +482,7 @@ struct esp { #define ESP_FLAG_QUICKIRQ_CHECK 0x00000010 #define ESP_FLAG_DISABLE_SYNC 0x00000020 #define ESP_FLAG_USE_FIFO 0x00000040 +#define ESP_FLAG_NO_DMA_MAP 0x00000080 u8 select_state; #define ESP_SELECT_NONE 0x00 /* Not selecting */ diff --git a/drivers/scsi/jazz_esp.c b/drivers/scsi/jazz_esp.c index 8f4f5c28b0dd..1ad28262b00a 100644 --- a/drivers/scsi/jazz_esp.c +++ b/drivers/scsi/jazz_esp.c @@ -38,30 +38,6 @@ static u8 jazz_esp_read8(struct esp *esp, unsigned long reg) return *(volatile u8 *)(esp->regs + reg); } -static dma_addr_t jazz_esp_map_single(struct esp *esp, void *buf, - size_t sz, int dir) -{ - return dma_map_single(esp->dev, buf, sz, dir); -} - -static int jazz_esp_map_sg(struct esp *esp, struct scatterlist *sg, - int num_sg, int dir) -{ - return dma_map_sg(esp->dev, sg, num_sg, dir); -} - -static void jazz_esp_unmap_single(struct esp *esp, dma_addr_t addr, - size_t sz, int dir) -{ - dma_unmap_single(esp->dev, addr, sz, dir); -} - -static void jazz_esp_unmap_sg(struct esp *esp, struct scatterlist *sg, - int num_sg, int dir) -{ - dma_unmap_sg(esp->dev, sg, num_sg, dir); -} - static int jazz_esp_irq_pending(struct esp *esp) { if (jazz_esp_read8(esp, ESP_STATUS) & ESP_STAT_INTR) @@ -117,10 +93,6 @@ static int jazz_esp_dma_error(struct esp *esp) static const struct esp_driver_ops jazz_esp_ops = { .esp_write8 = jazz_esp_write8, .esp_read8 = jazz_esp_read8, - .map_single = jazz_esp_map_single, - .map_sg = jazz_esp_map_sg, - .unmap_single = jazz_esp_unmap_single, - .unmap_sg = jazz_esp_unmap_sg, .irq_pending = jazz_esp_irq_pending, .reset_dma = jazz_esp_reset_dma, .dma_drain = jazz_esp_dma_drain, diff --git a/drivers/scsi/mac_esp.c b/drivers/scsi/mac_esp.c index 9299ff929f7f..2769df5acc07 100644 --- a/drivers/scsi/mac_esp.c +++ b/drivers/scsi/mac_esp.c @@ -70,38 +70,6 @@ static inline u8 mac_esp_read8(struct esp *esp, unsigned long reg) return nubus_readb(esp->regs + reg * 16); } -/* For pseudo DMA and PIO we need the virtual address - * so this address mapping is the identity mapping. - */ - -static dma_addr_t mac_esp_map_single(struct esp *esp, void *buf, - size_t sz, int dir) -{ - return (dma_addr_t)buf; -} - -static int mac_esp_map_sg(struct esp *esp, struct scatterlist *sg, - int num_sg, int dir) -{ - int i; - - for (i = 0; i < num_sg; i++) - sg[i].dma_address = (u32)sg_virt(&sg[i]); - return num_sg; -} - -static void mac_esp_unmap_single(struct esp *esp, dma_addr_t addr, - size_t sz, int dir) -{ - /* Nothing to do. */ -} - -static void mac_esp_unmap_sg(struct esp *esp, struct scatterlist *sg, - int num_sg, int dir) -{ - /* Nothing to do. */ -} - static void mac_esp_reset_dma(struct esp *esp) { /* Nothing to do. */ @@ -469,10 +437,6 @@ static irqreturn_t mac_scsi_esp_intr(int irq, void *dev_id) static struct esp_driver_ops mac_esp_ops = { .esp_write8 = mac_esp_write8, .esp_read8 = mac_esp_read8, - .map_single = mac_esp_map_single, - .map_sg = mac_esp_map_sg, - .unmap_single = mac_esp_unmap_single, - .unmap_sg = mac_esp_unmap_sg, .irq_pending = mac_esp_irq_pending, .dma_length_limit = mac_esp_dma_length_limit, .reset_dma = mac_esp_reset_dma, @@ -552,11 +516,12 @@ static int esp_mac_probe(struct platform_device *dev) } esp->ops = &mac_esp_ops; + esp->flags = ESP_FLAG_NO_DMA_MAP; if (mep->pdma_io == NULL) { printk(KERN_INFO PFX "using PIO for controller %d\n", dev->id); esp_write8(0, ESP_TCLOW); esp_write8(0, ESP_TCMED); - esp->flags = ESP_FLAG_DISABLE_SYNC; + esp->flags |= ESP_FLAG_DISABLE_SYNC; mac_esp_ops.send_dma_cmd = mac_esp_send_pio_cmd; } else { printk(KERN_INFO PFX "using PDMA for controller %d\n", dev->id); diff --git a/drivers/scsi/sun3x_esp.c b/drivers/scsi/sun3x_esp.c index e80c0a15fd8a..c9a55d0f076d 100644 --- a/drivers/scsi/sun3x_esp.c +++ b/drivers/scsi/sun3x_esp.c @@ -60,30 +60,6 @@ static u8 sun3x_esp_read8(struct esp *esp, unsigned long reg) return readb(esp->regs + (reg * 4UL)); } -static dma_addr_t sun3x_esp_map_single(struct esp *esp, void *buf, - size_t sz, int dir) -{ - return dma_map_single(esp->dev, buf, sz, dir); -} - -static int sun3x_esp_map_sg(struct esp *esp, struct scatterlist *sg, - int num_sg, int dir) -{ - return dma_map_sg(esp->dev, sg, num_sg, dir); -} - -static void sun3x_esp_unmap_single(struct esp *esp, dma_addr_t addr, - size_t sz, int dir) -{ - dma_unmap_single(esp->dev, addr, sz, dir); -} - -static void sun3x_esp_unmap_sg(struct esp *esp, struct scatterlist *sg, - int num_sg, int dir) -{ - dma_unmap_sg(esp->dev, sg, num_sg, dir); -} - static int sun3x_esp_irq_pending(struct esp *esp) { if (dma_read32(DMA_CSR) & (DMA_HNDL_INTR | DMA_HNDL_ERROR)) @@ -182,10 +158,6 @@ static int sun3x_esp_dma_error(struct esp *esp) static const struct esp_driver_ops sun3x_esp_ops = { .esp_write8 = sun3x_esp_write8, .esp_read8 = sun3x_esp_read8, - .map_single = sun3x_esp_map_single, - .map_sg = sun3x_esp_map_sg, - .unmap_single = sun3x_esp_unmap_single, - .unmap_sg = sun3x_esp_unmap_sg, .irq_pending = sun3x_esp_irq_pending, .reset_dma = sun3x_esp_reset_dma, .dma_drain = sun3x_esp_dma_drain, diff --git a/drivers/scsi/sun_esp.c b/drivers/scsi/sun_esp.c index 64e6d34e4364..a11efbcb7f8b 100644 --- a/drivers/scsi/sun_esp.c +++ b/drivers/scsi/sun_esp.c @@ -210,30 +210,6 @@ static u8 sbus_esp_read8(struct esp *esp, unsigned long reg) return sbus_readb(esp->regs + (reg * 4UL)); } -static dma_addr_t sbus_esp_map_single(struct esp *esp, void *buf, - size_t sz, int dir) -{ - return dma_map_single(esp->dev, buf, sz, dir); -} - -static int sbus_esp_map_sg(struct esp *esp, struct scatterlist *sg, - int num_sg, int dir) -{ - return dma_map_sg(esp->dev, sg, num_sg, dir); -} - -static void sbus_esp_unmap_single(struct esp *esp, dma_addr_t addr, - size_t sz, int dir) -{ - dma_unmap_single(esp->dev, addr, sz, dir); -} - -static void sbus_esp_unmap_sg(struct esp *esp, struct scatterlist *sg, - int num_sg, int dir) -{ - dma_unmap_sg(esp->dev, sg, num_sg, dir); -} - static int sbus_esp_irq_pending(struct esp *esp) { if (dma_read32(DMA_CSR) & (DMA_HNDL_INTR | DMA_HNDL_ERROR)) @@ -463,10 +439,6 @@ static int sbus_esp_dma_error(struct esp *esp) static const struct esp_driver_ops sbus_esp_ops = { .esp_write8 = sbus_esp_write8, .esp_read8 = sbus_esp_read8, - .map_single = sbus_esp_map_single, - .map_sg = sbus_esp_map_sg, - .unmap_single = sbus_esp_unmap_single, - .unmap_sg = sbus_esp_unmap_sg, .irq_pending = sbus_esp_irq_pending, .reset_dma = sbus_esp_reset_dma, .dma_drain = sbus_esp_dma_drain, diff --git a/drivers/scsi/zorro_esp.c b/drivers/scsi/zorro_esp.c index 274a873bd2d5..40d04affb5d3 100644 --- a/drivers/scsi/zorro_esp.c +++ b/drivers/scsi/zorro_esp.c @@ -182,30 +182,6 @@ static u8 zorro_esp_read8(struct esp *esp, unsigned long reg) return readb(esp->regs + (reg * 4UL)); } -static dma_addr_t zorro_esp_map_single(struct esp *esp, void *buf, - size_t sz, int dir) -{ - return dma_map_single(esp->dev, buf, sz, dir); -} - -static int zorro_esp_map_sg(struct esp *esp, struct scatterlist *sg, - int num_sg, int dir) -{ - return dma_map_sg(esp->dev, sg, num_sg, dir); -} - -static void zorro_esp_unmap_single(struct esp *esp, dma_addr_t addr, - size_t sz, int dir) -{ - dma_unmap_single(esp->dev, addr, sz, dir); -} - -static void zorro_esp_unmap_sg(struct esp *esp, struct scatterlist *sg, - int num_sg, int dir) -{ - dma_unmap_sg(esp->dev, sg, num_sg, dir); -} - static int zorro_esp_irq_pending(struct esp *esp) { /* check ESP status register; DMA has no status reg. */ @@ -739,10 +715,6 @@ static int zorro_esp_dma_error(struct esp *esp) static const struct esp_driver_ops blz1230_esp_ops = { .esp_write8 = zorro_esp_write8, .esp_read8 = zorro_esp_read8, - .map_single = zorro_esp_map_single, - .map_sg = zorro_esp_map_sg, - .unmap_single = zorro_esp_unmap_single, - .unmap_sg = zorro_esp_unmap_sg, .irq_pending = zorro_esp_irq_pending, .dma_length_limit = zorro_esp_dma_length_limit, .reset_dma = zorro_esp_reset_dma, @@ -755,10 +727,6 @@ static const struct esp_driver_ops blz1230_esp_ops = { static const struct esp_driver_ops blz1230II_esp_ops = { .esp_write8 = zorro_esp_write8, .esp_read8 = zorro_esp_read8, - .map_single = zorro_esp_map_single, - .map_sg = zorro_esp_map_sg, - .unmap_single = zorro_esp_unmap_single, - .unmap_sg = zorro_esp_unmap_sg, .irq_pending = zorro_esp_irq_pending, .dma_length_limit = zorro_esp_dma_length_limit, .reset_dma = zorro_esp_reset_dma, @@ -771,10 +739,6 @@ static const struct esp_driver_ops blz1230II_esp_ops = { static const struct esp_driver_ops blz2060_esp_ops = { .esp_write8 = zorro_esp_write8, .esp_read8 = zorro_esp_read8, - .map_single = zorro_esp_map_single, - .map_sg = zorro_esp_map_sg, - .unmap_single = zorro_esp_unmap_single, - .unmap_sg = zorro_esp_unmap_sg, .irq_pending = zorro_esp_irq_pending, .dma_length_limit = zorro_esp_dma_length_limit, .reset_dma = zorro_esp_reset_dma, @@ -787,10 +751,6 @@ static const struct esp_driver_ops blz2060_esp_ops = { static const struct esp_driver_ops cyber_esp_ops = { .esp_write8 = zorro_esp_write8, .esp_read8 = zorro_esp_read8, - .map_single = zorro_esp_map_single, - .map_sg = zorro_esp_map_sg, - .unmap_single = zorro_esp_unmap_single, - .unmap_sg = zorro_esp_unmap_sg, .irq_pending = cyber_esp_irq_pending, .dma_length_limit = zorro_esp_dma_length_limit, .reset_dma = zorro_esp_reset_dma, @@ -803,10 +763,6 @@ static const struct esp_driver_ops cyber_esp_ops = { static const struct esp_driver_ops cyberII_esp_ops = { .esp_write8 = zorro_esp_write8, .esp_read8 = zorro_esp_read8, - .map_single = zorro_esp_map_single, - .map_sg = zorro_esp_map_sg, - .unmap_single = zorro_esp_unmap_single, - .unmap_sg = zorro_esp_unmap_sg, .irq_pending = zorro_esp_irq_pending, .dma_length_limit = zorro_esp_dma_length_limit, .reset_dma = zorro_esp_reset_dma, @@ -819,10 +775,6 @@ static const struct esp_driver_ops cyberII_esp_ops = { static const struct esp_driver_ops fastlane_esp_ops = { .esp_write8 = zorro_esp_write8, .esp_read8 = zorro_esp_read8, - .map_single = zorro_esp_map_single, - .map_sg = zorro_esp_map_sg, - .unmap_single = zorro_esp_unmap_single, - .unmap_sg = zorro_esp_unmap_sg, .irq_pending = fastlane_esp_irq_pending, .dma_length_limit = zorro_esp_dma_length_limit, .reset_dma = zorro_esp_reset_dma, |