xref: /openbmc/linux/drivers/scsi/sun3x_esp.c (revision ecc1241e80a0bdc854b1602a44be3ad106753d4f)
10bb67f18SThomas Bogendoerfer /* sun3x_esp.c: ESP front-end for Sun3x systems.
21da177e4SLinus Torvalds  *
30bb67f18SThomas Bogendoerfer  * Copyright (C) 2007,2008 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
41da177e4SLinus Torvalds  */
51da177e4SLinus Torvalds 
61da177e4SLinus Torvalds #include <linux/kernel.h>
71da177e4SLinus Torvalds #include <linux/types.h>
81da177e4SLinus Torvalds #include <linux/delay.h>
90bb67f18SThomas Bogendoerfer #include <linux/module.h>
100bb67f18SThomas Bogendoerfer #include <linux/init.h>
110bb67f18SThomas Bogendoerfer #include <linux/platform_device.h>
120bb67f18SThomas Bogendoerfer #include <linux/dma-mapping.h>
131da177e4SLinus Torvalds #include <linux/interrupt.h>
141da177e4SLinus Torvalds 
151da177e4SLinus Torvalds #include <asm/sun3x.h>
160bb67f18SThomas Bogendoerfer #include <asm/io.h>
170bb67f18SThomas Bogendoerfer #include <asm/dma.h>
181da177e4SLinus Torvalds #include <asm/dvma.h>
191da177e4SLinus Torvalds 
200bb67f18SThomas Bogendoerfer /* DMA controller reg offsets */
210bb67f18SThomas Bogendoerfer #define DMA_CSR		0x00UL	/* rw  DMA control/status register    0x00   */
220bb67f18SThomas Bogendoerfer #define DMA_ADDR        0x04UL	/* rw  DMA transfer address register  0x04   */
230bb67f18SThomas Bogendoerfer #define DMA_COUNT       0x08UL	/* rw  DMA transfer count register    0x08   */
240bb67f18SThomas Bogendoerfer #define DMA_TEST        0x0cUL	/* rw  DMA test/debug register        0x0c   */
251da177e4SLinus Torvalds 
260bb67f18SThomas Bogendoerfer #include <scsi/scsi_host.h>
270bb67f18SThomas Bogendoerfer 
280bb67f18SThomas Bogendoerfer #include "esp_scsi.h"
290bb67f18SThomas Bogendoerfer 
300bb67f18SThomas Bogendoerfer #define DRV_MODULE_NAME		"sun3x_esp"
310bb67f18SThomas Bogendoerfer #define PFX DRV_MODULE_NAME	": "
320bb67f18SThomas Bogendoerfer #define DRV_VERSION		"1.000"
330bb67f18SThomas Bogendoerfer #define DRV_MODULE_RELDATE	"Nov 1, 2007"
340bb67f18SThomas Bogendoerfer 
350bb67f18SThomas Bogendoerfer /*
360bb67f18SThomas Bogendoerfer  * m68k always assumes readl/writel operate on little endian
370bb67f18SThomas Bogendoerfer  * mmio space; this is wrong at least for Sun3x, so we
380bb67f18SThomas Bogendoerfer  * need to workaround this until a proper way is found
391da177e4SLinus Torvalds  */
400bb67f18SThomas Bogendoerfer #if 0
410bb67f18SThomas Bogendoerfer #define dma_read32(REG) \
420bb67f18SThomas Bogendoerfer 	readl(esp->dma_regs + (REG))
430bb67f18SThomas Bogendoerfer #define dma_write32(VAL, REG) \
440bb67f18SThomas Bogendoerfer 	writel((VAL), esp->dma_regs + (REG))
450bb67f18SThomas Bogendoerfer #else
460bb67f18SThomas Bogendoerfer #define dma_read32(REG) \
470bb67f18SThomas Bogendoerfer 	*(volatile u32 *)(esp->dma_regs + (REG))
480bb67f18SThomas Bogendoerfer #define dma_write32(VAL, REG) \
490bb67f18SThomas Bogendoerfer 	do { *(volatile u32 *)(esp->dma_regs + (REG)) = (VAL); } while (0)
500bb67f18SThomas Bogendoerfer #endif
510bb67f18SThomas Bogendoerfer 
520bb67f18SThomas Bogendoerfer static void sun3x_esp_write8(struct esp *esp, u8 val, unsigned long reg)
531da177e4SLinus Torvalds {
540bb67f18SThomas Bogendoerfer 	writeb(val, esp->regs + (reg * 4UL));
550bb67f18SThomas Bogendoerfer }
561da177e4SLinus Torvalds 
570bb67f18SThomas Bogendoerfer static u8 sun3x_esp_read8(struct esp *esp, unsigned long reg)
580bb67f18SThomas Bogendoerfer {
590bb67f18SThomas Bogendoerfer 	return readb(esp->regs + (reg * 4UL));
600bb67f18SThomas Bogendoerfer }
611da177e4SLinus Torvalds 
620bb67f18SThomas Bogendoerfer static dma_addr_t sun3x_esp_map_single(struct esp *esp, void *buf,
630bb67f18SThomas Bogendoerfer 				      size_t sz, int dir)
640bb67f18SThomas Bogendoerfer {
650bb67f18SThomas Bogendoerfer 	return dma_map_single(esp->dev, buf, sz, dir);
660bb67f18SThomas Bogendoerfer }
671da177e4SLinus Torvalds 
680bb67f18SThomas Bogendoerfer static int sun3x_esp_map_sg(struct esp *esp, struct scatterlist *sg,
690bb67f18SThomas Bogendoerfer 				  int num_sg, int dir)
700bb67f18SThomas Bogendoerfer {
710bb67f18SThomas Bogendoerfer 	return dma_map_sg(esp->dev, sg, num_sg, dir);
720bb67f18SThomas Bogendoerfer }
731da177e4SLinus Torvalds 
740bb67f18SThomas Bogendoerfer static void sun3x_esp_unmap_single(struct esp *esp, dma_addr_t addr,
750bb67f18SThomas Bogendoerfer 				  size_t sz, int dir)
760bb67f18SThomas Bogendoerfer {
770bb67f18SThomas Bogendoerfer 	dma_unmap_single(esp->dev, addr, sz, dir);
780bb67f18SThomas Bogendoerfer }
791da177e4SLinus Torvalds 
800bb67f18SThomas Bogendoerfer static void sun3x_esp_unmap_sg(struct esp *esp, struct scatterlist *sg,
810bb67f18SThomas Bogendoerfer 			      int num_sg, int dir)
820bb67f18SThomas Bogendoerfer {
830bb67f18SThomas Bogendoerfer 	dma_unmap_sg(esp->dev, sg, num_sg, dir);
840bb67f18SThomas Bogendoerfer }
851da177e4SLinus Torvalds 
860bb67f18SThomas Bogendoerfer static int sun3x_esp_irq_pending(struct esp *esp)
870bb67f18SThomas Bogendoerfer {
880bb67f18SThomas Bogendoerfer 	if (dma_read32(DMA_CSR) & (DMA_HNDL_INTR | DMA_HNDL_ERROR))
890bb67f18SThomas Bogendoerfer 		return 1;
901da177e4SLinus Torvalds 	return 0;
911da177e4SLinus Torvalds }
921da177e4SLinus Torvalds 
930bb67f18SThomas Bogendoerfer static void sun3x_esp_reset_dma(struct esp *esp)
940bb67f18SThomas Bogendoerfer {
950bb67f18SThomas Bogendoerfer 	u32 val;
961da177e4SLinus Torvalds 
970bb67f18SThomas Bogendoerfer 	val = dma_read32(DMA_CSR);
980bb67f18SThomas Bogendoerfer 	dma_write32(val | DMA_RST_SCSI, DMA_CSR);
990bb67f18SThomas Bogendoerfer 	dma_write32(val & ~DMA_RST_SCSI, DMA_CSR);
1001da177e4SLinus Torvalds 
1010bb67f18SThomas Bogendoerfer 	/* Enable interrupts.  */
1020bb67f18SThomas Bogendoerfer 	val = dma_read32(DMA_CSR);
1030bb67f18SThomas Bogendoerfer 	dma_write32(val | DMA_INT_ENAB, DMA_CSR);
1041da177e4SLinus Torvalds }
1051da177e4SLinus Torvalds 
1060bb67f18SThomas Bogendoerfer static void sun3x_esp_dma_drain(struct esp *esp)
1071da177e4SLinus Torvalds {
1080bb67f18SThomas Bogendoerfer 	u32 csr;
1090bb67f18SThomas Bogendoerfer 	int lim;
1101da177e4SLinus Torvalds 
1110bb67f18SThomas Bogendoerfer 	csr = dma_read32(DMA_CSR);
1120bb67f18SThomas Bogendoerfer 	if (!(csr & DMA_FIFO_ISDRAIN))
1130bb67f18SThomas Bogendoerfer 		return;
1141da177e4SLinus Torvalds 
1150bb67f18SThomas Bogendoerfer 	dma_write32(csr | DMA_FIFO_STDRAIN, DMA_CSR);
1160bb67f18SThomas Bogendoerfer 
1170bb67f18SThomas Bogendoerfer 	lim = 1000;
1180bb67f18SThomas Bogendoerfer 	while (dma_read32(DMA_CSR) & DMA_FIFO_ISDRAIN) {
1190bb67f18SThomas Bogendoerfer 		if (--lim == 0) {
1200bb67f18SThomas Bogendoerfer 			printk(KERN_ALERT PFX "esp%d: DMA will not drain!\n",
1210bb67f18SThomas Bogendoerfer 			       esp->host->unique_id);
1220bb67f18SThomas Bogendoerfer 			break;
1230bb67f18SThomas Bogendoerfer 		}
1241da177e4SLinus Torvalds 		udelay(1);
1250bb67f18SThomas Bogendoerfer 	}
1261da177e4SLinus Torvalds }
1271da177e4SLinus Torvalds 
1280bb67f18SThomas Bogendoerfer static void sun3x_esp_dma_invalidate(struct esp *esp)
1290bb67f18SThomas Bogendoerfer {
1300bb67f18SThomas Bogendoerfer 	u32 val;
1310bb67f18SThomas Bogendoerfer 	int lim;
1321da177e4SLinus Torvalds 
1330bb67f18SThomas Bogendoerfer 	lim = 1000;
1340bb67f18SThomas Bogendoerfer 	while ((val = dma_read32(DMA_CSR)) & DMA_PEND_READ) {
1350bb67f18SThomas Bogendoerfer 		if (--lim == 0) {
1360bb67f18SThomas Bogendoerfer 			printk(KERN_ALERT PFX "esp%d: DMA will not "
1370bb67f18SThomas Bogendoerfer 			       "invalidate!\n", esp->host->unique_id);
1380bb67f18SThomas Bogendoerfer 			break;
1390bb67f18SThomas Bogendoerfer 		}
1401da177e4SLinus Torvalds 		udelay(1);
1411da177e4SLinus Torvalds 	}
1421da177e4SLinus Torvalds 
1430bb67f18SThomas Bogendoerfer 	val &= ~(DMA_ENABLE | DMA_ST_WRITE | DMA_BCNT_ENAB);
1440bb67f18SThomas Bogendoerfer 	val |= DMA_FIFO_INV;
1450bb67f18SThomas Bogendoerfer 	dma_write32(val, DMA_CSR);
1460bb67f18SThomas Bogendoerfer 	val &= ~DMA_FIFO_INV;
1470bb67f18SThomas Bogendoerfer 	dma_write32(val, DMA_CSR);
1481da177e4SLinus Torvalds }
1491da177e4SLinus Torvalds 
1500bb67f18SThomas Bogendoerfer static void sun3x_esp_send_dma_cmd(struct esp *esp, u32 addr, u32 esp_count,
1510bb67f18SThomas Bogendoerfer 				  u32 dma_count, int write, u8 cmd)
1521da177e4SLinus Torvalds {
1530bb67f18SThomas Bogendoerfer 	u32 csr;
1541da177e4SLinus Torvalds 
1550bb67f18SThomas Bogendoerfer 	BUG_ON(!(cmd & ESP_CMD_DMA));
1561da177e4SLinus Torvalds 
1570bb67f18SThomas Bogendoerfer 	sun3x_esp_write8(esp, (esp_count >> 0) & 0xff, ESP_TCLOW);
1580bb67f18SThomas Bogendoerfer 	sun3x_esp_write8(esp, (esp_count >> 8) & 0xff, ESP_TCMED);
1590bb67f18SThomas Bogendoerfer 	csr = dma_read32(DMA_CSR);
1600bb67f18SThomas Bogendoerfer 	csr |= DMA_ENABLE;
1611da177e4SLinus Torvalds 	if (write)
1620bb67f18SThomas Bogendoerfer 		csr |= DMA_ST_WRITE;
1630bb67f18SThomas Bogendoerfer 	else
1640bb67f18SThomas Bogendoerfer 		csr &= ~DMA_ST_WRITE;
1650bb67f18SThomas Bogendoerfer 	dma_write32(csr, DMA_CSR);
1660bb67f18SThomas Bogendoerfer 	dma_write32(addr, DMA_ADDR);
1670bb67f18SThomas Bogendoerfer 
1680bb67f18SThomas Bogendoerfer 	scsi_esp_cmd(esp, cmd);
1691da177e4SLinus Torvalds }
1701da177e4SLinus Torvalds 
1710bb67f18SThomas Bogendoerfer static int sun3x_esp_dma_error(struct esp *esp)
1721da177e4SLinus Torvalds {
1730bb67f18SThomas Bogendoerfer 	u32 csr = dma_read32(DMA_CSR);
1741da177e4SLinus Torvalds 
1750bb67f18SThomas Bogendoerfer 	if (csr & DMA_HNDL_ERROR)
1761da177e4SLinus Torvalds 		return 1;
1771da177e4SLinus Torvalds 
1780bb67f18SThomas Bogendoerfer 	return 0;
1791da177e4SLinus Torvalds }
1801da177e4SLinus Torvalds 
1810bb67f18SThomas Bogendoerfer static const struct esp_driver_ops sun3x_esp_ops = {
1820bb67f18SThomas Bogendoerfer 	.esp_write8	=	sun3x_esp_write8,
1830bb67f18SThomas Bogendoerfer 	.esp_read8	=	sun3x_esp_read8,
1840bb67f18SThomas Bogendoerfer 	.map_single	=	sun3x_esp_map_single,
1850bb67f18SThomas Bogendoerfer 	.map_sg		=	sun3x_esp_map_sg,
1860bb67f18SThomas Bogendoerfer 	.unmap_single	=	sun3x_esp_unmap_single,
1870bb67f18SThomas Bogendoerfer 	.unmap_sg	=	sun3x_esp_unmap_sg,
1880bb67f18SThomas Bogendoerfer 	.irq_pending	=	sun3x_esp_irq_pending,
1890bb67f18SThomas Bogendoerfer 	.reset_dma	=	sun3x_esp_reset_dma,
1900bb67f18SThomas Bogendoerfer 	.dma_drain	=	sun3x_esp_dma_drain,
1910bb67f18SThomas Bogendoerfer 	.dma_invalidate	=	sun3x_esp_dma_invalidate,
1920bb67f18SThomas Bogendoerfer 	.send_dma_cmd	=	sun3x_esp_send_dma_cmd,
1930bb67f18SThomas Bogendoerfer 	.dma_error	=	sun3x_esp_dma_error,
1941da177e4SLinus Torvalds };
1951da177e4SLinus Torvalds 
1960bb67f18SThomas Bogendoerfer static int __devinit esp_sun3x_probe(struct platform_device *dev)
1970bb67f18SThomas Bogendoerfer {
1980bb67f18SThomas Bogendoerfer 	struct scsi_host_template *tpnt = &scsi_esp_template;
1990bb67f18SThomas Bogendoerfer 	struct Scsi_Host *host;
2000bb67f18SThomas Bogendoerfer 	struct esp *esp;
2010bb67f18SThomas Bogendoerfer 	struct resource *res;
2020bb67f18SThomas Bogendoerfer 	int err = -ENOMEM;
2031da177e4SLinus Torvalds 
2040bb67f18SThomas Bogendoerfer 	host = scsi_host_alloc(tpnt, sizeof(struct esp));
2050bb67f18SThomas Bogendoerfer 	if (!host)
2060bb67f18SThomas Bogendoerfer 		goto fail;
2071da177e4SLinus Torvalds 
2080bb67f18SThomas Bogendoerfer 	host->max_id = 8;
2090bb67f18SThomas Bogendoerfer 	esp = shost_priv(host);
2100bb67f18SThomas Bogendoerfer 
2110bb67f18SThomas Bogendoerfer 	esp->host = host;
2120bb67f18SThomas Bogendoerfer 	esp->dev = dev;
2130bb67f18SThomas Bogendoerfer 	esp->ops = &sun3x_esp_ops;
2140bb67f18SThomas Bogendoerfer 
2150bb67f18SThomas Bogendoerfer 	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
2160bb67f18SThomas Bogendoerfer 	if (!res && !res->start)
2170bb67f18SThomas Bogendoerfer 		goto fail_unlink;
2180bb67f18SThomas Bogendoerfer 
2190bb67f18SThomas Bogendoerfer 	esp->regs = ioremap_nocache(res->start, 0x20);
2200bb67f18SThomas Bogendoerfer 	if (!esp->regs)
2210bb67f18SThomas Bogendoerfer 		goto fail_unmap_regs;
2220bb67f18SThomas Bogendoerfer 
2230bb67f18SThomas Bogendoerfer 	res = platform_get_resource(dev, IORESOURCE_MEM, 1);
2240bb67f18SThomas Bogendoerfer 	if (!res && !res->start)
2250bb67f18SThomas Bogendoerfer 		goto fail_unmap_regs;
2260bb67f18SThomas Bogendoerfer 
2270bb67f18SThomas Bogendoerfer 	esp->dma_regs = ioremap_nocache(res->start, 0x10);
2280bb67f18SThomas Bogendoerfer 
2290bb67f18SThomas Bogendoerfer 	esp->command_block = dma_alloc_coherent(esp->dev, 16,
2300bb67f18SThomas Bogendoerfer 						&esp->command_block_dma,
2310bb67f18SThomas Bogendoerfer 						GFP_KERNEL);
2320bb67f18SThomas Bogendoerfer 	if (!esp->command_block)
2330bb67f18SThomas Bogendoerfer 		goto fail_unmap_regs_dma;
2340bb67f18SThomas Bogendoerfer 
2350bb67f18SThomas Bogendoerfer 	host->irq = platform_get_irq(dev, 0);
2360bb67f18SThomas Bogendoerfer 	err = request_irq(host->irq, scsi_esp_intr, IRQF_SHARED,
2370bb67f18SThomas Bogendoerfer 			  "SUN3X ESP", esp);
2380bb67f18SThomas Bogendoerfer 	if (err < 0)
2390bb67f18SThomas Bogendoerfer 		goto fail_unmap_command_block;
2400bb67f18SThomas Bogendoerfer 
2410bb67f18SThomas Bogendoerfer 	esp->scsi_id = 7;
2420bb67f18SThomas Bogendoerfer 	esp->host->this_id = esp->scsi_id;
2430bb67f18SThomas Bogendoerfer 	esp->scsi_id_mask = (1 << esp->scsi_id);
2440bb67f18SThomas Bogendoerfer 	esp->cfreq = 20000000;
2450bb67f18SThomas Bogendoerfer 
2460bb67f18SThomas Bogendoerfer 	dev_set_drvdata(&dev->dev, esp);
2470bb67f18SThomas Bogendoerfer 
2480bb67f18SThomas Bogendoerfer 	err = scsi_esp_register(esp, &dev->dev);
2490bb67f18SThomas Bogendoerfer 	if (err)
2500bb67f18SThomas Bogendoerfer 		goto fail_free_irq;
2510bb67f18SThomas Bogendoerfer 
2520bb67f18SThomas Bogendoerfer 	return 0;
2530bb67f18SThomas Bogendoerfer 
2540bb67f18SThomas Bogendoerfer fail_free_irq:
2550bb67f18SThomas Bogendoerfer 	free_irq(host->irq, esp);
2560bb67f18SThomas Bogendoerfer fail_unmap_command_block:
2570bb67f18SThomas Bogendoerfer 	dma_free_coherent(esp->dev, 16,
2580bb67f18SThomas Bogendoerfer 			  esp->command_block,
2590bb67f18SThomas Bogendoerfer 			  esp->command_block_dma);
2600bb67f18SThomas Bogendoerfer fail_unmap_regs_dma:
2610bb67f18SThomas Bogendoerfer 	iounmap(esp->dma_regs);
2620bb67f18SThomas Bogendoerfer fail_unmap_regs:
2630bb67f18SThomas Bogendoerfer 	iounmap(esp->regs);
2640bb67f18SThomas Bogendoerfer fail_unlink:
2650bb67f18SThomas Bogendoerfer 	scsi_host_put(host);
2660bb67f18SThomas Bogendoerfer fail:
2670bb67f18SThomas Bogendoerfer 	return err;
2680bb67f18SThomas Bogendoerfer }
2690bb67f18SThomas Bogendoerfer 
2700bb67f18SThomas Bogendoerfer static int __devexit esp_sun3x_remove(struct platform_device *dev)
2710bb67f18SThomas Bogendoerfer {
2720bb67f18SThomas Bogendoerfer 	struct esp *esp = dev_get_drvdata(&dev->dev);
2730bb67f18SThomas Bogendoerfer 	unsigned int irq = esp->host->irq;
2740bb67f18SThomas Bogendoerfer 	u32 val;
2750bb67f18SThomas Bogendoerfer 
2760bb67f18SThomas Bogendoerfer 	scsi_esp_unregister(esp);
2770bb67f18SThomas Bogendoerfer 
2780bb67f18SThomas Bogendoerfer 	/* Disable interrupts.  */
2790bb67f18SThomas Bogendoerfer 	val = dma_read32(DMA_CSR);
2800bb67f18SThomas Bogendoerfer 	dma_write32(val & ~DMA_INT_ENAB, DMA_CSR);
2810bb67f18SThomas Bogendoerfer 
2820bb67f18SThomas Bogendoerfer 	free_irq(irq, esp);
2830bb67f18SThomas Bogendoerfer 	dma_free_coherent(esp->dev, 16,
2840bb67f18SThomas Bogendoerfer 			  esp->command_block,
2850bb67f18SThomas Bogendoerfer 			  esp->command_block_dma);
2860bb67f18SThomas Bogendoerfer 
2870bb67f18SThomas Bogendoerfer 	scsi_host_put(esp->host);
2880bb67f18SThomas Bogendoerfer 
2890bb67f18SThomas Bogendoerfer 	return 0;
2900bb67f18SThomas Bogendoerfer }
2910bb67f18SThomas Bogendoerfer 
2920bb67f18SThomas Bogendoerfer static struct platform_driver esp_sun3x_driver = {
2930bb67f18SThomas Bogendoerfer 	.probe          = esp_sun3x_probe,
2940bb67f18SThomas Bogendoerfer 	.remove         = __devexit_p(esp_sun3x_remove),
2950bb67f18SThomas Bogendoerfer 	.driver = {
2960bb67f18SThomas Bogendoerfer 		.name   = "sun3x_esp",
297*ecc1241eSKay Sievers 		.owner	= THIS_MODULE,
2980bb67f18SThomas Bogendoerfer 	},
2990bb67f18SThomas Bogendoerfer };
3000bb67f18SThomas Bogendoerfer 
3010bb67f18SThomas Bogendoerfer static int __init sun3x_esp_init(void)
3020bb67f18SThomas Bogendoerfer {
3030bb67f18SThomas Bogendoerfer 	return platform_driver_register(&esp_sun3x_driver);
3040bb67f18SThomas Bogendoerfer }
3050bb67f18SThomas Bogendoerfer 
3060bb67f18SThomas Bogendoerfer static void __exit sun3x_esp_exit(void)
3070bb67f18SThomas Bogendoerfer {
3080bb67f18SThomas Bogendoerfer 	platform_driver_unregister(&esp_sun3x_driver);
3090bb67f18SThomas Bogendoerfer }
3100bb67f18SThomas Bogendoerfer 
3110bb67f18SThomas Bogendoerfer MODULE_DESCRIPTION("Sun3x ESP SCSI driver");
3120bb67f18SThomas Bogendoerfer MODULE_AUTHOR("Thomas Bogendoerfer (tsbogend@alpha.franken.de)");
3131da177e4SLinus Torvalds MODULE_LICENSE("GPL");
3140bb67f18SThomas Bogendoerfer MODULE_VERSION(DRV_VERSION);
3150bb67f18SThomas Bogendoerfer 
3160bb67f18SThomas Bogendoerfer module_init(sun3x_esp_init);
3170bb67f18SThomas Bogendoerfer module_exit(sun3x_esp_exit);
318*ecc1241eSKay Sievers MODULE_ALIAS("platform:sun3x_esp");
319