brintos

brintos / linux-shallow public Read only

0
0
Text · 4.0 KiB · 86fe19e Raw
172 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2 3/* PARISC LASI driver for the 53c700 chip4 *5 * Copyright (C) 2001 by James.Bottomley@HansenPartnership.com6**-----------------------------------------------------------------------------7**  8**9**-----------------------------------------------------------------------------10 */11 12/*13 * Many thanks to Richard Hirst <rhirst@linuxcare.com> for patiently14 * debugging this driver on the parisc architecture and suggesting15 * many improvements and bug fixes.16 *17 * Thanks also go to Linuxcare Inc. for providing several PARISC18 * machines for me to debug the driver on.19 */20 21#include <linux/kernel.h>22#include <linux/module.h>23#include <linux/init.h>24#include <linux/types.h>25#include <linux/stat.h>26#include <linux/mm.h>27#include <linux/blkdev.h>28#include <linux/ioport.h>29#include <linux/dma-mapping.h>30#include <linux/slab.h>31 32#include <asm/page.h>33#include <asm/irq.h>34#include <asm/hardware.h>35#include <asm/parisc-device.h>36#include <asm/delay.h>37 38#include <scsi/scsi_host.h>39#include <scsi/scsi_device.h>40#include <scsi/scsi_transport.h>41#include <scsi/scsi_transport_spi.h>42 43#include "53c700.h"44 45MODULE_AUTHOR("James Bottomley");46MODULE_DESCRIPTION("lasi700 SCSI Driver");47MODULE_LICENSE("GPL");48 49#define LASI_700_SVERSION 0x0007150#define LASI_710_SVERSION 0x0008251 52#define LASI700_ID_TABLE {			\53	.hw_type	= HPHW_FIO,		\54	.sversion	= LASI_700_SVERSION,	\55	.hversion	= HVERSION_ANY_ID,	\56	.hversion_rev	= HVERSION_REV_ANY_ID,	\57}58 59#define LASI710_ID_TABLE {			\60	.hw_type	= HPHW_FIO,		\61	.sversion	= LASI_710_SVERSION,	\62	.hversion	= HVERSION_ANY_ID,	\63	.hversion_rev	= HVERSION_REV_ANY_ID,	\64}65 66#define LASI700_CLOCK	2567#define LASI710_CLOCK	4068#define LASI_SCSI_CORE_OFFSET 0x10069 70static const struct parisc_device_id lasi700_ids[] __initconst = {71	LASI700_ID_TABLE,72	LASI710_ID_TABLE,73	{ 0 }74};75 76static struct scsi_host_template lasi700_template = {77	.name		= "LASI SCSI 53c700",78	.proc_name	= "lasi700",79	.this_id	= 7,80	.module		= THIS_MODULE,81};82MODULE_DEVICE_TABLE(parisc, lasi700_ids);83 84static int __init85lasi700_probe(struct parisc_device *dev)86{87	unsigned long base = dev->hpa.start + LASI_SCSI_CORE_OFFSET;88	struct NCR_700_Host_Parameters *hostdata;89	struct Scsi_Host *host;90 91	hostdata = kzalloc(sizeof(*hostdata), GFP_KERNEL);92	if (!hostdata) {93		dev_printk(KERN_ERR, &dev->dev, "Failed to allocate host data\n");94		return -ENOMEM;95	}96 97	hostdata->dev = &dev->dev;98	dma_set_mask(&dev->dev, DMA_BIT_MASK(32));99	hostdata->base = ioremap(base, 0x100);100	hostdata->differential = 0;101 102	if (dev->id.sversion == LASI_700_SVERSION) {103		hostdata->clock = LASI700_CLOCK;104		hostdata->force_le_on_be = 1;105	} else {106		hostdata->clock = LASI710_CLOCK;107		hostdata->force_le_on_be = 0;108		hostdata->chip710 = 1;109		hostdata->dmode_extra = DMODE_FC2;110		hostdata->burst_length = 8;111	}112 113	host = NCR_700_detect(&lasi700_template, hostdata, &dev->dev);114	if (!host)115		goto out_kfree;116	host->this_id = 7;117	host->base = base;118	host->irq = dev->irq;119	if(request_irq(dev->irq, NCR_700_intr, IRQF_SHARED, "lasi700", host)) {120		printk(KERN_ERR "lasi700: request_irq failed!\n");121		goto out_put_host;122	}123 124	dev_set_drvdata(&dev->dev, host);125	scsi_scan_host(host);126 127	return 0;128 129 out_put_host:130	scsi_host_put(host);131 out_kfree:132	iounmap(hostdata->base);133	kfree(hostdata);134	return -ENODEV;135}136 137static void __exit138lasi700_driver_remove(struct parisc_device *dev)139{140	struct Scsi_Host *host = dev_get_drvdata(&dev->dev);141	struct NCR_700_Host_Parameters *hostdata = 142		(struct NCR_700_Host_Parameters *)host->hostdata[0];143 144	scsi_remove_host(host);145	NCR_700_release(host);146	free_irq(host->irq, host);147	iounmap(hostdata->base);148	kfree(hostdata);149}150 151static struct parisc_driver lasi700_driver __refdata = {152	.name =		"lasi_scsi",153	.id_table =	lasi700_ids,154	.probe =	lasi700_probe,155	.remove =	__exit_p(lasi700_driver_remove),156};157 158static int __init159lasi700_init(void)160{161	return register_parisc_driver(&lasi700_driver);162}163 164static void __exit165lasi700_exit(void)166{167	unregister_parisc_driver(&lasi700_driver);168}169 170module_init(lasi700_init);171module_exit(lasi700_exit);172