Linux Audio

Check our new training course

Linux BSP development engineering services

Need help to port Linux and bootloaders to your hardware?
Loading...
v4.17
  1// SPDX-License-Identifier: GPL-2.0
  2#include <linux/types.h>
  3#include <linux/mm.h>
  4#include <linux/blkdev.h>
  5#include <linux/interrupt.h>
  6#include <linux/init.h>
  7#include <linux/kernel.h>
  8#include <linux/module.h>
  9
 10#include <asm/page.h>
 11#include <asm/pgtable.h>
 12#include <asm/mvme147hw.h>
 13#include <asm/irq.h>
 14
 15#include "scsi.h"
 16#include <scsi/scsi_host.h>
 17#include "wd33c93.h"
 18#include "mvme147.h"
 19
 20static irqreturn_t mvme147_intr(int irq, void *data)
 21{
 22	struct Scsi_Host *instance = data;
 23
 24	if (irq == MVME147_IRQ_SCSI_PORT)
 25		wd33c93_intr(instance);
 26	else
 27		m147_pcc->dma_intr = 0x89;	/* Ack and enable ints */
 28	return IRQ_HANDLED;
 29}
 30
 31static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
 32{
 33	struct Scsi_Host *instance = cmd->device->host;
 34	struct WD33C93_hostdata *hdata = shost_priv(instance);
 35	unsigned char flags = 0x01;
 36	unsigned long addr = virt_to_bus(cmd->SCp.ptr);
 37
 38	/* setup dma direction */
 39	if (!dir_in)
 40		flags |= 0x04;
 41
 42	/* remember direction */
 43	hdata->dma_dir = dir_in;
 44
 45	if (dir_in) {
 46		/* invalidate any cache */
 47		cache_clear(addr, cmd->SCp.this_residual);
 48	} else {
 49		/* push any dirty cache */
 50		cache_push(addr, cmd->SCp.this_residual);
 51	}
 52
 53	/* start DMA */
 54	m147_pcc->dma_bcr = cmd->SCp.this_residual | (1 << 24);
 55	m147_pcc->dma_dadr = addr;
 56	m147_pcc->dma_cntrl = flags;
 57
 58	/* return success */
 59	return 0;
 60}
 61
 62static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
 63		     int status)
 64{
 65	m147_pcc->dma_cntrl = 0;
 66}
 67
 68static struct scsi_host_template mvme147_host_template = {
 69	.module			= THIS_MODULE,
 70	.proc_name		= "MVME147",
 71	.name			= "MVME147 built-in SCSI",
 72	.queuecommand		= wd33c93_queuecommand,
 73	.eh_abort_handler	= wd33c93_abort,
 74	.eh_host_reset_handler	= wd33c93_host_reset,
 75	.show_info		= wd33c93_show_info,
 76	.write_info		= wd33c93_write_info,
 77	.can_queue		= CAN_QUEUE,
 78	.this_id		= 7,
 79	.sg_tablesize		= SG_ALL,
 80	.cmd_per_lun		= CMD_PER_LUN,
 81	.use_clustering		= ENABLE_CLUSTERING
 82};
 83
 84static struct Scsi_Host *mvme147_shost;
 85
 86static int __init mvme147_init(void)
 87{
 88	wd33c93_regs regs;
 89	struct WD33C93_hostdata *hdata;
 90	int error = -ENOMEM;
 91
 92	if (!MACH_IS_MVME147)
 93		return 0;
 94
 95	mvme147_shost = scsi_host_alloc(&mvme147_host_template,
 96			sizeof(struct WD33C93_hostdata));
 97	if (!mvme147_shost)
 98		goto err_out;
 99	mvme147_shost->base = 0xfffe4000;
100	mvme147_shost->irq = MVME147_IRQ_SCSI_PORT;
101
102	regs.SASR = (volatile unsigned char *)0xfffe4000;
103	regs.SCMD = (volatile unsigned char *)0xfffe4001;
104
105	hdata = shost_priv(mvme147_shost);
106	hdata->no_sync = 0xff;
107	hdata->fast = 0;
108	hdata->dma_mode = CTRL_DMA;
109
110	wd33c93_init(mvme147_shost, regs, dma_setup, dma_stop, WD33C93_FS_8_10);
111
112	error = request_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr, 0,
113			"MVME147 SCSI PORT", mvme147_shost);
114	if (error)
115		goto err_unregister;
116	error = request_irq(MVME147_IRQ_SCSI_DMA, mvme147_intr, 0,
117			"MVME147 SCSI DMA", mvme147_shost);
118	if (error)
119		goto err_free_irq;
120#if 0	/* Disabled; causes problems booting */
121	m147_pcc->scsi_interrupt = 0x10;	/* Assert SCSI bus reset */
122	udelay(100);
123	m147_pcc->scsi_interrupt = 0x00;	/* Negate SCSI bus reset */
124	udelay(2000);
125	m147_pcc->scsi_interrupt = 0x40;	/* Clear bus reset interrupt */
126#endif
127	m147_pcc->scsi_interrupt = 0x09;	/* Enable interrupt */
128
129	m147_pcc->dma_cntrl = 0x00;	/* ensure DMA is stopped */
130	m147_pcc->dma_intr = 0x89;	/* Ack and enable ints */
131
132	error = scsi_add_host(mvme147_shost, NULL);
133	if (error)
134		goto err_free_irq;
135	scsi_scan_host(mvme147_shost);
136	return 0;
137
138err_free_irq:
139	free_irq(MVME147_IRQ_SCSI_PORT, mvme147_shost);
140err_unregister:
141	scsi_host_put(mvme147_shost);
142err_out:
143	return error;
144}
145
146static void __exit mvme147_exit(void)
147{
148	scsi_remove_host(mvme147_shost);
149
150	/* XXX Make sure DMA is stopped! */
151	free_irq(MVME147_IRQ_SCSI_PORT, mvme147_shost);
152	free_irq(MVME147_IRQ_SCSI_DMA, mvme147_shost);
153
154	scsi_host_put(mvme147_shost);
155}
156
157module_init(mvme147_init);
158module_exit(mvme147_exit);
v5.4
  1// SPDX-License-Identifier: GPL-2.0
  2#include <linux/types.h>
  3#include <linux/mm.h>
  4#include <linux/blkdev.h>
  5#include <linux/interrupt.h>
  6#include <linux/init.h>
  7#include <linux/kernel.h>
  8#include <linux/module.h>
  9
 10#include <asm/page.h>
 11#include <asm/pgtable.h>
 12#include <asm/mvme147hw.h>
 13#include <asm/irq.h>
 14
 15#include "scsi.h"
 16#include <scsi/scsi_host.h>
 17#include "wd33c93.h"
 18#include "mvme147.h"
 19
 20static irqreturn_t mvme147_intr(int irq, void *data)
 21{
 22	struct Scsi_Host *instance = data;
 23
 24	if (irq == MVME147_IRQ_SCSI_PORT)
 25		wd33c93_intr(instance);
 26	else
 27		m147_pcc->dma_intr = 0x89;	/* Ack and enable ints */
 28	return IRQ_HANDLED;
 29}
 30
 31static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
 32{
 33	struct Scsi_Host *instance = cmd->device->host;
 34	struct WD33C93_hostdata *hdata = shost_priv(instance);
 35	unsigned char flags = 0x01;
 36	unsigned long addr = virt_to_bus(cmd->SCp.ptr);
 37
 38	/* setup dma direction */
 39	if (!dir_in)
 40		flags |= 0x04;
 41
 42	/* remember direction */
 43	hdata->dma_dir = dir_in;
 44
 45	if (dir_in) {
 46		/* invalidate any cache */
 47		cache_clear(addr, cmd->SCp.this_residual);
 48	} else {
 49		/* push any dirty cache */
 50		cache_push(addr, cmd->SCp.this_residual);
 51	}
 52
 53	/* start DMA */
 54	m147_pcc->dma_bcr = cmd->SCp.this_residual | (1 << 24);
 55	m147_pcc->dma_dadr = addr;
 56	m147_pcc->dma_cntrl = flags;
 57
 58	/* return success */
 59	return 0;
 60}
 61
 62static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
 63		     int status)
 64{
 65	m147_pcc->dma_cntrl = 0;
 66}
 67
 68static struct scsi_host_template mvme147_host_template = {
 69	.module			= THIS_MODULE,
 70	.proc_name		= "MVME147",
 71	.name			= "MVME147 built-in SCSI",
 72	.queuecommand		= wd33c93_queuecommand,
 73	.eh_abort_handler	= wd33c93_abort,
 74	.eh_host_reset_handler	= wd33c93_host_reset,
 75	.show_info		= wd33c93_show_info,
 76	.write_info		= wd33c93_write_info,
 77	.can_queue		= CAN_QUEUE,
 78	.this_id		= 7,
 79	.sg_tablesize		= SG_ALL,
 80	.cmd_per_lun		= CMD_PER_LUN,
 
 81};
 82
 83static struct Scsi_Host *mvme147_shost;
 84
 85static int __init mvme147_init(void)
 86{
 87	wd33c93_regs regs;
 88	struct WD33C93_hostdata *hdata;
 89	int error = -ENOMEM;
 90
 91	if (!MACH_IS_MVME147)
 92		return 0;
 93
 94	mvme147_shost = scsi_host_alloc(&mvme147_host_template,
 95			sizeof(struct WD33C93_hostdata));
 96	if (!mvme147_shost)
 97		goto err_out;
 98	mvme147_shost->base = 0xfffe4000;
 99	mvme147_shost->irq = MVME147_IRQ_SCSI_PORT;
100
101	regs.SASR = (volatile unsigned char *)0xfffe4000;
102	regs.SCMD = (volatile unsigned char *)0xfffe4001;
103
104	hdata = shost_priv(mvme147_shost);
105	hdata->no_sync = 0xff;
106	hdata->fast = 0;
107	hdata->dma_mode = CTRL_DMA;
108
109	wd33c93_init(mvme147_shost, regs, dma_setup, dma_stop, WD33C93_FS_8_10);
110
111	error = request_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr, 0,
112			"MVME147 SCSI PORT", mvme147_shost);
113	if (error)
114		goto err_unregister;
115	error = request_irq(MVME147_IRQ_SCSI_DMA, mvme147_intr, 0,
116			"MVME147 SCSI DMA", mvme147_shost);
117	if (error)
118		goto err_free_irq;
119#if 0	/* Disabled; causes problems booting */
120	m147_pcc->scsi_interrupt = 0x10;	/* Assert SCSI bus reset */
121	udelay(100);
122	m147_pcc->scsi_interrupt = 0x00;	/* Negate SCSI bus reset */
123	udelay(2000);
124	m147_pcc->scsi_interrupt = 0x40;	/* Clear bus reset interrupt */
125#endif
126	m147_pcc->scsi_interrupt = 0x09;	/* Enable interrupt */
127
128	m147_pcc->dma_cntrl = 0x00;	/* ensure DMA is stopped */
129	m147_pcc->dma_intr = 0x89;	/* Ack and enable ints */
130
131	error = scsi_add_host(mvme147_shost, NULL);
132	if (error)
133		goto err_free_irq;
134	scsi_scan_host(mvme147_shost);
135	return 0;
136
137err_free_irq:
138	free_irq(MVME147_IRQ_SCSI_PORT, mvme147_shost);
139err_unregister:
140	scsi_host_put(mvme147_shost);
141err_out:
142	return error;
143}
144
145static void __exit mvme147_exit(void)
146{
147	scsi_remove_host(mvme147_shost);
148
149	/* XXX Make sure DMA is stopped! */
150	free_irq(MVME147_IRQ_SCSI_PORT, mvme147_shost);
151	free_irq(MVME147_IRQ_SCSI_DMA, mvme147_shost);
152
153	scsi_host_put(mvme147_shost);
154}
155
156module_init(mvme147_init);
157module_exit(mvme147_exit);