import of upstream 2.4.34.4 from kernel.org
[linux-2.4.git] / drivers / scsi / mac53c94.c
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.
6  *
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/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>
20 #include <asm/io.h>
21 #include <asm/pgtable.h>
22 #include <asm/prom.h>
23 #include <asm/system.h>
24
25 #include "scsi.h"
26 #include "hosts.h"
27 #include "mac53c94.h"
28
29 enum fsc_phase {
30         idle,
31         selecting,
32         dataing,
33         completing,
34         busfreeing,
35 };
36
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;
51 };
52
53 static struct fsc_state *all_53c94s;
54
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 *);
62
63 int
64 mac53c94_detect(Scsi_Host_Template *tp)
65 {
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;
73
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
87
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;
98
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;
106
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;
118
119                 *prev_statep = state;
120                 prev_statep = &state->next;
121
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);
125                 }
126
127                 mac53c94_init(state);
128
129                 ++nfscs;
130         }
131         return nfscs;
132 }
133
134 int
135 mac53c94_release(struct Scsi_Host *host)
136 {
137         struct fsc_state *fp = (struct fsc_state *) host->hostdata;
138
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;
148 }
149
150 int
151 mac53c94_queue(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
152 {
153         unsigned long flags;
154         struct fsc_state *state;
155
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);
164         }
165 #endif
166
167         cmd->scsi_done = done;
168         cmd->host_scribble = NULL;
169
170         state = (struct fsc_state *) cmd->host->hostdata;
171
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;
179
180         if (state->phase == idle)
181                 mac53c94_start(state);
182
183         restore_flags(flags);
184         return 0;
185 }
186
187 int
188 mac53c94_abort(Scsi_Cmnd *cmd)
189 {
190         return SCSI_ABORT_SNOOZE;
191 }
192
193 int
194 mac53c94_reset(Scsi_Cmnd *cmd, unsigned how)
195 {
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;
200
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;
215 }
216
217 int
218 mac53c94_command(Scsi_Cmnd *cmd)
219 {
220         printk(KERN_DEBUG "whoops... mac53c94_command called\n");
221         return -1;
222 }
223
224 static void
225 mac53c94_init(struct fsc_state *state)
226 {
227         volatile struct mac53c94_regs *regs = state->regs;
228         volatile struct dbdma_regs *dma = state->dma;
229         int x;
230
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);
241 }
242
243 /*
244  * Start the next command for a 53C94.
245  * Should be called with interrupts disabled.
246  */
247 static void
248 mac53c94_start(struct fsc_state *state)
249 {
250         Scsi_Cmnd *cmd;
251         volatile struct mac53c94_regs *regs = state->regs;
252         int i;
253
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;
260
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();
276
277         /* load the command into the FIFO */
278         for (i = 0; i < cmd->cmd_len; ++i) {
279                 regs->fifo = cmd->cmnd[i];
280                 eieio();
281         }
282
283         /* do select without ATN XXX */
284         regs->command = CMD_SELECT;
285         state->phase = selecting;
286
287         if (cmd->use_sg > 0 || cmd->request_bufflen != 0)
288                 set_dma_cmds(state, cmd);
289 }
290
291 static void
292 do_mac53c94_interrupt(int irq, void *dev_id, struct pt_regs *ptregs)
293 {
294         unsigned long flags;
295
296         spin_lock_irqsave(&io_request_lock, flags);
297         mac53c94_interrupt(irq, dev_id, ptregs);
298         spin_unlock_irqrestore(&io_request_lock, flags);
299 }
300
301 static void
302 mac53c94_interrupt(int irq, void *dev_id, struct pt_regs *ptregs)
303 {
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;
310
311         /*
312          * Apparently, reading the interrupt register unlatches
313          * the status and sequence step registers.
314          */
315         seq = regs->seqstep;
316         stat = regs->status;
317         intr = regs->interrupt;
318
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
323
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;
331         }
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;
337         }
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();
347         }
348         if (cmd == 0) {
349                 printk(KERN_DEBUG "53c94: interrupt with no command active?\n");
350                 return;
351         }
352         if (stat & STAT_PARITY) {
353                 printk(KERN_ERR "mac53c94: parity error\n");
354                 cmd_done(state, DID_PARITY << 16);
355                 return;
356         }
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;
363                 }
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;
368                 }
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;
373                 }
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;
402                 }
403                 break;
404
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;
410                 }
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;
425                 }
426                 if ((stat & STAT_PHASE) != STAT_CD + STAT_IO) {
427                         printk(KERN_DEBUG "intr %x before data xfer complete\n", intr);
428                 }
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;
439                 }
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);
449                 }
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);
455         }
456 }
457
458 static void
459 cmd_done(struct fsc_state *state, int result)
460 {
461         Scsi_Cmnd *cmd;
462
463         cmd = state->current_req;
464         if (cmd != 0) {
465                 cmd->result = result;
466                 (*cmd->scsi_done)(cmd);
467                 state->current_req = NULL;
468         }
469         state->phase = idle;
470         mac53c94_start(state);
471 }
472
473 /*
474  * Set up DMA commands for transferring data.
475  */
476 static void
477 set_dma_cmds(struct fsc_state *state, Scsi_Cmnd *cmd)
478 {
479         int i, dma_cmd, total;
480         struct scatterlist *scl;
481         struct dbdma_cmd *dcmds;
482
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;
498                 }
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;
507         }
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;
512 }
513
514 /*
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 :-)
518  */
519 static int
520 data_goes_out(Scsi_Cmnd *cmd)
521 {
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;
556         }
557 }
558
559 static Scsi_Host_Template driver_template = SCSI_MAC53C94;
560
561 #include "scsi_module.c"