Blame view

drivers/scsi/zalon.c 4.97 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
  /*
   * Zalon 53c7xx device driver.
   * By Richard Hirst (rhirst@linuxcare.com)
   */
  
  #include <linux/init.h>
  #include <linux/interrupt.h>
  #include <linux/module.h>
  #include <linux/types.h>
  #include <asm/hardware.h>
  #include <asm/io.h>
  
  #include "../parisc/gsc.h"
  
  #include "ncr53c8xx.h"
  
  MODULE_AUTHOR("Richard Hirst");
  MODULE_DESCRIPTION("Bluefish/Zalon 720 SCSI Driver");
  MODULE_LICENSE("GPL");
  
  #define GSC_SCSI_ZALON_OFFSET 0x800
  
  #define IO_MODULE_EIM		(1*4)
  #define IO_MODULE_DC_ADATA	(2*4)
  #define IO_MODULE_II_CDATA	(3*4)
  #define IO_MODULE_IO_COMMAND	(12*4)
  #define IO_MODULE_IO_STATUS	(13*4)
  
  #define IOSTATUS_RY		0x40
  #define IOSTATUS_FE		0x80
  #define IOIIDATA_SMINT5L	0x40000000
  #define IOIIDATA_MINT5EN	0x20000000
  #define IOIIDATA_PACKEN		0x10000000
  #define IOIIDATA_PREFETCHEN	0x08000000
  #define IOIIDATA_IOII		0x00000020
  
  #define CMD_RESET		5
  
  static struct ncr_chip zalon720_chip __initdata = {
  	.revision_id =	0x0f,
  	.burst_max =	3,
  	.offset_max =	8,
  	.nr_divisor =	4,
  	.features =	FE_WIDE | FE_DIFF | FE_EHP| FE_MUX | FE_EA,
  };
  
  
  
  #if 0
  /* FIXME:
   * Is this function dead code? or is someone planning on using it in the
   * future.  The clock = (int) pdc_result[16] does not look correct to
   * me ... I think it should be iodc_data[16].  Since this cause a compile
   * error with the new encapsulated PDC, I'm not compiling in this function.
   * - RB
   */
  /* poke SCSI clock out of iodc data */
  
  static u8 iodc_data[32] __attribute__ ((aligned (64)));
  static unsigned long pdc_result[32] __attribute__ ((aligned (16))) ={0,0,0,0};
  
  static int 
  lasi_scsi_clock(void * hpa, int defaultclock)
  {
  	int clock, status;
  
  	status = pdc_iodc_read(&pdc_result, hpa, 0, &iodc_data, 32 );
  	if (status == PDC_RET_OK) {
  		clock = (int) pdc_result[16];
  	} else {
cadbd4a5e   Harvey Harrison   [SCSI] replace __...
71
72
  		printk(KERN_WARNING "%s: pdc_iodc_read returned %d
  ", __func__, status);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
73
74
  		clock = defaultclock; 
  	}
cadbd4a5e   Harvey Harrison   [SCSI] replace __...
75
76
  	printk(KERN_DEBUG "%s: SCSI clock %d
  ", __func__, clock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
   	return clock;
  }
  #endif
  
  static struct scsi_host_template zalon7xx_template = {
  	.module		= THIS_MODULE,
  	.proc_name	= "zalon7xx",
  };
  
  static int __init
  zalon_probe(struct parisc_device *dev)
  {
  	struct gsc_irq gsc_irq;
  	u32 zalon_vers;
  	int error = -ENODEV;
5076c1586   Helge Deller   [PARISC] I/O-Spac...
92
  	void __iomem *zalon = ioremap_nocache(dev->hpa.start, 4096);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
  	void __iomem *io_port = zalon + GSC_SCSI_ZALON_OFFSET;
  	static int unit = 0;
  	struct Scsi_Host *host;
  	struct ncr_device device;
  
  	__raw_writel(CMD_RESET, zalon + IO_MODULE_IO_COMMAND);
  	while (!(__raw_readl(zalon + IO_MODULE_IO_STATUS) & IOSTATUS_RY))
  		cpu_relax();
  	__raw_writel(IOIIDATA_MINT5EN | IOIIDATA_PACKEN | IOIIDATA_PREFETCHEN,
  		zalon + IO_MODULE_II_CDATA);
  
  	/* XXX: Save the Zalon version for bug workarounds? */
  	zalon_vers = (__raw_readl(zalon + IO_MODULE_II_CDATA) >> 24) & 0x07;
  
  	/* Setup the interrupts first.
  	** Later on request_irq() will register the handler.
  	*/
  	dev->irq = gsc_alloc_irq(&gsc_irq);
cadbd4a5e   Harvey Harrison   [SCSI] replace __...
111
112
  	printk(KERN_INFO "%s: Zalon version %d, IRQ %d
  ", __func__,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
113
114
115
116
117
  		zalon_vers, dev->irq);
  
  	__raw_writel(gsc_irq.txn_addr | gsc_irq.txn_data, zalon + IO_MODULE_EIM);
  
  	if (zalon_vers == 0)
cadbd4a5e   Harvey Harrison   [SCSI] replace __...
118
119
  		printk(KERN_WARNING "%s: Zalon 1.1 or earlier
  ", __func__);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
120
121
122
123
124
125
126
127
128
129
130
131
  
  	memset(&device, 0, sizeof(struct ncr_device));
  
  	/* The following three are needed before any other access. */
  	__raw_writeb(0x20, io_port + 0x38); /* DCNTL_REG,  EA  */
  	__raw_writeb(0x04, io_port + 0x1b); /* CTEST0_REG, EHP */
  	__raw_writeb(0x80, io_port + 0x22); /* CTEST4_REG, MUX */
  
  	/* Initialise ncr_device structure with items required by ncr_attach. */
  	device.chip		= zalon720_chip;
  	device.host_id		= 7;
  	device.dev		= &dev->dev;
53f01bba4   Matthew Wilcox   [PARISC] Convert ...
132
  	device.slot.base	= dev->hpa.start + GSC_SCSI_ZALON_OFFSET;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
133
134
135
136
137
138
  	device.slot.base_v	= io_port;
  	device.slot.irq		= dev->irq;
  	device.differential	= 2;
  
  	host = ncr_attach(&zalon7xx_template, unit, &device);
  	if (!host)
d3a263a81   James Bottomley   [SCSI] zalon: fix...
139
  		return -ENODEV;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
140

1d6f359a2   Thomas Gleixner   [PATCH] irq-flags...
141
  	if (request_irq(dev->irq, ncr53c8xx_intr, IRQF_SHARED, "zalon", host)) {
7f384ce78   Helge Deller   parisc: fix dev_p...
142
143
  	  dev_printk(KERN_ERR, &dev->dev, "irq problem with %d, detaching
   ",
71610f55f   Kay Sievers   [SCSI] struct dev...
144
  		     dev->irq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
  		goto fail;
  	}
  
  	unit++;
  
  	dev_set_drvdata(&dev->dev, host);
  
  	error = scsi_add_host(host, &dev->dev);
  	if (error)
  		goto fail_free_irq;
  
  	scsi_scan_host(host);
  	return 0;
  
   fail_free_irq:
  	free_irq(dev->irq, host);
   fail:
  	ncr53c8xx_release(host);
  	return error;
  }
  
  static struct parisc_device_id zalon_tbl[] = {
  	{ HPHW_A_DMA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00089 }, 
  	{ 0, }
  };
  
  MODULE_DEVICE_TABLE(parisc, zalon_tbl);
  
  static int __exit zalon_remove(struct parisc_device *dev)
  {
  	struct Scsi_Host *host = dev_get_drvdata(&dev->dev);
  
  	scsi_remove_host(host);
  	ncr53c8xx_release(host);
  	free_irq(dev->irq, host);
  
  	return 0;
  }
  
  static struct parisc_driver zalon_driver = {
  	.name =		"zalon",
  	.id_table =	zalon_tbl,
  	.probe =	zalon_probe,
  	.remove =	__devexit_p(zalon_remove),
  };
  
  static int __init zalon7xx_init(void)
  {
  	int ret = ncr53c8xx_init();
  	if (!ret)
  		ret = register_parisc_driver(&zalon_driver);
  	if (ret)
  		ncr53c8xx_exit();
  	return ret;
  }
  
  static void __exit zalon7xx_exit(void)
  {
  	unregister_parisc_driver(&zalon_driver);
  	ncr53c8xx_exit();
  }
  
  module_init(zalon7xx_init);
  module_exit(zalon7xx_exit);