Linux Audio

Check our new training course

Loading...
v4.10.11
 
  1/*
  2 * Generic Generic NCR5380 driver
  3 *
  4 * Copyright 1995-2002, Russell King
  5 */
  6#include <linux/module.h>
  7#include <linux/ioport.h>
  8#include <linux/blkdev.h>
  9#include <linux/init.h>
 10
 11#include <asm/ecard.h>
 12#include <asm/io.h>
 13
 14#include <scsi/scsi_host.h>
 15
 16#define priv(host)			((struct NCR5380_hostdata *)(host)->hostdata)
 17#define NCR5380_read(reg)		cumanascsi_read(hostdata, reg)
 18#define NCR5380_write(reg, value)	cumanascsi_write(hostdata, reg, value)
 19
 20#define NCR5380_dma_xfer_len		cumanascsi_dma_xfer_len
 21#define NCR5380_dma_recv_setup		cumanascsi_pread
 22#define NCR5380_dma_send_setup		cumanascsi_pwrite
 23#define NCR5380_dma_residual		NCR5380_dma_residual_none
 24
 25#define NCR5380_intr			cumanascsi_intr
 26#define NCR5380_queue_command		cumanascsi_queue_command
 27#define NCR5380_info			cumanascsi_info
 28
 29#define NCR5380_implementation_fields	\
 30	unsigned ctrl
 31
 32struct NCR5380_hostdata;
 33static u8 cumanascsi_read(struct NCR5380_hostdata *, unsigned int);
 34static void cumanascsi_write(struct NCR5380_hostdata *, unsigned int, u8);
 35
 36#include "../NCR5380.h"
 37
 38#define CTRL	0x16fc
 39#define STAT	0x2004
 40#define L(v)	(((v)<<16)|((v) & 0x0000ffff))
 41#define H(v)	(((v)>>16)|((v) & 0xffff0000))
 42
 43static inline int cumanascsi_pwrite(struct NCR5380_hostdata *hostdata,
 44                                    unsigned char *addr, int len)
 45{
 46  unsigned long *laddr;
 47  u8 __iomem *base = hostdata->io;
 48  u8 __iomem *dma = hostdata->pdma_io + 0x2000;
 49
 50  if(!len) return 0;
 51
 52  writeb(0x02, base + CTRL);
 53  laddr = (unsigned long *)addr;
 54  while(len >= 32)
 55  {
 56    unsigned int status;
 57    unsigned long v;
 58    status = readb(base + STAT);
 59    if(status & 0x80)
 60      goto end;
 61    if(!(status & 0x40))
 62      continue;
 63    v=*laddr++; writew(L(v), dma); writew(H(v), dma);
 64    v=*laddr++; writew(L(v), dma); writew(H(v), dma);
 65    v=*laddr++; writew(L(v), dma); writew(H(v), dma);
 66    v=*laddr++; writew(L(v), dma); writew(H(v), dma);
 67    v=*laddr++; writew(L(v), dma); writew(H(v), dma);
 68    v=*laddr++; writew(L(v), dma); writew(H(v), dma);
 69    v=*laddr++; writew(L(v), dma); writew(H(v), dma);
 70    v=*laddr++; writew(L(v), dma); writew(H(v), dma);
 71    len -= 32;
 72    if(len == 0)
 73      break;
 74  }
 75
 76  addr = (unsigned char *)laddr;
 77  writeb(0x12, base + CTRL);
 78
 79  while(len > 0)
 80  {
 81    unsigned int status;
 82    status = readb(base + STAT);
 83    if(status & 0x80)
 84      goto end;
 85    if(status & 0x40)
 86    {
 87      writeb(*addr++, dma);
 88      if(--len == 0)
 89        break;
 90    }
 91
 92    status = readb(base + STAT);
 93    if(status & 0x80)
 94      goto end;
 95    if(status & 0x40)
 96    {
 97      writeb(*addr++, dma);
 98      if(--len == 0)
 99        break;
100    }
101  }
102end:
103  writeb(hostdata->ctrl | 0x40, base + CTRL);
104
105	if (len)
106		return -1;
107	return 0;
108}
109
110static inline int cumanascsi_pread(struct NCR5380_hostdata *hostdata,
111                                   unsigned char *addr, int len)
112{
113  unsigned long *laddr;
114  u8 __iomem *base = hostdata->io;
115  u8 __iomem *dma = hostdata->pdma_io + 0x2000;
116
117  if(!len) return 0;
118
119  writeb(0x00, base + CTRL);
120  laddr = (unsigned long *)addr;
121  while(len >= 32)
122  {
123    unsigned int status;
124    status = readb(base + STAT);
125    if(status & 0x80)
126      goto end;
127    if(!(status & 0x40))
128      continue;
129    *laddr++ = readw(dma) | (readw(dma) << 16);
130    *laddr++ = readw(dma) | (readw(dma) << 16);
131    *laddr++ = readw(dma) | (readw(dma) << 16);
132    *laddr++ = readw(dma) | (readw(dma) << 16);
133    *laddr++ = readw(dma) | (readw(dma) << 16);
134    *laddr++ = readw(dma) | (readw(dma) << 16);
135    *laddr++ = readw(dma) | (readw(dma) << 16);
136    *laddr++ = readw(dma) | (readw(dma) << 16);
137    len -= 32;
138    if(len == 0)
139      break;
140  }
141
142  addr = (unsigned char *)laddr;
143  writeb(0x10, base + CTRL);
144
145  while(len > 0)
146  {
147    unsigned int status;
148    status = readb(base + STAT);
149    if(status & 0x80)
150      goto end;
151    if(status & 0x40)
152    {
153      *addr++ = readb(dma);
154      if(--len == 0)
155        break;
156    }
157
158    status = readb(base + STAT);
159    if(status & 0x80)
160      goto end;
161    if(status & 0x40)
162    {
163      *addr++ = readb(dma);
164      if(--len == 0)
165        break;
166    }
167  }
168end:
169  writeb(hostdata->ctrl | 0x40, base + CTRL);
170
171	if (len)
172		return -1;
173	return 0;
174}
175
176static int cumanascsi_dma_xfer_len(struct NCR5380_hostdata *hostdata,
177                                   struct scsi_cmnd *cmd)
178{
179	return cmd->transfersize;
180}
181
182static u8 cumanascsi_read(struct NCR5380_hostdata *hostdata,
183                          unsigned int reg)
184{
185	u8 __iomem *base = hostdata->io;
186	u8 val;
187
188	writeb(0, base + CTRL);
189
190	val = readb(base + 0x2100 + (reg << 2));
191
192	hostdata->ctrl = 0x40;
193	writeb(0x40, base + CTRL);
194
195	return val;
196}
197
198static void cumanascsi_write(struct NCR5380_hostdata *hostdata,
199                             unsigned int reg, u8 value)
200{
201	u8 __iomem *base = hostdata->io;
202
203	writeb(0, base + CTRL);
204
205	writeb(value, base + 0x2100 + (reg << 2));
206
207	hostdata->ctrl = 0x40;
208	writeb(0x40, base + CTRL);
209}
210
211#include "../NCR5380.c"
212
213static struct scsi_host_template cumanascsi_template = {
214	.module			= THIS_MODULE,
215	.name			= "Cumana 16-bit SCSI",
216	.info			= cumanascsi_info,
217	.queuecommand		= cumanascsi_queue_command,
218	.eh_abort_handler	= NCR5380_abort,
219	.eh_bus_reset_handler	= NCR5380_bus_reset,
220	.can_queue		= 16,
221	.this_id		= 7,
222	.sg_tablesize		= SG_ALL,
223	.cmd_per_lun		= 2,
224	.use_clustering		= DISABLE_CLUSTERING,
225	.proc_name		= "CumanaSCSI-1",
226	.cmd_size		= NCR5380_CMD_SIZE,
227	.max_sectors		= 128,
 
228};
229
230static int cumanascsi1_probe(struct expansion_card *ec,
231			     const struct ecard_id *id)
232{
233	struct Scsi_Host *host;
234	int ret;
235
236	ret = ecard_request_resources(ec);
237	if (ret)
238		goto out;
239
240	host = scsi_host_alloc(&cumanascsi_template, sizeof(struct NCR5380_hostdata));
241	if (!host) {
242		ret = -ENOMEM;
243		goto out_release;
244	}
245
246	priv(host)->io = ioremap(ecard_resource_start(ec, ECARD_RES_IOCSLOW),
247	                         ecard_resource_len(ec, ECARD_RES_IOCSLOW));
248	priv(host)->pdma_io = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC),
249	                              ecard_resource_len(ec, ECARD_RES_MEMC));
250	if (!priv(host)->io || !priv(host)->pdma_io) {
251		ret = -ENOMEM;
252		goto out_unmap;
253	}
254
255	host->irq = ec->irq;
256
257	ret = NCR5380_init(host, FLAG_DMA_FIXUP | FLAG_LATE_DMA_SETUP);
258	if (ret)
259		goto out_unmap;
260
261	NCR5380_maybe_reset_bus(host);
262
263        priv(host)->ctrl = 0;
264        writeb(0, priv(host)->io + CTRL);
265
266	ret = request_irq(host->irq, cumanascsi_intr, 0,
267			  "CumanaSCSI-1", host);
268	if (ret) {
269		printk("scsi%d: IRQ%d not free: %d\n",
270		    host->host_no, host->irq, ret);
271		goto out_exit;
272	}
273
274	ret = scsi_add_host(host, &ec->dev);
275	if (ret)
276		goto out_free_irq;
277
278	scsi_scan_host(host);
279	goto out;
280
281 out_free_irq:
282	free_irq(host->irq, host);
283 out_exit:
284	NCR5380_exit(host);
285 out_unmap:
286	iounmap(priv(host)->io);
287	iounmap(priv(host)->pdma_io);
288	scsi_host_put(host);
289 out_release:
290	ecard_release_resources(ec);
291 out:
292	return ret;
293}
294
295static void cumanascsi1_remove(struct expansion_card *ec)
296{
297	struct Scsi_Host *host = ecard_get_drvdata(ec);
298	void __iomem *base = priv(host)->io;
299	void __iomem *dma = priv(host)->pdma_io;
300
301	ecard_set_drvdata(ec, NULL);
302
303	scsi_remove_host(host);
304	free_irq(host->irq, host);
305	NCR5380_exit(host);
306	scsi_host_put(host);
307	iounmap(base);
308	iounmap(dma);
309	ecard_release_resources(ec);
310}
311
312static const struct ecard_id cumanascsi1_cids[] = {
313	{ MANU_CUMANA, PROD_CUMANA_SCSI_1 },
314	{ 0xffff, 0xffff }
315};
316
317static struct ecard_driver cumanascsi1_driver = {
318	.probe		= cumanascsi1_probe,
319	.remove		= cumanascsi1_remove,
320	.id_table	= cumanascsi1_cids,
321	.drv = {
322		.name		= "cumanascsi1",
323	},
324};
325
326static int __init cumanascsi_init(void)
327{
328	return ecard_register_driver(&cumanascsi1_driver);
329}
330
331static void __exit cumanascsi_exit(void)
332{
333	ecard_remove_driver(&cumanascsi1_driver);
334}
335
336module_init(cumanascsi_init);
337module_exit(cumanascsi_exit);
338
339MODULE_DESCRIPTION("Cumana SCSI-1 driver for Acorn machines");
340MODULE_LICENSE("GPL");
v6.13.7
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Generic Generic NCR5380 driver
  4 *
  5 * Copyright 1995-2002, Russell King
  6 */
  7#include <linux/module.h>
  8#include <linux/ioport.h>
  9#include <linux/blkdev.h>
 10#include <linux/init.h>
 11
 12#include <asm/ecard.h>
 13#include <asm/io.h>
 14
 15#include <scsi/scsi_host.h>
 16
 17#define priv(host)			((struct NCR5380_hostdata *)(host)->hostdata)
 18#define NCR5380_read(reg)		cumanascsi_read(hostdata, reg)
 19#define NCR5380_write(reg, value)	cumanascsi_write(hostdata, reg, value)
 20
 21#define NCR5380_dma_xfer_len		cumanascsi_dma_xfer_len
 22#define NCR5380_dma_recv_setup		cumanascsi_pread
 23#define NCR5380_dma_send_setup		cumanascsi_pwrite
 24#define NCR5380_dma_residual		NCR5380_dma_residual_none
 25
 26#define NCR5380_intr			cumanascsi_intr
 27#define NCR5380_queue_command		cumanascsi_queue_command
 28#define NCR5380_info			cumanascsi_info
 29
 30#define NCR5380_implementation_fields	\
 31	unsigned ctrl
 32
 33struct NCR5380_hostdata;
 34static u8 cumanascsi_read(struct NCR5380_hostdata *, unsigned int);
 35static void cumanascsi_write(struct NCR5380_hostdata *, unsigned int, u8);
 36
 37#include "../NCR5380.h"
 38
 39#define CTRL	0x16fc
 40#define STAT	0x2004
 41#define L(v)	(((v)<<16)|((v) & 0x0000ffff))
 42#define H(v)	(((v)>>16)|((v) & 0xffff0000))
 43
 44static inline int cumanascsi_pwrite(struct NCR5380_hostdata *hostdata,
 45                                    unsigned char *addr, int len)
 46{
 47  unsigned long *laddr;
 48  u8 __iomem *base = hostdata->io;
 49  u8 __iomem *dma = hostdata->pdma_io + 0x2000;
 50
 51  if(!len) return 0;
 52
 53  writeb(0x02, base + CTRL);
 54  laddr = (unsigned long *)addr;
 55  while(len >= 32)
 56  {
 57    unsigned int status;
 58    unsigned long v;
 59    status = readb(base + STAT);
 60    if(status & 0x80)
 61      goto end;
 62    if(!(status & 0x40))
 63      continue;
 64    v=*laddr++; writew(L(v), dma); writew(H(v), dma);
 65    v=*laddr++; writew(L(v), dma); writew(H(v), dma);
 66    v=*laddr++; writew(L(v), dma); writew(H(v), dma);
 67    v=*laddr++; writew(L(v), dma); writew(H(v), dma);
 68    v=*laddr++; writew(L(v), dma); writew(H(v), dma);
 69    v=*laddr++; writew(L(v), dma); writew(H(v), dma);
 70    v=*laddr++; writew(L(v), dma); writew(H(v), dma);
 71    v=*laddr++; writew(L(v), dma); writew(H(v), dma);
 72    len -= 32;
 73    if(len == 0)
 74      break;
 75  }
 76
 77  addr = (unsigned char *)laddr;
 78  writeb(0x12, base + CTRL);
 79
 80  while(len > 0)
 81  {
 82    unsigned int status;
 83    status = readb(base + STAT);
 84    if(status & 0x80)
 85      goto end;
 86    if(status & 0x40)
 87    {
 88      writeb(*addr++, dma);
 89      if(--len == 0)
 90        break;
 91    }
 92
 93    status = readb(base + STAT);
 94    if(status & 0x80)
 95      goto end;
 96    if(status & 0x40)
 97    {
 98      writeb(*addr++, dma);
 99      if(--len == 0)
100        break;
101    }
102  }
103end:
104  writeb(hostdata->ctrl | 0x40, base + CTRL);
105
106	if (len)
107		return -1;
108	return 0;
109}
110
111static inline int cumanascsi_pread(struct NCR5380_hostdata *hostdata,
112                                   unsigned char *addr, int len)
113{
114  unsigned long *laddr;
115  u8 __iomem *base = hostdata->io;
116  u8 __iomem *dma = hostdata->pdma_io + 0x2000;
117
118  if(!len) return 0;
119
120  writeb(0x00, base + CTRL);
121  laddr = (unsigned long *)addr;
122  while(len >= 32)
123  {
124    unsigned int status;
125    status = readb(base + STAT);
126    if(status & 0x80)
127      goto end;
128    if(!(status & 0x40))
129      continue;
130    *laddr++ = readw(dma) | (readw(dma) << 16);
131    *laddr++ = readw(dma) | (readw(dma) << 16);
132    *laddr++ = readw(dma) | (readw(dma) << 16);
133    *laddr++ = readw(dma) | (readw(dma) << 16);
134    *laddr++ = readw(dma) | (readw(dma) << 16);
135    *laddr++ = readw(dma) | (readw(dma) << 16);
136    *laddr++ = readw(dma) | (readw(dma) << 16);
137    *laddr++ = readw(dma) | (readw(dma) << 16);
138    len -= 32;
139    if(len == 0)
140      break;
141  }
142
143  addr = (unsigned char *)laddr;
144  writeb(0x10, base + CTRL);
145
146  while(len > 0)
147  {
148    unsigned int status;
149    status = readb(base + STAT);
150    if(status & 0x80)
151      goto end;
152    if(status & 0x40)
153    {
154      *addr++ = readb(dma);
155      if(--len == 0)
156        break;
157    }
158
159    status = readb(base + STAT);
160    if(status & 0x80)
161      goto end;
162    if(status & 0x40)
163    {
164      *addr++ = readb(dma);
165      if(--len == 0)
166        break;
167    }
168  }
169end:
170  writeb(hostdata->ctrl | 0x40, base + CTRL);
171
172	if (len)
173		return -1;
174	return 0;
175}
176
177static int cumanascsi_dma_xfer_len(struct NCR5380_hostdata *hostdata,
178                                   struct scsi_cmnd *cmd)
179{
180	return cmd->transfersize;
181}
182
183static u8 cumanascsi_read(struct NCR5380_hostdata *hostdata,
184                          unsigned int reg)
185{
186	u8 __iomem *base = hostdata->io;
187	u8 val;
188
189	writeb(0, base + CTRL);
190
191	val = readb(base + 0x2100 + (reg << 2));
192
193	hostdata->ctrl = 0x40;
194	writeb(0x40, base + CTRL);
195
196	return val;
197}
198
199static void cumanascsi_write(struct NCR5380_hostdata *hostdata,
200                             unsigned int reg, u8 value)
201{
202	u8 __iomem *base = hostdata->io;
203
204	writeb(0, base + CTRL);
205
206	writeb(value, base + 0x2100 + (reg << 2));
207
208	hostdata->ctrl = 0x40;
209	writeb(0x40, base + CTRL);
210}
211
212#include "../NCR5380.c"
213
214static const struct scsi_host_template cumanascsi_template = {
215	.module			= THIS_MODULE,
216	.name			= "Cumana 16-bit SCSI",
217	.info			= cumanascsi_info,
218	.queuecommand		= cumanascsi_queue_command,
219	.eh_abort_handler	= NCR5380_abort,
220	.eh_host_reset_handler	= NCR5380_host_reset,
221	.can_queue		= 16,
222	.this_id		= 7,
223	.sg_tablesize		= SG_ALL,
224	.cmd_per_lun		= 2,
 
225	.proc_name		= "CumanaSCSI-1",
226	.cmd_size		= sizeof(struct NCR5380_cmd),
227	.max_sectors		= 128,
228	.dma_boundary		= PAGE_SIZE - 1,
229};
230
231static int cumanascsi1_probe(struct expansion_card *ec,
232			     const struct ecard_id *id)
233{
234	struct Scsi_Host *host;
235	int ret;
236
237	ret = ecard_request_resources(ec);
238	if (ret)
239		goto out;
240
241	host = scsi_host_alloc(&cumanascsi_template, sizeof(struct NCR5380_hostdata));
242	if (!host) {
243		ret = -ENOMEM;
244		goto out_release;
245	}
246
247	priv(host)->io = ioremap(ecard_resource_start(ec, ECARD_RES_IOCSLOW),
248	                         ecard_resource_len(ec, ECARD_RES_IOCSLOW));
249	priv(host)->pdma_io = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC),
250	                              ecard_resource_len(ec, ECARD_RES_MEMC));
251	if (!priv(host)->io || !priv(host)->pdma_io) {
252		ret = -ENOMEM;
253		goto out_unmap;
254	}
255
256	host->irq = ec->irq;
257
258	ret = NCR5380_init(host, FLAG_DMA_FIXUP | FLAG_LATE_DMA_SETUP);
259	if (ret)
260		goto out_unmap;
261
262	NCR5380_maybe_reset_bus(host);
263
264        priv(host)->ctrl = 0;
265        writeb(0, priv(host)->io + CTRL);
266
267	ret = request_irq(host->irq, cumanascsi_intr, 0,
268			  "CumanaSCSI-1", host);
269	if (ret) {
270		printk("scsi%d: IRQ%d not free: %d\n",
271		    host->host_no, host->irq, ret);
272		goto out_exit;
273	}
274
275	ret = scsi_add_host(host, &ec->dev);
276	if (ret)
277		goto out_free_irq;
278
279	scsi_scan_host(host);
280	goto out;
281
282 out_free_irq:
283	free_irq(host->irq, host);
284 out_exit:
285	NCR5380_exit(host);
286 out_unmap:
287	iounmap(priv(host)->io);
288	iounmap(priv(host)->pdma_io);
289	scsi_host_put(host);
290 out_release:
291	ecard_release_resources(ec);
292 out:
293	return ret;
294}
295
296static void cumanascsi1_remove(struct expansion_card *ec)
297{
298	struct Scsi_Host *host = ecard_get_drvdata(ec);
299	void __iomem *base = priv(host)->io;
300	void __iomem *dma = priv(host)->pdma_io;
301
302	ecard_set_drvdata(ec, NULL);
303
304	scsi_remove_host(host);
305	free_irq(host->irq, host);
306	NCR5380_exit(host);
307	scsi_host_put(host);
308	iounmap(base);
309	iounmap(dma);
310	ecard_release_resources(ec);
311}
312
313static const struct ecard_id cumanascsi1_cids[] = {
314	{ MANU_CUMANA, PROD_CUMANA_SCSI_1 },
315	{ 0xffff, 0xffff }
316};
317
318static struct ecard_driver cumanascsi1_driver = {
319	.probe		= cumanascsi1_probe,
320	.remove		= cumanascsi1_remove,
321	.id_table	= cumanascsi1_cids,
322	.drv = {
323		.name		= "cumanascsi1",
324	},
325};
326
327static int __init cumanascsi_init(void)
328{
329	return ecard_register_driver(&cumanascsi1_driver);
330}
331
332static void __exit cumanascsi_exit(void)
333{
334	ecard_remove_driver(&cumanascsi1_driver);
335}
336
337module_init(cumanascsi_init);
338module_exit(cumanascsi_exit);
339
340MODULE_DESCRIPTION("Cumana SCSI-1 driver for Acorn machines");
341MODULE_LICENSE("GPL");