Blame view

drivers/scsi/mvme147.c 3.91 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
74
  
  	if (!MACH_IS_MVME147 || called)
  		return 0;
  	called++;
  
  	tpnt->proc_name = "MVME147";
  	tpnt->proc_info = &wd33c93_proc_info;
4616ac7e8   Geert Uytterhoeven   m68k/scsi: mvme14...
75
76
  	instance = scsi_register(tpnt, sizeof(struct WD33C93_hostdata));
  	if (!instance)
be4540db0   Geert Uytterhoeven   [SCSI] mvme147: R...
77
  		goto err_out;
4616ac7e8   Geert Uytterhoeven   m68k/scsi: mvme14...
78
79
  	instance->base = 0xfffe4000;
  	instance->irq = MVME147_IRQ_SCSI_PORT;
be4540db0   Geert Uytterhoeven   [SCSI] mvme147: R...
80
81
  	regs.SASR = (volatile unsigned char *)0xfffe4000;
  	regs.SCMD = (volatile unsigned char *)0xfffe4001;
4616ac7e8   Geert Uytterhoeven   m68k/scsi: mvme14...
82
  	hdata = shost_priv(instance);
ce195662b   Geert Uytterhoeven   [SCSI] mvme147: U...
83
84
85
  	hdata->no_sync = 0xff;
  	hdata->fast = 0;
  	hdata->dma_mode = CTRL_DMA;
4616ac7e8   Geert Uytterhoeven   m68k/scsi: mvme14...
86
  	wd33c93_init(instance, regs, dma_setup, dma_stop, WD33C93_FS_8_10);
be4540db0   Geert Uytterhoeven   [SCSI] mvme147: R...
87
88
  
  	if (request_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr, 0,
4616ac7e8   Geert Uytterhoeven   m68k/scsi: mvme14...
89
  			"MVME147 SCSI PORT", instance))
be4540db0   Geert Uytterhoeven   [SCSI] mvme147: R...
90
91
  		goto err_unregister;
  	if (request_irq(MVME147_IRQ_SCSI_DMA, mvme147_intr, 0,
4616ac7e8   Geert Uytterhoeven   m68k/scsi: mvme14...
92
  			"MVME147 SCSI DMA", instance))
be4540db0   Geert Uytterhoeven   [SCSI] mvme147: R...
93
  		goto err_free_irq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
94
  #if 0	/* Disabled; causes problems booting */
be4540db0   Geert Uytterhoeven   [SCSI] mvme147: R...
95
96
97
98
99
  	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
100
  #endif
be4540db0   Geert Uytterhoeven   [SCSI] mvme147: R...
101
  	m147_pcc->scsi_interrupt = 0x09;	/* Enable interrupt */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
102

be4540db0   Geert Uytterhoeven   [SCSI] mvme147: R...
103
104
  	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
105

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

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

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

d0be4a7d2   Christoph Hellwig   [SCSI] remove Scs...
127
  static struct scsi_host_template driver_template = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
  	.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...
149
150
151
  	/* 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
152
  #endif
be4540db0   Geert Uytterhoeven   [SCSI] mvme147: R...
153
  	return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
154
  }