Commit 3f9295b6 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Martin K. Petersen
Browse files

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: default avatarChristoph Hellwig <hch@lst.de>
Tested-by: default avatarFinn Thain <fthain@telegraphics.com.au>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 44b1b4d2
Loading
Loading
Loading
Loading
+0 −28
Original line number Diff line number Diff line
@@ -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,
+44 −33
Original line number Diff line number Diff line
@@ -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);
	spriv->cur_residue = sg_dma_len(sg);
	spriv->cur_sg = sg;

	total = 0;
	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;
	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);
+1 −13
Original line number Diff line number Diff line
@@ -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 */
+0 −28
Original line number Diff line number Diff line
@@ -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,
+2 −37
Original line number Diff line number Diff line
@@ -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);
Loading