Diff markup
1 /* 1 /*
2 * Sun3 SCSI stuff by Erik Verbruggen (erik@bi 2 * Sun3 SCSI stuff by Erik Verbruggen (erik@bigmama.xtdnet.nl)
3 * 3 *
4 * Sun3 DMA routines added by Sam Creasey (sam 4 * Sun3 DMA routines added by Sam Creasey (sammy@sammy.net)
5 * 5 *
6 * VME support added by Sam Creasey 6 * VME support added by Sam Creasey
7 * 7 *
8 * Adapted from sun3_scsi.c -- see there for o 8 * Adapted from sun3_scsi.c -- see there for other headers
9 * 9 *
10 * TODO: modify this driver to support multipl 10 * TODO: modify this driver to support multiple Sun3 SCSI VME boards
11 * 11 *
12 */ 12 */
13 13
14 #define AUTOSENSE 14 #define AUTOSENSE
15 15
16 #include <linux/types.h> 16 #include <linux/types.h>
17 #include <linux/stddef.h> 17 #include <linux/stddef.h>
18 #include <linux/ctype.h> 18 #include <linux/ctype.h>
19 #include <linux/delay.h> 19 #include <linux/delay.h>
20 20
21 #include <linux/module.h> 21 #include <linux/module.h>
22 #include <linux/signal.h> 22 #include <linux/signal.h>
23 #include <linux/ioport.h> 23 #include <linux/ioport.h>
24 #include <linux/init.h> 24 #include <linux/init.h>
25 #include <linux/blkdev.h> 25 #include <linux/blkdev.h>
26 26
27 #include <asm/io.h> 27 #include <asm/io.h>
28 #include <asm/system.h> 28 #include <asm/system.h>
29 29
30 #include <asm/sun3ints.h> 30 #include <asm/sun3ints.h>
31 #include <asm/dvma.h> 31 #include <asm/dvma.h>
32 #include <asm/idprom.h> 32 #include <asm/idprom.h>
33 #include <asm/machines.h> 33 #include <asm/machines.h>
34 34
35 #define SUN3_SCSI_VME 35 #define SUN3_SCSI_VME
36 36
37 #undef SUN3_SCSI_DEBUG 37 #undef SUN3_SCSI_DEBUG
38 38
39 /* dma on! */ 39 /* dma on! */
40 #define REAL_DMA 40 #define REAL_DMA
41 41
42 #include "scsi.h" 42 #include "scsi.h"
43 #include "initio.h" 43 #include "initio.h"
44 #include <scsi/scsi_host.h> 44 #include <scsi/scsi_host.h>
45 #include "sun3_scsi.h" 45 #include "sun3_scsi.h"
46 46
47 extern int sun3_map_test(unsigned long, char * 47 extern int sun3_map_test(unsigned long, char *);
48 48
49 #define USE_WRAPPER 49 #define USE_WRAPPER
50 /*#define RESET_BOOT */ 50 /*#define RESET_BOOT */
51 #define DRIVER_SETUP 51 #define DRIVER_SETUP
52 52
53 #define NDEBUG 0 53 #define NDEBUG 0
54 54
55 /* 55 /*
56 * BUG can be used to trigger a strange code-s 56 * BUG can be used to trigger a strange code-size related hang on 2.1 kernels
57 */ 57 */
58 #ifdef BUG 58 #ifdef BUG
59 #undef RESET_BOOT 59 #undef RESET_BOOT
60 #undef DRIVER_SETUP 60 #undef DRIVER_SETUP
61 #endif 61 #endif
62 62
63 /* #define SUPPORT_TAGS */ 63 /* #define SUPPORT_TAGS */
64 64
65 //#define ENABLE_IRQ() enable_irq( SU 65 //#define ENABLE_IRQ() enable_irq( SUN3_VEC_VMESCSI0 );
66 #define ENABLE_IRQ() 66 #define ENABLE_IRQ()
67 67
68 68
69 static irqreturn_t scsi_sun3_intr(int irq, voi 69 static irqreturn_t scsi_sun3_intr(int irq, void *dummy);
70 static inline unsigned char sun3scsi_read(int 70 static inline unsigned char sun3scsi_read(int reg);
71 static inline void sun3scsi_write(int reg, int 71 static inline void sun3scsi_write(int reg, int value);
72 72
73 static int setup_can_queue = -1; 73 static int setup_can_queue = -1;
74 module_param(setup_can_queue, int, 0); 74 module_param(setup_can_queue, int, 0);
75 static int setup_cmd_per_lun = -1; 75 static int setup_cmd_per_lun = -1;
76 module_param(setup_cmd_per_lun, int, 0); 76 module_param(setup_cmd_per_lun, int, 0);
77 static int setup_sg_tablesize = -1; 77 static int setup_sg_tablesize = -1;
78 module_param(setup_sg_tablesize, int, 0); 78 module_param(setup_sg_tablesize, int, 0);
79 #ifdef SUPPORT_TAGS 79 #ifdef SUPPORT_TAGS
80 static int setup_use_tagged_queuing = -1; 80 static int setup_use_tagged_queuing = -1;
81 module_param(setup_use_tagged_queuing, int, 0) 81 module_param(setup_use_tagged_queuing, int, 0);
82 #endif 82 #endif
83 static int setup_hostid = -1; 83 static int setup_hostid = -1;
84 module_param(setup_hostid, int, 0); 84 module_param(setup_hostid, int, 0);
85 85
86 static struct scsi_cmnd *sun3_dma_setup_done = 86 static struct scsi_cmnd *sun3_dma_setup_done = NULL;
87 87
88 #define AFTER_RESET_DELAY (HZ/2) 88 #define AFTER_RESET_DELAY (HZ/2)
89 89
90 /* ms to wait after hitting dma regs */ 90 /* ms to wait after hitting dma regs */
91 #define SUN3_DMA_DELAY 10 91 #define SUN3_DMA_DELAY 10
92 92
93 /* dvma buffer to allocate -- 32k should hopef 93 /* dvma buffer to allocate -- 32k should hopefully be more than sufficient */
94 #define SUN3_DVMA_BUFSIZE 0xe000 94 #define SUN3_DVMA_BUFSIZE 0xe000
95 95
96 /* minimum number of bytes to do dma on */ 96 /* minimum number of bytes to do dma on */
97 #define SUN3_DMA_MINSIZE 128 97 #define SUN3_DMA_MINSIZE 128
98 98
99 static volatile unsigned char *sun3_scsi_regp; 99 static volatile unsigned char *sun3_scsi_regp;
100 static volatile struct sun3_dma_regs *dregs; 100 static volatile struct sun3_dma_regs *dregs;
101 #ifdef OLDDMA 101 #ifdef OLDDMA
102 static unsigned char *dmabuf = NULL; /* dma me 102 static unsigned char *dmabuf = NULL; /* dma memory buffer */
103 #endif 103 #endif
104 static unsigned char *sun3_dma_orig_addr = NUL 104 static unsigned char *sun3_dma_orig_addr = NULL;
105 static unsigned long sun3_dma_orig_count = 0; 105 static unsigned long sun3_dma_orig_count = 0;
106 static int sun3_dma_active = 0; 106 static int sun3_dma_active = 0;
107 static unsigned long last_residual = 0; 107 static unsigned long last_residual = 0;
108 108
109 /* 109 /*
110 * NCR 5380 register access functions 110 * NCR 5380 register access functions
111 */ 111 */
112 112
113 static inline unsigned char sun3scsi_read(int 113 static inline unsigned char sun3scsi_read(int reg)
114 { 114 {
115 return( sun3_scsi_regp[reg] ); 115 return( sun3_scsi_regp[reg] );
116 } 116 }
117 117
118 static inline void sun3scsi_write(int reg, int 118 static inline void sun3scsi_write(int reg, int value)
119 { 119 {
120 sun3_scsi_regp[reg] = value; 120 sun3_scsi_regp[reg] = value;
121 } 121 }
122 122
123 /* 123 /*
124 * XXX: status debug 124 * XXX: status debug
125 */ 125 */
126 static struct Scsi_Host *default_instance; 126 static struct Scsi_Host *default_instance;
127 127
128 /* 128 /*
129 * Function : int sun3scsi_detect(struct scsi_ 129 * Function : int sun3scsi_detect(struct scsi_host_template * tpnt)
130 * 130 *
131 * Purpose : initializes mac NCR5380 driver ba 131 * Purpose : initializes mac NCR5380 driver based on the
132 * command line / compile time port and i 132 * command line / compile time port and irq definitions.
133 * 133 *
134 * Inputs : tpnt - template for this SCSI adap 134 * Inputs : tpnt - template for this SCSI adapter.
135 * 135 *
136 * Returns : 1 if a host adapter was found, 0 136 * Returns : 1 if a host adapter was found, 0 if not.
137 * 137 *
138 */ 138 */
139 139
140 static int sun3scsi_detect(struct scsi_host_te 140 static int sun3scsi_detect(struct scsi_host_template * tpnt)
141 { 141 {
142 unsigned long ioaddr, irq = 0; 142 unsigned long ioaddr, irq = 0;
143 static int called = 0; 143 static int called = 0;
144 struct Scsi_Host *instance; 144 struct Scsi_Host *instance;
145 int i; 145 int i;
146 unsigned long addrs[3] = { IOBASE_SUN3 146 unsigned long addrs[3] = { IOBASE_SUN3_VMESCSI,
147 IOBASE_SUN3 147 IOBASE_SUN3_VMESCSI + 0x4000,
148 0 }; 148 0 };
149 unsigned long vecs[3] = { SUN3_VEC_VME 149 unsigned long vecs[3] = { SUN3_VEC_VMESCSI0,
150 SUN3_VEC_VME 150 SUN3_VEC_VMESCSI1,
151 0 }; 151 0 };
152 /* check that this machine has an onbo 152 /* check that this machine has an onboard 5380 */
153 switch(idprom->id_machtype) { 153 switch(idprom->id_machtype) {
154 case SM_SUN3|SM_3_160: 154 case SM_SUN3|SM_3_160:
155 case SM_SUN3|SM_3_260: 155 case SM_SUN3|SM_3_260:
156 break; 156 break;
157 157
158 default: 158 default:
159 return 0; 159 return 0;
160 } 160 }
161 161
162 if(called) 162 if(called)
163 return 0; 163 return 0;
164 164
165 tpnt->proc_name = "Sun3 5380 VME SCSI" 165 tpnt->proc_name = "Sun3 5380 VME SCSI";
166 166
167 /* setup variables */ 167 /* setup variables */
168 tpnt->can_queue = 168 tpnt->can_queue =
169 (setup_can_queue > 0) ? setup_ 169 (setup_can_queue > 0) ? setup_can_queue : CAN_QUEUE;
170 tpnt->cmd_per_lun = 170 tpnt->cmd_per_lun =
171 (setup_cmd_per_lun > 0) ? setu 171 (setup_cmd_per_lun > 0) ? setup_cmd_per_lun : CMD_PER_LUN;
172 tpnt->sg_tablesize = 172 tpnt->sg_tablesize =
173 (setup_sg_tablesize >= 0) ? se 173 (setup_sg_tablesize >= 0) ? setup_sg_tablesize : SG_TABLESIZE;
174 174
175 if (setup_hostid >= 0) 175 if (setup_hostid >= 0)
176 tpnt->this_id = setup_hostid; 176 tpnt->this_id = setup_hostid;
177 else { 177 else {
178 /* use 7 as default */ 178 /* use 7 as default */
179 tpnt->this_id = 7; 179 tpnt->this_id = 7;
180 } 180 }
181 181
182 ioaddr = 0; 182 ioaddr = 0;
183 for(i = 0; addrs[i] != 0; i++) { 183 for(i = 0; addrs[i] != 0; i++) {
184 unsigned char x; 184 unsigned char x;
185 185
186 ioaddr = (unsigned long)sun3_i 186 ioaddr = (unsigned long)sun3_ioremap(addrs[i], PAGE_SIZE,
187 187 SUN3_PAGE_TYPE_VME16);
188 irq = vecs[i]; 188 irq = vecs[i];
189 sun3_scsi_regp = (unsigned cha 189 sun3_scsi_regp = (unsigned char *)ioaddr;
190 190
191 dregs = (struct sun3_dma_regs 191 dregs = (struct sun3_dma_regs *)(((unsigned char *)ioaddr) + 8);
192 192
193 if(sun3_map_test((unsigned lon 193 if(sun3_map_test((unsigned long)dregs, &x)) {
194 unsigned short oldcsr; 194 unsigned short oldcsr;
195 195
196 oldcsr = dregs->csr; 196 oldcsr = dregs->csr;
197 dregs->csr = 0; 197 dregs->csr = 0;
198 udelay(SUN3_DMA_DELAY) 198 udelay(SUN3_DMA_DELAY);
199 if(dregs->csr == 0x140 199 if(dregs->csr == 0x1400)
200 break; 200 break;
201 201
202 dregs->csr = oldcsr; 202 dregs->csr = oldcsr;
203 } 203 }
204 204
205 iounmap((void *)ioaddr); 205 iounmap((void *)ioaddr);
206 ioaddr = 0; 206 ioaddr = 0;
207 } 207 }
208 208
209 if(!ioaddr) 209 if(!ioaddr)
210 return 0; 210 return 0;
211 211
212 #ifdef SUPPORT_TAGS 212 #ifdef SUPPORT_TAGS
213 if (setup_use_tagged_queuing < 0) 213 if (setup_use_tagged_queuing < 0)
214 setup_use_tagged_queuing = USE 214 setup_use_tagged_queuing = USE_TAGGED_QUEUING;
215 #endif 215 #endif
216 216
217 instance = scsi_register (tpnt, sizeof 217 instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
218 if(instance == NULL) 218 if(instance == NULL)
219 return 0; 219 return 0;
220 220
221 default_instance = instance; 221 default_instance = instance;
222 222
223 instance->io_port = (unsigned long) io 223 instance->io_port = (unsigned long) ioaddr;
224 instance->irq = irq; 224 instance->irq = irq;
225 225
226 NCR5380_init(instance, 0); 226 NCR5380_init(instance, 0);
227 227
228 instance->n_io_port = 32; 228 instance->n_io_port = 32;
229 229
230 ((struct NCR5380_hostdata *)instance-> 230 ((struct NCR5380_hostdata *)instance->hostdata)->ctrl = 0;
231 231
232 if (request_irq(instance->irq, scsi_su 232 if (request_irq(instance->irq, scsi_sun3_intr,
233 0, "Sun3SCSI-5380VME", 233 0, "Sun3SCSI-5380VME", instance)) {
234 #ifndef REAL_DMA 234 #ifndef REAL_DMA
235 printk("scsi%d: IRQ%d not free 235 printk("scsi%d: IRQ%d not free, interrupts disabled\n",
236 instance->host_no, inst 236 instance->host_no, instance->irq);
237 instance->irq = SCSI_IRQ_NONE; 237 instance->irq = SCSI_IRQ_NONE;
238 #else 238 #else
239 printk("scsi%d: IRQ%d not free 239 printk("scsi%d: IRQ%d not free, bailing out\n",
240 instance->host_no, inst 240 instance->host_no, instance->irq);
241 return 0; 241 return 0;
242 #endif 242 #endif
243 } 243 }
244 244
245 printk("scsi%d: Sun3 5380 VME at port 245 printk("scsi%d: Sun3 5380 VME at port %lX irq", instance->host_no, instance->io_port);
246 if (instance->irq == SCSI_IRQ_NONE) 246 if (instance->irq == SCSI_IRQ_NONE)
247 printk ("s disabled"); 247 printk ("s disabled");
248 else 248 else
249 printk (" %d", instance->irq); 249 printk (" %d", instance->irq);
250 printk(" options CAN_QUEUE=%d CMD_PER_ 250 printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d",
251 instance->can_queue, instance-> 251 instance->can_queue, instance->cmd_per_lun,
252 SUN3SCSI_PUBLIC_RELEASE); 252 SUN3SCSI_PUBLIC_RELEASE);
253 printk("\nscsi%d:", instance->host_no) 253 printk("\nscsi%d:", instance->host_no);
254 NCR5380_print_options(instance); 254 NCR5380_print_options(instance);
255 printk("\n"); 255 printk("\n");
256 256
257 dregs->csr = 0; 257 dregs->csr = 0;
258 udelay(SUN3_DMA_DELAY); 258 udelay(SUN3_DMA_DELAY);
259 dregs->csr = CSR_SCSI | CSR_FIFO | CSR 259 dregs->csr = CSR_SCSI | CSR_FIFO | CSR_INTR;
260 udelay(SUN3_DMA_DELAY); 260 udelay(SUN3_DMA_DELAY);
261 dregs->fifo_count = 0; 261 dregs->fifo_count = 0;
262 dregs->fifo_count_hi = 0; 262 dregs->fifo_count_hi = 0;
263 dregs->dma_addr_hi = 0; 263 dregs->dma_addr_hi = 0;
264 dregs->dma_addr_lo = 0; 264 dregs->dma_addr_lo = 0;
265 dregs->dma_count_hi = 0; 265 dregs->dma_count_hi = 0;
266 dregs->dma_count_lo = 0; 266 dregs->dma_count_lo = 0;
267 267
268 dregs->ivect = VME_DATA24 | (instance- 268 dregs->ivect = VME_DATA24 | (instance->irq & 0xff);
269 269
270 called = 1; 270 called = 1;
271 271
272 #ifdef RESET_BOOT 272 #ifdef RESET_BOOT
273 sun3_scsi_reset_boot(instance); 273 sun3_scsi_reset_boot(instance);
274 #endif 274 #endif
275 275
276 return 1; 276 return 1;
277 } 277 }
278 278
279 int sun3scsi_release (struct Scsi_Host *shpnt) 279 int sun3scsi_release (struct Scsi_Host *shpnt)
280 { 280 {
281 if (shpnt->irq != SCSI_IRQ_NONE) 281 if (shpnt->irq != SCSI_IRQ_NONE)
282 free_irq(shpnt->irq, shpnt); 282 free_irq(shpnt->irq, shpnt);
283 283
284 iounmap((void *)sun3_scsi_regp); 284 iounmap((void *)sun3_scsi_regp);
285 285
286 return 0; 286 return 0;
287 } 287 }
288 288
289 #ifdef RESET_BOOT 289 #ifdef RESET_BOOT
290 /* 290 /*
291 * Our 'bus reset on boot' function 291 * Our 'bus reset on boot' function
292 */ 292 */
293 293
294 static void sun3_scsi_reset_boot(struct Scsi_H 294 static void sun3_scsi_reset_boot(struct Scsi_Host *instance)
295 { 295 {
296 unsigned long end; 296 unsigned long end;
297 297
298 NCR5380_local_declare(); 298 NCR5380_local_declare();
299 NCR5380_setup(instance); 299 NCR5380_setup(instance);
300 300
301 /* 301 /*
302 * Do a SCSI reset to clean up the bus 302 * Do a SCSI reset to clean up the bus during initialization. No
303 * messing with the queues, interrupts 303 * messing with the queues, interrupts, or locks necessary here.
304 */ 304 */
305 305
306 printk( "Sun3 SCSI: resetting the SCSI 306 printk( "Sun3 SCSI: resetting the SCSI bus..." );
307 307
308 /* switch off SCSI IRQ - catch an inte 308 /* switch off SCSI IRQ - catch an interrupt without IRQ bit set else */
309 // sun3_disable_irq( IRQ_SUN3_SCS 309 // sun3_disable_irq( IRQ_SUN3_SCSI );
310 310
311 /* get in phase */ 311 /* get in phase */
312 NCR5380_write( TARGET_COMMAND_REG, 312 NCR5380_write( TARGET_COMMAND_REG,
313 PHASE_SR_TO_TCR( NCR5380 313 PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) ));
314 314
315 /* assert RST */ 315 /* assert RST */
316 NCR5380_write( INITIATOR_COMMAND_REG, 316 NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST );
317 317
318 /* The min. reset hold time is 25us, s 318 /* The min. reset hold time is 25us, so 40us should be enough */
319 udelay( 50 ); 319 udelay( 50 );
320 320
321 /* reset RST and interrupt */ 321 /* reset RST and interrupt */
322 NCR5380_write( INITIATOR_COMMAND_REG, 322 NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE );
323 NCR5380_read( RESET_PARITY_INTERRUPT_R 323 NCR5380_read( RESET_PARITY_INTERRUPT_REG );
324 324
325 for( end = jiffies + AFTER_RESET_DELAY 325 for( end = jiffies + AFTER_RESET_DELAY; time_before(jiffies, end); )
326 barrier(); 326 barrier();
327 327
328 /* switch on SCSI IRQ again */ 328 /* switch on SCSI IRQ again */
329 // sun3_enable_irq( IRQ_SUN3_SCSI 329 // sun3_enable_irq( IRQ_SUN3_SCSI );
330 330
331 printk( " done\n" ); 331 printk( " done\n" );
332 } 332 }
333 #endif 333 #endif
334 334
335 static const char * sun3scsi_info (struct Scsi 335 static const char * sun3scsi_info (struct Scsi_Host *spnt) {
336 return ""; 336 return "";
337 } 337 }
338 338
339 // safe bits for the CSR 339 // safe bits for the CSR
340 #define CSR_GOOD 0x060f 340 #define CSR_GOOD 0x060f
341 341
342 static irqreturn_t scsi_sun3_intr(int irq, voi 342 static irqreturn_t scsi_sun3_intr(int irq, void *dummy)
343 { 343 {
344 unsigned short csr = dregs->csr; 344 unsigned short csr = dregs->csr;
345 int handled = 0; 345 int handled = 0;
346 346
347 dregs->csr &= ~CSR_DMA_ENABLE; 347 dregs->csr &= ~CSR_DMA_ENABLE;
348 348
349 349
350 #ifdef SUN3_SCSI_DEBUG 350 #ifdef SUN3_SCSI_DEBUG
351 printk("scsi_intr csr %x\n", csr); 351 printk("scsi_intr csr %x\n", csr);
352 #endif 352 #endif
353 353
354 if(csr & ~CSR_GOOD) { 354 if(csr & ~CSR_GOOD) {
355 if(csr & CSR_DMA_BUSERR) { 355 if(csr & CSR_DMA_BUSERR) {
356 printk("scsi%d: bus er 356 printk("scsi%d: bus error in dma\n", default_instance->host_no);
357 #ifdef SUN3_SCSI_DEBUG 357 #ifdef SUN3_SCSI_DEBUG
358 printk("scsi: residual 358 printk("scsi: residual %x count %x addr %p dmaaddr %x\n",
359 dregs->fifo_cou 359 dregs->fifo_count,
360 dregs->dma_coun 360 dregs->dma_count_lo | (dregs->dma_count_hi << 16),
361 sun3_dma_orig_a 361 sun3_dma_orig_addr,
362 dregs->dma_addr 362 dregs->dma_addr_lo | (dregs->dma_addr_hi << 16));
363 #endif 363 #endif
364 } 364 }
365 365
366 if(csr & CSR_DMA_CONFLICT) { 366 if(csr & CSR_DMA_CONFLICT) {
367 printk("scsi%d: dma co 367 printk("scsi%d: dma conflict\n", default_instance->host_no);
368 } 368 }
369 handled = 1; 369 handled = 1;
370 } 370 }
371 371
372 if(csr & (CSR_SDB_INT | CSR_DMA_INT)) 372 if(csr & (CSR_SDB_INT | CSR_DMA_INT)) {
373 NCR5380_intr(irq, dummy); 373 NCR5380_intr(irq, dummy);
374 handled = 1; 374 handled = 1;
375 } 375 }
376 376
377 return IRQ_RETVAL(handled); 377 return IRQ_RETVAL(handled);
378 } 378 }
379 379
380 /* 380 /*
381 * Debug stuff - to be called on NMI, or sysrq 381 * Debug stuff - to be called on NMI, or sysrq key. Use at your own risk;
382 * reentering NCR5380_print_status seems to ha 382 * reentering NCR5380_print_status seems to have ugly side effects
383 */ 383 */
384 384
385 /* this doesn't seem to get used at all -- sam 385 /* this doesn't seem to get used at all -- sam */
386 #if 0 386 #if 0
387 void sun3_sun3_debug (void) 387 void sun3_sun3_debug (void)
388 { 388 {
389 unsigned long flags; 389 unsigned long flags;
390 NCR5380_local_declare(); 390 NCR5380_local_declare();
391 391
392 if (default_instance) { 392 if (default_instance) {
393 local_irq_save(flags); 393 local_irq_save(flags);
394 NCR5380_print_status(d 394 NCR5380_print_status(default_instance);
395 local_irq_restore(flag 395 local_irq_restore(flags);
396 } 396 }
397 } 397 }
398 #endif 398 #endif
399 399
400 400
401 /* sun3scsi_dma_setup() -- initialize the dma 401 /* sun3scsi_dma_setup() -- initialize the dma controller for a read/write */
402 static unsigned long sun3scsi_dma_setup(void * 402 static unsigned long sun3scsi_dma_setup(void *data, unsigned long count, int write_flag)
403 { 403 {
404 void *addr; 404 void *addr;
405 405
406 if(sun3_dma_orig_addr != NULL) 406 if(sun3_dma_orig_addr != NULL)
407 dvma_unmap(sun3_dma_orig_addr) 407 dvma_unmap(sun3_dma_orig_addr);
408 408
409 // addr = sun3_dvma_page((unsigned long)d 409 // addr = sun3_dvma_page((unsigned long)data, (unsigned long)dmabuf);
410 addr = (void *)dvma_map_vme((unsigned 410 addr = (void *)dvma_map_vme((unsigned long) data, count);
411 411
412 sun3_dma_orig_addr = addr; 412 sun3_dma_orig_addr = addr;
413 sun3_dma_orig_count = count; 413 sun3_dma_orig_count = count;
414 414
415 #ifdef SUN3_SCSI_DEBUG 415 #ifdef SUN3_SCSI_DEBUG
416 printk("scsi: dma_setup addr %p count 416 printk("scsi: dma_setup addr %p count %x\n", addr, count);
417 #endif 417 #endif
418 418
419 // dregs->fifo_count = 0; 419 // dregs->fifo_count = 0;
420 #if 0 420 #if 0
421 /* reset fifo */ 421 /* reset fifo */
422 dregs->csr &= ~CSR_FIFO; 422 dregs->csr &= ~CSR_FIFO;
423 dregs->csr |= CSR_FIFO; 423 dregs->csr |= CSR_FIFO;
424 #endif 424 #endif
425 /* set direction */ 425 /* set direction */
426 if(write_flag) 426 if(write_flag)
427 dregs->csr |= CSR_SEND; 427 dregs->csr |= CSR_SEND;
428 else 428 else
429 dregs->csr &= ~CSR_SEND; 429 dregs->csr &= ~CSR_SEND;
430 430
431 /* reset fifo */ 431 /* reset fifo */
432 // dregs->csr &= ~CSR_FIFO; 432 // dregs->csr &= ~CSR_FIFO;
433 // dregs->csr |= CSR_FIFO; 433 // dregs->csr |= CSR_FIFO;
434 434
435 dregs->csr |= CSR_PACK_ENABLE; 435 dregs->csr |= CSR_PACK_ENABLE;
436 436
437 dregs->dma_addr_hi = ((unsigned long)a 437 dregs->dma_addr_hi = ((unsigned long)addr >> 16);
438 dregs->dma_addr_lo = ((unsigned long)a 438 dregs->dma_addr_lo = ((unsigned long)addr & 0xffff);
439 439
440 dregs->dma_count_hi = 0; 440 dregs->dma_count_hi = 0;
441 dregs->dma_count_lo = 0; 441 dregs->dma_count_lo = 0;
442 dregs->fifo_count_hi = 0; 442 dregs->fifo_count_hi = 0;
443 dregs->fifo_count = 0; 443 dregs->fifo_count = 0;
444 444
445 #ifdef SUN3_SCSI_DEBUG 445 #ifdef SUN3_SCSI_DEBUG
446 printk("scsi: dma_setup done csr %x\n" 446 printk("scsi: dma_setup done csr %x\n", dregs->csr);
447 #endif 447 #endif
448 return count; 448 return count;
449 449
450 } 450 }
451 451
452 static inline unsigned long sun3scsi_dma_resid 452 static inline unsigned long sun3scsi_dma_residual(struct Scsi_Host *instance)
453 { 453 {
454 return last_residual; 454 return last_residual;
455 } 455 }
456 456
457 static inline unsigned long sun3scsi_dma_xfer_ 457 static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted,
458 458 struct scsi_cmnd *cmd,
459 459 int write_flag)
460 { 460 {
461 if(blk_fs_request(cmd->request)) 461 if(blk_fs_request(cmd->request))
462 return wanted; 462 return wanted;
463 else 463 else
464 return 0; 464 return 0;
465 } 465 }
466 466
467 static int sun3scsi_dma_start(unsigned long co 467 static int sun3scsi_dma_start(unsigned long count, char *data)
468 { 468 {
469 469
470 unsigned short csr; 470 unsigned short csr;
471 471
472 csr = dregs->csr; 472 csr = dregs->csr;
473 #ifdef SUN3_SCSI_DEBUG 473 #ifdef SUN3_SCSI_DEBUG
474 printk("scsi: dma_start data %p count 474 printk("scsi: dma_start data %p count %x csr %x fifo %x\n", data, count, csr, dregs->fifo_count);
475 #endif 475 #endif
476 476
477 dregs->dma_count_hi = (sun3_dma_orig_c 477 dregs->dma_count_hi = (sun3_dma_orig_count >> 16);
478 dregs->dma_count_lo = (sun3_dma_orig_c 478 dregs->dma_count_lo = (sun3_dma_orig_count & 0xffff);
479 479
480 dregs->fifo_count_hi = (sun3_dma_orig_ 480 dregs->fifo_count_hi = (sun3_dma_orig_count >> 16);
481 dregs->fifo_count = (sun3_dma_orig_cou 481 dregs->fifo_count = (sun3_dma_orig_count & 0xffff);
482 482
483 // if(!(csr & CSR_DMA_ENABLE)) 483 // if(!(csr & CSR_DMA_ENABLE))
484 // dregs->csr |= CSR_DMA_ENABLE; 484 // dregs->csr |= CSR_DMA_ENABLE;
485 485
486 return 0; 486 return 0;
487 } 487 }
488 488
489 /* clean up after our dma is done */ 489 /* clean up after our dma is done */
490 static int sun3scsi_dma_finish(int write_flag) 490 static int sun3scsi_dma_finish(int write_flag)
491 { 491 {
492 unsigned short fifo; 492 unsigned short fifo;
493 int ret = 0; 493 int ret = 0;
494 494
495 sun3_dma_active = 0; 495 sun3_dma_active = 0;
496 496
497 dregs->csr &= ~CSR_DMA_ENABLE; 497 dregs->csr &= ~CSR_DMA_ENABLE;
498 498
499 fifo = dregs->fifo_count; 499 fifo = dregs->fifo_count;
500 if(write_flag) { 500 if(write_flag) {
501 if((fifo > 0) && (fifo < sun3_ 501 if((fifo > 0) && (fifo < sun3_dma_orig_count))
502 fifo++; 502 fifo++;
503 } 503 }
504 504
505 last_residual = fifo; 505 last_residual = fifo;
506 #ifdef SUN3_SCSI_DEBUG 506 #ifdef SUN3_SCSI_DEBUG
507 printk("scsi: residual %x total %x\n", 507 printk("scsi: residual %x total %x\n", fifo, sun3_dma_orig_count);
508 #endif 508 #endif
509 /* empty bytes from the fifo which did 509 /* empty bytes from the fifo which didn't make it */
510 if((!write_flag) && (dregs->csr & CSR_ 510 if((!write_flag) && (dregs->csr & CSR_LEFT)) {
511 unsigned char *vaddr; 511 unsigned char *vaddr;
512 512
513 #ifdef SUN3_SCSI_DEBUG 513 #ifdef SUN3_SCSI_DEBUG
514 printk("scsi: got left over by 514 printk("scsi: got left over bytes\n");
515 #endif 515 #endif
516 516
517 vaddr = (unsigned char *)dvma_ 517 vaddr = (unsigned char *)dvma_vmetov(sun3_dma_orig_addr);
518 518
519 vaddr += (sun3_dma_orig_count 519 vaddr += (sun3_dma_orig_count - fifo);
520 vaddr--; 520 vaddr--;
521 521
522 switch(dregs->csr & CSR_LEFT) 522 switch(dregs->csr & CSR_LEFT) {
523 case CSR_LEFT_3: 523 case CSR_LEFT_3:
524 *vaddr = (dregs->bpack 524 *vaddr = (dregs->bpack_lo & 0xff00) >> 8;
525 vaddr--; 525 vaddr--;
526 526
527 case CSR_LEFT_2: 527 case CSR_LEFT_2:
528 *vaddr = (dregs->bpack 528 *vaddr = (dregs->bpack_hi & 0x00ff);
529 vaddr--; 529 vaddr--;
530 530
531 case CSR_LEFT_1: 531 case CSR_LEFT_1:
532 *vaddr = (dregs->bpack 532 *vaddr = (dregs->bpack_hi & 0xff00) >> 8;
533 break; 533 break;
534 } 534 }
535 535
536 536
537 } 537 }
538 538
539 dvma_unmap(sun3_dma_orig_addr); 539 dvma_unmap(sun3_dma_orig_addr);
540 sun3_dma_orig_addr = NULL; 540 sun3_dma_orig_addr = NULL;
541 541
542 dregs->dma_addr_hi = 0; 542 dregs->dma_addr_hi = 0;
543 dregs->dma_addr_lo = 0; 543 dregs->dma_addr_lo = 0;
544 dregs->dma_count_hi = 0; 544 dregs->dma_count_hi = 0;
545 dregs->dma_count_lo = 0; 545 dregs->dma_count_lo = 0;
546 546
547 dregs->fifo_count = 0; 547 dregs->fifo_count = 0;
548 dregs->fifo_count_hi = 0; 548 dregs->fifo_count_hi = 0;
549 549
550 dregs->csr &= ~CSR_SEND; 550 dregs->csr &= ~CSR_SEND;
551 551
552 // dregs->csr |= CSR_DMA_ENABLE; 552 // dregs->csr |= CSR_DMA_ENABLE;
553 553
554 #if 0 554 #if 0
555 /* reset fifo */ 555 /* reset fifo */
556 dregs->csr &= ~CSR_FIFO; 556 dregs->csr &= ~CSR_FIFO;
557 dregs->csr |= CSR_FIFO; 557 dregs->csr |= CSR_FIFO;
558 #endif 558 #endif
559 sun3_dma_setup_done = NULL; 559 sun3_dma_setup_done = NULL;
560 560
561 return ret; 561 return ret;
562 562
563 } 563 }
564 564
565 #include "sun3_NCR5380.c" 565 #include "sun3_NCR5380.c"
566 566
567 static struct scsi_host_template driver_templa 567 static struct scsi_host_template driver_template = {
568 .name = SUN3_SCSI_NA 568 .name = SUN3_SCSI_NAME,
569 .detect = sun3scsi_det 569 .detect = sun3scsi_detect,
570 .release = sun3scsi_rel 570 .release = sun3scsi_release,
571 .info = sun3scsi_inf 571 .info = sun3scsi_info,
572 .queuecommand = sun3scsi_que 572 .queuecommand = sun3scsi_queue_command,
573 .eh_abort_handler = sun3scsi_abo 573 .eh_abort_handler = sun3scsi_abort,
574 .eh_bus_reset_handler = sun3scsi_bus 574 .eh_bus_reset_handler = sun3scsi_bus_reset,
575 .can_queue = CAN_QUEUE, 575 .can_queue = CAN_QUEUE,
576 .this_id = 7, 576 .this_id = 7,
577 .sg_tablesize = SG_TABLESIZE 577 .sg_tablesize = SG_TABLESIZE,
578 .cmd_per_lun = CMD_PER_LUN, 578 .cmd_per_lun = CMD_PER_LUN,
579 .use_clustering = DISABLE_CLUS 579 .use_clustering = DISABLE_CLUSTERING
580 }; 580 };
581 581
582 582
583 #include "scsi_module.c" 583 #include "scsi_module.c"
584 584
585 585
|
This page was automatically generated by the
LXR engine.
|