Blame view
drivers/scsi/zalon.c
4.97 KB
1da177e4c 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 [SCSI] replace __... |
71 72 |
printk(KERN_WARNING "%s: pdc_iodc_read returned %d ", __func__, status); |
1da177e4c Linux-2.6.12-rc2 |
73 74 |
clock = defaultclock; } |
cadbd4a5e [SCSI] replace __... |
75 76 |
printk(KERN_DEBUG "%s: SCSI clock %d ", __func__, clock); |
1da177e4c 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 [PARISC] I/O-Spac... |
92 |
void __iomem *zalon = ioremap_nocache(dev->hpa.start, 4096); |
1da177e4c 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 [SCSI] replace __... |
111 112 |
printk(KERN_INFO "%s: Zalon version %d, IRQ %d ", __func__, |
1da177e4c 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 [SCSI] replace __... |
118 119 |
printk(KERN_WARNING "%s: Zalon 1.1 or earlier ", __func__); |
1da177e4c 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 [PARISC] Convert ... |
132 |
device.slot.base = dev->hpa.start + GSC_SCSI_ZALON_OFFSET; |
1da177e4c 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 [SCSI] zalon: fix... |
139 |
return -ENODEV; |
1da177e4c Linux-2.6.12-rc2 |
140 |
|
1d6f359a2 [PATCH] irq-flags... |
141 |
if (request_irq(dev->irq, ncr53c8xx_intr, IRQF_SHARED, "zalon", host)) { |
7f384ce78 parisc: fix dev_p... |
142 143 |
dev_printk(KERN_ERR, &dev->dev, "irq problem with %d, detaching ", |
71610f55f [SCSI] struct dev... |
144 |
dev->irq); |
1da177e4c 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); |