Blame view

drivers/scsi/mvme147.c 3.95 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
  #include <linux/types.h>
  #include <linux/mm.h>
  #include <linux/blkdev.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4
5
6
7
8
9
10
11
12
13
14
  #include <linux/interrupt.h>
  
  #include <asm/page.h>
  #include <asm/pgtable.h>
  #include <asm/mvme147hw.h>
  #include <asm/irq.h>
  
  #include "scsi.h"
  #include <scsi/scsi_host.h>
  #include "wd33c93.h"
  #include "mvme147.h"
be4540db0   Geert Uytterhoeven   [SCSI] mvme147: R...
15
  #include <linux/stat.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
16

be4540db0   Geert Uytterhoeven   [SCSI] mvme147: R...
17

4616ac7e8   Geert Uytterhoeven   m68k/scsi: mvme14...
18
  static irqreturn_t mvme147_intr(int irq, void *data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
19
  {
4616ac7e8   Geert Uytterhoeven   m68k/scsi: mvme14...
20
  	struct Scsi_Host *instance = data;
be4540db0   Geert Uytterhoeven   [SCSI] mvme147: R...
21
  	if (irq == MVME147_IRQ_SCSI_PORT)
4616ac7e8   Geert Uytterhoeven   m68k/scsi: mvme14...
22
  		wd33c93_intr(instance);
be4540db0   Geert Uytterhoeven   [SCSI] mvme147: R...
23
24
25
  	else
  		m147_pcc->dma_intr = 0x89;	/* Ack and enable ints */
  	return IRQ_HANDLED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
26
  }
65396410a   Henrik Kretzschmar   [SCSI] wd33c93: S...
27
  static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
28
  {
4616ac7e8   Geert Uytterhoeven   m68k/scsi: mvme14...
29
30
  	struct Scsi_Host *instance = cmd->device->host;
  	struct WD33C93_hostdata *hdata = shost_priv(instance);
be4540db0   Geert Uytterhoeven   [SCSI] mvme147: R...
31
32
33
34
35
36
37
38
  	unsigned char flags = 0x01;
  	unsigned long addr = virt_to_bus(cmd->SCp.ptr);
  
  	/* setup dma direction */
  	if (!dir_in)
  		flags |= 0x04;
  
  	/* remember direction */
ce195662b   Geert Uytterhoeven   [SCSI] mvme147: U...
39
  	hdata->dma_dir = dir_in;
be4540db0   Geert Uytterhoeven   [SCSI] mvme147: R...
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
  
  	if (dir_in) {
  		/* invalidate any cache */
  		cache_clear(addr, cmd->SCp.this_residual);
  	} else {
  		/* push any dirty cache */
  		cache_push(addr, cmd->SCp.this_residual);
  	}
  
  	/* start DMA */
  	m147_pcc->dma_bcr = cmd->SCp.this_residual | (1 << 24);
  	m147_pcc->dma_dadr = addr;
  	m147_pcc->dma_cntrl = flags;
  
  	/* return success */
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
56
  }
65396410a   Henrik Kretzschmar   [SCSI] wd33c93: S...
57
  static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
be4540db0   Geert Uytterhoeven   [SCSI] mvme147: R...
58
  		     int status)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59
  {
be4540db0   Geert Uytterhoeven   [SCSI] mvme147: R...
60
  	m147_pcc->dma_cntrl = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
61
  }
d0be4a7d2   Christoph Hellwig   [SCSI] remove Scs...
62
  int mvme147_detect(struct scsi_host_template *tpnt)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
63
  {
be4540db0   Geert Uytterhoeven   [SCSI] mvme147: R...
64
  	static unsigned char called = 0;
4616ac7e8   Geert Uytterhoeven   m68k/scsi: mvme14...
65
  	struct Scsi_Host *instance;
be4540db0   Geert Uytterhoeven   [SCSI] mvme147: R...
66
  	wd33c93_regs regs;
ce195662b   Geert Uytterhoeven   [SCSI] mvme147: U...
67
  	struct WD33C93_hostdata *hdata;
be4540db0   Geert Uytterhoeven   [SCSI] mvme147: R...
68
69
70
71
72
73
  
  	if (!MACH_IS_MVME147 || called)
  		return 0;
  	called++;
  
  	tpnt->proc_name = "MVME147";
408bb25ba   Al Viro   switch wd33c93 to...
74
75
  	tpnt->show_info = wd33c93_show_info,
  	tpnt->write_info = wd33c93_write_info,
be4540db0   Geert Uytterhoeven   [SCSI] mvme147: R...
76

4616ac7e8   Geert Uytterhoeven   m68k/scsi: mvme14...
77
78
  	instance = scsi_register(tpnt, sizeof(struct WD33C93_hostdata));
  	if (!instance)
be4540db0   Geert Uytterhoeven   [SCSI] mvme147: R...
79
  		goto err_out;
4616ac7e8   Geert Uytterhoeven   m68k/scsi: mvme14...
80
81
  	instance->base = 0xfffe4000;
  	instance->irq = MVME147_IRQ_SCSI_PORT;
be4540db0   Geert Uytterhoeven   [SCSI] mvme147: R...
82
83
  	regs.SASR = (volatile unsigned char *)0xfffe4000;
  	regs.SCMD = (volatile unsigned char *)0xfffe4001;
4616ac7e8   Geert Uytterhoeven   m68k/scsi: mvme14...
84
  	hdata = shost_priv(instance);
ce195662b   Geert Uytterhoeven   [SCSI] mvme147: U...
85
86
87
  	hdata->no_sync = 0xff;
  	hdata->fast = 0;
  	hdata->dma_mode = CTRL_DMA;
4616ac7e8   Geert Uytterhoeven   m68k/scsi: mvme14...
88
  	wd33c93_init(instance, regs, dma_setup, dma_stop, WD33C93_FS_8_10);
be4540db0   Geert Uytterhoeven   [SCSI] mvme147: R...
89
90
  
  	if (request_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr, 0,
4616ac7e8   Geert Uytterhoeven   m68k/scsi: mvme14...
91
  			"MVME147 SCSI PORT", instance))
