- Kai Germaschewski: ISDN update (including Makefiles)
[davej-history.git] / drivers / scsi / mac53c94.c
blobba29e33d8f2bfb7b3b08d2f85470d07e3ed9e726
1 /*
2 * SCSI low-level driver for the 53c94 SCSI bus adaptor found
3 * on Power Macintosh computers, controlling the external SCSI chain.
4 * We assume the 53c94 is connected to a DBDMA (descriptor-based DMA)
5 * controller.
7 * Paul Mackerras, August 1996.
8 * Copyright (C) 1996 Paul Mackerras.
9 */
10 #include <linux/kernel.h>
11 #include <linux/delay.h>
12 #include <linux/types.h>
13 #include <linux/string.h>
14 #include <linux/malloc.h>
15 #include <linux/blk.h>
16 #include <linux/proc_fs.h>
17 #include <linux/stat.h>
18 #include <linux/spinlock.h>
19 #include <asm/dbdma.h>
20 #include <asm/io.h>
21 #include <asm/pgtable.h>
22 #include <asm/prom.h>
23 #include <asm/system.h>
25 #include "scsi.h"
26 #include "hosts.h"
27 #include "mac53c94.h"
29 enum fsc_phase {
30 idle,
31 selecting,
32 dataing,
33 completing,
34 busfreeing,
37 struct fsc_state {
38 volatile struct mac53c94_regs *regs;
39 int intr;
40 volatile struct dbdma_regs *dma;
41 int dmaintr;
42 int clk_freq;
43 struct Scsi_Host *host;
44 struct fsc_state *next;
45 Scsi_Cmnd *request_q;
46 Scsi_Cmnd *request_qtail;
47 Scsi_Cmnd *current_req; /* req we're currently working on */
48 enum fsc_phase phase; /* what we're currently trying to do */
49 struct dbdma_cmd *dma_cmds; /* space for dbdma commands, aligned */
50 void *dma_cmd_space;
53 static struct fsc_state *all_53c94s;
55 static void mac53c94_init(struct fsc_state *);
56 static void mac53c94_start(struct fsc_state *);
57 static void mac53c94_interrupt(int, void *, struct pt_regs *);
58 static void do_mac53c94_interrupt(int, void *, struct pt_regs *);
59 static void cmd_done(struct fsc_state *, int result);
60 static void set_dma_cmds(struct fsc_state *, Scsi_Cmnd *);
61 static int data_goes_out(Scsi_Cmnd *);
63 int
64 mac53c94_detect(Scsi_Host_Template *tp)
66 struct device_node *node;
67 int nfscs;
68 struct fsc_state *state, **prev_statep;
69 struct Scsi_Host *host;
70 void *dma_cmd_space;
71 unsigned char *clkprop;
72 int proplen;
74 nfscs = 0;
75 prev_statep = &all_53c94s;
76 for (node = find_devices("53c94"); node != 0; node = node->next) {
77 if (node->n_addrs != 2 || node->n_intrs != 2)
78 panic("53c94: expected 2 addrs and intrs (got %d/%d)",
79 node->n_addrs, node->n_intrs);
80 host = scsi_register(tp, sizeof(struct fsc_state));
81 if (host == NULL)
82 break;
83 host->unique_id = nfscs;
84 #ifndef MODULE
85 note_scsi_host(node, host);
86 #endif
88 state = (struct fsc_state *) host->hostdata;
89 if (state == 0)
90 panic("no 53c94 state");
91 state->host = host;
92 state->regs = (volatile struct mac53c94_regs *)
93 ioremap(node->addrs[0].address, 0x1000);
94 state->intr = node->intrs[0].line;
95 state->dma = (volatile struct dbdma_regs *)
96 ioremap(node->addrs[1].address, 0x1000);
97 state->dmaintr = node->intrs[1].line;
99 clkprop = get_property(node, "clock-frequency", &proplen);
100 if (clkprop == NULL || proplen != sizeof(int)) {
101 printk(KERN_ERR "%s: can't get clock frequency\n",
102 node->full_name);
103 state->clk_freq = 25000000;
104 } else
105 state->clk_freq = *(int *)clkprop;
107 /* Space for dma command list: +1 for stop command,
108 +1 to allow for aligning. */
109 dma_cmd_space = kmalloc((host->sg_tablesize + 2) *
110 sizeof(struct dbdma_cmd), GFP_KERNEL);
111 if (dma_cmd_space == 0)
112 panic("53c94: couldn't allocate dma command space");
113 state->dma_cmds = (struct dbdma_cmd *)
114 DBDMA_ALIGN(dma_cmd_space);
115 memset(state->dma_cmds, 0, (host->sg_tablesize + 1)
116 * sizeof(struct dbdma_cmd));
117 state->dma_cmd_space = dma_cmd_space;
119 *prev_statep = state;
120 prev_statep = &state->next;
122 if (request_irq(state->intr, do_mac53c94_interrupt, 0,
123 "53C94", state)) {
124 printk(KERN_ERR "mac53C94: can't get irq %d\n", state->intr);
127 mac53c94_init(state);
129 ++nfscs;
131 return nfscs;
135 mac53c94_release(struct Scsi_Host *host)
137 struct fsc_state *fp = (struct fsc_state *) host->hostdata;
139 if (fp == 0)
140 return 0;
141 if (fp->regs)
142 iounmap((void *) fp->regs);
143 if (fp->dma)
144 iounmap((void *) fp->dma);
145 kfree(fp->dma_cmd_space);
146 free_irq(fp->intr, fp);
147 return 0;
151 mac53c94_queue(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
153 unsigned long flags;
154 struct fsc_state *state;
156 #if 0
157 if (data_goes_out(cmd)) {
158 int i;
159 printk(KERN_DEBUG "mac53c94_queue %p: command is", cmd);
160 for (i = 0; i < cmd->cmd_len; ++i)
161 printk(" %.2x", cmd->cmnd[i]);
162 printk("\n" KERN_DEBUG "use_sg=%d request_bufflen=%d request_buffer=%p\n",
163 cmd->use_sg, cmd->request_bufflen, cmd->request_buffer);
165 #endif
167 cmd->scsi_done = done;
168 cmd->host_scribble = NULL;
170 state = (struct fsc_state *) cmd->host->hostdata;
172 save_flags(flags);
173 cli();
174 if (state->request_q == NULL)
175 state->request_q = cmd;
176 else
177 state->request_qtail->host_scribble = (void *) cmd;
178 state->request_qtail = cmd;
180 if (state->phase == idle)
181 mac53c94_start(state);
183 restore_flags(flags);
184 return 0;
188 mac53c94_abort(Scsi_Cmnd *cmd)
190 return SCSI_ABORT_SNOOZE;
194 mac53c94_reset(Scsi_Cmnd *cmd, unsigned how)
196 struct fsc_state *state = (struct fsc_state *) cmd->host->hostdata;
197 volatile struct mac53c94_regs *regs = state->regs;
198 volatile struct dbdma_regs *dma = state->dma;
199 unsigned long flags;
201 save_flags(flags);
202 cli();
203 st_le32(&dma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
204 regs->command = CMD_SCSI_RESET; /* assert RST */
205 eieio();
206 udelay(100); /* leave it on for a while (>= 25us) */
207 regs->command = CMD_RESET;
208 eieio();
209 udelay(20);
210 mac53c94_init(state);
211 regs->command = CMD_NOP;
212 eieio();
213 restore_flags(flags);
214 return SCSI_RESET_PENDING;
218 mac53c94_command(Scsi_Cmnd *cmd)
220 printk(KERN_DEBUG "whoops... mac53c94_command called\n");
221 return -1;
224 static void
225 mac53c94_init(struct fsc_state *state)
227 volatile struct mac53c94_regs *regs = state->regs;
228 volatile struct dbdma_regs *dma = state->dma;
229 int x;
231 regs->config1 = state->host->this_id | CF1_PAR_ENABLE;
232 regs->sel_timeout = TIMO_VAL(250); /* 250ms */
233 regs->clk_factor = CLKF_VAL(state->clk_freq);
234 regs->config2 = CF2_FEATURE_EN;
235 regs->config3 = 0;
236 regs->sync_period = 0;
237 regs->sync_offset = 0;
238 eieio();
239 x = regs->interrupt;
240 st_le32(&dma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
244 * Start the next command for a 53C94.
245 * Should be called with interrupts disabled.
247 static void
248 mac53c94_start(struct fsc_state *state)
250 Scsi_Cmnd *cmd;
251 volatile struct mac53c94_regs *regs = state->regs;
252 int i;
254 if (state->phase != idle || state->current_req != NULL)
255 panic("inappropriate mac53c94_start (state=%p)", state);
256 if (state->request_q == NULL)
257 return;
258 state->current_req = cmd = state->request_q;
259 state->request_q = (Scsi_Cmnd *) cmd->host_scribble;
261 /* Off we go */
262 regs->count_lo = 0;
263 regs->count_mid = 0;
264 regs->count_hi = 0;
265 eieio();
266 regs->command = CMD_NOP + CMD_DMA_MODE;
267 udelay(1);
268 eieio();
269 regs->command = CMD_FLUSH;
270 udelay(1);
271 eieio();
272 regs->dest_id = cmd->target;
273 regs->sync_period = 0;
274 regs->sync_offset = 0;
275 eieio();
277 /* load the command into the FIFO */
278 for (i = 0; i < cmd->cmd_len; ++i) {
279 regs->fifo = cmd->cmnd[i];
280 eieio();
283 /* do select without ATN XXX */
284 regs->command = CMD_SELECT;
285 state->phase = selecting;
287 if (cmd->use_sg > 0 || cmd->request_bufflen != 0)
288 set_dma_cmds(state, cmd);
291 static void
292 do_mac53c94_interrupt(int irq, void *dev_id, struct pt_regs *ptregs)
294 unsigned long flags;
296 spin_lock_irqsave(&io_request_lock, flags);
297 mac53c94_interrupt(irq, dev_id, ptregs);
298 spin_unlock_irqrestore(&io_request_lock, flags);
301 static void
302 mac53c94_interrupt(int irq, void *dev_id, struct pt_regs *ptregs)
304 struct fsc_state *state = (struct fsc_state *) dev_id;
305 volatile struct mac53c94_regs *regs = state->regs;
306 volatile struct dbdma_regs *dma = state->dma;
307 Scsi_Cmnd *cmd = state->current_req;
308 int nb, stat, seq, intr;
309 static int mac53c94_errors;
312 * Apparently, reading the interrupt register unlatches
313 * the status and sequence step registers.
315 seq = regs->seqstep;
316 stat = regs->status;
317 intr = regs->interrupt;
319 #if 0
320 printk(KERN_DEBUG "mac53c94_intr, intr=%x stat=%x seq=%x phase=%d\n",
321 intr, stat, seq, state->phase);
322 #endif
324 if (intr & INTR_RESET) {
325 /* SCSI bus was reset */
326 printk(KERN_INFO "external SCSI bus reset detected\n");
327 regs->command = CMD_NOP;
328 st_le32(&dma->control, RUN << 16); /* stop dma */
329 cmd_done(state, DID_RESET << 16);
330 return;
332 if (intr & INTR_ILL_CMD) {
333 printk(KERN_ERR "53c94: illegal cmd, intr=%x stat=%x seq=%x phase=%d\n",
334 intr, stat, seq, state->phase);
335 cmd_done(state, DID_ERROR << 16);
336 return;
338 if (stat & STAT_ERROR) {
339 #if 0
340 /* XXX these seem to be harmless? */
341 printk("53c94: bad error, intr=%x stat=%x seq=%x phase=%d\n",
342 intr, stat, seq, state->phase);
343 #endif
344 ++mac53c94_errors;
345 regs->command = CMD_NOP + CMD_DMA_MODE;
346 eieio();
348 if (cmd == 0) {
349 printk(KERN_DEBUG "53c94: interrupt with no command active?\n");
350 return;
352 if (stat & STAT_PARITY) {
353 printk(KERN_ERR "mac53c94: parity error\n");
354 cmd_done(state, DID_PARITY << 16);
355 return;
357 switch (state->phase) {
358 case selecting:
359 if (intr & INTR_DISCONNECT) {
360 /* selection timed out */
361 cmd_done(state, DID_BAD_TARGET << 16);
362 return;
364 if (intr != INTR_BUS_SERV + INTR_DONE) {
365 printk(KERN_DEBUG "got intr %x during selection\n", intr);
366 cmd_done(state, DID_ERROR << 16);
367 return;
369 if ((seq & SS_MASK) != SS_DONE) {
370 printk(KERN_DEBUG "seq step %x after command\n", seq);
371 cmd_done(state, DID_ERROR << 16);
372 return;
374 regs->command = CMD_NOP;
375 /* set DMA controller going if any data to transfer */
376 if ((stat & (STAT_MSG|STAT_CD)) == 0
377 && (cmd->use_sg > 0 || cmd->request_bufflen != 0)) {
378 nb = cmd->SCp.this_residual;
379 if (nb > 0xfff0)
380 nb = 0xfff0;
381 cmd->SCp.this_residual -= nb;
382 regs->count_lo = nb;
383 regs->count_mid = nb >> 8;
384 eieio();
385 regs->command = CMD_DMA_MODE + CMD_NOP;
386 eieio();
387 st_le32(&dma->cmdptr, virt_to_phys(state->dma_cmds));
388 st_le32(&dma->control, (RUN << 16) | RUN);
389 eieio();
390 regs->command = CMD_DMA_MODE + CMD_XFER_DATA;
391 state->phase = dataing;
392 break;
393 } else if ((stat & STAT_PHASE) == STAT_CD + STAT_IO) {
394 /* up to status phase already */
395 regs->command = CMD_I_COMPLETE;
396 state->phase = completing;
397 } else {
398 printk(KERN_DEBUG "in unexpected phase %x after cmd\n",
399 stat & STAT_PHASE);
400 cmd_done(state, DID_ERROR << 16);
401 return;
403 break;
405 case dataing:
406 if (intr != INTR_BUS_SERV) {
407 printk(KERN_DEBUG "got intr %x before status\n", intr);
408 cmd_done(state, DID_ERROR << 16);
409 return;
411 if (cmd->SCp.this_residual != 0
412 && (stat & (STAT_MSG|STAT_CD)) == 0) {
413 /* Set up the count regs to transfer more */
414 nb = cmd->SCp.this_residual;
415 if (nb > 0xfff0)
416 nb = 0xfff0;
417 cmd->SCp.this_residual -= nb;
418 regs->count_lo = nb;
419 regs->count_mid = nb >> 8;
420 eieio();
421 regs->command = CMD_DMA_MODE + CMD_NOP;
422 eieio();
423 regs->command = CMD_DMA_MODE + CMD_XFER_DATA;
424 break;
426 if ((stat & STAT_PHASE) != STAT_CD + STAT_IO) {
427 printk(KERN_DEBUG "intr %x before data xfer complete\n", intr);
429 st_le32(&dma->control, RUN << 16); /* stop dma */
430 /* should check dma status */
431 regs->command = CMD_I_COMPLETE;
432 state->phase = completing;
433 break;
434 case completing:
435 if (intr != INTR_DONE) {
436 printk(KERN_DEBUG "got intr %x on completion\n", intr);
437 cmd_done(state, DID_ERROR << 16);
438 return;
440 cmd->SCp.Status = regs->fifo; eieio();
441 cmd->SCp.Message = regs->fifo; eieio();
442 cmd->result =
443 regs->command = CMD_ACCEPT_MSG;
444 state->phase = busfreeing;
445 break;
446 case busfreeing:
447 if (intr != INTR_DISCONNECT) {
448 printk(KERN_DEBUG "got intr %x when expected disconnect\n", intr);
450 cmd_done(state, (DID_OK << 16) + (cmd->SCp.Message << 8)
451 + cmd->SCp.Status);
452 break;
453 default:
454 printk(KERN_DEBUG "don't know about phase %d\n", state->phase);
458 static void
459 cmd_done(struct fsc_state *state, int result)
461 Scsi_Cmnd *cmd;
463 cmd = state->current_req;
464 if (cmd != 0) {
465 cmd->result = result;
466 (*cmd->scsi_done)(cmd);
467 state->current_req = NULL;
469 state->phase = idle;
470 mac53c94_start(state);
474 * Set up DMA commands for transferring data.
476 static void
477 set_dma_cmds(struct fsc_state *state, Scsi_Cmnd *cmd)
479 int i, dma_cmd, total;
480 struct scatterlist *scl;
481 struct dbdma_cmd *dcmds;
483 dma_cmd = data_goes_out(cmd)? OUTPUT_MORE: INPUT_MORE;
484 dcmds = state->dma_cmds;
485 if (cmd->use_sg > 0) {
486 total = 0;
487 scl = (struct scatterlist *) cmd->buffer;
488 for (i = 0; i < cmd->use_sg; ++i) {
489 if (scl->length > 0xffff)
490 panic("mac53c94: scatterlist element >= 64k");
491 total += scl->length;
492 st_le16(&dcmds->req_count, scl->length);
493 st_le16(&dcmds->command, dma_cmd);
494 st_le32(&dcmds->phy_addr, virt_to_phys(scl->address));
495 dcmds->xfer_status = 0;
496 ++scl;
497 ++dcmds;
499 } else {
500 total = cmd->request_bufflen;
501 if (total > 0xffff)
502 panic("mac53c94: transfer size >= 64k");
503 st_le16(&dcmds->req_count, total);
504 st_le32(&dcmds->phy_addr, virt_to_phys(cmd->request_buffer));
505 dcmds->xfer_status = 0;
506 ++dcmds;
508 dma_cmd += OUTPUT_LAST - OUTPUT_MORE;
509 st_le16(&dcmds[-1].command, dma_cmd);
510 st_le16(&dcmds->command, DBDMA_STOP);
511 cmd->SCp.this_residual = total;
515 * Work out whether data will be going out from the host adaptor or into it.
516 * (If this information is available from somewhere else in the scsi
517 * code, somebody please let me know :-)
519 static int
520 data_goes_out(Scsi_Cmnd *cmd)
522 switch (cmd->cmnd[0]) {
523 case CHANGE_DEFINITION:
524 case COMPARE:
525 case COPY:
526 case COPY_VERIFY:
527 case FORMAT_UNIT:
528 case LOG_SELECT:
529 case MEDIUM_SCAN:
530 case MODE_SELECT:
531 case MODE_SELECT_10:
532 case REASSIGN_BLOCKS:
533 case RESERVE:
534 case SEARCH_EQUAL:
535 case SEARCH_EQUAL_12:
536 case SEARCH_HIGH:
537 case SEARCH_HIGH_12:
538 case SEARCH_LOW:
539 case SEARCH_LOW_12:
540 case SEND_DIAGNOSTIC:
541 case SEND_VOLUME_TAG:
542 case SET_WINDOW:
543 case UPDATE_BLOCK:
544 case WRITE_BUFFER:
545 case WRITE_6:
546 case WRITE_10:
547 case WRITE_12:
548 case WRITE_LONG:
549 case WRITE_LONG_2: /* alternate code for WRITE_LONG */
550 case WRITE_SAME:
551 case WRITE_VERIFY:
552 case WRITE_VERIFY_12:
553 return 1;
554 default:
555 return 0;
559 static Scsi_Host_Template driver_template = SCSI_MAC53C94;
561 #include "scsi_module.c"