import of ftp.dlink.com/GPL/DSMG-600_reB/ppclinux.tar.gz
[linux-2.4.21-pre4.git] / drivers / acorn / scsi / fas216.c
1 /*
2  *  linux/arch/arm/drivers/scsi/fas216.c
3  *
4  *  Copyright (C) 1997-2000 Russell King
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * Based on information in qlogicfas.c by Tom Zerucha, Michael Griffith, and
11  * other sources, including:
12  *   the AMD Am53CF94 data sheet
13  *   the AMD Am53C94 data sheet 
14  *
15  * This is a generic driver.  To use it, have a look at cumana_2.c.  You
16  * should define your own structure that overlays FAS216_Info, eg:
17  * struct my_host_data {
18  *    FAS216_Info info;
19  *    ... my host specific data ...
20  * };
21  *
22  * Changelog:
23  *  30-08-1997  RMK     Created
24  *  14-09-1997  RMK     Started disconnect support
25  *  08-02-1998  RMK     Corrected real DMA support
26  *  15-02-1998  RMK     Started sync xfer support
27  *  06-04-1998  RMK     Tightened conditions for printing incomplete
28  *                      transfers
29  *  02-05-1998  RMK     Added extra checks in fas216_reset
30  *  24-05-1998  RMK     Fixed synchronous transfers with period >= 200ns
31  *  27-06-1998  RMK     Changed asm/delay.h to linux/delay.h
32  *  26-08-1998  RMK     Improved message support wrt MESSAGE_REJECT
33  *  02-04-2000  RMK     Converted to use the new error handling, and
34  *                      automatically request sense data upon check
35  *                      condition status from targets.
36  *
37  * Todo:
38  *  - allow individual devices to enable sync xfers.
39  */
40 #include <linux/module.h>
41 #include <linux/blk.h>
42 #include <linux/kernel.h>
43 #include <linux/string.h>
44 #include <linux/ioport.h>
45 #include <linux/sched.h>
46 #include <linux/proc_fs.h>
47 #include <linux/unistd.h>
48 #include <linux/stat.h>
49 #include <linux/delay.h>
50 #include <linux/init.h>
51
52 #include <asm/dma.h>
53 #include <asm/io.h>
54 #include <asm/irq.h>
55 #include <asm/ecard.h>
56
57 #define FAS216_C
58
59 #include "../../scsi/scsi.h"
60 #include "../../scsi/hosts.h"
61 #include "fas216.h"
62
63 #define VER_MAJOR       0
64 #define VER_MINOR       0
65 #define VER_PATCH       5
66
67 /* NOTE: SCSI2 Synchronous transfers *require* DMA according to
68  *  the data sheet.  This restriction is crazy, especially when
69  *  you only want to send 16 bytes!  What were the guys who
70  *  designed this chip on at that time?  Did they read the SCSI2
71  *  spec at all?  The following sections are taken from the SCSI2
72  *  standard (s2r10) concerning this:
73  *
74  * > IMPLEMENTORS NOTES:
75  * >   (1)  Re-negotiation at every selection is not recommended, since a
76  * >   significant performance impact is likely.
77  *
78  * >  The implied synchronous agreement shall remain in effect until a BUS DEVICE
79  * >  RESET message is received, until a hard reset condition occurs, or until one
80  * >  of the two SCSI devices elects to modify the agreement.  The default data
81  * >  transfer mode is asynchronous data transfer mode.  The default data transfer
82  * >  mode is entered at power on, after a BUS DEVICE RESET message, or after a hard
83  * >  reset condition.
84  *
85  *  In total, this means that once you have elected to use synchronous
86  *  transfers, you must always use DMA.
87  *
88  *  I was thinking that this was a good chip until I found this restriction ;(
89  */
90 #define SCSI2_SYNC
91 #undef  SCSI2_WIDE
92 #undef  SCSI2_TAG
93
94 #undef DEBUG_CONNECT
95 #undef DEBUG_BUSSERVICE
96 #undef DEBUG_FUNCTIONDONE
97 #undef DEBUG_MESSAGES
98
99 #undef CHECK_STRUCTURE
100
101 static struct { int stat, ssr, isr, ph; } list[8];
102 static int ptr;
103
104 static void fas216_dumpstate(FAS216_Info *info)
105 {
106         unsigned char is, stat, inst;
107
108         is   = inb(REG_IS(info));
109         stat = inb(REG_STAT(info));
110         inst = inb(REG_INST(info));
111         
112         printk("FAS216: CTCL=%02X CTCM=%02X CMD=%02X STAT=%02X"
113                " INST=%02X IS=%02X CFIS=%02X",
114                 inb(REG_CTCL(info)), inb(REG_CTCM(info)),
115                 inb(REG_CMD(info)),  stat, inst, is,
116                 inb(REG_CFIS(info)));
117         printk(" CNTL1=%02X CNTL2=%02X CNTL3=%02X CTCH=%02X\n",
118                 inb(REG_CNTL1(info)), inb(REG_CNTL2(info)),
119                 inb(REG_CNTL3(info)), inb(REG_CTCH(info)));
120 }
121
122 static void fas216_dumpinfo(FAS216_Info *info)
123 {
124         static int used = 0;
125         int i;
126
127         if (used++)
128                 return;
129
130         printk("FAS216_Info=\n");
131         printk("  { magic_start=%lX host=%p SCpnt=%p origSCpnt=%p\n",
132                 info->magic_start, info->host, info->SCpnt,
133                 info->origSCpnt);
134         printk("    scsi={ io_port=%X io_shift=%X irq=%X cfg={ %X %X %X %X }\n",
135                 info->scsi.io_port, info->scsi.io_shift, info->scsi.irq,
136                 info->scsi.cfg[0], info->scsi.cfg[1], info->scsi.cfg[2],
137                 info->scsi.cfg[3]);
138         printk("           type=%p phase=%X reconnected={ target=%d lun=%d tag=%d }\n",
139                 info->scsi.type, info->scsi.phase,
140                 info->scsi.reconnected.target,
141                 info->scsi.reconnected.lun, info->scsi.reconnected.tag);
142         printk("           SCp={ ptr=%p this_residual=%X buffer=%p buffers_residual=%X }\n",
143                 info->scsi.SCp.ptr, info->scsi.SCp.this_residual,
144                 info->scsi.SCp.buffer, info->scsi.SCp.buffers_residual);
145         printk("      msgs async_stp=%X disconnectable=%d aborting=%d }\n",
146                 info->scsi.async_stp,
147                 info->scsi.disconnectable, info->scsi.aborting);
148         printk("    stats={ queues=%X removes=%X fins=%X reads=%X writes=%X miscs=%X\n"
149                "            disconnects=%X aborts=%X bus_resets=%X host_resets=%X}\n",
150                 info->stats.queues, info->stats.removes, info->stats.fins,
151                 info->stats.reads, info->stats.writes, info->stats.miscs,
152                 info->stats.disconnects, info->stats.aborts, info->stats.bus_resets,
153                 info->stats.host_resets);
154         printk("    ifcfg={ clockrate=%X select_timeout=%X asyncperiod=%X sync_max_depth=%X }\n",
155                 info->ifcfg.clockrate, info->ifcfg.select_timeout,
156                 info->ifcfg.asyncperiod, info->ifcfg.sync_max_depth);
157         for (i = 0; i < 8; i++) {
158                 printk("    busyluns[%d]=%X dev[%d]={ disconnect_ok=%d stp=%X sof=%X sync_state=%X }\n",
159                         i, info->busyluns[i], i,
160                         info->device[i].disconnect_ok, info->device[i].stp,
161                         info->device[i].sof, info->device[i].sync_state);
162         }
163         printk("    dma={ transfer_type=%X setup=%p pseudo=%p stop=%p }\n",
164                 info->dma.transfer_type, info->dma.setup,
165                 info->dma.pseudo, info->dma.stop);
166         printk("    internal_done=%X magic_end=%lX }\n",
167                 info->internal_done, info->magic_end);
168 }
169
170 #ifdef CHECK_STRUCTURE
171 static void __fas216_checkmagic(FAS216_Info *info, const char *func)
172 {
173         int corruption = 0;
174         if (info->magic_start != MAGIC) {
175                 printk(KERN_CRIT "FAS216 Error: magic at start corrupted\n");
176                 corruption++;
177         }
178         if (info->magic_end != MAGIC) {
179                 printk(KERN_CRIT "FAS216 Error: magic at end corrupted\n");
180                 corruption++;
181         }
182         if (corruption) {
183                 fas216_dumpinfo(info);
184                 panic("scsi memory space corrupted in %s", func);
185         }
186 }
187 #define fas216_checkmagic(info) __fas216_checkmagic((info), __FUNCTION__)
188 #else
189 #define fas216_checkmagic(info)
190 #endif
191
192 static const char *fas216_bus_phase(int stat)
193 {
194         static const char *phases[] = {
195                 "DATA OUT", "DATA IN",
196                 "COMMAND", "STATUS",
197                 "MISC OUT", "MISC IN",
198                 "MESG OUT", "MESG IN"
199         };
200
201         return phases[stat & STAT_BUSMASK];
202 }
203
204 static const char *fas216_drv_phase(FAS216_Info *info)
205 {
206         switch (info->scsi.phase) {
207         case PHASE_IDLE:                return "idle";
208         case PHASE_SELECTION:           return "selection";
209         case PHASE_COMMAND:             return "command";
210         case PHASE_RECONNECTED:         return "reconnected";
211         case PHASE_DATAOUT:             return "data out";
212         case PHASE_DATAIN:              return "data in";
213         case PHASE_MSGIN:               return "message in";
214         case PHASE_MSGIN_DISCONNECT:    return "disconnect";
215         case PHASE_MSGOUT_EXPECT:       return "expect message out";
216         case PHASE_MSGOUT:              return "message out";
217         case PHASE_STATUS:              return "status";
218         case PHASE_DONE:                return "done";
219         default:                        return "???";
220         }
221 }
222
223 static char fas216_target(FAS216_Info *info)
224 {
225         if (info->SCpnt)
226                 return '0' + info->SCpnt->target;
227         else
228                 return 'H';
229 }
230
231 static void add_debug_list(int stat, int ssr, int isr, int ph)
232 {
233         list[ptr].stat = stat;
234         list[ptr].ssr = ssr;
235         list[ptr].isr = isr;
236         list[ptr].ph = ph;
237
238         ptr = (ptr + 1) & 7;
239 }
240
241 static void print_debug_list(void)
242 {
243         int i;
244
245         i = ptr;
246
247         printk(KERN_ERR "SCSI IRQ trail: ");
248         do {
249                 printk("%02X:%02X:%02X:%1X ",
250                         list[i].stat, list[i].ssr,
251                         list[i].isr, list[i].ph);
252                 i = (i + 1) & 7;
253         } while (i != ptr);
254         printk("\n");
255 }
256
257 static void fas216_done(FAS216_Info *info, unsigned int result);
258
259 /* Function: int fas216_clockrate(unsigned int clock)
260  * Purpose : calculate correct value to be written into clock conversion
261  *           factor register.
262  * Params  : clock - clock speed in MHz
263  * Returns : CLKF_ value
264  */
265 static int fas216_clockrate(int clock)
266 {
267         if (clock <= 10 || clock > 40) {
268                 printk(KERN_CRIT
269                        "fas216: invalid clock rate: check your driver!\n");
270                 clock = -1;
271         } else
272                 clock = ((clock - 1) / 5 + 1) & 7;
273
274         return clock;
275 }
276
277 /* Function: unsigned short fas216_get_last_msg(FAS216_Info *info, int pos)
278  * Purpose : retrieve a last message from the list, using position in fifo
279  * Params  : info - interface to search
280  *         : pos  - current fifo position
281  */
282 static inline unsigned short
283 fas216_get_last_msg(FAS216_Info *info, int pos)
284 {
285         unsigned short packed_msg = NOP;
286         struct message *msg;
287         int msgnr = 0;
288
289         while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
290                 if (pos >= msg->fifo)
291                         break;
292         }
293
294         if (msg) {
295                 if (msg->msg[0] == EXTENDED_MESSAGE)
296                         packed_msg = EXTENDED_MESSAGE | msg->msg[2] << 8;
297                 else
298                         packed_msg = msg->msg[0];
299         }
300
301 #ifdef DEBUG_MESSAGES
302         printk("Message: %04X found at position %02X\n",
303                 packed_msg, pos);
304 #endif
305         return packed_msg;
306 }
307
308 /* Function: int fas216_syncperiod(FAS216_Info *info, int ns)
309  * Purpose : Calculate value to be loaded into the STP register
310  *           for a given period in ns
311  * Params  : info - state structure for interface connected to device
312  *         : ns   - period in ns (between subsequent bytes)
313  * Returns : Value suitable for REG_STP
314  */
315 static int
316 fas216_syncperiod(FAS216_Info *info, int ns)
317 {
318         int value = (info->ifcfg.clockrate * ns) / 1000;
319
320         fas216_checkmagic(info);
321
322         if (value < 4)
323                 value = 4;
324         else if (value > 35)
325                 value = 35;
326
327         return value & 31;
328 }
329
330 /* Function: void fas216_set_sync(FAS216_Info *info, int target)
331  * Purpose : Correctly setup FAS216 chip for specified transfer period.
332  * Params  : info   - state structure for interface
333  *         : target - target
334  * Notes   : we need to switch the chip out of FASTSCSI mode if we have
335  *           a transfer period >= 200ns - otherwise the chip will violate
336  *           the SCSI timings.
337  */
338 static void
339 fas216_set_sync(FAS216_Info *info, int target)
340 {
341         outb(info->device[target].sof, REG_SOF(info));
342         outb(info->device[target].stp, REG_STP(info));
343         if (info->device[target].period >= (200 / 4))
344                 outb(info->scsi.cfg[2] & ~CNTL3_FASTSCSI, REG_CNTL3(info));
345         else
346                 outb(info->scsi.cfg[2], REG_CNTL3(info));
347 }
348
349 /* Synchronous transfer support
350  *
351  * Note: The SCSI II r10 spec says (5.6.12):
352  *
353  *  (2)  Due to historical problems with early host adapters that could
354  *  not accept an SDTR message, some targets may not initiate synchronous
355  *  negotiation after a power cycle as required by this standard.  Host
356  *  adapters that support synchronous mode may avoid the ensuing failure
357  *  modes when the target is independently power cycled by initiating a
358  *  synchronous negotiation on each REQUEST SENSE and INQUIRY command.
359  *  This approach increases the SCSI bus overhead and is not recommended
360  *  for new implementations.  The correct method is to respond to an
361  *  SDTR message with a MESSAGE REJECT message if the either the
362  *  initiator or target devices does not support synchronous transfers
363  *  or does not want to negotiate for synchronous transfers at the time.
364  *  Using the correct method assures compatibility with wide data
365  *  transfers and future enhancements.
366  *
367  * We will always initiate a synchronous transfer negociation request on
368  * every INQUIRY or REQUEST SENSE message, unless the target itself has
369  * at some point performed a synchronous transfer negociation request, or
370  * we have synchronous transfers disabled for this device.
371  */
372
373 /* Function: void fas216_handlesync(FAS216_Info *info, char *msg)
374  * Purpose : Handle a synchronous transfer message from the target
375  * Params  : info - state structure for interface
376  *         : msg  - message from target
377  */
378 static void
379 fas216_handlesync(FAS216_Info *info, char *msg)
380 {
381         struct fas216_device *dev = &info->device[info->SCpnt->target];
382         enum { sync, async, none, reject } res = none;
383
384 #ifdef SCSI2_SYNC
385         switch (msg[0]) {
386         case MESSAGE_REJECT:
387                 /* Synchronous transfer request failed.
388                  * Note: SCSI II r10:
389                  *
390                  *  SCSI devices that are capable of synchronous
391                  *  data transfers shall not respond to an SDTR
392                  *  message with a MESSAGE REJECT message.
393                  *
394                  * Hence, if we get this condition, we disable
395                  * negociation for this device.
396                  */
397                 if (dev->sync_state == neg_inprogress) {
398                         dev->sync_state = neg_invalid;
399                         res = async;
400                 }
401                 break;
402
403         case EXTENDED_MESSAGE:
404                 switch (dev->sync_state) {
405                 /* We don't accept synchronous transfer requests.
406                  * Respond with a MESSAGE_REJECT to prevent a
407                  * synchronous transfer agreement from being reached.
408                  */
409                 case neg_invalid:
410                         res = reject;
411                         break;
412
413                 /* We were not negociating a synchronous transfer,
414                  * but the device sent us a negociation request.
415                  * Honour the request by sending back a SDTR
416                  * message containing our capability, limited by
417                  * the targets capability.
418                  */
419                 default:
420                         outb(CMD_SETATN, REG_CMD(info));
421                         if (msg[4] > info->ifcfg.sync_max_depth)
422                                 msg[4] = info->ifcfg.sync_max_depth;
423                         if (msg[3] < 1000 / info->ifcfg.clockrate)
424                                 msg[3] = 1000 / info->ifcfg.clockrate;
425
426                         msgqueue_flush(&info->scsi.msgs);
427                         msgqueue_addmsg(&info->scsi.msgs, 5,
428                                         EXTENDED_MESSAGE, 3, EXTENDED_SDTR,
429                                         msg[3], msg[4]);
430                         info->scsi.phase = PHASE_MSGOUT_EXPECT;
431
432                         /* This is wrong.  The agreement is not in effect
433                          * until this message is accepted by the device
434                          */
435                         dev->sync_state = neg_targcomplete;
436                         res = sync;
437                         break;
438
439                 /* We initiated the synchronous transfer negociation,
440                  * and have successfully received a response from the
441                  * target.  The synchronous transfer agreement has been
442                  * reached.  Note: if the values returned are out of our
443                  * bounds, we must reject the message.
444                  */
445                 case neg_inprogress:
446                         res = reject;
447                         if (msg[4] <= info->ifcfg.sync_max_depth &&
448                             msg[3] >= 1000 / info->ifcfg.clockrate) {
449                                 dev->sync_state = neg_complete;
450                                 res = sync;
451                         }
452                         break;
453                 }
454         }
455 #else
456         res = reject;
457 #endif
458
459         switch (res) {
460         case sync:
461                 dev->period = msg[3];
462                 dev->sof    = msg[4];
463                 dev->stp    = fas216_syncperiod(info, msg[3] * 4);
464                 fas216_set_sync(info, info->SCpnt->target);
465                 break;
466
467         case reject:
468                 outb(CMD_SETATN, REG_CMD(info));
469                 msgqueue_flush(&info->scsi.msgs);
470                 msgqueue_addmsg(&info->scsi.msgs, 1, MESSAGE_REJECT);
471                 info->scsi.phase = PHASE_MSGOUT_EXPECT;
472
473         case async:
474                 dev->period = info->ifcfg.asyncperiod / 4;
475                 dev->sof    = 0;
476                 dev->stp    = info->scsi.async_stp;
477                 fas216_set_sync(info, info->SCpnt->target);
478                 break;
479
480         case none:
481                 break;
482         }
483 }
484
485 /* Function: void fas216_handlewide(FAS216_Info *info, char *msg)
486  * Purpose : Handle a wide transfer message from the target
487  * Params  : info - state structure for interface
488  *         : msg  - message from target
489  */
490 static void
491 fas216_handlewide(FAS216_Info *info, char *msg)
492 {
493         struct fas216_device *dev = &info->device[info->SCpnt->target];
494         enum { wide, bit8, none, reject } res = none;
495
496 #ifdef SCSI2_WIDE
497         switch (msg[0]) {
498         case MESSAGE_REJECT:
499                 /* Wide transfer request failed.
500                  * Note: SCSI II r10:
501                  *
502                  *  SCSI devices that are capable of wide
503                  *  data transfers shall not respond to a
504                  *  WDTR message with a MESSAGE REJECT message.
505                  *
506                  * Hence, if we get this condition, we never
507                  * reattempt negociation for this device.
508                  */
509                 if (dev->wide_state == neg_inprogress) {
510                         dev->wide_state = neg_invalid;
511                         res = bit8;
512                 }
513                 break;
514
515         case EXTENDED_MESSAGE:
516                 switch (dev->wide_state) {
517                 /* We don't accept wide data transfer requests.
518                  * Respond with a MESSAGE REJECT to prevent a
519                  * wide data transfer agreement from being reached.
520                  */
521                 case neg_invalid:
522                         res = reject;
523                         break;
524
525                 /* We were not negociating a wide data transfer,
526                  * but the device sent is a negociation request.
527                  * Honour the request by sending back a WDTR
528                  * message containing our capability, limited by
529                  * the targets capability.
530                  */
531                 default:
532                         outb(CMD_SETATN, REG_CMD(info));
533                         if (msg[3] > info->ifcfg.wide_max_size)
534                                 msg[3] = info->ifcfg.wide_max_size;
535
536                         msgqueue_flush(&info->scsi.msgs);
537                         msgqueue_addmsg(&info->scsi.msgs, 4,
538                                         EXTENDED_MESSAGE, 2, EXTENDED_WDTR,
539                                         msg[3]);
540                         info->scsi.phase = PHASE_MSGOUT_EXPECT;
541                         res = wide;
542                         break;
543
544                 /* We initiated the wide data transfer negociation,
545                  * and have successfully received a response from the
546                  * target.  The synchronous transfer agreement has been
547                  * reached.  Note: if the values returned are out of our
548                  * bounds, we must reject the message.
549                  */
550                 case neg_inprogress:
551                         res = reject;
552                         if (msg[3] <= info->ifcfg.wide_max_size) {
553                                 dev->wide_state = neg_complete;
554                                 res = wide;
555                         }
556                         break;
557                 }
558         }
559 #else
560         res = reject;
561 #endif
562
563         switch (res) {
564         case wide:
565                 dev->wide_xfer = msg[3];
566                 break;
567
568         case reject:
569                 outb(CMD_SETATN, REG_CMD(info));
570                 msgqueue_flush(&info->scsi.msgs);
571                 msgqueue_addmsg(&info->scsi.msgs, 1, MESSAGE_REJECT);
572                 info->scsi.phase = PHASE_MSGOUT_EXPECT;
573
574         case bit8:
575                 dev->wide_xfer = 0;
576                 break;
577
578         case none:
579                 break;
580         }
581 }
582
583 /* Function: void fas216_updateptrs(FAS216_Info *info, int bytes_transferred)
584  * Purpose : update data pointers after transfer suspended/paused
585  * Params  : info              - interface's local pointer to update
586  *           bytes_transferred - number of bytes transferred
587  */
588 static void
589 fas216_updateptrs(FAS216_Info *info, int bytes_transferred)
590 {
591         unsigned char *ptr;
592         unsigned int residual;
593
594         fas216_checkmagic(info);
595
596         ptr = info->scsi.SCp.ptr;
597         residual = info->scsi.SCp.this_residual;
598
599         info->SCpnt->request_bufflen -= bytes_transferred;
600
601         while (residual <= bytes_transferred && bytes_transferred) {
602                 /* We have used up this buffer */
603                 bytes_transferred -= residual;
604                 if (info->scsi.SCp.buffers_residual) {
605                         info->scsi.SCp.buffer++;
606                         info->scsi.SCp.buffers_residual--;
607                         ptr = (unsigned char *)info->scsi.SCp.buffer->address;
608                         residual = info->scsi.SCp.buffer->length;
609                 } else {
610                         ptr = NULL;
611                         residual = 0;
612                 }
613         }
614
615         residual -= bytes_transferred;
616         ptr += bytes_transferred;
617
618         if (residual == 0)
619                 ptr = NULL;
620
621         info->scsi.SCp.ptr = ptr;
622         info->scsi.SCp.this_residual = residual;
623 }
624
625 /* Function: void fas216_pio(FAS216_Info *info, fasdmadir_t direction)
626  * Purpose : transfer data off of/on to card using programmed IO
627  * Params  : info      - interface to transfer data to/from
628  *           direction - direction to transfer data (DMA_OUT/DMA_IN)
629  * Notes   : this is incredibly slow
630  */
631 static void
632 fas216_pio(FAS216_Info *info, fasdmadir_t direction)
633 {
634         unsigned int residual;
635         char *ptr;
636
637         fas216_checkmagic(info);
638
639         residual = info->scsi.SCp.this_residual;
640         ptr = info->scsi.SCp.ptr;
641
642         if (direction == DMA_OUT)
643                 outb(*ptr++, REG_FF(info));
644         else
645                 *ptr++ = inb(REG_FF(info));
646
647         residual -= 1;
648
649         if (residual == 0) {
650                 if (info->scsi.SCp.buffers_residual) {
651                         info->scsi.SCp.buffer++;
652                         info->scsi.SCp.buffers_residual--;
653                         ptr = (unsigned char *)info->scsi.SCp.buffer->address;
654                         residual = info->scsi.SCp.buffer->length;
655                 } else {
656                         ptr = NULL;
657                         residual = 0;
658                 }
659         }
660
661         info->scsi.SCp.ptr = ptr;
662         info->scsi.SCp.this_residual = residual;
663 }
664
665 /* Function: void fas216_starttransfer(FAS216_Info *info,
666  *                                     fasdmadir_t direction)
667  * Purpose : Start a DMA/PIO transfer off of/on to card
668  * Params  : info      - interface from which device disconnected from
669  *           direction - transfer direction (DMA_OUT/DMA_IN)
670  */
671 static void
672 fas216_starttransfer(FAS216_Info *info, fasdmadir_t direction, int flush_fifo)
673 {
674         fasdmatype_t dmatype;
675
676         fas216_checkmagic(info);
677
678         info->scsi.phase = (direction == DMA_OUT) ?
679                                 PHASE_DATAOUT : PHASE_DATAIN;
680
681         if (info->dma.transfer_type != fasdma_none &&
682             info->dma.transfer_type != fasdma_pio) {
683                 unsigned long total, residual;
684
685                 if (info->dma.transfer_type == fasdma_real_all)
686                         total = info->SCpnt->request_bufflen;
687                 else
688                         total = info->scsi.SCp.this_residual;
689
690                 residual = (inb(REG_CFIS(info)) & CFIS_CF) +
691                             inb(REG_CTCL(info)) +
692                             (inb(REG_CTCM(info)) << 8) +
693                             (inb(REG_CTCH(info)) << 16);
694                 fas216_updateptrs(info, total - residual);
695         }
696         info->dma.transfer_type = fasdma_none;
697
698         if (!info->scsi.SCp.ptr) {
699                 printk("scsi%d.%c: null buffer passed to "
700                         "fas216_starttransfer\n", info->host->host_no,
701                         fas216_target(info));
702                 return;
703         }
704
705         /* flush FIFO */
706         if (flush_fifo)
707                 outb(CMD_FLUSHFIFO, REG_CMD(info));
708
709         /*
710          * Default to PIO mode or DMA mode if we have a synchronous
711          * transfer agreement.
712          */
713         if (info->device[info->SCpnt->target].sof && info->dma.setup)
714                 dmatype = fasdma_real_all;
715         else
716                 dmatype = fasdma_pio;
717
718         if (info->dma.setup)
719                 dmatype = info->dma.setup(info->host, &info->scsi.SCp,
720                                           direction, dmatype);
721         info->dma.transfer_type = dmatype;
722
723         switch (dmatype) {
724         case fasdma_pio:
725                 outb(0, REG_SOF(info));
726                 outb(info->scsi.async_stp, REG_STP(info));
727                 outb(info->scsi.SCp.this_residual, REG_STCL(info));
728                 outb(info->scsi.SCp.this_residual >> 8, REG_STCM(info));
729                 outb(info->scsi.SCp.this_residual >> 16, REG_STCH(info));
730                 outb(CMD_TRANSFERINFO, REG_CMD(info));
731                 fas216_pio(info, direction);
732                 break;
733
734         case fasdma_pseudo:
735                 outb(info->scsi.SCp.this_residual, REG_STCL(info));
736                 outb(info->scsi.SCp.this_residual >> 8, REG_STCM(info));
737                 outb(info->scsi.SCp.this_residual >> 16, REG_STCH(info));
738                 outb(CMD_TRANSFERINFO | CMD_WITHDMA, REG_CMD(info));
739                 info->dma.pseudo(info->host, &info->scsi.SCp,
740                                  direction, info->SCpnt->transfersize);
741                 break;
742
743         case fasdma_real_block:
744                 outb(info->scsi.SCp.this_residual, REG_STCL(info));
745                 outb(info->scsi.SCp.this_residual >> 8, REG_STCM(info));
746                 outb(info->scsi.SCp.this_residual >> 16, REG_STCH(info));
747                 outb(CMD_TRANSFERINFO | CMD_WITHDMA, REG_CMD(info));
748                 break;
749
750         case fasdma_real_all:
751                 outb(info->SCpnt->request_bufflen, REG_STCL(info));
752                 outb(info->SCpnt->request_bufflen >> 8, REG_STCM(info));
753                 outb(info->SCpnt->request_bufflen >> 16, REG_STCH(info));
754                 outb(CMD_TRANSFERINFO | CMD_WITHDMA, REG_CMD(info));
755                 break;
756
757         default:
758                 printk(KERN_ERR "scsi%d.%d: invalid FAS216 DMA type\n",
759                        info->host->host_no, fas216_target(info));
760                 break;
761         }
762 }
763
764 /* Function: void fas216_stoptransfer(FAS216_Info *info)
765  * Purpose : Stop a DMA transfer onto / off of the card
766  * Params  : info      - interface from which device disconnected from
767  */
768 static void
769 fas216_stoptransfer(FAS216_Info *info)
770 {
771         fas216_checkmagic(info);
772
773         if (info->dma.transfer_type != fasdma_none &&
774             info->dma.transfer_type != fasdma_pio) {
775                 unsigned long total, residual;
776
777                 if ((info->dma.transfer_type == fasdma_real_all ||
778                      info->dma.transfer_type == fasdma_real_block) &&
779                     info->dma.stop)
780                         info->dma.stop(info->host, &info->scsi.SCp);
781
782                 if (info->dma.transfer_type == fasdma_real_all)
783                         total = info->SCpnt->request_bufflen;
784                 else
785                         total = info->scsi.SCp.this_residual;
786
787                 residual = (inb(REG_CFIS(info)) & CFIS_CF) +
788                             inb(REG_CTCL(info)) +
789                             (inb(REG_CTCM(info)) << 8) +
790                             (inb(REG_CTCH(info)) << 16);
791                 fas216_updateptrs(info, total - residual);
792                 info->dma.transfer_type = fasdma_none;
793         }
794         if (info->scsi.phase == PHASE_DATAOUT)
795                 outb(CMD_FLUSHFIFO, REG_CMD(info));
796 }
797
798 /* Function: void fas216_disconnected_intr(FAS216_Info *info)
799  * Purpose : handle device disconnection
800  * Params  : info - interface from which device disconnected from
801  */
802 static void
803 fas216_disconnect_intr(FAS216_Info *info)
804 {
805         fas216_checkmagic(info);
806
807 #ifdef DEBUG_CONNECT
808         printk("scsi%d.%c: disconnect phase=%02X\n", info->host->host_no,
809                 fas216_target(info), info->scsi.phase);
810 #endif
811         msgqueue_flush(&info->scsi.msgs);
812
813         switch (info->scsi.phase) {
814         case PHASE_SELECTION:                   /* while selecting - no target          */
815         case PHASE_SELSTEPS:
816                 fas216_done(info, DID_NO_CONNECT);
817                 break;
818
819         case PHASE_MSGIN_DISCONNECT:            /* message in - disconnecting           */
820                 outb(CMD_ENABLESEL, REG_CMD(info));
821                 info->scsi.disconnectable = 1;
822                 info->scsi.reconnected.tag = 0;
823                 info->scsi.phase = PHASE_IDLE;
824                 info->stats.disconnects += 1;
825                 break;
826
827         case PHASE_DONE:                        /* at end of command - complete         */
828                 fas216_done(info, DID_OK);
829                 break;
830
831         case PHASE_MSGOUT:                      /* message out - possible ABORT message */
832                 if (fas216_get_last_msg(info, info->scsi.msgin_fifo) == ABORT) {
833                         info->scsi.aborting = 0;
834                         fas216_done(info, DID_ABORT);
835                         break;
836                 }
837
838         default:                                /* huh?                                 */
839                 printk(KERN_ERR "scsi%d.%c: unexpected disconnect in phase %s\n",
840                         info->host->host_no, fas216_target(info), fas216_drv_phase(info));
841                 print_debug_list();
842                 fas216_stoptransfer(info);
843                 fas216_done(info, DID_ERROR);
844                 break;
845         }
846 }
847
848 /* Function: void fas216_reselected_intr(FAS216_Info *info)
849  * Purpose : Start reconnection of a device
850  * Params  : info - interface which was reselected
851  */
852 static void
853 fas216_reselected_intr(FAS216_Info *info)
854 {
855         unsigned char target, identify_msg, ok;
856
857         fas216_checkmagic(info);
858
859         if ((info->scsi.phase == PHASE_SELECTION ||
860              info->scsi.phase == PHASE_SELSTEPS) && info->SCpnt) {
861                 Scsi_Cmnd *SCpnt = info->SCpnt;
862
863                 info->origSCpnt = SCpnt;
864                 info->SCpnt = NULL;
865
866                 if (info->device[SCpnt->target].wide_state == neg_inprogress)
867                         info->device[SCpnt->target].wide_state = neg_wait;
868                 if (info->device[SCpnt->target].sync_state == neg_inprogress)
869                         info->device[SCpnt->target].sync_state = neg_wait;
870         }
871
872 #ifdef DEBUG_CONNECT
873         printk("scsi%d.%c: reconnect phase=%02X\n", info->host->host_no,
874                 fas216_target(info), info->scsi.phase);
875 #endif
876
877         if ((inb(REG_CFIS(info)) & CFIS_CF) != 2) {
878                 printk(KERN_ERR "scsi%d.H: incorrect number of bytes after reselect\n",
879                         info->host->host_no);
880                 outb(CMD_SETATN, REG_CMD(info));
881                 outb(CMD_MSGACCEPTED, REG_CMD(info));
882                 msgqueue_flush(&info->scsi.msgs);
883                 msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
884                 info->scsi.phase = PHASE_MSGOUT_EXPECT;
885                 return;
886         }
887
888         target = inb(REG_FF(info));
889         identify_msg = inb(REG_FF(info));
890
891         ok = 1;
892         if (!(target & (1 << info->host->this_id))) {
893                 printk(KERN_ERR "scsi%d.H: invalid host id on reselect\n", info->host->host_no);
894                 ok = 0;
895         }
896
897         if (!(identify_msg & 0x80)) {
898                 printk(KERN_ERR "scsi%d.H: no IDENTIFY message on reselect, got msg %02X\n",
899                         info->host->host_no, identify_msg);
900                 ok = 0;
901         }
902
903         if (!ok) {
904                 /*
905                  * Something went wrong - send an initiator error to
906                  * the target.
907                  */
908                 outb(CMD_SETATN, REG_CMD(info));
909                 outb(CMD_MSGACCEPTED, REG_CMD(info));
910                 msgqueue_flush(&info->scsi.msgs);
911                 msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
912                 info->scsi.phase = PHASE_MSGOUT_EXPECT;
913                 return;
914         }
915
916         target &= ~(1 << info->host->this_id);
917         switch (target) {
918         case   1:  target = 0; break;
919         case   2:  target = 1; break;
920         case   4:  target = 2; break;
921         case   8:  target = 3; break;
922         case  16:  target = 4; break;
923         case  32:  target = 5; break;
924         case  64:  target = 6; break;
925         case 128:  target = 7; break;
926         default:   target = info->host->this_id; break;
927         }
928
929         identify_msg &= 7;
930         info->scsi.reconnected.target = target;
931         info->scsi.reconnected.lun    = identify_msg;
932         info->scsi.reconnected.tag    = 0;
933
934         ok = 0;
935         if (info->scsi.disconnectable && info->SCpnt &&
936             info->SCpnt->target == target && info->SCpnt->lun == identify_msg)
937                 ok = 1;
938
939         if (!ok && queue_probetgtlun(&info->queues.disconnected, target, identify_msg))
940                 ok = 1;
941
942         msgqueue_flush(&info->scsi.msgs);
943         if (ok) {
944                 info->scsi.phase = PHASE_RECONNECTED;
945                 outb(target, REG_SDID(info));
946         } else {
947                 /*
948                  * Our command structure not found - abort the
949                  * command on the target.  Since we have no
950                  * record of this command, we can't send
951                  * an INITIATOR DETECTED ERROR message.
952                  */
953                 outb(CMD_SETATN, REG_CMD(info));
954                 msgqueue_addmsg(&info->scsi.msgs, 1, ABORT);
955                 info->scsi.phase = PHASE_MSGOUT_EXPECT;
956         }
957
958         outb(CMD_MSGACCEPTED, REG_CMD(info));
959 }
960
961 /* Function: void fas216_finish_reconnect(FAS216_Info *info)
962  * Purpose : finish reconnection sequence for device
963  * Params  : info - interface which caused function done interrupt
964  */
965 static void
966 fas216_finish_reconnect(FAS216_Info *info)
967 {
968         fas216_checkmagic(info);
969
970 #ifdef DEBUG_CONNECT
971         printk("Connected: %1X %1X %02X, reconnected: %1X %1X %02X\n",
972                 info->SCpnt->target, info->SCpnt->lun, info->SCpnt->tag,
973                 info->scsi.reconnected.target, info->scsi.reconnected.lun,
974                 info->scsi.reconnected.tag);
975 #endif
976
977         if (info->scsi.disconnectable && info->SCpnt) {
978                 info->scsi.disconnectable = 0;
979                 if (info->SCpnt->target == info->scsi.reconnected.target &&
980                     info->SCpnt->lun    == info->scsi.reconnected.lun &&
981                     info->SCpnt->tag    == info->scsi.reconnected.tag) {
982 #ifdef DEBUG_CONNECT
983                         printk("scsi%d.%c: reconnected",
984                                 info->host->host_no, fas216_target(info));
985 #endif
986                 } else {
987                         queue_add_cmd_tail(&info->queues.disconnected, info->SCpnt);
988 #ifdef DEBUG_CONNECT
989                         printk("scsi%d.%c: had to move command to disconnected queue\n",
990                                 info->host->host_no, fas216_target(info));
991 #endif
992                         info->SCpnt = NULL;
993                 }
994         }
995         if (!info->SCpnt) {
996                 info->SCpnt = queue_remove_tgtluntag(&info->queues.disconnected,
997                                         info->scsi.reconnected.target,
998                                         info->scsi.reconnected.lun,
999                                         info->scsi.reconnected.tag);
1000 #ifdef DEBUG_CONNECT
1001                 printk("scsi%d.%c: had to get command",
1002                         info->host->host_no, fas216_target(info));
1003 #endif
1004         }
1005         if (!info->SCpnt) {
1006                 outb(CMD_SETATN, REG_CMD(info));
1007                 msgqueue_flush(&info->scsi.msgs);
1008 #if 0
1009                 if (info->scsi.reconnected.tag)
1010                         msgqueue_addmsg(&info->scsi.msgs, 2, ABORT_TAG, info->scsi.reconnected.tag);
1011                 else
1012 #endif
1013                         msgqueue_addmsg(&info->scsi.msgs, 1, ABORT);
1014                 info->scsi.phase = PHASE_MSGOUT_EXPECT;
1015                 info->scsi.aborting = 1;
1016         } else {
1017                 /*
1018                  * Restore data pointer from SAVED data pointer
1019                  */
1020                 info->scsi.SCp = info->SCpnt->SCp;
1021 #ifdef DEBUG_CONNECT
1022                 printk(", data pointers: [%p, %X]",
1023                         info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
1024 #endif
1025         }
1026 #ifdef DEBUG_CONNECT
1027         printk("\n");
1028 #endif
1029 }
1030
1031 static int fas216_wait_cmd(FAS216_Info *info, int cmd)
1032 {
1033         int tout;
1034         int stat;
1035
1036         outb(cmd, REG_CMD(info));
1037
1038         for (tout = 1000; tout; tout -= 1) {
1039                 stat = inb(REG_STAT(info));
1040                 if (stat & STAT_INT)
1041                         break;
1042                 udelay(1);
1043         }
1044
1045         return stat;
1046 }
1047
1048 static int fas216_get_msg_byte(FAS216_Info *info)
1049 {
1050         int stat;
1051
1052         stat = fas216_wait_cmd(info, CMD_MSGACCEPTED);
1053
1054         if ((stat & STAT_INT) == 0)
1055                 goto timedout;
1056
1057         if ((stat & STAT_BUSMASK) != STAT_MESGIN)
1058                 goto unexpected_phase_change;
1059
1060         inb(REG_INST(info));
1061
1062         stat = fas216_wait_cmd(info, CMD_TRANSFERINFO);
1063
1064         if ((stat & STAT_INT) == 0)
1065                 goto timedout;
1066
1067         if ((stat & STAT_BUSMASK) != STAT_MESGIN)
1068                 goto unexpected_phase_change;
1069
1070         inb(REG_INST(info));
1071
1072         return inb(REG_FF(info));
1073
1074 timedout:
1075         printk("scsi%d.%c: timed out waiting for message byte\n",
1076                 info->host->host_no, fas216_target(info));
1077         return -1;
1078
1079 unexpected_phase_change:
1080         printk("scsi%d.%c: unexpected phase change: status = %02X\n",
1081                 info->host->host_no, fas216_target(info), stat);
1082
1083         return -2;
1084 }
1085
1086 /* Function: void fas216_message(FAS216_Info *info)
1087  * Purpose : handle a function done interrupt from FAS216 chip
1088  * Params  : info - interface which caused function done interrupt
1089  */
1090 static void fas216_message(FAS216_Info *info)
1091 {
1092         unsigned char *message = info->scsi.message;
1093         unsigned int msglen = 1, i;
1094         int msgbyte = 0;
1095
1096         fas216_checkmagic(info);
1097
1098         message[0] = inb(REG_FF(info));
1099
1100         if (message[0] == EXTENDED_MESSAGE) {
1101                 msgbyte = fas216_get_msg_byte(info);
1102
1103                 if (msgbyte >= 0) {
1104                         message[1] = msgbyte;
1105
1106                         for (msglen = 2; msglen < message[1] + 2; msglen++) {
1107                                 msgbyte = fas216_get_msg_byte(info);
1108
1109                                 if (msgbyte >= 0)
1110                                         message[msglen] = msgbyte;
1111                                 else
1112                                         break;
1113                         }
1114                 }
1115         }
1116
1117         info->scsi.msglen = msglen;
1118
1119 #ifdef DEBUG_MESSAGES
1120         {
1121                 int i;
1122
1123                 printk("scsi%d.%c: message in: ",
1124                         info->host->host_no, fas216_target(info));
1125                 for (i = 0; i < msglen; i++)
1126                         printk("%02X ", message[i]);
1127                 printk("\n");
1128         }
1129 #endif
1130
1131         if (info->scsi.phase == PHASE_RECONNECTED) {
1132                 if (message[0] == SIMPLE_QUEUE_TAG)
1133                         info->scsi.reconnected.tag = message[1];
1134                 fas216_finish_reconnect(info);
1135                 info->scsi.phase = PHASE_MSGIN;
1136         }
1137
1138         switch (message[0]) {
1139         case COMMAND_COMPLETE:
1140                 if (msglen != 1)
1141                         goto unrecognised;
1142
1143                 printk(KERN_ERR "scsi%d.%c: command complete with no "
1144                         "status in MESSAGE_IN?\n",
1145                         info->host->host_no, fas216_target(info));
1146                 break;
1147
1148         case SAVE_POINTERS:
1149                 if (msglen != 1)
1150                         goto unrecognised;
1151
1152                 /*
1153                  * Save current data pointer to SAVED data pointer
1154                  * SCSI II standard says that we must not acknowledge
1155                  * this until we have really saved pointers.
1156                  * NOTE: we DO NOT save the command nor status pointers
1157                  * as required by the SCSI II standard.  These always
1158                  * point to the start of their respective areas.
1159                  */
1160                 info->SCpnt->SCp = info->scsi.SCp;
1161                 info->SCpnt->SCp.sent_command = 0;
1162 #if defined (DEBUG_MESSAGES) || defined (DEBUG_CONNECT)
1163                 printk("scsi%d.%c: save data pointers: [%p, %X]\n",
1164                         info->host->host_no, fas216_target(info),
1165                         info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
1166 #endif
1167                 break;
1168
1169         case RESTORE_POINTERS:
1170                 if (msglen != 1)
1171                         goto unrecognised;
1172
1173                 /*
1174                  * Restore current data pointer from SAVED data pointer
1175                  */
1176                 info->scsi.SCp = info->SCpnt->SCp;
1177 #if defined (DEBUG_MESSAGES) || defined (DEBUG_CONNECT)
1178                 printk("scsi%d.%c: restore data pointers: [%p, %X]\n",
1179                         info->host->host_no, fas216_target(info),
1180                         info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
1181 #endif
1182                 break;
1183
1184         case DISCONNECT:
1185                 if (msglen != 1)
1186                         goto unrecognised;
1187
1188                 info->scsi.phase = PHASE_MSGIN_DISCONNECT;
1189                 break;
1190
1191         case MESSAGE_REJECT:
1192                 if (msglen != 1)
1193                         goto unrecognised;
1194
1195                 switch (fas216_get_last_msg(info, info->scsi.msgin_fifo)) {
1196                 case EXTENDED_MESSAGE | EXTENDED_SDTR << 8:
1197                         fas216_handlesync(info, message);
1198                         break;
1199
1200                 case EXTENDED_MESSAGE | EXTENDED_WDTR << 8:
1201                         fas216_handlewide(info, message);
1202                         break;
1203
1204                 default:
1205                         printk("scsi%d.%c: reject, last message %04X\n",
1206                                 info->host->host_no, fas216_target(info),
1207                                 fas216_get_last_msg(info, info->scsi.msgin_fifo));
1208                 }
1209                 break;
1210
1211         case NOP:
1212                 break;
1213
1214         case SIMPLE_QUEUE_TAG:
1215                 if (msglen < 2)
1216                         goto unrecognised;
1217
1218                 /* handled above - print a warning since this is untested */
1219                 printk("scsi%d.%c: reconnect queue tag %02X\n",
1220                         info->host->host_no, fas216_target(info),
1221                         message[1]);
1222                 break;
1223
1224         case EXTENDED_MESSAGE:
1225                 if (msglen < 3)
1226                         goto unrecognised;
1227
1228                 switch (message[2]) {
1229                 case EXTENDED_SDTR:     /* Sync transfer negociation request/reply */
1230                         fas216_handlesync(info, message);
1231                         break;
1232
1233                 case EXTENDED_WDTR:     /* Wide transfer negociation request/reply */
1234                         fas216_handlewide(info, message);
1235                         break;
1236
1237                 default:
1238                         goto unrecognised;
1239                 }
1240                 break;
1241
1242         default:
1243                 goto unrecognised;
1244         }
1245         outb(CMD_MSGACCEPTED, REG_CMD(info));
1246         return;
1247
1248 unrecognised:
1249         printk("scsi%d.%c: unrecognised message, rejecting\n",
1250                 info->host->host_no, fas216_target(info));
1251         printk("scsi%d.%c: message was", info->host->host_no, fas216_target(info));
1252         for (i = 0; i < msglen; i++)
1253                 printk("%s%02X", i & 31 ? " " : "\n  ", message[i]);
1254         printk("\n");
1255
1256         /*
1257          * Something strange seems to be happening here -
1258          * I can't use SETATN since the chip gives me an
1259          * invalid command interrupt when I do.  Weird.
1260          */
1261 outb(CMD_NOP, REG_CMD(info));
1262 fas216_dumpstate(info);
1263         outb(CMD_SETATN, REG_CMD(info));
1264         msgqueue_flush(&info->scsi.msgs);
1265         msgqueue_addmsg(&info->scsi.msgs, 1, MESSAGE_REJECT);
1266         info->scsi.phase = PHASE_MSGOUT_EXPECT;
1267 fas216_dumpstate(info);
1268         outb(CMD_MSGACCEPTED, REG_CMD(info));
1269 }
1270
1271 /* Function: void fas216_send_command(FAS216_Info *info)
1272  * Purpose : send a command to a target after all message bytes have been sent
1273  * Params  : info - interface which caused bus service
1274  */
1275 static void fas216_send_command(FAS216_Info *info)
1276 {
1277         int i;
1278
1279         fas216_checkmagic(info);
1280
1281         outb(CMD_NOP|CMD_WITHDMA, REG_CMD(info));
1282         outb(CMD_FLUSHFIFO, REG_CMD(info));
1283
1284         /* load command */
1285         for (i = info->scsi.SCp.sent_command; i < info->SCpnt->cmd_len; i++)
1286                 outb(info->SCpnt->cmnd[i], REG_FF(info));
1287
1288         outb(CMD_TRANSFERINFO, REG_CMD(info));
1289
1290         info->scsi.phase = PHASE_COMMAND;
1291 }
1292
1293 /* Function: void fas216_send_messageout(FAS216_Info *info, int start)
1294  * Purpose : handle bus service to send a message
1295  * Params  : info - interface which caused bus service
1296  * Note    : We do not allow the device to change the data direction!
1297  */
1298 static void fas216_send_messageout(FAS216_Info *info, int start)
1299 {
1300         unsigned int tot_msglen = msgqueue_msglength(&info->scsi.msgs);
1301
1302         fas216_checkmagic(info);
1303
1304         outb(CMD_FLUSHFIFO, REG_CMD(info));
1305
1306         if (tot_msglen) {
1307                 struct message *msg;
1308                 int msgnr = 0;
1309
1310                 while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
1311                         int i;
1312
1313                         for (i = start; i < msg->length; i++)
1314                                 outb(msg->msg[i], REG_FF(info));
1315
1316                         msg->fifo = tot_msglen - (inb(REG_CFIS(info)) & CFIS_CF);
1317                         start = 0;
1318                 }
1319         } else
1320                 outb(NOP, REG_FF(info));
1321
1322         outb(CMD_TRANSFERINFO, REG_CMD(info));
1323
1324         info->scsi.phase = PHASE_MSGOUT;
1325 }
1326
1327 /* Function: void fas216_busservice_intr(FAS216_Info *info, unsigned int stat, unsigned int ssr)
1328  * Purpose : handle a bus service interrupt from FAS216 chip
1329  * Params  : info - interface which caused bus service interrupt
1330  *           stat - Status register contents
1331  *           ssr  - SCSI Status register contents
1332  */
1333 static void fas216_busservice_intr(FAS216_Info *info, unsigned int stat, unsigned int ssr)
1334 {
1335         fas216_checkmagic(info);
1336
1337 #ifdef DEBUG_BUSSERVICE
1338         printk("scsi%d.%c: bus service: stat=%02X ssr=%02X phase=%02X\n",
1339                 info->host->host_no, fas216_target(info), stat, ssr, info->scsi.phase);
1340 #endif
1341
1342         switch (info->scsi.phase) {
1343         case PHASE_SELECTION:
1344                 if ((ssr & IS_BITS) != 1)
1345                         goto bad_is;
1346                 break;
1347
1348         case PHASE_SELSTEPS:
1349                 switch (ssr & IS_BITS) {
1350                 case IS_SELARB:
1351                 case IS_MSGBYTESENT:
1352                         goto bad_is;
1353
1354                 case IS_NOTCOMMAND:
1355                 case IS_EARLYPHASE:
1356                         if ((stat & STAT_BUSMASK) == STAT_MESGIN)
1357                                 break;
1358                         goto bad_is;
1359
1360                 case IS_COMPLETE:
1361                         break;
1362                 }
1363
1364         default:
1365                 break;
1366         }
1367
1368         outb(CMD_NOP, REG_CMD(info));
1369
1370 #define STATE(st,ph) ((ph) << 3 | (st))
1371         /* This table describes the legal SCSI state transitions,
1372          * as described by the SCSI II spec.
1373          */
1374         switch (STATE(stat & STAT_BUSMASK, info->scsi.phase)) {
1375                                                 /* Reselmsgin   -> Data In      */
1376         case STATE(STAT_DATAIN, PHASE_RECONNECTED):
1377                 fas216_finish_reconnect(info);
1378         case STATE(STAT_DATAIN, PHASE_SELSTEPS):/* Sel w/ steps -> Data In      */
1379         case STATE(STAT_DATAIN, PHASE_DATAIN):  /* Data In      -> Data In      */
1380         case STATE(STAT_DATAIN, PHASE_MSGOUT):  /* Message Out  -> Data In      */
1381         case STATE(STAT_DATAIN, PHASE_COMMAND): /* Command      -> Data In      */
1382         case STATE(STAT_DATAIN, PHASE_MSGIN):   /* Message In   -> Data In      */
1383                 fas216_starttransfer(info, DMA_IN, 0);
1384                 return;
1385
1386         case STATE(STAT_DATAOUT, PHASE_DATAOUT):/* Data Out     -> Data Out     */
1387                 fas216_starttransfer(info, DMA_OUT, 0);
1388                 return;
1389
1390                                                 /* Reselmsgin   -> Data Out     */
1391         case STATE(STAT_DATAOUT, PHASE_RECONNECTED):
1392                 fas216_finish_reconnect(info);
1393         case STATE(STAT_DATAOUT, PHASE_SELSTEPS):/* Sel w/ steps-> Data Out     */
1394         case STATE(STAT_DATAOUT, PHASE_MSGOUT): /* Message Out  -> Data Out     */
1395         case STATE(STAT_DATAOUT, PHASE_COMMAND):/* Command      -> Data Out     */
1396         case STATE(STAT_DATAOUT, PHASE_MSGIN):  /* Message In   -> Data Out     */
1397                 fas216_starttransfer(info, DMA_OUT, 1);
1398                 return;
1399
1400                                                 /* Reselmsgin   -> Status       */
1401         case STATE(STAT_STATUS, PHASE_RECONNECTED):
1402                 fas216_finish_reconnect(info);
1403                 goto status;
1404         case STATE(STAT_STATUS, PHASE_DATAOUT): /* Data Out     -> Status       */
1405         case STATE(STAT_STATUS, PHASE_DATAIN):  /* Data In      -> Status       */
1406                 fas216_stoptransfer(info);
1407         case STATE(STAT_STATUS, PHASE_SELSTEPS):/* Sel w/ steps -> Status       */
1408         case STATE(STAT_STATUS, PHASE_MSGOUT):  /* Message Out  -> Status       */
1409         case STATE(STAT_STATUS, PHASE_COMMAND): /* Command      -> Status       */
1410         case STATE(STAT_STATUS, PHASE_MSGIN):   /* Message In   -> Status       */
1411         status:
1412                 outb(CMD_INITCMDCOMPLETE, REG_CMD(info));
1413                 info->scsi.phase = PHASE_STATUS;
1414                 return;
1415
1416         case STATE(STAT_MESGIN, PHASE_DATAOUT): /* Data Out     -> Message In   */
1417         case STATE(STAT_MESGIN, PHASE_DATAIN):  /* Data In      -> Message In   */
1418                 fas216_stoptransfer(info);
1419         case STATE(STAT_MESGIN, PHASE_COMMAND): /* Command      -> Message In   */
1420         case STATE(STAT_MESGIN, PHASE_SELSTEPS):/* Sel w/ steps -> Message In   */
1421         case STATE(STAT_MESGIN, PHASE_MSGOUT):  /* Message Out  -> Message In   */
1422                 info->scsi.msgin_fifo = inb(REG_CFIS(info)) & CFIS_CF;
1423                 outb(CMD_FLUSHFIFO, REG_CMD(info));
1424                 outb(CMD_TRANSFERINFO, REG_CMD(info));
1425                 info->scsi.phase = PHASE_MSGIN;
1426                 return;
1427
1428                                                 /* Reselmsgin   -> Message In   */
1429         case STATE(STAT_MESGIN, PHASE_RECONNECTED):
1430         case STATE(STAT_MESGIN, PHASE_MSGIN):
1431                 info->scsi.msgin_fifo = inb(REG_CFIS(info)) & CFIS_CF;
1432                 outb(CMD_TRANSFERINFO, REG_CMD(info));
1433                 return;
1434
1435                                                 /* Reselmsgin   -> Command      */
1436         case STATE(STAT_COMMAND, PHASE_RECONNECTED):
1437                 fas216_finish_reconnect(info);
1438         case STATE(STAT_COMMAND, PHASE_MSGOUT): /* Message Out  -> Command      */
1439         case STATE(STAT_COMMAND, PHASE_MSGIN):  /* Message In   -> Command      */
1440                 fas216_send_command(info);
1441                 info->scsi.phase = PHASE_COMMAND;
1442                 return;
1443                                                 /* Selection    -> Message Out  */
1444         case STATE(STAT_MESGOUT, PHASE_SELECTION):
1445                 fas216_send_messageout(info, 1);
1446                 return;
1447                                                 /* Any          -> Message Out  */
1448         case STATE(STAT_MESGOUT, PHASE_MSGOUT_EXPECT):
1449                 fas216_send_messageout(info, 0);
1450                 return;
1451
1452         /* Error recovery rules.
1453          *   These either attempt to abort or retry the operation.
1454          * TODO: we need more of these
1455          */
1456         case STATE(STAT_COMMAND, PHASE_COMMAND):/* Command      -> Command      */
1457                 /* error - we've sent out all the command bytes
1458                  * we have.
1459                  * NOTE: we need SAVE DATA POINTERS/RESTORE DATA POINTERS
1460                  * to include the command bytes sent for this to work
1461                  * correctly.
1462                  */
1463                 printk(KERN_ERR "scsi%d.%c: "
1464                         "target trying to receive more command bytes\n",
1465                         info->host->host_no, fas216_target(info));
1466                 outb(CMD_SETATN, REG_CMD(info));
1467                 outb(15, REG_STCL(info));
1468                 outb(0, REG_STCM(info));
1469                 outb(0, REG_STCH(info));
1470                 outb(CMD_PADBYTES | CMD_WITHDMA, REG_CMD(info));
1471                 msgqueue_flush(&info->scsi.msgs);
1472                 msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
1473                 info->scsi.phase = PHASE_MSGOUT_EXPECT;
1474                 return;
1475
1476                                                 /* Selection    -> Message Out  */
1477         case STATE(STAT_MESGOUT, PHASE_SELSTEPS):
1478         case STATE(STAT_MESGOUT, PHASE_MSGOUT): /* Message Out  -> Message Out  */
1479                 /* If we get another message out phase, this
1480                  * usually means some parity error occurred.
1481                  * Resend complete set of messages.  If we have
1482                  * more than 1 byte to send, we need to assert
1483                  * ATN again.
1484                  */
1485                 if (msgqueue_msglength(&info->scsi.msgs) > 1)
1486                         outb(CMD_SETATN, REG_CMD(info));
1487
1488                 fas216_send_messageout(info, 0);
1489                 return;
1490         }
1491
1492         if (info->scsi.phase == PHASE_MSGIN_DISCONNECT) {
1493                 printk(KERN_ERR "scsi%d.%c: disconnect message received, but bus service %s?\n",
1494                         info->host->host_no, fas216_target(info),
1495                         fas216_bus_phase(stat));
1496                 msgqueue_flush(&info->scsi.msgs);
1497                 outb(CMD_SETATN, REG_CMD(info));
1498                 msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
1499                 info->scsi.phase = PHASE_MSGOUT_EXPECT;
1500                 info->scsi.aborting = 1;
1501                 outb(CMD_TRANSFERINFO, REG_CMD(info));
1502                 return;
1503         }
1504         printk(KERN_ERR "scsi%d.%c: bus phase %s after %s?\n",
1505                 info->host->host_no, fas216_target(info),
1506                 fas216_bus_phase(stat),
1507                 fas216_drv_phase(info));
1508         print_debug_list();
1509         return;
1510
1511 bad_is:
1512         printk("scsi%d.%c: bus service at step %d?\n",
1513                 info->host->host_no, fas216_target(info),
1514                 ssr & IS_BITS);
1515         print_debug_list();
1516
1517         fas216_done(info, DID_ERROR);
1518 }
1519
1520 /* Function: void fas216_funcdone_intr(FAS216_Info *info, unsigned int stat, unsigned int ssr)
1521  * Purpose : handle a function done interrupt from FAS216 chip
1522  * Params  : info - interface which caused function done interrupt
1523  *           stat - Status register contents
1524  *           ssr  - SCSI Status register contents
1525  */
1526 static void fas216_funcdone_intr(FAS216_Info *info, unsigned int stat, unsigned int ssr)
1527 {
1528         int status, message;
1529
1530         fas216_checkmagic(info);
1531
1532 #ifdef DEBUG_FUNCTIONDONE
1533         printk("scsi%d.%c: function done: stat=%X ssr=%X phase=%02X\n",
1534                 info->host->host_no, fas216_target(info), stat, ssr, info->scsi.phase);
1535 #endif
1536         switch (info->scsi.phase) {
1537         case PHASE_STATUS:                      /* status phase - read status and msg   */
1538                 status = inb(REG_FF(info));
1539                 message = inb(REG_FF(info));
1540                 info->scsi.SCp.Message = message;
1541                 info->scsi.SCp.Status = status;
1542                 info->scsi.phase = PHASE_DONE;
1543                 outb(CMD_MSGACCEPTED, REG_CMD(info));
1544                 break;
1545
1546         case PHASE_IDLE:                        /* reselected?                          */
1547         case PHASE_MSGIN:                       /* message in phase                     */
1548         case PHASE_RECONNECTED:                 /* reconnected command                  */
1549                 if ((stat & STAT_BUSMASK) == STAT_MESGIN) {
1550                         info->scsi.msgin_fifo = inb(REG_CFIS(info)) & CFIS_CF;
1551                         fas216_message(info);
1552                         break;
1553                 }
1554
1555         default:
1556                 printk("scsi%d.%c: internal phase %s for function done?"
1557                         "  What do I do with this?\n",
1558                         info->host->host_no, fas216_target(info),
1559                         fas216_drv_phase(info));
1560         }
1561 }
1562
1563 /* Function: void fas216_intr(struct Scsi_Host *instance)
1564  * Purpose : handle interrupts from the interface to progress a command
1565  * Params  : instance - interface to service
1566  */
1567 void fas216_intr(struct Scsi_Host *instance)
1568 {
1569         FAS216_Info *info = (FAS216_Info *)instance->hostdata;
1570         unsigned char isr, ssr, stat;
1571
1572         fas216_checkmagic(info);
1573
1574         stat = inb(REG_STAT(info));
1575         ssr = inb(REG_IS(info));
1576         isr = inb(REG_INST(info));
1577
1578         add_debug_list(stat, ssr, isr, info->scsi.phase);
1579
1580         if (stat & STAT_INT) {
1581                 if (isr & INST_BUSRESET) {
1582                         printk(KERN_DEBUG "scsi%d.H: bus reset detected\n", instance->host_no);
1583                         scsi_report_bus_reset(instance, 0);
1584                 } else if (isr & INST_ILLEGALCMD) {
1585                         printk(KERN_CRIT "scsi%d.H: illegal command given\n", instance->host_no);
1586                         fas216_dumpstate(info);
1587                 } else if (isr & INST_DISCONNECT)
1588                         fas216_disconnect_intr(info);
1589                 else if (isr & INST_RESELECTED)         /* reselected                   */
1590                         fas216_reselected_intr(info);
1591                 else if (isr & INST_BUSSERVICE)         /* bus service request          */
1592                         fas216_busservice_intr(info, stat, ssr);
1593                 else if (isr & INST_FUNCDONE)           /* function done                */
1594                         fas216_funcdone_intr(info, stat, ssr);
1595                 else
1596                         printk("scsi%d.%c: unknown interrupt received:"
1597                                 " phase %s isr %02X ssr %02X stat %02X\n",
1598                                 instance->host_no, fas216_target(info),
1599                                 fas216_drv_phase(info), isr, ssr, stat);
1600         }
1601 }
1602
1603 /* Function: void fas216_kick(FAS216_Info *info)
1604  * Purpose : kick a command to the interface - interface should be idle
1605  * Params  : info - our host interface to kick
1606  * Notes   : Interrupts are always disabled!
1607  */
1608 static void fas216_kick(FAS216_Info *info)
1609 {
1610         Scsi_Cmnd *SCpnt = NULL;
1611         int tot_msglen, from_queue = 0, disconnect_ok;
1612
1613         fas216_checkmagic(info);
1614
1615         /*
1616          * Obtain the next command to process.
1617          */
1618         do {
1619                 if (info->reqSCpnt) {
1620                         SCpnt = info->reqSCpnt;
1621                         info->reqSCpnt = NULL;
1622                         break;
1623                 }
1624
1625                 if (info->origSCpnt) {
1626                         SCpnt = info->origSCpnt;
1627                         info->origSCpnt = NULL;
1628                         break;
1629                 }
1630
1631                 /* retrieve next command */
1632                 if (!SCpnt) {
1633                         SCpnt = queue_remove_exclude(&info->queues.issue,
1634                                                      info->busyluns);
1635                         from_queue = 1;
1636                         break;
1637                 }
1638         } while (0);
1639
1640         if (!SCpnt) /* no command pending - just exit */
1641                 return;
1642
1643         if (info->scsi.disconnectable && info->SCpnt) {
1644                 queue_add_cmd_tail(&info->queues.disconnected, info->SCpnt);
1645                 info->scsi.disconnectable = 0;
1646                 info->SCpnt = NULL;
1647                 printk("scsi%d.%c: moved command to disconnected queue\n",
1648                         info->host->host_no, fas216_target(info));
1649         }
1650
1651         /*
1652          * claim host busy
1653          */
1654         info->scsi.phase = PHASE_SELECTION;
1655         info->SCpnt = SCpnt;
1656         info->scsi.SCp = SCpnt->SCp;
1657         info->dma.transfer_type = fasdma_none;
1658
1659 #ifdef DEBUG_CONNECT
1660         printk("scsi%d.%c: starting cmd %02X",
1661                 info->host->host_no, '0' + SCpnt->target,
1662                 SCpnt->cmnd[0]);
1663 #endif
1664
1665         if (from_queue) {
1666 #ifdef SCSI2_TAG
1667                 /*
1668                  * tagged queuing - allocate a new tag to this command
1669                  */
1670                 if (SCpnt->device->tagged_queue && SCpnt->cmnd[0] != REQUEST_SENSE &&
1671                     SCpnt->cmnd[0] != INQUIRY) {
1672                     SCpnt->device->current_tag += 1;
1673                         if (SCpnt->device->current_tag == 0)
1674                             SCpnt->device->current_tag = 1;
1675                                 SCpnt->tag = SCpnt->device->current_tag;
1676                 } else
1677 #endif
1678                         set_bit(SCpnt->target * 8 + SCpnt->lun, info->busyluns);
1679
1680                 info->stats.removes += 1;
1681                 switch (SCpnt->cmnd[0]) {
1682                 case WRITE_6:
1683                 case WRITE_10:
1684                 case WRITE_12:
1685                         info->stats.writes += 1;
1686                         break;
1687                 case READ_6:
1688                 case READ_10:
1689                 case READ_12:
1690                         info->stats.reads += 1;
1691                         break;
1692                 default:
1693                         info->stats.miscs += 1;
1694                         break;
1695                 }
1696         }
1697
1698         /*
1699          * Don't allow request sense commands to disconnect.
1700          */
1701         disconnect_ok = SCpnt->cmnd[0] != REQUEST_SENSE &&
1702                         info->device[SCpnt->target].disconnect_ok;
1703
1704         /*
1705          * build outgoing message bytes
1706          */
1707         msgqueue_flush(&info->scsi.msgs);
1708         msgqueue_addmsg(&info->scsi.msgs, 1, IDENTIFY(disconnect_ok, SCpnt->lun));
1709
1710         /*
1711          * add tag message if required
1712          */
1713         if (SCpnt->tag)
1714                 msgqueue_addmsg(&info->scsi.msgs, 2, SIMPLE_QUEUE_TAG, SCpnt->tag);
1715
1716         do {
1717 #ifdef SCSI2_WIDE
1718                 if (info->device[SCpnt->target].wide_state == neg_wait) {
1719                         info->device[SCpnt->target].wide_state = neg_inprogress;
1720                         msgqueue_addmsg(&info->scsi.msgs, 4,
1721                                         EXTENDED_MESSAGE, 2, EXTENDED_WDTR,
1722                                         info->ifcfg.wide_max_size);
1723                         break;
1724                 }
1725 #endif
1726 #ifdef SCSI2_SYNC
1727                 if ((info->device[SCpnt->target].sync_state == neg_wait ||
1728                      info->device[SCpnt->target].sync_state == neg_complete) &&
1729                     (SCpnt->cmnd[0] == REQUEST_SENSE ||
1730                      SCpnt->cmnd[0] == INQUIRY)) {
1731                         info->device[SCpnt->target].sync_state = neg_inprogress;
1732                         msgqueue_addmsg(&info->scsi.msgs, 5,
1733                                         EXTENDED_MESSAGE, 3, EXTENDED_SDTR,
1734                                         1000 / info->ifcfg.clockrate,
1735                                         info->ifcfg.sync_max_depth);
1736                         break;
1737                 }
1738 #endif
1739         } while (0);
1740
1741         /* following what the ESP driver says */
1742         outb(0, REG_STCL(info));
1743         outb(0, REG_STCM(info));
1744         outb(0, REG_STCH(info));
1745         outb(CMD_NOP | CMD_WITHDMA, REG_CMD(info));
1746
1747         /* flush FIFO */
1748         outb(CMD_FLUSHFIFO, REG_CMD(info));
1749
1750         /* load bus-id and timeout */
1751         outb(BUSID(SCpnt->target), REG_SDID(info));
1752         outb(info->ifcfg.select_timeout, REG_STIM(info));
1753
1754         /* synchronous transfers */
1755         fas216_set_sync(info, SCpnt->target);
1756
1757         tot_msglen = msgqueue_msglength(&info->scsi.msgs);
1758
1759 #ifdef DEBUG_MESSAGES
1760         {
1761                 struct message *msg;
1762                 int msgnr = 0, i;
1763
1764                 printk("scsi%d.%c: message out: ",
1765                         info->host->host_no, '0' + SCpnt->target);
1766                 while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
1767                         printk("{ ");
1768                         for (i = 0; i < msg->length; i++)
1769                                 printk("%02x ", msg->msg[i]);
1770                         printk("} ");
1771                 }
1772                 printk("\n");
1773         }
1774 #endif
1775
1776         if (tot_msglen == 1 || tot_msglen == 3) {
1777                 /*
1778                  * We have an easy message length to send...
1779                  */
1780                 struct message *msg;
1781                 int msgnr = 0, i;
1782
1783                 info->scsi.phase = PHASE_SELSTEPS;
1784
1785                 /* load message bytes */
1786                 while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
1787                         for (i = 0; i < msg->length; i++)
1788                                 outb(msg->msg[i], REG_FF(info));
1789                         msg->fifo = tot_msglen - (inb(REG_CFIS(info)) & CFIS_CF);
1790                 }
1791
1792                 /* load command */
1793                 for (i = 0; i < SCpnt->cmd_len; i++)
1794                         outb(SCpnt->cmnd[i], REG_FF(info));
1795
1796                 if (tot_msglen == 1)
1797                         outb(CMD_SELECTATN, REG_CMD(info));
1798                 else
1799                         outb(CMD_SELECTATN3, REG_CMD(info));
1800         } else {
1801                 /*
1802                  * We have an unusual number of message bytes to send.
1803                  *  Load first byte into fifo, and issue SELECT with ATN and
1804                  *  stop steps.
1805                  */
1806                 struct message *msg = msgqueue_getmsg(&info->scsi.msgs, 0);
1807
1808                 outb(msg->msg[0], REG_FF(info));
1809                 msg->fifo = 1;
1810
1811                 outb(CMD_SELECTATNSTOP, REG_CMD(info));
1812         }
1813
1814 #ifdef DEBUG_CONNECT
1815         printk(", data pointers [%p, %X]\n",
1816                 info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
1817 #endif
1818         /* should now get either DISCONNECT or (FUNCTION DONE with BUS SERVICE) intr */
1819 }
1820
1821 /* Function: void fas216_rq_sns_done(info, SCpnt, result)
1822  * Purpose : Finish processing automatic request sense command
1823  * Params  : info   - interface that completed
1824  *           SCpnt  - command that completed
1825  *           result - driver byte of result
1826  */
1827 static void
1828 fas216_rq_sns_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result)
1829 {
1830 #ifdef DEBUG_CONNECT
1831         printk("scsi%d.%c: request sense complete, result=%04X%02X%02X\n",
1832                 info->host->host_no, '0' + SCpnt->target, result,
1833                 SCpnt->SCp.Message, SCpnt->SCp.Status);
1834 #endif
1835
1836         if (result != DID_OK || SCpnt->SCp.Status != GOOD)
1837                 /*
1838                  * Something went wrong.  Make sure that we don't
1839                  * have valid data in the sense buffer that could
1840                  * confuse the higher levels.
1841                  */
1842                 memset(SCpnt->sense_buffer, 0, sizeof(SCpnt->sense_buffer));
1843
1844         /*
1845          * Note that we don't set SCpnt->result, since that should
1846          * reflect the status of the command that we were asked by
1847          * the upper layers to process.  This would have been set
1848          * correctly by fas216_std_done.
1849          */
1850         SCpnt->scsi_done(SCpnt);
1851 }
1852
1853 /* Function: void fas216_std_done(info, SCpnt, result)
1854  * Purpose : Finish processing of standard command
1855  * Params  : info   - interface that completed
1856  *           SCpnt  - command that completed
1857  *           result - driver byte of result
1858  */
1859 static void
1860 fas216_std_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result)
1861 {
1862         info->stats.fins += 1;
1863
1864         SCpnt->result = result << 16 | info->scsi.SCp.Message << 8 |
1865                         info->scsi.SCp.Status;
1866
1867 #ifdef DEBUG_CONNECT
1868         printk("scsi%d.%c: command complete, result=%08X, command=",
1869                 info->host->host_no, '0' + SCpnt->target, SCpnt->result);
1870         print_command(SCpnt->cmnd);
1871 #endif
1872
1873         /*
1874          * If the driver detected an error, or the command
1875          * was request sense, then we're all done.
1876          */
1877         if (result != DID_OK || SCpnt->cmnd[0] == REQUEST_SENSE)
1878                 goto done;
1879
1880         /*
1881          * If the command returned CHECK_CONDITION status,
1882          * request the sense information.
1883          */
1884         if (info->scsi.SCp.Status == CHECK_CONDITION)
1885                 goto request_sense;
1886
1887         /*
1888          * If the command did not complete with GOOD status,
1889          * we are all done here.
1890          */
1891         if (info->scsi.SCp.Status != GOOD)
1892                 goto done;
1893
1894         /*
1895          * We have successfully completed a command.  Make sure that
1896          * we do not have any buffers left to transfer.  The world
1897          * is not perfect, and we seem to occasionally hit this.
1898          * It can be indicative of a buggy driver, target or the upper
1899          * levels of the SCSI code.
1900          */
1901         if (info->scsi.SCp.ptr) {
1902                 switch (SCpnt->cmnd[0]) {
1903                 case INQUIRY:
1904                 case START_STOP:
1905 //              case READ_CAPACITY:
1906                 case MODE_SENSE:
1907                         break;
1908
1909                 default:
1910                         printk(KERN_ERR "scsi%d.%c: incomplete data transfer "
1911                                 "detected: res=%08X ptr=%p len=%X command=",
1912                                 info->host->host_no, '0' + SCpnt->target,
1913                                 SCpnt->result, info->scsi.SCp.ptr,
1914                                 info->scsi.SCp.this_residual);
1915                         print_command(SCpnt->cmnd);
1916                 }
1917         }
1918
1919 done:   SCpnt->scsi_done(SCpnt);
1920         return;
1921
1922 request_sense:
1923         memset(SCpnt->cmnd, 0, sizeof (SCpnt->cmnd));
1924         SCpnt->cmnd[0] = REQUEST_SENSE;
1925         SCpnt->cmnd[1] = SCpnt->lun << 5;
1926         SCpnt->cmnd[4] = sizeof(SCpnt->sense_buffer);
1927         SCpnt->cmd_len = COMMAND_SIZE(SCpnt->cmnd[0]);
1928         SCpnt->SCp.buffer = NULL;
1929         SCpnt->SCp.buffers_residual = 0;
1930         SCpnt->SCp.ptr = (char *)SCpnt->sense_buffer;
1931         SCpnt->SCp.this_residual = sizeof(SCpnt->sense_buffer);
1932         SCpnt->SCp.Message = 0;
1933         SCpnt->SCp.Status = 0;
1934         SCpnt->sc_data_direction = SCSI_DATA_READ;
1935         SCpnt->use_sg = 0;
1936         SCpnt->tag = 0;
1937         SCpnt->host_scribble = (void *)fas216_rq_sns_done;
1938
1939         /*
1940          * Place this command into the high priority "request
1941          * sense" slot.  This will be the very next command
1942          * executed, unless a target connects to us.
1943          */
1944         if (info->reqSCpnt)
1945                 printk(KERN_WARNING "scsi%d.%c: loosing request command\n",
1946                         info->host->host_no, '0' + SCpnt->target);
1947         info->reqSCpnt = SCpnt;
1948 }
1949
1950 /* Function: void fas216_done(FAS216_Info *info, unsigned int result)
1951  * Purpose : complete processing for current command
1952  * Params  : info   - interface that completed
1953  *           result - driver byte of result
1954  */
1955 static void fas216_done(FAS216_Info *info, unsigned int result)
1956 {
1957         void (*fn)(FAS216_Info *, Scsi_Cmnd *, unsigned int);
1958         Scsi_Cmnd *SCpnt;
1959
1960         fas216_checkmagic(info);
1961
1962         if (!info->SCpnt)
1963                 goto no_command;
1964
1965         SCpnt = info->SCpnt;
1966         info->SCpnt = NULL;
1967         info->scsi.phase = PHASE_IDLE;
1968
1969         if (!SCpnt->scsi_done)
1970                 goto no_done;
1971
1972         if (info->scsi.aborting) {
1973                 printk("scsi%d.%c: uncaught abort - returning DID_ABORT\n",
1974                         info->host->host_no, fas216_target(info));
1975                 result = DID_ABORT;
1976                 info->scsi.aborting = 0;
1977         }
1978
1979         /*
1980          * Sanity check the completion - if we have zero bytes left
1981          * to transfer, we should not have a valid pointer.
1982          */
1983         if (info->scsi.SCp.ptr && info->scsi.SCp.this_residual == 0) {
1984                 printk("scsi%d.%c: zero bytes left to transfer, but "
1985                        "buffer pointer still valid: ptr=%p len=%08x command=",
1986                        info->host->host_no, '0' + SCpnt->target,
1987                        info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
1988                 info->scsi.SCp.ptr = NULL;
1989                 print_command(SCpnt->cmnd);
1990         }
1991
1992         /*
1993          * Clear down this command as completed.  If we need to request
1994          * the sense information, fas216_kick will re-assert the busy
1995          * status.
1996          */
1997         clear_bit(SCpnt->target * 8 + SCpnt->lun, info->busyluns);
1998
1999         fn = (void (*)(FAS216_Info *, Scsi_Cmnd *, unsigned int))SCpnt->host_scribble;
2000         fn(info, SCpnt, result);
2001
2002         if (info->scsi.irq != NO_IRQ)
2003                 fas216_kick(info);
2004         return;
2005
2006 no_command:
2007         panic("scsi%d.H: null command in fas216_done",
2008                 info->host->host_no);
2009 no_done:
2010         panic("scsi%d.H: null scsi_done function in fas216_done",
2011                 info->host->host_no);
2012 }
2013
2014 /* Function: int fas216_queue_command(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
2015  * Purpose : queue a command for adapter to process.
2016  * Params  : SCpnt - Command to queue
2017  *           done  - done function to call once command is complete
2018  * Returns : 0 - success, else error
2019  * Notes   : io_request_lock is held, interrupts are disabled.
2020  */
2021 int fas216_queue_command(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
2022 {
2023         FAS216_Info *info = (FAS216_Info *)SCpnt->host->hostdata;
2024         int result;
2025
2026         fas216_checkmagic(info);
2027
2028 #ifdef DEBUG_CONNECT
2029         printk("scsi%d.%c: received queuable command (%p) %02X\n",
2030                 SCpnt->host->host_no, '0' + SCpnt->target,
2031                 SCpnt, SCpnt->cmnd[0]);
2032 #endif
2033
2034         SCpnt->scsi_done = done;
2035         SCpnt->host_scribble = (void *)fas216_std_done;
2036         SCpnt->result = 0;
2037         SCpnt->SCp.Message = 0;
2038         SCpnt->SCp.Status = 0;
2039
2040         if (SCpnt->use_sg) {
2041                 unsigned long len = 0;
2042                 int buf;
2043
2044                 SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->buffer;
2045                 SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
2046                 SCpnt->SCp.ptr = (char *) SCpnt->SCp.buffer->address;
2047                 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
2048                 /*
2049                  * Calculate correct buffer length.  Some commands
2050                  * come in with the wrong request_bufflen.
2051                  */
2052                 for (buf = 0; buf <= SCpnt->SCp.buffers_residual; buf++)
2053                         len += SCpnt->SCp.buffer[buf].length;
2054
2055                 if (SCpnt->request_bufflen != len)
2056                         printk(KERN_WARNING "scsi%d.%c: bad request buffer "
2057                                "length %d, should be %ld\n", info->host->host_no,
2058                                '0' + SCpnt->target, SCpnt->request_bufflen, len);
2059                 SCpnt->request_bufflen = len;
2060         } else {
2061                 SCpnt->SCp.buffer = NULL;
2062                 SCpnt->SCp.buffers_residual = 0;
2063                 SCpnt->SCp.ptr = (unsigned char *)SCpnt->request_buffer;
2064                 SCpnt->SCp.this_residual = SCpnt->request_bufflen;
2065         }
2066
2067         /*
2068          * If the upper SCSI layers pass a buffer, but zero length,
2069          * we aren't interested in the buffer pointer.
2070          */
2071         if (SCpnt->SCp.this_residual == 0 && SCpnt->SCp.ptr) {
2072 #if 0
2073                 printk(KERN_WARNING "scsi%d.%c: zero length buffer passed for "
2074                        "command ", info->host->host_no, '0' + SCpnt->target);
2075                 print_command(SCpnt->cmnd);
2076 #endif
2077                 SCpnt->SCp.ptr = NULL;
2078         }
2079
2080         info->stats.queues += 1;
2081         SCpnt->tag = 0;
2082
2083         /*
2084          * Add command into execute queue and let it complete under
2085          * whatever scheme we're using.
2086          */
2087         result = !queue_add_cmd_ordered(&info->queues.issue, SCpnt);
2088
2089         /*
2090          * If we successfully added the command,
2091          * kick the interface to get it moving.
2092          */
2093         if (result == 0 && (!info->SCpnt || info->scsi.disconnectable))
2094                 fas216_kick(info);
2095
2096         return result;
2097 }
2098
2099 /* Function: void fas216_internal_done(Scsi_Cmnd *SCpnt)
2100  * Purpose : trigger restart of a waiting thread in fas216_command
2101  * Params  : SCpnt - Command to wake
2102  */
2103 static void fas216_internal_done(Scsi_Cmnd *SCpnt)
2104 {
2105         FAS216_Info *info = (FAS216_Info *)SCpnt->host->hostdata;
2106
2107         fas216_checkmagic(info);
2108
2109         info->internal_done = 1;
2110 }
2111
2112 /* Function: int fas216_command(Scsi_Cmnd *SCpnt)
2113  * Purpose : queue a command for adapter to process.
2114  * Params  : SCpnt - Command to queue
2115  * Returns : scsi result code
2116  * Notes   : io_request_lock is held, interrupts are disabled.
2117  */
2118 int fas216_command(Scsi_Cmnd *SCpnt)
2119 {
2120         FAS216_Info *info = (FAS216_Info *)SCpnt->host->hostdata;
2121
2122         fas216_checkmagic(info);
2123
2124         /*
2125          * We should only be using this if we don't have an interrupt.
2126          * Provide some "incentive" to use the queueing code.
2127          */
2128         if (info->scsi.irq != NO_IRQ)
2129                 BUG();
2130
2131         info->internal_done = 0;
2132         fas216_queue_command(SCpnt, fas216_internal_done);
2133
2134         /*
2135          * This wastes time, since we can't return until the command is
2136          * complete. We can't sleep either since we may get re-entered!
2137          * However, we must re-enable interrupts, or else we'll be
2138          * waiting forever.
2139          */
2140         spin_unlock_irq(&io_request_lock);
2141
2142         while (!info->internal_done) {
2143                 /*
2144                  * If we don't have an IRQ, then we must poll the card for
2145                  * it's interrupt, and use that to call this driver's
2146                  * interrupt routine.  That way, we keep the command
2147                  * progressing.  Maybe we can add some inteligence here
2148                  * and go to sleep if we know that the device is going
2149                  * to be some time (eg, disconnected).
2150                  */
2151                 if (inb(REG_STAT(info)) & STAT_INT) {
2152                         spin_lock_irq(&io_request_lock);
2153                         fas216_intr(info->host);
2154                         spin_unlock_irq(&io_request_lock);
2155                 }
2156         }
2157
2158         spin_lock_irq(&io_request_lock);
2159
2160         return SCpnt->result;
2161 }
2162
2163 enum res_abort {
2164         res_failed,             /* unable to abort              */
2165         res_success,            /* command on issue queue       */
2166         res_success_clear,      /* command marked tgt/lun busy  */
2167         res_hw_abort            /* command on disconnected dev  */
2168 };
2169
2170 /*
2171  * Prototype: enum res_abort fas216_do_abort(FAS216_Info *info, Scsi_Cmnd *SCpnt)
2172  * Purpose  : decide how to abort a command
2173  * Params   : SCpnt - command to abort
2174  * Returns  : abort status
2175  */
2176 static enum res_abort
2177 fas216_do_abort(FAS216_Info *info, Scsi_Cmnd *SCpnt)
2178 {
2179         enum res_abort res = res_failed;
2180
2181         if (queue_remove_cmd(&info->queues.issue, SCpnt)) {
2182                 /*
2183                  * The command was on the issue queue, and has not been
2184                  * issued yet.  We can remove the command from the queue,
2185                  * and acknowledge the abort.  Neither the device nor the
2186                  * interface know about the command.
2187                  */
2188                 printk("on issue queue ");
2189
2190                 res = res_success;
2191         } else if (queue_remove_cmd(&info->queues.disconnected, SCpnt)) {
2192                 /*
2193                  * The command was on the disconnected queue.  We must
2194                  * reconnect with the device if possible, and send it
2195                  * an abort message.
2196                  */
2197                 printk("on disconnected queue ");
2198
2199                 res = res_hw_abort;
2200         } else if (info->SCpnt == SCpnt) {
2201                 printk("executing ");
2202
2203                 switch (info->scsi.phase) {
2204                 /*
2205                  * If the interface is idle, and the command is 'disconnectable',
2206                  * then it is the same as on the disconnected queue.
2207                  */
2208                 case PHASE_IDLE:
2209                         if (info->scsi.disconnectable) {
2210                                 info->scsi.disconnectable = 0;
2211                                 info->SCpnt = NULL;
2212                                 res = res_hw_abort;
2213                         }
2214                         break;
2215
2216                 default:
2217                         break;
2218                 }
2219         } else if (info->origSCpnt == SCpnt) {
2220                 /*
2221                  * The command will be executed next, but a command
2222                  * is currently using the interface.  This is similar to
2223                  * being on the issue queue, except the busylun bit has
2224                  * been set.
2225                  */
2226                 info->origSCpnt = NULL;
2227                 printk("waiting for execution ");
2228                 res = res_success_clear;
2229         } else
2230                 printk("unknown ");
2231
2232         return res;
2233 }
2234
2235 /* Function: int fas216_eh_abort(Scsi_Cmnd *SCpnt)
2236  * Purpose : abort this command
2237  * Params  : SCpnt - command to abort
2238  * Returns : FAILED if unable to abort
2239  * Notes   : io_request_lock is taken, and irqs are disabled
2240  */
2241 int fas216_eh_abort(Scsi_Cmnd *SCpnt)
2242 {
2243         FAS216_Info *info = (FAS216_Info *)SCpnt->host->hostdata;
2244         int result = FAILED;
2245
2246         fas216_checkmagic(info);
2247
2248         info->stats.aborts += 1;
2249
2250         print_debug_list();
2251         fas216_dumpstate(info);
2252         fas216_dumpinfo(info);
2253
2254         printk(KERN_WARNING "scsi%d: abort ", info->host->host_no);
2255
2256         switch (fas216_do_abort(info, SCpnt)) {
2257         /*
2258          * We managed to find the command and cleared it out.
2259          * We do not expect the command to be executing on the
2260          * target, but we have set the busylun bit.
2261          */
2262         case res_success_clear:
2263                 printk("clear ");
2264                 clear_bit(SCpnt->target * 8 + SCpnt->lun, info->busyluns);
2265
2266         /*
2267          * We found the command, and cleared it out.  Either
2268          * the command is still known to be executing on the
2269          * target, or the busylun bit is not set.
2270          */
2271         case res_success:
2272                 printk("success\n");
2273                 result = SUCCESS;
2274                 break;
2275
2276         /*
2277          * We need to reconnect to the target and send it an
2278          * ABORT or ABORT_TAG message.  We can only do this
2279          * if the bus is free.
2280          */
2281         case res_hw_abort:
2282                 
2283
2284         /*
2285          * We are unable to abort the command for some reason.
2286          */
2287         default:
2288         case res_failed:
2289                 printk("failed\n");
2290                 break;
2291         }
2292
2293         return result;
2294 }
2295
2296 /* Function: void fas216_reset_state(FAS216_Info *info)
2297  * Purpose : Initialise driver internal state
2298  * Params  : info - state to initialise
2299  */
2300 static void fas216_reset_state(FAS216_Info *info)
2301 {
2302         neg_t sync_state, wide_state;
2303         int i;
2304
2305         fas216_checkmagic(info);
2306
2307         /*
2308          * Clear out all stale info in our state structure
2309          */
2310         memset(info->busyluns, 0, sizeof(info->busyluns));
2311         msgqueue_flush(&info->scsi.msgs);
2312         info->scsi.reconnected.target = 0;
2313         info->scsi.reconnected.lun = 0;
2314         info->scsi.reconnected.tag = 0;
2315         info->scsi.disconnectable = 0;
2316         info->scsi.aborting = 0;
2317         info->scsi.phase = PHASE_IDLE;
2318         info->scsi.async_stp =
2319                         fas216_syncperiod(info, info->ifcfg.asyncperiod);
2320
2321         if (info->ifcfg.wide_max_size == 0)
2322                 wide_state = neg_invalid;
2323         else
2324 #ifdef SCSI2_WIDE
2325                 wide_state = neg_wait;
2326 #else
2327                 wide_state = neg_invalid;
2328 #endif
2329
2330         if (info->host->dma_channel == NO_DMA || !info->dma.setup)
2331                 sync_state = neg_invalid;
2332         else
2333 #ifdef SCSI2_SYNC
2334                 sync_state = neg_wait;
2335 #else
2336                 sync_state = neg_invalid;
2337 #endif
2338
2339         for (i = 0; i < 8; i++) {
2340                 info->device[i].disconnect_ok   = info->ifcfg.disconnect_ok;
2341                 info->device[i].sync_state      = sync_state;
2342                 info->device[i].wide_state      = wide_state;
2343                 info->device[i].period          = info->ifcfg.asyncperiod / 4;
2344                 info->device[i].stp             = info->scsi.async_stp;
2345                 info->device[i].sof             = 0;
2346                 info->device[i].wide_xfer       = 0;
2347         }
2348
2349         /*
2350          * Drain all commands on disconnected queue
2351          */
2352         while (queue_remove(&info->queues.disconnected) != NULL);
2353
2354         /*
2355          * Remove executing commands.
2356          */
2357         info->SCpnt     = NULL;
2358         info->reqSCpnt  = NULL;
2359         info->origSCpnt = NULL;
2360 }
2361
2362 /* Function: int fas216_eh_device_reset(Scsi_Cmnd *SCpnt)
2363  * Purpose : Reset the device associated with this command
2364  * Params  : SCpnt - command specifing device to reset
2365  * Returns : FAILED if unable to reset
2366  */
2367 int fas216_eh_device_reset(Scsi_Cmnd *SCpnt)
2368 {
2369         FAS216_Info *info = (FAS216_Info *)SCpnt->host->hostdata;
2370
2371         printk("scsi%d.%c: "__FUNCTION__": called\n",
2372                 info->host->host_no, '0' + SCpnt->target);
2373         return FAILED;
2374 }
2375
2376 /* Function: int fas216_eh_bus_reset(Scsi_Cmnd *SCpnt)
2377  * Purpose : Reset the bus associated with the command
2378  * Params  : SCpnt - command specifing bus to reset
2379  * Returns : FAILED if unable to reset
2380  * Notes   : io_request_lock is taken, and irqs are disabled
2381  */
2382 int fas216_eh_bus_reset(Scsi_Cmnd *SCpnt)
2383 {
2384         FAS216_Info *info = (FAS216_Info *)SCpnt->host->hostdata;
2385         int result = FAILED;
2386
2387         fas216_checkmagic(info);
2388
2389         info->stats.bus_resets += 1;
2390
2391         printk("scsi%d.%c: "__FUNCTION__": resetting bus\n",
2392                 info->host->host_no, '0' + SCpnt->target);
2393
2394         /*
2395          * Attempt to stop all activity on this interface.
2396          */
2397         outb(info->scsi.cfg[2], REG_CNTL3(info));
2398         fas216_stoptransfer(info);
2399
2400         /*
2401          * Clear any pending interrupts
2402          */
2403         while (inb(REG_STAT(info)) & STAT_INT)
2404                 inb(REG_INST(info));
2405
2406         /*
2407          * Reset the SCSI bus
2408          */
2409         outb(CMD_RESETSCSI, REG_CMD(info));
2410         udelay(5);
2411
2412         /*
2413          * Clear reset interrupt
2414          */
2415         if (inb(REG_STAT(info)) & STAT_INT &&
2416             inb(REG_INST(info)) & INST_BUSRESET)
2417                 result = SUCCESS;
2418
2419         fas216_reset_state(info);
2420
2421         return result;
2422 }
2423
2424 /* Function: void fas216_init_chip(FAS216_Info *info)
2425  * Purpose : Initialise FAS216 state after reset
2426  * Params  : info - state structure for interface
2427  */
2428 static void fas216_init_chip(FAS216_Info *info)
2429 {
2430         outb(fas216_clockrate(info->ifcfg.clockrate), REG_CLKF(info));
2431         outb(info->scsi.cfg[0], REG_CNTL1(info));
2432         outb(info->scsi.cfg[1], REG_CNTL2(info));
2433         outb(info->scsi.cfg[2], REG_CNTL3(info));
2434         outb(info->ifcfg.select_timeout, REG_STIM(info));
2435         outb(0, REG_SOF(info));
2436         outb(info->scsi.async_stp, REG_STP(info));
2437         outb(info->scsi.cfg[0], REG_CNTL1(info));
2438 }
2439
2440 /* Function: int fas216_eh_host_reset(Scsi_Cmnd *SCpnt)
2441  * Purpose : Reset the host associated with this command
2442  * Params  : SCpnt - command specifing host to reset
2443  * Returns : FAILED if unable to reset
2444  * Notes   : io_request_lock is taken, and irqs are disabled
2445  */
2446 int fas216_eh_host_reset(Scsi_Cmnd *SCpnt)
2447 {
2448         FAS216_Info *info = (FAS216_Info *)SCpnt->host->hostdata;
2449
2450         fas216_checkmagic(info);
2451
2452         printk("scsi%d.%c: "__FUNCTION__": resetting host\n",
2453                 info->host->host_no, '0' + SCpnt->target);
2454
2455         /*
2456          * Reset the SCSI chip.
2457          */
2458         outb(CMD_RESETCHIP, REG_CMD(info));
2459
2460         /*
2461          * Ugly ugly ugly!
2462          * We need to release the io_request_lock and enable
2463          * IRQs if we sleep, but we must relock and disable
2464          * IRQs after the sleep.
2465          */
2466         spin_unlock_irq(&io_request_lock);
2467         scsi_sleep(25*HZ/100);
2468         spin_lock_irq(&io_request_lock);
2469
2470         /*
2471          * Release the SCSI reset.
2472          */
2473         outb(CMD_NOP, REG_CMD(info));
2474
2475         fas216_init_chip(info);
2476
2477         return SUCCESS;
2478 }
2479
2480 #define TYPE_UNKNOWN    0
2481 #define TYPE_NCR53C90   1
2482 #define TYPE_NCR53C90A  2
2483 #define TYPE_NCR53C9x   3
2484 #define TYPE_Am53CF94   4
2485 #define TYPE_EmFAS216   5
2486 #define TYPE_QLFAS216   6
2487
2488 static char *chip_types[] = {
2489         "unknown",
2490         "NS NCR53C90",
2491         "NS NCR53C90A",
2492         "NS NCR53C9x",
2493         "AMD Am53CF94",
2494         "Emulex FAS216",
2495         "QLogic FAS216"
2496 };
2497
2498 static int fas216_detect_type(FAS216_Info *info)
2499 {
2500         int family, rev;
2501
2502         /*
2503          * Reset the chip.
2504          */
2505         outb(CMD_RESETCHIP, REG_CMD(info));
2506         udelay(50);
2507         outb(CMD_NOP, REG_CMD(info));
2508
2509         /*
2510          * Check to see if control reg 2 is present.
2511          */
2512         outb(0, REG_CNTL3(info));
2513         outb(CNTL2_S2FE, REG_CNTL2(info));
2514
2515         /*
2516          * If we are unable to read back control reg 2
2517          * correctly, it is not present, and we have a
2518          * NCR53C90.
2519          */
2520         if ((inb(REG_CNTL2(info)) & (~0xe0)) != CNTL2_S2FE)
2521                 return TYPE_NCR53C90;
2522
2523         /*
2524          * Now, check control register 3
2525          */
2526         outb(0, REG_CNTL2(info));
2527         outb(0, REG_CNTL3(info));
2528         outb(5, REG_CNTL3(info));
2529
2530         /*
2531          * If we are unable to read the register back
2532          * correctly, we have a NCR53C90A
2533          */
2534         if (inb(REG_CNTL3(info)) != 5)
2535                 return TYPE_NCR53C90A;
2536
2537         /*
2538          * Now read the ID from the chip.
2539          */
2540         outb(0, REG_CNTL3(info));
2541
2542         outb(CNTL3_ADIDCHK, REG_CNTL3(info));
2543         outb(0, REG_CNTL3(info));
2544
2545         outb(CMD_RESETCHIP, REG_CMD(info));
2546         udelay(5);
2547         outb(CMD_WITHDMA | CMD_NOP, REG_CMD(info));
2548
2549         outb(CNTL2_ENF, REG_CNTL2(info));
2550         outb(CMD_RESETCHIP, REG_CMD(info));
2551         udelay(5);
2552         outb(CMD_NOP, REG_CMD(info));
2553
2554         rev     = inb(REG1_ID(info));
2555         family  = rev >> 3;
2556         rev    &= 7;
2557
2558         switch (family) {
2559         case 0x01:
2560                 if (rev == 4)
2561                         return TYPE_Am53CF94;
2562                 break;
2563
2564         case 0x02:
2565                 switch (rev) {
2566                 case 2:
2567                         return TYPE_EmFAS216;
2568                 case 3:
2569                         return TYPE_QLFAS216;
2570                 }
2571                 break;
2572
2573         default:
2574                 break;
2575         }
2576         printk("family %x rev %x\n", family, rev);
2577         return TYPE_NCR53C9x;
2578 }
2579
2580 /* Function: int fas216_init(struct Scsi_Host *instance)
2581  * Purpose : initialise FAS/NCR/AMD SCSI ic.
2582  * Params  : instance - a driver-specific filled-out structure
2583  * Returns : 0 on success
2584  */
2585 int fas216_init(struct Scsi_Host *instance)
2586 {
2587         FAS216_Info *info = (FAS216_Info *)instance->hostdata;
2588         int type;
2589
2590         info->magic_start = MAGIC;
2591         info->magic_end   = MAGIC;
2592         info->host        = instance;
2593         info->scsi.cfg[0] = instance->this_id;
2594         info->scsi.cfg[1] = CNTL2_ENF | CNTL2_S2FE;
2595         info->scsi.cfg[2] = info->ifcfg.cntl3 | CNTL3_ADIDCHK | CNTL3_G2CB;
2596
2597         memset(&info->stats, 0, sizeof(info->stats));
2598
2599         msgqueue_initialise(&info->scsi.msgs);
2600
2601         if (!queue_initialise(&info->queues.issue))
2602                 return 1;
2603
2604         if (!queue_initialise(&info->queues.disconnected)) {
2605                 queue_free(&info->queues.issue);
2606                 return 1;
2607         }
2608
2609         fas216_reset_state(info);
2610         type = fas216_detect_type(info);
2611         info->scsi.type = chip_types[type];
2612
2613         udelay(300);
2614
2615         /*
2616          * Initialise the chip correctly.
2617          */
2618         fas216_init_chip(info);
2619
2620         /*
2621          * Reset the SCSI bus.  We don't want to see
2622          * the resulting reset interrupt, so mask it
2623          * out.
2624          */
2625         outb(info->scsi.cfg[0] | CNTL1_DISR, REG_CNTL1(info));
2626         outb(CMD_RESETSCSI, REG_CMD(info));
2627
2628         /*
2629          * scsi standard says wait 250ms
2630          */
2631         spin_unlock_irq(&io_request_lock);
2632         scsi_sleep(25*HZ/100);
2633         spin_lock_irq(&io_request_lock);
2634
2635         outb(info->scsi.cfg[0], REG_CNTL1(info));
2636         inb(REG_INST(info));
2637
2638         fas216_checkmagic(info);
2639
2640         return 0;
2641 }
2642
2643 /* Function: int fas216_release(struct Scsi_Host *instance)
2644  * Purpose : release all resources and put everything to bed for
2645  *           FAS/NCR/AMD SCSI ic.
2646  * Params  : instance - a driver-specific filled-out structure
2647  * Returns : 0 on success
2648  */
2649 int fas216_release(struct Scsi_Host *instance)
2650 {
2651         FAS216_Info *info = (FAS216_Info *)instance->hostdata;
2652
2653         fas216_checkmagic(info);
2654
2655         outb(CMD_RESETCHIP, REG_CMD(info));
2656         queue_free(&info->queues.disconnected);
2657         queue_free(&info->queues.issue);
2658
2659         return 0;
2660 }
2661
2662 /*
2663  * Function: int fas216_info(FAS216_Info *info, char *buffer)
2664  * Purpose : generate a string containing information about this
2665  *           host.
2666  * Params  : info   - FAS216 host information
2667  *           buffer - string buffer to build string
2668  * Returns : size of built string
2669  */
2670 int fas216_info(FAS216_Info *info, char *buffer)
2671 {
2672         char *p = buffer;
2673
2674         p += sprintf(p, "(%s) at port 0x%08lX ",
2675                      info->scsi.type, info->host->io_port);
2676
2677         if (info->host->irq != NO_IRQ)
2678                 p += sprintf(p, "irq %d ", info->host->irq);
2679         else
2680                 p += sprintf(p, "no irq ");
2681
2682         if (info->host->dma_channel != NO_DMA)
2683                 p += sprintf(p, "dma %d ", info->host->dma_channel);
2684         else
2685                 p += sprintf(p, "no dma ");
2686
2687         return p - buffer;
2688 }
2689
2690 int fas216_print_host(FAS216_Info *info, char *buffer)
2691 {
2692         
2693         return sprintf(buffer,
2694                         "\n"
2695                         "Chip    : %s\n"
2696                         " Address: 0x%08lX\n"
2697                         " IRQ    : %d\n"
2698                         " DMA    : %d\n",
2699                         info->scsi.type, info->host->io_port,
2700                         info->host->irq, info->host->dma_channel);
2701 }
2702
2703 int fas216_print_stats(FAS216_Info *info, char *buffer)
2704 {
2705         return sprintf(buffer,
2706                         "\n"
2707                         "Command Statistics:\n"
2708                         " Queued     : %u\n"
2709                         " Issued     : %u\n"
2710                         " Completed  : %u\n"
2711                         " Reads      : %u\n"
2712                         " Writes     : %u\n"
2713                         " Others     : %u\n"
2714                         " Disconnects: %u\n"
2715                         " Aborts     : %u\n"
2716                         " Bus resets : %u\n"
2717                         " Host resets: %u\n",
2718                         info->stats.queues,      info->stats.removes,
2719                         info->stats.fins,        info->stats.reads,
2720                         info->stats.writes,      info->stats.miscs,
2721                         info->stats.disconnects, info->stats.aborts,
2722                         info->stats.bus_resets,  info->stats.host_resets);
2723 }
2724
2725 int fas216_print_device(FAS216_Info *info, Scsi_Device *scd, char *buffer)
2726 {
2727         struct fas216_device *dev = &info->device[scd->id];
2728         int len = 0;
2729         char *p;
2730
2731         proc_print_scsidevice(scd, buffer, &len, 0);
2732         p = buffer + len;
2733
2734         p += sprintf(p, "  Extensions: ");
2735
2736         if (scd->tagged_supported)
2737                 p += sprintf(p, "TAG %sabled [%d] ",
2738                              scd->tagged_queue ? "en" : "dis",
2739                              scd->current_tag);
2740
2741         p += sprintf(p, "\n  Transfers : %d-bit ",
2742                      8 << dev->wide_xfer);
2743
2744         if (dev->sof)
2745                 p += sprintf(p, "sync offset %d, %d ns\n",
2746                                 dev->sof, dev->period * 4);
2747         else
2748                 p += sprintf(p, "async\n");
2749
2750         return p - buffer;
2751 }
2752
2753 EXPORT_SYMBOL(fas216_info);
2754 EXPORT_SYMBOL(fas216_init);
2755 EXPORT_SYMBOL(fas216_queue_command);
2756 EXPORT_SYMBOL(fas216_command);
2757 EXPORT_SYMBOL(fas216_intr);
2758 EXPORT_SYMBOL(fas216_release);
2759 EXPORT_SYMBOL(fas216_eh_abort);
2760 EXPORT_SYMBOL(fas216_eh_device_reset);
2761 EXPORT_SYMBOL(fas216_eh_bus_reset);
2762 EXPORT_SYMBOL(fas216_eh_host_reset);
2763 EXPORT_SYMBOL(fas216_print_host);
2764 EXPORT_SYMBOL(fas216_print_stats);
2765 EXPORT_SYMBOL(fas216_print_device);
2766
2767 MODULE_AUTHOR("Russell King");
2768 MODULE_DESCRIPTION("Generic FAS216/NCR53C9x driver core");
2769 MODULE_LICENSE("GPL");