be4540db0   Geert Uytterhoeven   [SCSI] mvme147: R...
92
93
  		goto err_unregister;
  	if (request_irq(MVME147_IRQ_SCSI_DMA, mvme147_intr, 0,
4616ac7e8   Geert Uytterhoeven   m68k/scsi: mvme14...
94
  			"MVME147 SCSI DMA", instance))
be4540db0   Geert Uytterhoeven   [SCSI] mvme147: R...
95
  		goto err_free_irq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
96
  #if 0	/* Disabled; causes problems booting */
be4540db0   Geert Uytterhoeven   [SCSI] mvme147: R...
97
98
99
100
101
  	m147_pcc->scsi_interrupt = 0x10;	/* Assert SCSI bus reset */
  	udelay(100);
  	m147_pcc->scsi_interrupt = 0x00;	/* Negate SCSI bus reset */
  	udelay(2000);
  	m147_pcc->scsi_interrupt = 0x40;	/* Clear bus reset interrupt */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
102
  #endif
be4540db0   Geert Uytterhoeven   [SCSI] mvme147: R...
103
  	m147_pcc->scsi_interrupt = 0x09;	/* Enable interrupt */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
104

be4540db0   Geert Uytterhoeven   [SCSI] mvme147: R...
105
106
  	m147_pcc->dma_cntrl = 0x00;	/* ensure DMA is stopped */
  	m147_pcc->dma_intr = 0x89;	/* Ack and enable ints */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
107

be4540db0   Geert Uytterhoeven   [SCSI] mvme147: R...
108
  	return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
109

be4540db0   Geert Uytterhoeven   [SCSI] mvme147: R...
110
111
112
  err_free_irq:
  	free_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr);
  err_unregister:
4616ac7e8   Geert Uytterhoeven   m68k/scsi: mvme14...
113
  	scsi_unregister(instance);
be4540db0   Geert Uytterhoeven   [SCSI] mvme147: R...
114
115
  err_out:
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
116
  }
65396410a   Henrik Kretzschmar   [SCSI] wd33c93: S...
117
  static int mvme147_bus_reset(struct scsi_cmnd *cmd)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
118
119
  {
  	/* FIXME perform bus-specific reset */
68b3aa7c9   Jeff Garzik   [SCSI] allow slee...
120

be4540db0   Geert Uytterhoeven   [SCSI] mvme147: R...
121
  	/* FIXME 2: kill this function, and let midlayer fallback to
df0ae2497   Jeff Garzik   [SCSI] allow slee...
122
  	   the same result, calling wd33c93_host_reset() */
68b3aa7c9   Jeff Garzik   [SCSI] allow slee...
123
  	spin_lock_irq(cmd->device->host->host_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
124
  	wd33c93_host_reset(cmd);
68b3aa7c9   Jeff Garzik   [SCSI] allow slee...
125
  	spin_unlock_irq(cmd->device->host->host_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
126
127
  	return SUCCESS;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
128

d0be4a7d2   Christoph Hellwig   [SCSI] remove Scs...
129
  static struct scsi_host_template driver_template = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
  	.proc_name		= "MVME147",
  	.name			= "MVME147 built-in SCSI",
  	.detect			= mvme147_detect,
  	.release		= mvme147_release,
  	.queuecommand		= wd33c93_queuecommand,
  	.eh_abort_handler	= wd33c93_abort,
  	.eh_bus_reset_handler	= mvme147_bus_reset,
  	.eh_host_reset_handler	= wd33c93_host_reset,
  	.can_queue		= CAN_QUEUE,
  	.this_id		= 7,
  	.sg_tablesize		= SG_ALL,
  	.cmd_per_lun		= CMD_PER_LUN,
  	.use_clustering		= ENABLE_CLUSTERING
  };
  
  
  #include "scsi_module.c"
  
  int mvme147_release(struct Scsi_Host *instance)
  {
  #ifdef MODULE
be4540db0   Geert Uytterhoeven   [SCSI] mvme147: R...
151
152
153
  	/* XXX Make sure DMA is stopped! */
  	free_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr);
  	free_irq(MVME147_IRQ_SCSI_DMA, mvme147_intr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
154
  #endif
be4540db0   Geert Uytterhoeven   [SCSI] mvme147: R...
155
  	return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
156
  }