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)
7 * Paul Mackerras, August 1996.
8 * Copyright (C) 1996 Paul Mackerras.
10 #include <linux/kernel.h>
11 #include <linux/delay.h>
12 #include <linux/types.h>
13 #include <linux/string.h>
14 #include <linux/slab.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>
21 #include <asm/pgtable.h>
23 #include <asm/system.h>
38 volatile struct mac53c94_regs *regs;
40 volatile struct dbdma_regs *dma;
43 struct Scsi_Host *host;
44 struct fsc_state *next;
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 */
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 *);
64 mac53c94_detect(Scsi_Host_Template *tp)
66 struct device_node *node;
68 struct fsc_state *state, **prev_statep;
69 struct Scsi_Host *host;
71 unsigned char *clkprop;
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));
83 host->unique_id = nfscs;
85 note_scsi_host(node, host);
88 state = (struct fsc_state *) host->hostdata;
90 panic("no 53c94 state");
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",
103 state->clk_freq = 25000000;
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,
124 printk(KERN_ERR "mac53C94: can't get irq %d\n", state->intr);
127 mac53c94_init(state);
135 mac53c94_release(struct Scsi_Host *host)
137 struct fsc_state *fp = (struct fsc_state *) host->hostdata;
142 iounmap((void *) fp->regs);
144 iounmap((void *) fp->dma);
145 kfree(fp->dma_cmd_space);
146 free_irq(fp->intr, fp);
151 mac53c94_queue(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
154 struct fsc_state *state;
157 if (data_goes_out(cmd)) {
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);
167 cmd->scsi_done = done;
168 cmd->host_scribble = NULL;
170 state = (struct fsc_state *) cmd->host->hostdata;
174 if (state->request_q == NULL)
175 state->request_q = cmd;
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);
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;
203 st_le32(&dma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
204 regs->command = CMD_SCSI_RESET; /* assert RST */
206 udelay(100); /* leave it on for a while (>= 25us) */
207 regs->command = CMD_RESET;
210 mac53c94_init(state);
211 regs->command = CMD_NOP;
213 restore_flags(flags);
214 return SCSI_RESET_PENDING;
218 mac53c94_command(Scsi_Cmnd *cmd)
220 printk(KERN_DEBUG "whoops... mac53c94_command called\n");
225 mac53c94_init(struct fsc_state *state)
227 volatile struct mac53c94_regs *regs = state->regs;
228 volatile struct dbdma_regs *dma = state->dma;
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;
236 regs->sync_period = 0;
237 regs->sync_offset = 0;
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.
248 mac53c94_start(struct fsc_state *state)
251 volatile struct mac53c94_regs *regs = state->regs;
254 if (state->phase != idle || state->current_req != NULL)
255 panic("inappropriate mac53c94_start (state=%p)", state);
256 if (state->request_q == NULL)
258 state->current_req = cmd = state->request_q;
259 state->request_q = (Scsi_Cmnd *) cmd->host_scribble;
266 regs->command = CMD_NOP + CMD_DMA_MODE;
269 regs->command = CMD_FLUSH;
272 regs->dest_id = cmd->target;
273 regs->sync_period = 0;
274 regs->sync_offset = 0;
277 /* load the command into the FIFO */
278 for (i = 0; i < cmd->cmd_len; ++i) {
279 regs->fifo = cmd->cmnd[i];
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);
292 do_mac53c94_interrupt(int irq, void *dev_id, struct pt_regs *ptregs)
296 spin_lock_irqsave(&io_request_lock, flags);
297 mac53c94_interrupt(irq, dev_id, ptregs);
298 spin_unlock_irqrestore(&io_request_lock, flags);
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.
317 intr = regs->interrupt;
320 printk(KERN_DEBUG "mac53c94_intr, intr=%x stat=%x seq=%x phase=%d\n",
321 intr, stat, seq, state->phase);
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);
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);
338 if (stat & STAT_ERROR) {
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);
345 regs->command = CMD_NOP + CMD_DMA_MODE;
349 printk(KERN_DEBUG "53c94: interrupt with no command active?\n");
352 if (stat & STAT_PARITY) {
353 printk(KERN_ERR "mac53c94: parity error\n");
354 cmd_done(state, DID_PARITY << 16);
357 switch (state->phase) {
359 if (intr & INTR_DISCONNECT) {
360 /* selection timed out */
361 cmd_done(state, DID_BAD_TARGET << 16);
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);
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);
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;
381 cmd->SCp.this_residual -= nb;
383 regs->count_mid = nb >> 8;
385 regs->command = CMD_DMA_MODE + CMD_NOP;
387 st_le32(&dma->cmdptr, virt_to_phys(state->dma_cmds));
388 st_le32(&dma->control, (RUN << 16) | RUN);
390 regs->command = CMD_DMA_MODE + CMD_XFER_DATA;
391 state->phase = dataing;
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;
398 printk(KERN_DEBUG "in unexpected phase %x after cmd\n",
400 cmd_done(state, DID_ERROR << 16);
406 if (intr != INTR_BUS_SERV) {
407 printk(KERN_DEBUG "got intr %x before status\n", intr);
408 cmd_done(state, DID_ERROR << 16);
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;
417 cmd->SCp.this_residual -= nb;
419 regs->count_mid = nb >> 8;
421 regs->command = CMD_DMA_MODE + CMD_NOP;
423 regs->command = CMD_DMA_MODE + CMD_XFER_DATA;
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;
435 if (intr != INTR_DONE) {
436 printk(KERN_DEBUG "got intr %x on completion\n", intr);
437 cmd_done(state, DID_ERROR << 16);
440 cmd->SCp.Status = regs->fifo; eieio();
441 cmd->SCp.Message = regs->fifo; eieio();
443 regs->command = CMD_ACCEPT_MSG;
444 state->phase = 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)
454 printk(KERN_DEBUG "don't know about phase %d\n", state->phase);
459 cmd_done(struct fsc_state *state, int result)
463 cmd = state->current_req;
465 cmd->result = result;
466 (*cmd->scsi_done)(cmd);
467 state->current_req = NULL;
470 mac53c94_start(state);
474 * Set up DMA commands for transferring data.
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) {
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;
500 total = cmd->request_bufflen;
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;
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 :-)
520 data_goes_out(Scsi_Cmnd *cmd)
522 switch (cmd->cmnd[0]) {
523 case CHANGE_DEFINITION:
532 case REASSIGN_BLOCKS:
535 case SEARCH_EQUAL_12:
540 case SEND_DIAGNOSTIC:
541 case SEND_VOLUME_TAG:
549 case WRITE_LONG_2: /* alternate code for WRITE_LONG */
552 case WRITE_VERIFY_12:
559 static Scsi_Host_Template driver_template = SCSI_MAC53C94;
561 #include "scsi_module.c"