1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37#include <linux/module.h>
38#include <linux/blkdev.h>
39#include <linux/kernel.h>
40#include <linux/string.h>
41#include <linux/ioport.h>
42#include <linux/proc_fs.h>
43#include <linux/delay.h>
44#include <linux/bitops.h>
45#include <linux/init.h>
46#include <linux/interrupt.h>
47
48#include <asm/dma.h>
49#include <asm/io.h>
50#include <asm/irq.h>
51#include <asm/ecard.h>
52
53#include "../scsi.h"
54#include <scsi/scsi_dbg.h>
55#include <scsi/scsi_host.h>
56#include "fas216.h"
57#include "scsi.h"
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82#define SCSI2_SYNC
83#undef SCSI2_TAG
84
85#undef DEBUG_CONNECT
86#undef DEBUG_MESSAGES
87
88#undef CHECK_STRUCTURE
89
90#define LOG_CONNECT (1 << 0)
91#define LOG_BUSSERVICE (1 << 1)
92#define LOG_FUNCTIONDONE (1 << 2)
93#define LOG_MESSAGES (1 << 3)
94#define LOG_BUFFER (1 << 4)
95#define LOG_ERROR (1 << 8)
96
97static int level_mask = LOG_ERROR;
98
99module_param(level_mask, int, 0644);
100
101static int __init fas216_log_setup(char *str)
102{
103 char *s;
104
105 level_mask = 0;
106
107 while ((s = strsep(&str, ",")) != NULL) {
108 switch (s[0]) {
109 case 'a':
110 if (strcmp(s, "all") == 0)
111 level_mask |= -1;
112 break;
113 case 'b':
114 if (strncmp(s, "bus", 3) == 0)
115 level_mask |= LOG_BUSSERVICE;
116 if (strncmp(s, "buf", 3) == 0)
117 level_mask |= LOG_BUFFER;
118 break;
119 case 'c':
120 level_mask |= LOG_CONNECT;
121 break;
122 case 'e':
123 level_mask |= LOG_ERROR;
124 break;
125 case 'm':
126 level_mask |= LOG_MESSAGES;
127 break;
128 case 'n':
129 if (strcmp(s, "none") == 0)
130 level_mask = 0;
131 break;
132 case 's':
133 level_mask |= LOG_FUNCTIONDONE;
134 break;
135 }
136 }
137 return 1;
138}
139
140__setup("fas216_logging=", fas216_log_setup);
141
142static inline unsigned char fas216_readb(FAS216_Info *info, unsigned int reg)
143{
144 unsigned int off = reg << info->scsi.io_shift;
145 return readb(info->scsi.io_base + off);
146}
147
148static inline void fas216_writeb(FAS216_Info *info, unsigned int reg, unsigned int val)
149{
150 unsigned int off = reg << info->scsi.io_shift;
151 writeb(val, info->scsi.io_base + off);
152}
153
154static void fas216_dumpstate(FAS216_Info *info)
155{
156 unsigned char is, stat, inst;
157
158 is = fas216_readb(info, REG_IS);
159 stat = fas216_readb(info, REG_STAT);
160 inst = fas216_readb(info, REG_INST);
161
162 printk("FAS216: CTCL=%02X CTCM=%02X CMD=%02X STAT=%02X"
163 " INST=%02X IS=%02X CFIS=%02X",
164 fas216_readb(info, REG_CTCL),
165 fas216_readb(info, REG_CTCM),
166 fas216_readb(info, REG_CMD), stat, inst, is,
167 fas216_readb(info, REG_CFIS));
168 printk(" CNTL1=%02X CNTL2=%02X CNTL3=%02X CTCH=%02X\n",
169 fas216_readb(info, REG_CNTL1),
170 fas216_readb(info, REG_CNTL2),
171 fas216_readb(info, REG_CNTL3),
172 fas216_readb(info, REG_CTCH));
173}
174
175static void print_SCp(struct scsi_pointer *SCp, const char *prefix, const char *suffix)
176{
177 printk("%sptr %p this_residual 0x%x buffer %p buffers_residual 0x%x%s",
178 prefix, SCp->ptr, SCp->this_residual, SCp->buffer,
179 SCp->buffers_residual, suffix);
180}
181
182#ifdef CHECK_STRUCTURE
183static void fas216_dumpinfo(FAS216_Info *info)
184{
185 static int used = 0;
186 int i;
187
188 if (used++)
189 return;
190
191 printk("FAS216_Info=\n");
192 printk(" { magic_start=%lX host=%p SCpnt=%p origSCpnt=%p\n",
193 info->magic_start, info->host, info->SCpnt,
194 info->origSCpnt);
195 printk(" scsi={ io_shift=%X irq=%X cfg={ %X %X %X %X }\n",
196 info->scsi.io_shift, info->scsi.irq,
197 info->scsi.cfg[0], info->scsi.cfg[1], info->scsi.cfg[2],
198 info->scsi.cfg[3]);
199 printk(" type=%p phase=%X\n",
200 info->scsi.type, info->scsi.phase);
201 print_SCp(&info->scsi.SCp, " SCp={ ", " }\n");
202 printk(" msgs async_stp=%X disconnectable=%d aborting=%d }\n",
203 info->scsi.async_stp,
204 info->scsi.disconnectable, info->scsi.aborting);
205 printk(" stats={ queues=%X removes=%X fins=%X reads=%X writes=%X miscs=%X\n"
206 " disconnects=%X aborts=%X bus_resets=%X host_resets=%X}\n",
207 info->stats.queues, info->stats.removes, info->stats.fins,
208 info->stats.reads, info->stats.writes, info->stats.miscs,
209 info->stats.disconnects, info->stats.aborts, info->stats.bus_resets,
210 info->stats.host_resets);
211 printk(" ifcfg={ clockrate=%X select_timeout=%X asyncperiod=%X sync_max_depth=%X }\n",
212 info->ifcfg.clockrate, info->ifcfg.select_timeout,
213 info->ifcfg.asyncperiod, info->ifcfg.sync_max_depth);
214 for (i = 0; i < 8; i++) {
215 printk(" busyluns[%d]=%08lx dev[%d]={ disconnect_ok=%d stp=%X sof=%X sync_state=%X }\n",
216 i, info->busyluns[i], i,
217 info->device[i].disconnect_ok, info->device[i].stp,
218 info->device[i].sof, info->device[i].sync_state);
219 }
220 printk(" dma={ transfer_type=%X setup=%p pseudo=%p stop=%p }\n",
221 info->dma.transfer_type, info->dma.setup,
222 info->dma.pseudo, info->dma.stop);
223 printk(" internal_done=%X magic_end=%lX }\n",
224 info->internal_done, info->magic_end);
225}
226
227static void __fas216_checkmagic(FAS216_Info *info, const char *func)
228{
229 int corruption = 0;
230 if (info->magic_start != MAGIC) {
231 printk(KERN_CRIT "FAS216 Error: magic at start corrupted\n");
232 corruption++;
233 }
234 if (info->magic_end != MAGIC) {
235 printk(KERN_CRIT "FAS216 Error: magic at end corrupted\n");
236 corruption++;
237 }
238 if (corruption) {
239 fas216_dumpinfo(info);
240 panic("scsi memory space corrupted in %s", func);
241 }
242}
243#define fas216_checkmagic(info) __fas216_checkmagic((info), __func__)
244#else
245#define fas216_checkmagic(info)
246#endif
247
248static const char *fas216_bus_phase(int stat)
249{
250 static const char *phases[] = {
251 "DATA OUT", "DATA IN",
252 "COMMAND", "STATUS",
253 "MISC OUT", "MISC IN",
254 "MESG OUT", "MESG IN"
255 };
256
257 return phases[stat & STAT_BUSMASK];
258}
259
260static const char *fas216_drv_phase(FAS216_Info *info)
261{
262 static const char *phases[] = {
263 [PHASE_IDLE] = "idle",
264 [PHASE_SELECTION] = "selection",
265 [PHASE_COMMAND] = "command",
266 [PHASE_DATAOUT] = "data out",
267 [PHASE_DATAIN] = "data in",
268 [PHASE_MSGIN] = "message in",
269 [PHASE_MSGIN_DISCONNECT]= "disconnect",
270 [PHASE_MSGOUT_EXPECT] = "expect message out",
271 [PHASE_MSGOUT] = "message out",
272 [PHASE_STATUS] = "status",
273 [PHASE_DONE] = "done",
274 };
275
276 if (info->scsi.phase < ARRAY_SIZE(phases) &&
277 phases[info->scsi.phase])
278 return phases[info->scsi.phase];
279 return "???";
280}
281
282static char fas216_target(FAS216_Info *info)
283{
284 if (info->SCpnt)
285 return '0' + info->SCpnt->device->id;
286 else
287 return 'H';
288}
289
290static void
291fas216_do_log(FAS216_Info *info, char target, char *fmt, va_list ap)
292{
293 static char buf[1024];
294
295 vsnprintf(buf, sizeof(buf), fmt, ap);
296 printk("scsi%d.%c: %s", info->host->host_no, target, buf);
297}
298
299static void fas216_log_command(FAS216_Info *info, int level,
300 struct scsi_cmnd *SCpnt, char *fmt, ...)
301{
302 va_list args;
303
304 if (level != 0 && !(level & level_mask))
305 return;
306
307 va_start(args, fmt);
308 fas216_do_log(info, '0' + SCpnt->device->id, fmt, args);
309 va_end(args);
310
311 scsi_print_command(SCpnt);
312}
313
314static void
315fas216_log_target(FAS216_Info *info, int level, int target, char *fmt, ...)
316{
317 va_list args;
318
319 if (level != 0 && !(level & level_mask))
320 return;
321
322 if (target < 0)
323 target = 'H';
324 else
325 target += '0';
326
327 va_start(args, fmt);
328 fas216_do_log(info, target, fmt, args);
329 va_end(args);
330
331 printk("\n");
332}
333
334static void fas216_log(FAS216_Info *info, int level, char *fmt, ...)
335{
336 va_list args;
337
338 if (level != 0 && !(level & level_mask))
339 return;
340
341 va_start(args, fmt);
342 fas216_do_log(info, fas216_target(info), fmt, args);
343 va_end(args);
344
345 printk("\n");
346}
347
348#define PH_SIZE 32
349
350static struct { int stat, ssr, isr, ph; } ph_list[PH_SIZE];
351static int ph_ptr;
352
353static void add_debug_list(int stat, int ssr, int isr, int ph)
354{
355 ph_list[ph_ptr].stat = stat;
356 ph_list[ph_ptr].ssr = ssr;
357 ph_list[ph_ptr].isr = isr;
358 ph_list[ph_ptr].ph = ph;
359
360 ph_ptr = (ph_ptr + 1) & (PH_SIZE-1);
361}
362
363static struct { int command; void *from; } cmd_list[8];
364static int cmd_ptr;
365
366static void fas216_cmd(FAS216_Info *info, unsigned int command)
367{
368 cmd_list[cmd_ptr].command = command;
369 cmd_list[cmd_ptr].from = __builtin_return_address(0);
370
371 cmd_ptr = (cmd_ptr + 1) & 7;
372
373 fas216_writeb(info, REG_CMD, command);
374}
375
376static void print_debug_list(void)
377{
378 int i;
379
380 i = ph_ptr;
381
382 printk(KERN_ERR "SCSI IRQ trail\n");
383 do {
384 printk(" %02x:%02x:%02x:%1x",
385 ph_list[i].stat, ph_list[i].ssr,
386 ph_list[i].isr, ph_list[i].ph);
387 i = (i + 1) & (PH_SIZE - 1);
388 if (((i ^ ph_ptr) & 7) == 0)
389 printk("\n");
390 } while (i != ph_ptr);
391 if ((i ^ ph_ptr) & 7)
392 printk("\n");
393
394 i = cmd_ptr;
395 printk(KERN_ERR "FAS216 commands: ");
396 do {
397 printk("%02x:%p ", cmd_list[i].command, cmd_list[i].from);
398 i = (i + 1) & 7;
399 } while (i != cmd_ptr);
400 printk("\n");
401}
402
403static void fas216_done(FAS216_Info *info, unsigned int result);
404
405
406
407
408
409
410
411
412static inline unsigned short
413fas216_get_last_msg(FAS216_Info *info, int pos)
414{
415 unsigned short packed_msg = NOP;
416 struct message *msg;
417 int msgnr = 0;
418
419 while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
420 if (pos >= msg->fifo)
421 break;
422 }
423
424 if (msg) {
425 if (msg->msg[0] == EXTENDED_MESSAGE)
426 packed_msg = EXTENDED_MESSAGE | msg->msg[2] << 8;
427 else
428 packed_msg = msg->msg[0];
429 }
430
431 fas216_log(info, LOG_MESSAGES,
432 "Message: %04x found at position %02x\n", packed_msg, pos);
433
434 return packed_msg;
435}
436
437
438
439
440
441
442
443
444
445static int fas216_syncperiod(FAS216_Info *info, int ns)
446{
447 int value = (info->ifcfg.clockrate * ns) / 1000;
448
449 fas216_checkmagic(info);
450
451 if (value < 4)
452 value = 4;
453 else if (value > 35)
454 value = 35;
455
456 return value & 31;
457}
458
459
460
461
462
463
464
465
466
467
468
469static void fas216_set_sync(FAS216_Info *info, int target)
470{
471 unsigned int cntl3;
472
473 fas216_writeb(info, REG_SOF, info->device[target].sof);
474 fas216_writeb(info, REG_STP, info->device[target].stp);
475
476 cntl3 = info->scsi.cfg[2];
477 if (info->device[target].period >= (200 / 4))
478 cntl3 = cntl3 & ~CNTL3_FASTSCSI;
479
480 fas216_writeb(info, REG_CNTL3, cntl3);
481}
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514static void fas216_handlesync(FAS216_Info *info, char *msg)
515{
516 struct fas216_device *dev = &info->device[info->SCpnt->device->id];
517 enum { sync, async, none, reject } res = none;
518
519#ifdef SCSI2_SYNC
520 switch (msg[0]) {
521 case MESSAGE_REJECT:
522
523
524
525
526
527
528
529
530
531
532 if (dev->sync_state == neg_inprogress) {
533 dev->sync_state = neg_invalid;
534 res = async;
535 }
536 break;
537
538 case EXTENDED_MESSAGE:
539 switch (dev->sync_state) {
540
541
542
543
544 case neg_invalid:
545 res = reject;
546 break;
547
548
549
550
551
552
553
554 default:
555 fas216_cmd(info, CMD_SETATN);
556 if (msg[4] > info->ifcfg.sync_max_depth)
557 msg[4] = info->ifcfg.sync_max_depth;
558 if (msg[3] < 1000 / info->ifcfg.clockrate)
559 msg[3] = 1000 / info->ifcfg.clockrate;
560
561 msgqueue_flush(&info->scsi.msgs);
562 msgqueue_addmsg(&info->scsi.msgs, 5,
563 EXTENDED_MESSAGE, 3, EXTENDED_SDTR,
564 msg[3], msg[4]);
565 info->scsi.phase = PHASE_MSGOUT_EXPECT;
566
567
568
569
570 dev->sync_state = neg_targcomplete;
571 res = sync;
572 break;
573
574
575
576
577
578
579
580 case neg_inprogress:
581 res = reject;
582 if (msg[4] <= info->ifcfg.sync_max_depth &&
583 msg[3] >= 1000 / info->ifcfg.clockrate) {
584 dev->sync_state = neg_complete;
585 res = sync;
586 }
587 break;
588 }
589 }
590#else
591 res = reject;
592#endif
593
594 switch (res) {
595 case sync:
596 dev->period = msg[3];
597 dev->sof = msg[4];
598 dev->stp = fas216_syncperiod(info, msg[3] * 4);
599 fas216_set_sync(info, info->SCpnt->device->id);
600 break;
601
602 case reject:
603 fas216_cmd(info, CMD_SETATN);
604 msgqueue_flush(&info->scsi.msgs);
605 msgqueue_addmsg(&info->scsi.msgs, 1, MESSAGE_REJECT);
606 info->scsi.phase = PHASE_MSGOUT_EXPECT;
607
608 case async:
609 dev->period = info->ifcfg.asyncperiod / 4;
610 dev->sof = 0;
611 dev->stp = info->scsi.async_stp;
612 fas216_set_sync(info, info->SCpnt->device->id);
613 break;
614
615 case none:
616 break;
617 }
618}
619
620
621
622
623
624
625
626
627static void fas216_updateptrs(FAS216_Info *info, int bytes_transferred)
628{
629 struct scsi_pointer *SCp = &info->scsi.SCp;
630
631 fas216_checkmagic(info);
632
633 BUG_ON(bytes_transferred < 0);
634
635 SCp->phase -= bytes_transferred;
636
637 while (bytes_transferred != 0) {
638 if (SCp->this_residual > bytes_transferred)
639 break;
640
641
642
643
644 bytes_transferred -= SCp->this_residual;
645 if (!next_SCp(SCp) && bytes_transferred) {
646 printk(KERN_WARNING "scsi%d.%c: out of buffers\n",
647 info->host->host_no, '0' + info->SCpnt->device->id);
648 return;
649 }
650 }
651
652 SCp->this_residual -= bytes_transferred;
653 if (SCp->this_residual)
654 SCp->ptr += bytes_transferred;
655 else
656 SCp->ptr = NULL;
657}
658
659
660
661
662
663
664
665
666
667static void fas216_pio(FAS216_Info *info, fasdmadir_t direction)
668{
669 struct scsi_pointer *SCp = &info->scsi.SCp;
670
671 fas216_checkmagic(info);
672
673 if (direction == DMA_OUT)
674 fas216_writeb(info, REG_FF, get_next_SCp_byte(SCp));
675 else
676 put_next_SCp_byte(SCp, fas216_readb(info, REG_FF));
677
678 if (SCp->this_residual == 0)
679 next_SCp(SCp);
680}
681
682static void fas216_set_stc(FAS216_Info *info, unsigned int length)
683{
684 fas216_writeb(info, REG_STCL, length);
685 fas216_writeb(info, REG_STCM, length >> 8);
686 fas216_writeb(info, REG_STCH, length >> 16);
687}
688
689static unsigned int fas216_get_ctc(FAS216_Info *info)
690{
691 return fas216_readb(info, REG_CTCL) +
692 (fas216_readb(info, REG_CTCM) << 8) +
693 (fas216_readb(info, REG_CTCH) << 16);
694}
695
696
697
698
699
700
701
702
703static void fas216_cleanuptransfer(FAS216_Info *info)
704{
705 unsigned long total, residual, fifo;
706 fasdmatype_t dmatype = info->dma.transfer_type;
707
708 info->dma.transfer_type = fasdma_none;
709
710
711
712
713 if (dmatype == fasdma_pio || dmatype == fasdma_none)
714 return;
715
716 if (dmatype == fasdma_real_all)
717 total = info->scsi.SCp.phase;
718 else
719 total = info->scsi.SCp.this_residual;
720
721 residual = fas216_get_ctc(info);
722
723 fifo = fas216_readb(info, REG_CFIS) & CFIS_CF;
724
725 fas216_log(info, LOG_BUFFER, "cleaning up from previous "
726 "transfer: length 0x%06x, residual 0x%x, fifo %d",
727 total, residual, fifo);
728
729
730
731
732
733
734
735 if (info->scsi.phase == PHASE_DATAOUT)
736 residual += fifo;
737
738 fas216_updateptrs(info, total - residual);
739}
740
741
742
743
744
745
746
747static void fas216_transfer(FAS216_Info *info)
748{
749 fasdmadir_t direction;
750 fasdmatype_t dmatype;
751
752 fas216_log(info, LOG_BUFFER,
753 "starttransfer: buffer %p length 0x%06x reqlen 0x%06x",
754 info->scsi.SCp.ptr, info->scsi.SCp.this_residual,
755 info->scsi.SCp.phase);
756
757 if (!info->scsi.SCp.ptr) {
758 fas216_log(info, LOG_ERROR, "null buffer passed to "
759 "fas216_starttransfer");
760 print_SCp(&info->scsi.SCp, "SCp: ", "\n");
761 print_SCp(&info->SCpnt->SCp, "Cmnd SCp: ", "\n");
762 return;
763 }
764
765
766
767
768
769
770 if (info->device[info->SCpnt->device->id].sof)
771 dmatype = fasdma_real_all;
772 else
773 dmatype = fasdma_pio;
774
775 if (info->scsi.phase == PHASE_DATAOUT)
776 direction = DMA_OUT;
777 else
778 direction = DMA_IN;
779
780 if (info->dma.setup)
781 dmatype = info->dma.setup(info->host, &info->scsi.SCp,
782 direction, dmatype);
783 info->dma.transfer_type = dmatype;
784
785 if (dmatype == fasdma_real_all)
786 fas216_set_stc(info, info->scsi.SCp.phase);
787 else
788 fas216_set_stc(info, info->scsi.SCp.this_residual);
789
790 switch (dmatype) {
791 case fasdma_pio:
792 fas216_log(info, LOG_BUFFER, "PIO transfer");
793 fas216_writeb(info, REG_SOF, 0);
794 fas216_writeb(info, REG_STP, info->scsi.async_stp);
795 fas216_cmd(info, CMD_TRANSFERINFO);
796 fas216_pio(info, direction);
797 break;
798
799 case fasdma_pseudo:
800 fas216_log(info, LOG_BUFFER, "pseudo transfer");
801 fas216_cmd(info, CMD_TRANSFERINFO | CMD_WITHDMA);
802 info->dma.pseudo(info->host, &info->scsi.SCp,
803 direction, info->SCpnt->transfersize);
804 break;
805
806 case fasdma_real_block:
807 fas216_log(info, LOG_BUFFER, "block dma transfer");
808 fas216_cmd(info, CMD_TRANSFERINFO | CMD_WITHDMA);
809 break;
810
811 case fasdma_real_all:
812 fas216_log(info, LOG_BUFFER, "total dma transfer");
813 fas216_cmd(info, CMD_TRANSFERINFO | CMD_WITHDMA);
814 break;
815
816 default:
817 fas216_log(info, LOG_BUFFER | LOG_ERROR,
818 "invalid FAS216 DMA type");
819 break;
820 }
821}
822
823
824
825
826
827
828
829static void fas216_stoptransfer(FAS216_Info *info)
830{
831 fas216_checkmagic(info);
832
833 if (info->dma.transfer_type == fasdma_real_all ||
834 info->dma.transfer_type == fasdma_real_block)
835 info->dma.stop(info->host, &info->scsi.SCp);
836
837 fas216_cleanuptransfer(info);
838
839 if (info->scsi.phase == PHASE_DATAIN) {
840 unsigned int fifo;
841
842
843
844
845
846
847 fifo = fas216_readb(info, REG_CFIS) & CFIS_CF;
848 while (fifo && info->scsi.SCp.ptr) {
849 *info->scsi.SCp.ptr = fas216_readb(info, REG_FF);
850 fas216_updateptrs(info, 1);
851 fifo--;
852 }
853 } else {
854
855
856
857
858 fas216_cmd(info, CMD_FLUSHFIFO);
859 }
860}
861
862static void fas216_aborttransfer(FAS216_Info *info)
863{
864 fas216_checkmagic(info);
865
866 if (info->dma.transfer_type == fasdma_real_all ||
867 info->dma.transfer_type == fasdma_real_block)
868 info->dma.stop(info->host, &info->scsi.SCp);
869
870 info->dma.transfer_type = fasdma_none;
871 fas216_cmd(info, CMD_FLUSHFIFO);
872}
873
874static void fas216_kick(FAS216_Info *info);
875
876
877
878
879
880
881
882static void fas216_disconnect_intr(FAS216_Info *info)
883{
884 unsigned long flags;
885
886 fas216_checkmagic(info);
887
888 fas216_log(info, LOG_CONNECT, "disconnect phase=%02x",
889 info->scsi.phase);
890
891 msgqueue_flush(&info->scsi.msgs);
892
893 switch (info->scsi.phase) {
894 case PHASE_SELECTION:
895 case PHASE_SELSTEPS:
896 fas216_done(info, DID_NO_CONNECT);
897 break;
898
899 case PHASE_MSGIN_DISCONNECT:
900 info->scsi.disconnectable = 1;
901 info->scsi.phase = PHASE_IDLE;
902 info->stats.disconnects += 1;
903 spin_lock_irqsave(&info->host_lock, flags);
904 if (info->scsi.phase == PHASE_IDLE)
905 fas216_kick(info);
906 spin_unlock_irqrestore(&info->host_lock, flags);
907 break;
908
909 case PHASE_DONE:
910 fas216_done(info, DID_OK);
911 break;
912
913 case PHASE_MSGOUT:
914 if (fas216_get_last_msg(info, info->scsi.msgin_fifo) == ABORT) {
915 info->scsi.aborting = 0;
916 fas216_done(info, DID_ABORT);
917 break;
918 }
919
920 default:
921 printk(KERN_ERR "scsi%d.%c: unexpected disconnect in phase %s\n",
922 info->host->host_no, fas216_target(info), fas216_drv_phase(info));
923 print_debug_list();
924 fas216_stoptransfer(info);
925 fas216_done(info, DID_ERROR);
926 break;
927 }
928}
929
930
931
932
933
934
935
936static void
937fas216_reselected_intr(FAS216_Info *info)
938{
939 unsigned int cfis, i;
940 unsigned char msg[4];
941 unsigned char target, lun, tag;
942
943 fas216_checkmagic(info);
944
945 WARN_ON(info->scsi.phase == PHASE_SELECTION ||
946 info->scsi.phase == PHASE_SELSTEPS);
947
948 cfis = fas216_readb(info, REG_CFIS);
949
950 fas216_log(info, LOG_CONNECT, "reconnect phase=%02x cfis=%02x",
951 info->scsi.phase, cfis);
952
953 cfis &= CFIS_CF;
954
955 if (cfis < 2 || cfis > 4) {
956 printk(KERN_ERR "scsi%d.H: incorrect number of bytes after reselect\n",
957 info->host->host_no);
958 goto bad_message;
959 }
960
961 for (i = 0; i < cfis; i++)
962 msg[i] = fas216_readb(info, REG_FF);
963
964 if (!(msg[0] & (1 << info->host->this_id)) ||
965 !(msg[1] & 0x80))
966 goto initiator_error;
967
968 target = msg[0] & ~(1 << info->host->this_id);
969 target = ffs(target) - 1;
970 lun = msg[1] & 7;
971 tag = 0;
972
973 if (cfis >= 3) {
974 if (msg[2] != SIMPLE_QUEUE_TAG)
975 goto initiator_error;
976
977 tag = msg[3];
978 }
979
980
981 fas216_writeb(info, REG_SDID, target);
982 fas216_set_sync(info, target);
983 msgqueue_flush(&info->scsi.msgs);
984
985 fas216_log(info, LOG_CONNECT, "Reconnected: target %1x lun %1x tag %02x",
986 target, lun, tag);
987
988 if (info->scsi.disconnectable && info->SCpnt) {
989 info->scsi.disconnectable = 0;
990 if (info->SCpnt->device->id == target &&
991 info->SCpnt->device->lun == lun &&
992 info->SCpnt->tag == tag) {
993 fas216_log(info, LOG_CONNECT, "reconnected previously executing command");
994 } else {
995 queue_add_cmd_tail(&info->queues.disconnected, info->SCpnt);
996 fas216_log(info, LOG_CONNECT, "had to move command to disconnected queue");
997 info->SCpnt = NULL;
998 }
999 }
1000 if (!info->SCpnt) {
1001 info->SCpnt = queue_remove_tgtluntag(&info->queues.disconnected,
1002 target, lun, tag);
1003 fas216_log(info, LOG_CONNECT, "had to get command");
1004 }
1005
1006 if (info->SCpnt) {
1007
1008
1009
1010 info->scsi.SCp = info->SCpnt->SCp;
1011
1012 fas216_log(info, LOG_CONNECT, "data pointers: [%p, %X]",
1013 info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
1014 info->scsi.phase = PHASE_MSGIN;
1015 } else {
1016
1017
1018
1019
1020
1021
1022 fas216_cmd(info, CMD_SETATN);
1023
1024#if 0
1025 if (tag)
1026 msgqueue_addmsg(&info->scsi.msgs, 2, ABORT_TAG, tag);
1027 else
1028#endif
1029 msgqueue_addmsg(&info->scsi.msgs, 1, ABORT);
1030 info->scsi.phase = PHASE_MSGOUT_EXPECT;
1031 info->scsi.aborting = 1;
1032 }
1033
1034 fas216_cmd(info, CMD_MSGACCEPTED);
1035 return;
1036
1037 initiator_error:
1038 printk(KERN_ERR "scsi%d.H: error during reselection: bytes",
1039 info->host->host_no);
1040 for (i = 0; i < cfis; i++)
1041 printk(" %02x", msg[i]);
1042 printk("\n");
1043 bad_message:
1044 fas216_cmd(info, CMD_SETATN);
1045 msgqueue_flush(&info->scsi.msgs);
1046 msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
1047 info->scsi.phase = PHASE_MSGOUT_EXPECT;
1048 fas216_cmd(info, CMD_MSGACCEPTED);
1049}
1050
1051static void fas216_parse_message(FAS216_Info *info, unsigned char *message, int msglen)
1052{
1053 int i;
1054
1055 switch (message[0]) {
1056 case COMMAND_COMPLETE:
1057 if (msglen != 1)
1058 goto unrecognised;
1059
1060 printk(KERN_ERR "scsi%d.%c: command complete with no "
1061 "status in MESSAGE_IN?\n",
1062 info->host->host_no, fas216_target(info));
1063 break;
1064
1065 case SAVE_POINTERS:
1066 if (msglen != 1)
1067 goto unrecognised;
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077 info->SCpnt->SCp = info->scsi.SCp;
1078 info->SCpnt->SCp.sent_command = 0;
1079 fas216_log(info, LOG_CONNECT | LOG_MESSAGES | LOG_BUFFER,
1080 "save data pointers: [%p, %X]",
1081 info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
1082 break;
1083
1084 case RESTORE_POINTERS:
1085 if (msglen != 1)
1086 goto unrecognised;
1087
1088
1089
1090
1091 info->scsi.SCp = info->SCpnt->SCp;
1092 fas216_log(info, LOG_CONNECT | LOG_MESSAGES | LOG_BUFFER,
1093 "restore data pointers: [%p, 0x%x]",
1094 info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
1095 break;
1096
1097 case DISCONNECT:
1098 if (msglen != 1)
1099 goto unrecognised;
1100
1101 info->scsi.phase = PHASE_MSGIN_DISCONNECT;
1102 break;
1103
1104 case MESSAGE_REJECT:
1105 if (msglen != 1)
1106 goto unrecognised;
1107
1108 switch (fas216_get_last_msg(info, info->scsi.msgin_fifo)) {
1109 case EXTENDED_MESSAGE | EXTENDED_SDTR << 8:
1110 fas216_handlesync(info, message);
1111 break;
1112
1113 default:
1114 fas216_log(info, 0, "reject, last message 0x%04x",
1115 fas216_get_last_msg(info, info->scsi.msgin_fifo));
1116 }
1117 break;
1118
1119 case NOP:
1120 break;
1121
1122 case EXTENDED_MESSAGE:
1123 if (msglen < 3)
1124 goto unrecognised;
1125
1126 switch (message[2]) {
1127 case EXTENDED_SDTR:
1128 fas216_handlesync(info, message);
1129 break;
1130
1131 default:
1132 goto unrecognised;
1133 }
1134 break;
1135
1136 default:
1137 goto unrecognised;
1138 }
1139 return;
1140
1141unrecognised:
1142 fas216_log(info, 0, "unrecognised message, rejecting");
1143 printk("scsi%d.%c: message was", info->host->host_no, fas216_target(info));
1144 for (i = 0; i < msglen; i++)
1145 printk("%s%02X", i & 31 ? " " : "\n ", message[i]);
1146 printk("\n");
1147
1148
1149
1150
1151
1152
1153fas216_cmd(info, CMD_NOP);
1154fas216_dumpstate(info);
1155 fas216_cmd(info, CMD_SETATN);
1156 msgqueue_flush(&info->scsi.msgs);
1157 msgqueue_addmsg(&info->scsi.msgs, 1, MESSAGE_REJECT);
1158 info->scsi.phase = PHASE_MSGOUT_EXPECT;
1159fas216_dumpstate(info);
1160}
1161
1162static int fas216_wait_cmd(FAS216_Info *info, int cmd)
1163{
1164 int tout;
1165 int stat;
1166
1167 fas216_cmd(info, cmd);
1168
1169 for (tout = 1000; tout; tout -= 1) {
1170 stat = fas216_readb(info, REG_STAT);
1171 if (stat & (STAT_INT|STAT_PARITYERROR))
1172 break;
1173 udelay(1);
1174 }
1175
1176 return stat;
1177}
1178
1179static int fas216_get_msg_byte(FAS216_Info *info)
1180{
1181 unsigned int stat = fas216_wait_cmd(info, CMD_MSGACCEPTED);
1182
1183 if ((stat & STAT_INT) == 0)
1184 goto timedout;
1185
1186 if ((stat & STAT_BUSMASK) != STAT_MESGIN)
1187 goto unexpected_phase_change;
1188
1189 fas216_readb(info, REG_INST);
1190
1191 stat = fas216_wait_cmd(info, CMD_TRANSFERINFO);
1192
1193 if ((stat & STAT_INT) == 0)
1194 goto timedout;
1195
1196 if (stat & STAT_PARITYERROR)
1197 goto parity_error;
1198
1199 if ((stat & STAT_BUSMASK) != STAT_MESGIN)
1200 goto unexpected_phase_change;
1201
1202 fas216_readb(info, REG_INST);
1203
1204 return fas216_readb(info, REG_FF);
1205
1206timedout:
1207 fas216_log(info, LOG_ERROR, "timed out waiting for message byte");
1208 return -1;
1209
1210unexpected_phase_change:
1211 fas216_log(info, LOG_ERROR, "unexpected phase change: status = %02x", stat);
1212 return -2;
1213
1214parity_error:
1215 fas216_log(info, LOG_ERROR, "parity error during message in phase");
1216 return -3;
1217}
1218
1219
1220
1221
1222
1223
1224
1225static void fas216_message(FAS216_Info *info)
1226{
1227 unsigned char *message = info->scsi.message;
1228 unsigned int msglen = 1;
1229 int msgbyte = 0;
1230
1231 fas216_checkmagic(info);
1232
1233 message[0] = fas216_readb(info, REG_FF);
1234
1235 if (message[0] == EXTENDED_MESSAGE) {
1236 msgbyte = fas216_get_msg_byte(info);
1237
1238 if (msgbyte >= 0) {
1239 message[1] = msgbyte;
1240
1241 for (msglen = 2; msglen < message[1] + 2; msglen++) {
1242 msgbyte = fas216_get_msg_byte(info);
1243
1244 if (msgbyte >= 0)
1245 message[msglen] = msgbyte;
1246 else
1247 break;
1248 }
1249 }
1250 }
1251
1252 if (msgbyte == -3)
1253 goto parity_error;
1254
1255#ifdef DEBUG_MESSAGES
1256 {
1257 int i;
1258
1259 printk("scsi%d.%c: message in: ",
1260 info->host->host_no, fas216_target(info));
1261 for (i = 0; i < msglen; i++)
1262 printk("%02X ", message[i]);
1263 printk("\n");
1264 }
1265#endif
1266
1267 fas216_parse_message(info, message, msglen);
1268 fas216_cmd(info, CMD_MSGACCEPTED);
1269 return;
1270
1271parity_error:
1272 fas216_cmd(info, CMD_SETATN);
1273 msgqueue_flush(&info->scsi.msgs);
1274 msgqueue_addmsg(&info->scsi.msgs, 1, MSG_PARITY_ERROR);
1275 info->scsi.phase = PHASE_MSGOUT_EXPECT;
1276 fas216_cmd(info, CMD_MSGACCEPTED);
1277 return;
1278}
1279
1280
1281
1282
1283
1284
1285
1286static void fas216_send_command(FAS216_Info *info)
1287{
1288 int i;
1289
1290 fas216_checkmagic(info);
1291
1292 fas216_cmd(info, CMD_NOP|CMD_WITHDMA);
1293 fas216_cmd(info, CMD_FLUSHFIFO);
1294
1295
1296 for (i = info->scsi.SCp.sent_command; i < info->SCpnt->cmd_len; i++)
1297 fas216_writeb(info, REG_FF, info->SCpnt->cmnd[i]);
1298
1299 fas216_cmd(info, CMD_TRANSFERINFO);
1300
1301 info->scsi.phase = PHASE_COMMAND;
1302}
1303
1304
1305
1306
1307
1308
1309
1310
1311static void fas216_send_messageout(FAS216_Info *info, int start)
1312{
1313 unsigned int tot_msglen = msgqueue_msglength(&info->scsi.msgs);
1314
1315 fas216_checkmagic(info);
1316
1317 fas216_cmd(info, CMD_FLUSHFIFO);
1318
1319 if (tot_msglen) {
1320 struct message *msg;
1321 int msgnr = 0;
1322
1323 while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
1324 int i;
1325
1326 for (i = start; i < msg->length; i++)
1327 fas216_writeb(info, REG_FF, msg->msg[i]);
1328
1329 msg->fifo = tot_msglen - (fas216_readb(info, REG_CFIS) & CFIS_CF);
1330 start = 0;
1331 }
1332 } else
1333 fas216_writeb(info, REG_FF, NOP);
1334
1335 fas216_cmd(info, CMD_TRANSFERINFO);
1336
1337 info->scsi.phase = PHASE_MSGOUT;
1338}
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348static void fas216_busservice_intr(FAS216_Info *info, unsigned int stat, unsigned int is)
1349{
1350 fas216_checkmagic(info);
1351
1352 fas216_log(info, LOG_BUSSERVICE,
1353 "bus service: stat=%02x is=%02x phase=%02x",
1354 stat, is, info->scsi.phase);
1355
1356 switch (info->scsi.phase) {
1357 case PHASE_SELECTION:
1358 if ((is & IS_BITS) != IS_MSGBYTESENT)
1359 goto bad_is;
1360 break;
1361
1362 case PHASE_SELSTEPS:
1363 switch (is & IS_BITS) {
1364 case IS_SELARB:
1365 case IS_MSGBYTESENT:
1366 goto bad_is;
1367
1368 case IS_NOTCOMMAND:
1369 case IS_EARLYPHASE:
1370 if ((stat & STAT_BUSMASK) == STAT_MESGIN)
1371 break;
1372 goto bad_is;
1373
1374 case IS_COMPLETE:
1375 break;
1376 }
1377
1378 default:
1379 break;
1380 }
1381
1382 fas216_cmd(info, CMD_NOP);
1383
1384#define STATE(st,ph) ((ph) << 3 | (st))
1385
1386
1387
1388 switch (STATE(stat & STAT_BUSMASK, info->scsi.phase)) {
1389 case STATE(STAT_DATAIN, PHASE_SELSTEPS):
1390 case STATE(STAT_DATAIN, PHASE_MSGOUT):
1391 case STATE(STAT_DATAIN, PHASE_COMMAND):
1392 case STATE(STAT_DATAIN, PHASE_MSGIN):
1393 info->scsi.phase = PHASE_DATAIN;
1394 fas216_transfer(info);
1395 return;
1396
1397 case STATE(STAT_DATAIN, PHASE_DATAIN):
1398 case STATE(STAT_DATAOUT, PHASE_DATAOUT):
1399 fas216_cleanuptransfer(info);
1400 fas216_transfer(info);
1401 return;
1402
1403 case STATE(STAT_DATAOUT, PHASE_SELSTEPS):
1404 case STATE(STAT_DATAOUT, PHASE_MSGOUT):
1405 case STATE(STAT_DATAOUT, PHASE_COMMAND):
1406 case STATE(STAT_DATAOUT, PHASE_MSGIN):
1407 fas216_cmd(info, CMD_FLUSHFIFO);
1408 info->scsi.phase = PHASE_DATAOUT;
1409 fas216_transfer(info);
1410 return;
1411
1412 case STATE(STAT_STATUS, PHASE_DATAOUT):
1413 case STATE(STAT_STATUS, PHASE_DATAIN):
1414 fas216_stoptransfer(info);
1415 case STATE(STAT_STATUS, PHASE_SELSTEPS):
1416 case STATE(STAT_STATUS, PHASE_MSGOUT):
1417 case STATE(STAT_STATUS, PHASE_COMMAND):
1418 case STATE(STAT_STATUS, PHASE_MSGIN):
1419 fas216_cmd(info, CMD_INITCMDCOMPLETE);
1420 info->scsi.phase = PHASE_STATUS;
1421 return;
1422
1423 case STATE(STAT_MESGIN, PHASE_DATAOUT):
1424 case STATE(STAT_MESGIN, PHASE_DATAIN):
1425 fas216_stoptransfer(info);
1426 case STATE(STAT_MESGIN, PHASE_COMMAND):
1427 case STATE(STAT_MESGIN, PHASE_SELSTEPS):
1428 case STATE(STAT_MESGIN, PHASE_MSGOUT):
1429 info->scsi.msgin_fifo = fas216_readb(info, REG_CFIS) & CFIS_CF;
1430 fas216_cmd(info, CMD_FLUSHFIFO);
1431 fas216_cmd(info, CMD_TRANSFERINFO);
1432 info->scsi.phase = PHASE_MSGIN;
1433 return;
1434
1435 case STATE(STAT_MESGIN, PHASE_MSGIN):
1436 info->scsi.msgin_fifo = fas216_readb(info, REG_CFIS) & CFIS_CF;
1437 fas216_cmd(info, CMD_TRANSFERINFO);
1438 return;
1439
1440 case STATE(STAT_COMMAND, PHASE_MSGOUT):
1441 case STATE(STAT_COMMAND, PHASE_MSGIN):
1442 fas216_send_command(info);
1443 info->scsi.phase = PHASE_COMMAND;
1444 return;
1445
1446
1447
1448
1449
1450 case STATE(STAT_MESGOUT, PHASE_SELECTION):
1451 fas216_send_messageout(info, 1);
1452 return;
1453
1454
1455
1456
1457 case STATE(STAT_MESGOUT, PHASE_SELSTEPS):
1458 case STATE(STAT_MESGOUT, PHASE_MSGOUT):
1459
1460
1461
1462
1463
1464
1465 if (info->device[info->SCpnt->device->id].parity_check) {
1466
1467
1468
1469
1470 info->device[info->SCpnt->device->id].parity_check = 0;
1471 info->device[info->SCpnt->device->id].parity_enabled = 1;
1472 fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]);
1473 }
1474
1475 if (msgqueue_msglength(&info->scsi.msgs) > 1)
1476 fas216_cmd(info, CMD_SETATN);
1477
1478
1479
1480
1481
1482 case STATE(STAT_MESGOUT, PHASE_MSGOUT_EXPECT):
1483 fas216_send_messageout(info, 0);
1484 return;
1485
1486
1487
1488
1489
1490 case STATE(STAT_COMMAND, PHASE_COMMAND):
1491
1492
1493
1494
1495
1496
1497 printk(KERN_ERR "scsi%d.%c: "
1498 "target trying to receive more command bytes\n",
1499 info->host->host_no, fas216_target(info));
1500 fas216_cmd(info, CMD_SETATN);
1501 fas216_set_stc(info, 15);
1502 fas216_cmd(info, CMD_PADBYTES | CMD_WITHDMA);
1503 msgqueue_flush(&info->scsi.msgs);
1504 msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
1505 info->scsi.phase = PHASE_MSGOUT_EXPECT;
1506 return;
1507 }
1508
1509 if (info->scsi.phase == PHASE_MSGIN_DISCONNECT) {
1510 printk(KERN_ERR "scsi%d.%c: disconnect message received, but bus service %s?\n",
1511 info->host->host_no, fas216_target(info),
1512 fas216_bus_phase(stat));
1513 msgqueue_flush(&info->scsi.msgs);
1514 fas216_cmd(info, CMD_SETATN);
1515 msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
1516 info->scsi.phase = PHASE_MSGOUT_EXPECT;
1517 info->scsi.aborting = 1;
1518 fas216_cmd(info, CMD_TRANSFERINFO);
1519 return;
1520 }
1521 printk(KERN_ERR "scsi%d.%c: bus phase %s after %s?\n",
1522 info->host->host_no, fas216_target(info),
1523 fas216_bus_phase(stat),
1524 fas216_drv_phase(info));
1525 print_debug_list();
1526 return;
1527
1528bad_is:
1529 fas216_log(info, 0, "bus service at step %d?", is & IS_BITS);
1530 fas216_dumpstate(info);
1531 print_debug_list();
1532
1533 fas216_done(info, DID_ERROR);
1534}
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544static void fas216_funcdone_intr(FAS216_Info *info, unsigned int stat, unsigned int is)
1545{
1546 unsigned int fifo_len = fas216_readb(info, REG_CFIS) & CFIS_CF;
1547
1548 fas216_checkmagic(info);
1549
1550 fas216_log(info, LOG_FUNCTIONDONE,
1551 "function done: stat=%02x is=%02x phase=%02x",
1552 stat, is, info->scsi.phase);
1553
1554 switch (info->scsi.phase) {
1555 case PHASE_STATUS:
1556 if (fifo_len != 2) {
1557 fas216_log(info, 0, "odd number of bytes in FIFO: %d", fifo_len);
1558 }
1559
1560
1561
1562 info->scsi.SCp.Status = fas216_readb(info, REG_FF);
1563 info->scsi.SCp.Message = fas216_readb(info, REG_FF);
1564 info->scsi.phase = PHASE_DONE;
1565 fas216_cmd(info, CMD_MSGACCEPTED);
1566 break;
1567
1568 case PHASE_IDLE:
1569 case PHASE_SELECTION:
1570 case PHASE_SELSTEPS:
1571 break;
1572
1573 case PHASE_MSGIN:
1574 if ((stat & STAT_BUSMASK) == STAT_MESGIN) {
1575 info->scsi.msgin_fifo = fifo_len;
1576 fas216_message(info);
1577 break;
1578 }
1579
1580 default:
1581 fas216_log(info, 0, "internal phase %s for function done?"
1582 " What do I do with this?",
1583 fas216_target(info), fas216_drv_phase(info));
1584 }
1585}
1586
1587static void fas216_bus_reset(FAS216_Info *info)
1588{
1589 neg_t sync_state;
1590 int i;
1591
1592 msgqueue_flush(&info->scsi.msgs);
1593
1594 sync_state = neg_invalid;
1595
1596#ifdef SCSI2_SYNC
1597 if (info->ifcfg.capabilities & (FASCAP_DMA|FASCAP_PSEUDODMA))
1598 sync_state = neg_wait;
1599#endif
1600
1601 info->scsi.phase = PHASE_IDLE;
1602 info->SCpnt = NULL;
1603 memset(&info->scsi.SCp, 0, sizeof(info->scsi.SCp));
1604
1605 for (i = 0; i < 8; i++) {
1606 info->device[i].disconnect_ok = info->ifcfg.disconnect_ok;
1607 info->device[i].sync_state = sync_state;
1608 info->device[i].period = info->ifcfg.asyncperiod / 4;
1609 info->device[i].stp = info->scsi.async_stp;
1610 info->device[i].sof = 0;
1611 info->device[i].wide_xfer = 0;
1612 }
1613
1614 info->rst_bus_status = 1;
1615 wake_up(&info->eh_wait);
1616}
1617
1618
1619
1620
1621
1622
1623
1624irqreturn_t fas216_intr(FAS216_Info *info)
1625{
1626 unsigned char inst, is, stat;
1627 int handled = IRQ_NONE;
1628
1629 fas216_checkmagic(info);
1630
1631 stat = fas216_readb(info, REG_STAT);
1632 is = fas216_readb(info, REG_IS);
1633 inst = fas216_readb(info, REG_INST);
1634
1635 add_debug_list(stat, is, inst, info->scsi.phase);
1636
1637 if (stat & STAT_INT) {
1638 if (inst & INST_BUSRESET) {
1639 fas216_log(info, 0, "bus reset detected");
1640 fas216_bus_reset(info);
1641 scsi_report_bus_reset(info->host, 0);
1642 } else if (inst & INST_ILLEGALCMD) {
1643 fas216_log(info, LOG_ERROR, "illegal command given\n");
1644 fas216_dumpstate(info);
1645 print_debug_list();
1646 } else if (inst & INST_DISCONNECT)
1647 fas216_disconnect_intr(info);
1648 else if (inst & INST_RESELECTED)
1649 fas216_reselected_intr(info);
1650 else if (inst & INST_BUSSERVICE)
1651 fas216_busservice_intr(info, stat, is);
1652 else if (inst & INST_FUNCDONE)
1653 fas216_funcdone_intr(info, stat, is);
1654 else
1655 fas216_log(info, 0, "unknown interrupt received:"
1656 " phase %s inst %02X is %02X stat %02X",
1657 fas216_drv_phase(info), inst, is, stat);
1658 handled = IRQ_HANDLED;
1659 }
1660 return handled;
1661}
1662
1663static void __fas216_start_command(FAS216_Info *info, struct scsi_cmnd *SCpnt)
1664{
1665 int tot_msglen;
1666
1667
1668 fas216_set_stc(info, 0);
1669 fas216_cmd(info, CMD_NOP | CMD_WITHDMA);
1670
1671
1672 fas216_cmd(info, CMD_FLUSHFIFO);
1673
1674
1675 fas216_writeb(info, REG_SDID, BUSID(SCpnt->device->id));
1676 fas216_writeb(info, REG_STIM, info->ifcfg.select_timeout);
1677
1678
1679 fas216_set_sync(info, SCpnt->device->id);
1680
1681 tot_msglen = msgqueue_msglength(&info->scsi.msgs);
1682
1683#ifdef DEBUG_MESSAGES
1684 {
1685 struct message *msg;
1686 int msgnr = 0, i;
1687
1688 printk("scsi%d.%c: message out: ",
1689 info->host->host_no, '0' + SCpnt->device->id);
1690 while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
1691 printk("{ ");
1692 for (i = 0; i < msg->length; i++)
1693 printk("%02x ", msg->msg[i]);
1694 printk("} ");
1695 }
1696 printk("\n");
1697 }
1698#endif
1699
1700 if (tot_msglen == 1 || tot_msglen == 3) {
1701
1702
1703
1704 struct message *msg;
1705 int msgnr = 0, i;
1706
1707 info->scsi.phase = PHASE_SELSTEPS;
1708
1709
1710 while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
1711 for (i = 0; i < msg->length; i++)
1712 fas216_writeb(info, REG_FF, msg->msg[i]);
1713 msg->fifo = tot_msglen - (fas216_readb(info, REG_CFIS) & CFIS_CF);
1714 }
1715
1716
1717 for (i = 0; i < SCpnt->cmd_len; i++)
1718 fas216_writeb(info, REG_FF, SCpnt->cmnd[i]);
1719
1720 if (tot_msglen == 1)
1721 fas216_cmd(info, CMD_SELECTATN);
1722 else
1723 fas216_cmd(info, CMD_SELECTATN3);
1724 } else {
1725
1726
1727
1728
1729
1730 struct message *msg = msgqueue_getmsg(&info->scsi.msgs, 0);
1731
1732 fas216_writeb(info, REG_FF, msg->msg[0]);
1733 msg->fifo = 1;
1734
1735 fas216_cmd(info, CMD_SELECTATNSTOP);
1736 }
1737}
1738
1739
1740
1741
1742
1743
1744static int parity_test(FAS216_Info *info, int target)
1745{
1746#if 0
1747 if (target == 3) {
1748 info->device[target].parity_check = 0;
1749 return 1;
1750 }
1751#endif
1752 return info->device[target].parity_check;
1753}
1754
1755static void fas216_start_command(FAS216_Info *info, struct scsi_cmnd *SCpnt)
1756{
1757 int disconnect_ok;
1758
1759
1760
1761
1762 info->scsi.phase = PHASE_SELECTION;
1763 info->scsi.SCp = SCpnt->SCp;
1764 info->SCpnt = SCpnt;
1765 info->dma.transfer_type = fasdma_none;
1766
1767 if (parity_test(info, SCpnt->device->id))
1768 fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0] | CNTL1_PTE);
1769 else
1770 fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]);
1771
1772
1773
1774
1775 disconnect_ok = SCpnt->cmnd[0] != REQUEST_SENSE &&
1776 info->device[SCpnt->device->id].disconnect_ok;
1777
1778
1779
1780
1781 msgqueue_flush(&info->scsi.msgs);
1782 msgqueue_addmsg(&info->scsi.msgs, 1, IDENTIFY(disconnect_ok, SCpnt->device->lun));
1783
1784
1785
1786
1787 if (SCpnt->tag)
1788 msgqueue_addmsg(&info->scsi.msgs, 2, SIMPLE_QUEUE_TAG, SCpnt->tag);
1789
1790 do {
1791#ifdef SCSI2_SYNC
1792 if ((info->device[SCpnt->device->id].sync_state == neg_wait ||
1793 info->device[SCpnt->device->id].sync_state == neg_complete) &&
1794 (SCpnt->cmnd[0] == REQUEST_SENSE ||
1795 SCpnt->cmnd[0] == INQUIRY)) {
1796 info->device[SCpnt->device->id].sync_state = neg_inprogress;
1797 msgqueue_addmsg(&info->scsi.msgs, 5,
1798 EXTENDED_MESSAGE, 3, EXTENDED_SDTR,
1799 1000 / info->ifcfg.clockrate,
1800 info->ifcfg.sync_max_depth);
1801 break;
1802 }
1803#endif
1804 } while (0);
1805
1806 __fas216_start_command(info, SCpnt);
1807}
1808
1809static void fas216_allocate_tag(FAS216_Info *info, struct scsi_cmnd *SCpnt)
1810{
1811#ifdef SCSI2_TAG
1812
1813
1814
1815 if (SCpnt->device->simple_tags && SCpnt->cmnd[0] != REQUEST_SENSE &&
1816 SCpnt->cmnd[0] != INQUIRY) {
1817 SCpnt->device->current_tag += 1;
1818 if (SCpnt->device->current_tag == 0)
1819 SCpnt->device->current_tag = 1;
1820 SCpnt->tag = SCpnt->device->current_tag;
1821 } else
1822#endif
1823 set_bit(SCpnt->device->id * 8 +
1824 (u8)(SCpnt->device->lun & 0x7), info->busyluns);
1825
1826 info->stats.removes += 1;
1827 switch (SCpnt->cmnd[0]) {
1828 case WRITE_6:
1829 case WRITE_10:
1830 case WRITE_12:
1831 info->stats.writes += 1;
1832 break;
1833 case READ_6:
1834 case READ_10:
1835 case READ_12:
1836 info->stats.reads += 1;
1837 break;
1838 default:
1839 info->stats.miscs += 1;
1840 break;
1841 }
1842}
1843
1844static void fas216_do_bus_device_reset(FAS216_Info *info,
1845 struct scsi_cmnd *SCpnt)
1846{
1847 struct message *msg;
1848
1849
1850
1851
1852 info->scsi.phase = PHASE_SELECTION;
1853 info->scsi.SCp = SCpnt->SCp;
1854 info->SCpnt = SCpnt;
1855 info->dma.transfer_type = fasdma_none;
1856
1857 fas216_log(info, LOG_ERROR, "sending bus device reset");
1858
1859 msgqueue_flush(&info->scsi.msgs);
1860 msgqueue_addmsg(&info->scsi.msgs, 1, BUS_DEVICE_RESET);
1861
1862
1863 fas216_set_stc(info, 0);
1864 fas216_cmd(info, CMD_NOP | CMD_WITHDMA);
1865
1866
1867 fas216_cmd(info, CMD_FLUSHFIFO);
1868
1869
1870 fas216_writeb(info, REG_SDID, BUSID(SCpnt->device->id));
1871 fas216_writeb(info, REG_STIM, info->ifcfg.select_timeout);
1872
1873
1874 fas216_set_sync(info, SCpnt->device->id);
1875
1876 msg = msgqueue_getmsg(&info->scsi.msgs, 0);
1877
1878 fas216_writeb(info, REG_FF, BUS_DEVICE_RESET);
1879 msg->fifo = 1;
1880
1881 fas216_cmd(info, CMD_SELECTATNSTOP);
1882}
1883
1884
1885
1886
1887
1888
1889
1890
1891static void fas216_kick(FAS216_Info *info)
1892{
1893 struct scsi_cmnd *SCpnt = NULL;
1894#define TYPE_OTHER 0
1895#define TYPE_RESET 1
1896#define TYPE_QUEUE 2
1897 int where_from = TYPE_OTHER;
1898
1899 fas216_checkmagic(info);
1900
1901
1902
1903
1904 do {
1905 if (info->rstSCpnt) {
1906 SCpnt = info->rstSCpnt;
1907
1908 where_from = TYPE_RESET;
1909 break;
1910 }
1911
1912 if (info->reqSCpnt) {
1913 SCpnt = info->reqSCpnt;
1914 info->reqSCpnt = NULL;
1915 break;
1916 }
1917
1918 if (info->origSCpnt) {
1919 SCpnt = info->origSCpnt;
1920 info->origSCpnt = NULL;
1921 break;
1922 }
1923
1924
1925 if (!SCpnt) {
1926 SCpnt = queue_remove_exclude(&info->queues.issue,
1927 info->busyluns);
1928 where_from = TYPE_QUEUE;
1929 break;
1930 }
1931 } while (0);
1932
1933 if (!SCpnt) {
1934
1935
1936
1937 fas216_cmd(info, CMD_ENABLESEL);
1938 return;
1939 }
1940
1941
1942
1943
1944 fas216_cmd(info, CMD_DISABLESEL);
1945
1946 if (info->scsi.disconnectable && info->SCpnt) {
1947 fas216_log(info, LOG_CONNECT,
1948 "moved command for %d to disconnected queue",
1949 info->SCpnt->device->id);
1950 queue_add_cmd_tail(&info->queues.disconnected, info->SCpnt);
1951 info->scsi.disconnectable = 0;
1952 info->SCpnt = NULL;
1953 }
1954
1955 fas216_log_command(info, LOG_CONNECT | LOG_MESSAGES, SCpnt,
1956 "starting");
1957
1958 switch (where_from) {
1959 case TYPE_QUEUE:
1960 fas216_allocate_tag(info, SCpnt);
1961 case TYPE_OTHER:
1962 fas216_start_command(info, SCpnt);
1963 break;
1964 case TYPE_RESET:
1965 fas216_do_bus_device_reset(info, SCpnt);
1966 break;
1967 }
1968
1969 fas216_log(info, LOG_CONNECT, "select: data pointers [%p, %X]",
1970 info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
1971
1972
1973
1974
1975
1976}
1977
1978
1979
1980
1981static void fas216_devicereset_done(FAS216_Info *info, struct scsi_cmnd *SCpnt,
1982 unsigned int result)
1983{
1984 fas216_log(info, LOG_ERROR, "fas216 device reset complete");
1985
1986 info->rstSCpnt = NULL;
1987 info->rst_dev_status = 1;
1988 wake_up(&info->eh_wait);
1989}
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999static void fas216_rq_sns_done(FAS216_Info *info, struct scsi_cmnd *SCpnt,
2000 unsigned int result)
2001{
2002 fas216_log_target(info, LOG_CONNECT, SCpnt->device->id,
2003 "request sense complete, result=0x%04x%02x%02x",
2004 result, SCpnt->SCp.Message, SCpnt->SCp.Status);
2005
2006 if (result != DID_OK || SCpnt->SCp.Status != GOOD)
2007
2008
2009
2010
2011
2012 memset(SCpnt->sense_buffer, 0, sizeof(SCpnt->sense_buffer));
2013
2014
2015
2016
2017
2018
2019
2020
2021 scsi_eh_restore_cmnd(SCpnt, &info->ses);
2022 SCpnt->scsi_done(SCpnt);
2023}
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033static void
2034fas216_std_done(FAS216_Info *info, struct scsi_cmnd *SCpnt, unsigned int result)
2035{
2036 info->stats.fins += 1;
2037
2038 SCpnt->result = result << 16 | info->scsi.SCp.Message << 8 |
2039 info->scsi.SCp.Status;
2040
2041 fas216_log_command(info, LOG_CONNECT, SCpnt,
2042 "command complete, result=0x%08x", SCpnt->result);
2043
2044
2045
2046
2047 if (host_byte(SCpnt->result) != DID_OK ||
2048 msg_byte(SCpnt->result) != COMMAND_COMPLETE)
2049 goto done;
2050
2051
2052
2053
2054
2055 if (status_byte(SCpnt->result) == CHECK_CONDITION ||
2056 status_byte(SCpnt->result) == COMMAND_TERMINATED)
2057 goto request_sense;
2058
2059
2060
2061
2062
2063 if (status_byte(SCpnt->result) != GOOD)
2064 goto done;
2065
2066
2067
2068
2069
2070
2071
2072
2073 if (info->scsi.SCp.ptr) {
2074 switch (SCpnt->cmnd[0]) {
2075 case INQUIRY:
2076 case START_STOP:
2077 case MODE_SENSE:
2078 break;
2079
2080 default:
2081 scmd_printk(KERN_ERR, SCpnt,
2082 "incomplete data transfer detected: res=%08X ptr=%p len=%X\n",
2083 SCpnt->result, info->scsi.SCp.ptr,
2084 info->scsi.SCp.this_residual);
2085 scsi_print_command(SCpnt);
2086 set_host_byte(SCpnt, DID_ERROR);
2087 goto request_sense;
2088 }
2089 }
2090
2091done:
2092 if (SCpnt->scsi_done) {
2093 SCpnt->scsi_done(SCpnt);
2094 return;
2095 }
2096
2097 panic("scsi%d.H: null scsi_done function in fas216_done",
2098 info->host->host_no);
2099
2100
2101request_sense:
2102 if (SCpnt->cmnd[0] == REQUEST_SENSE)
2103 goto done;
2104
2105 scsi_eh_prep_cmnd(SCpnt, &info->ses, NULL, 0, ~0);
2106 fas216_log_target(info, LOG_CONNECT, SCpnt->device->id,
2107 "requesting sense");
2108 init_SCp(SCpnt);
2109 SCpnt->SCp.Message = 0;
2110 SCpnt->SCp.Status = 0;
2111 SCpnt->tag = 0;
2112 SCpnt->host_scribble = (void *)fas216_rq_sns_done;
2113
2114
2115
2116
2117
2118
2119 if (info->reqSCpnt)
2120 printk(KERN_WARNING "scsi%d.%c: losing request command\n",
2121 info->host->host_no, '0' + SCpnt->device->id);
2122 info->reqSCpnt = SCpnt;
2123}
2124
2125
2126
2127
2128
2129
2130
2131
2132static void fas216_done(FAS216_Info *info, unsigned int result)
2133{
2134 void (*fn)(FAS216_Info *, struct scsi_cmnd *, unsigned int);
2135 struct scsi_cmnd *SCpnt;
2136 unsigned long flags;
2137
2138 fas216_checkmagic(info);
2139
2140 if (!info->SCpnt)
2141 goto no_command;
2142
2143 SCpnt = info->SCpnt;
2144 info->SCpnt = NULL;
2145 info->scsi.phase = PHASE_IDLE;
2146
2147 if (info->scsi.aborting) {
2148 fas216_log(info, 0, "uncaught abort - returning DID_ABORT");
2149 result = DID_ABORT;
2150 info->scsi.aborting = 0;
2151 }
2152
2153
2154
2155
2156
2157 if (info->scsi.SCp.ptr && info->scsi.SCp.this_residual == 0) {
2158 scmd_printk(KERN_INFO, SCpnt,
2159 "zero bytes left to transfer, but buffer pointer still valid: ptr=%p len=%08x\n",
2160 info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
2161 info->scsi.SCp.ptr = NULL;
2162 scsi_print_command(SCpnt);
2163 }
2164
2165
2166
2167
2168
2169
2170 info->device[SCpnt->device->id].parity_check = 0;
2171 clear_bit(SCpnt->device->id * 8 +
2172 (u8)(SCpnt->device->lun & 0x7), info->busyluns);
2173
2174 fn = (void (*)(FAS216_Info *, struct scsi_cmnd *, unsigned int))SCpnt->host_scribble;
2175 fn(info, SCpnt, result);
2176
2177 if (info->scsi.irq) {
2178 spin_lock_irqsave(&info->host_lock, flags);
2179 if (info->scsi.phase == PHASE_IDLE)
2180 fas216_kick(info);
2181 spin_unlock_irqrestore(&info->host_lock, flags);
2182 }
2183 return;
2184
2185no_command:
2186 panic("scsi%d.H: null command in fas216_done",
2187 info->host->host_no);
2188}
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199static int fas216_queue_command_lck(struct scsi_cmnd *SCpnt,
2200 void (*done)(struct scsi_cmnd *))
2201{
2202 FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
2203 int result;
2204
2205 fas216_checkmagic(info);
2206
2207 fas216_log_command(info, LOG_CONNECT, SCpnt,
2208 "received command (%p)", SCpnt);
2209
2210 SCpnt->scsi_done = done;
2211 SCpnt->host_scribble = (void *)fas216_std_done;
2212 SCpnt->result = 0;
2213
2214 init_SCp(SCpnt);
2215
2216 info->stats.queues += 1;
2217 SCpnt->tag = 0;
2218
2219 spin_lock(&info->host_lock);
2220
2221
2222
2223
2224
2225 result = !queue_add_cmd_ordered(&info->queues.issue, SCpnt);
2226
2227
2228
2229
2230
2231 if (result == 0 && info->scsi.phase == PHASE_IDLE)
2232 fas216_kick(info);
2233 spin_unlock(&info->host_lock);
2234
2235 fas216_log_target(info, LOG_CONNECT, -1, "queue %s",
2236 result ? "failure" : "success");
2237
2238 return result;
2239}
2240
2241DEF_SCSI_QCMD(fas216_queue_command)
2242
2243
2244
2245
2246
2247
2248
2249static void fas216_internal_done(struct scsi_cmnd *SCpnt)
2250{
2251 FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
2252
2253 fas216_checkmagic(info);
2254
2255 info->internal_done = 1;
2256}
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266static int fas216_noqueue_command_lck(struct scsi_cmnd *SCpnt,
2267 void (*done)(struct scsi_cmnd *))
2268{
2269 FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
2270
2271 fas216_checkmagic(info);
2272
2273
2274
2275
2276
2277 BUG_ON(info->scsi.irq);
2278
2279 info->internal_done = 0;
2280 fas216_queue_command_lck(SCpnt, fas216_internal_done);
2281
2282
2283
2284
2285
2286
2287
2288 spin_unlock_irq(info->host->host_lock);
2289
2290 while (!info->internal_done) {
2291
2292
2293
2294
2295
2296
2297
2298
2299 if (fas216_readb(info, REG_STAT) & STAT_INT) {
2300 spin_lock_irq(info->host->host_lock);
2301 fas216_intr(info);
2302 spin_unlock_irq(info->host->host_lock);
2303 }
2304 }
2305
2306 spin_lock_irq(info->host->host_lock);
2307
2308 done(SCpnt);
2309
2310 return 0;
2311}
2312
2313DEF_SCSI_QCMD(fas216_noqueue_command)
2314
2315
2316
2317
2318
2319static void fas216_eh_timer(unsigned long data)
2320{
2321 FAS216_Info *info = (FAS216_Info *)data;
2322
2323 fas216_log(info, LOG_ERROR, "error handling timed out\n");
2324
2325 del_timer(&info->eh_timer);
2326
2327 if (info->rst_bus_status == 0)
2328 info->rst_bus_status = -1;
2329 if (info->rst_dev_status == 0)
2330 info->rst_dev_status = -1;
2331
2332 wake_up(&info->eh_wait);
2333}
2334
2335enum res_find {
2336 res_failed,
2337 res_success,
2338 res_hw_abort
2339};
2340
2341
2342
2343
2344
2345
2346
2347
2348static enum res_find fas216_find_command(FAS216_Info *info,
2349 struct scsi_cmnd *SCpnt)
2350{
2351 enum res_find res = res_failed;
2352
2353 if (queue_remove_cmd(&info->queues.issue, SCpnt)) {
2354
2355
2356
2357
2358
2359
2360 printk("on issue queue ");
2361
2362 res = res_success;
2363 } else if (queue_remove_cmd(&info->queues.disconnected, SCpnt)) {
2364
2365
2366
2367
2368
2369 printk("on disconnected queue ");
2370
2371 res = res_hw_abort;
2372 } else if (info->SCpnt == SCpnt) {
2373 printk("executing ");
2374
2375 switch (info->scsi.phase) {
2376
2377
2378
2379
2380 case PHASE_IDLE:
2381 if (info->scsi.disconnectable) {
2382 info->scsi.disconnectable = 0;
2383 info->SCpnt = NULL;
2384 res = res_hw_abort;
2385 }
2386 break;
2387
2388 default:
2389 break;
2390 }
2391 } else if (info->origSCpnt == SCpnt) {
2392
2393
2394
2395
2396
2397
2398 info->origSCpnt = NULL;
2399 clear_bit(SCpnt->device->id * 8 +
2400 (u8)(SCpnt->device->lun & 0x7), info->busyluns);
2401 printk("waiting for execution ");
2402 res = res_success;
2403 } else
2404 printk("unknown ");
2405
2406 return res;
2407}
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417int fas216_eh_abort(struct scsi_cmnd *SCpnt)
2418{
2419 FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
2420 int result = FAILED;
2421
2422 fas216_checkmagic(info);
2423
2424 info->stats.aborts += 1;
2425
2426 scmd_printk(KERN_WARNING, SCpnt, "abort command\n");
2427
2428 print_debug_list();
2429 fas216_dumpstate(info);
2430
2431 switch (fas216_find_command(info, SCpnt)) {
2432
2433
2434
2435
2436
2437 case res_success:
2438 scmd_printk(KERN_WARNING, SCpnt, "abort %p success\n", SCpnt);
2439 result = SUCCESS;
2440 break;
2441
2442
2443
2444
2445
2446
2447 case res_hw_abort:
2448
2449
2450
2451
2452 default:
2453 case res_failed:
2454 scmd_printk(KERN_WARNING, SCpnt, "abort %p failed\n", SCpnt);
2455 break;
2456 }
2457
2458 return result;
2459}
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470int fas216_eh_device_reset(struct scsi_cmnd *SCpnt)
2471{
2472 FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
2473 unsigned long flags;
2474 int i, res = FAILED, target = SCpnt->device->id;
2475
2476 fas216_log(info, LOG_ERROR, "device reset for target %d", target);
2477
2478 spin_lock_irqsave(&info->host_lock, flags);
2479
2480 do {
2481
2482
2483
2484
2485
2486
2487 if (info->SCpnt && !info->scsi.disconnectable &&
2488 info->SCpnt->device->id == SCpnt->device->id)
2489 break;
2490
2491
2492
2493
2494
2495
2496
2497 queue_remove_all_target(&info->queues.issue, target);
2498 queue_remove_all_target(&info->queues.disconnected, target);
2499 if (info->origSCpnt && info->origSCpnt->device->id == target)
2500 info->origSCpnt = NULL;
2501 if (info->reqSCpnt && info->reqSCpnt->device->id == target)
2502 info->reqSCpnt = NULL;
2503 for (i = 0; i < 8; i++)
2504 clear_bit(target * 8 + i, info->busyluns);
2505
2506
2507
2508
2509
2510 SCpnt->host_scribble = (void *)fas216_devicereset_done;
2511
2512 info->rst_dev_status = 0;
2513 info->rstSCpnt = SCpnt;
2514
2515 if (info->scsi.phase == PHASE_IDLE)
2516 fas216_kick(info);
2517
2518 mod_timer(&info->eh_timer, jiffies + 30 * HZ);
2519 spin_unlock_irqrestore(&info->host_lock, flags);
2520
2521
2522
2523
2524 wait_event(info->eh_wait, info->rst_dev_status);
2525
2526 del_timer_sync(&info->eh_timer);
2527 spin_lock_irqsave(&info->host_lock, flags);
2528 info->rstSCpnt = NULL;
2529
2530 if (info->rst_dev_status == 1)
2531 res = SUCCESS;
2532 } while (0);
2533
2534 SCpnt->host_scribble = NULL;
2535 spin_unlock_irqrestore(&info->host_lock, flags);
2536
2537 fas216_log(info, LOG_ERROR, "device reset complete: %s\n",
2538 res == SUCCESS ? "success" : "failed");
2539
2540 return res;
2541}
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551int fas216_eh_bus_reset(struct scsi_cmnd *SCpnt)
2552{
2553 FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
2554 unsigned long flags;
2555 struct scsi_device *SDpnt;
2556
2557 fas216_checkmagic(info);
2558 fas216_log(info, LOG_ERROR, "resetting bus");
2559
2560 info->stats.bus_resets += 1;
2561
2562 spin_lock_irqsave(&info->host_lock, flags);
2563
2564
2565
2566
2567 fas216_aborttransfer(info);
2568 fas216_writeb(info, REG_CNTL3, info->scsi.cfg[2]);
2569
2570
2571
2572
2573 while (fas216_readb(info, REG_STAT) & STAT_INT)
2574 fas216_readb(info, REG_INST);
2575
2576 info->rst_bus_status = 0;
2577
2578
2579
2580
2581
2582
2583 shost_for_each_device(SDpnt, info->host) {
2584 int i;
2585
2586 if (SDpnt->soft_reset)
2587 continue;
2588
2589 queue_remove_all_target(&info->queues.issue, SDpnt->id);
2590 queue_remove_all_target(&info->queues.disconnected, SDpnt->id);
2591 if (info->origSCpnt && info->origSCpnt->device->id == SDpnt->id)
2592 info->origSCpnt = NULL;
2593 if (info->reqSCpnt && info->reqSCpnt->device->id == SDpnt->id)
2594 info->reqSCpnt = NULL;
2595 info->SCpnt = NULL;
2596
2597 for (i = 0; i < 8; i++)
2598 clear_bit(SDpnt->id * 8 + i, info->busyluns);
2599 }
2600
2601 info->scsi.phase = PHASE_IDLE;
2602
2603
2604
2605
2606
2607 fas216_cmd(info, CMD_RESETSCSI);
2608
2609 mod_timer(&info->eh_timer, jiffies + HZ);
2610 spin_unlock_irqrestore(&info->host_lock, flags);
2611
2612
2613
2614
2615 wait_event(info->eh_wait, info->rst_bus_status);
2616 del_timer_sync(&info->eh_timer);
2617
2618 fas216_log(info, LOG_ERROR, "bus reset complete: %s\n",
2619 info->rst_bus_status == 1 ? "success" : "failed");
2620
2621 return info->rst_bus_status == 1 ? SUCCESS : FAILED;
2622}
2623
2624
2625
2626
2627
2628
2629
2630static void fas216_init_chip(FAS216_Info *info)
2631{
2632 unsigned int clock = ((info->ifcfg.clockrate - 1) / 5 + 1) & 7;
2633 fas216_writeb(info, REG_CLKF, clock);
2634 fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]);
2635 fas216_writeb(info, REG_CNTL2, info->scsi.cfg[1]);
2636 fas216_writeb(info, REG_CNTL3, info->scsi.cfg[2]);
2637 fas216_writeb(info, REG_STIM, info->ifcfg.select_timeout);
2638 fas216_writeb(info, REG_SOF, 0);
2639 fas216_writeb(info, REG_STP, info->scsi.async_stp);
2640 fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]);
2641}
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651int fas216_eh_host_reset(struct scsi_cmnd *SCpnt)
2652{
2653 FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
2654
2655 spin_lock_irq(info->host->host_lock);
2656
2657 fas216_checkmagic(info);
2658
2659 fas216_log(info, LOG_ERROR, "resetting host");
2660
2661
2662
2663
2664 fas216_cmd(info, CMD_RESETCHIP);
2665
2666
2667
2668
2669
2670
2671
2672 spin_unlock_irq(info->host->host_lock);
2673 msleep(50 * 1000/100);
2674 spin_lock_irq(info->host->host_lock);
2675
2676
2677
2678
2679 fas216_cmd(info, CMD_NOP);
2680
2681 fas216_init_chip(info);
2682
2683 spin_unlock_irq(info->host->host_lock);
2684 return SUCCESS;
2685}
2686
2687#define TYPE_UNKNOWN 0
2688#define TYPE_NCR53C90 1
2689#define TYPE_NCR53C90A 2
2690#define TYPE_NCR53C9x 3
2691#define TYPE_Am53CF94 4
2692#define TYPE_EmFAS216 5
2693#define TYPE_QLFAS216 6
2694
2695static char *chip_types[] = {
2696 "unknown",
2697 "NS NCR53C90",
2698 "NS NCR53C90A",
2699 "NS NCR53C9x",
2700 "AMD Am53CF94",
2701 "Emulex FAS216",
2702 "QLogic FAS216"
2703};
2704
2705static int fas216_detect_type(FAS216_Info *info)
2706{
2707 int family, rev;
2708
2709
2710
2711
2712 fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
2713 udelay(50);
2714 fas216_writeb(info, REG_CMD, CMD_NOP);
2715
2716
2717
2718
2719 fas216_writeb(info, REG_CNTL3, 0);
2720 fas216_writeb(info, REG_CNTL2, CNTL2_S2FE);
2721
2722
2723
2724
2725
2726
2727 if ((fas216_readb(info, REG_CNTL2) & (~0xe0)) != CNTL2_S2FE)
2728 return TYPE_NCR53C90;
2729
2730
2731
2732
2733 fas216_writeb(info, REG_CNTL2, 0);
2734 fas216_writeb(info, REG_CNTL3, 0);
2735 fas216_writeb(info, REG_CNTL3, 5);
2736
2737
2738
2739
2740
2741 if (fas216_readb(info, REG_CNTL3) != 5)
2742 return TYPE_NCR53C90A;
2743
2744
2745
2746
2747 fas216_writeb(info, REG_CNTL3, 0);
2748
2749 fas216_writeb(info, REG_CNTL3, CNTL3_ADIDCHK);
2750 fas216_writeb(info, REG_CNTL3, 0);
2751
2752 fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
2753 udelay(50);
2754 fas216_writeb(info, REG_CMD, CMD_WITHDMA | CMD_NOP);
2755
2756 fas216_writeb(info, REG_CNTL2, CNTL2_ENF);
2757 fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
2758 udelay(50);
2759 fas216_writeb(info, REG_CMD, CMD_NOP);
2760
2761 rev = fas216_readb(info, REG_ID);
2762 family = rev >> 3;
2763 rev &= 7;
2764
2765 switch (family) {
2766 case 0x01:
2767 if (rev == 4)
2768 return TYPE_Am53CF94;
2769 break;
2770
2771 case 0x02:
2772 switch (rev) {
2773 case 2:
2774 return TYPE_EmFAS216;
2775 case 3:
2776 return TYPE_QLFAS216;
2777 }
2778 break;
2779
2780 default:
2781 break;
2782 }
2783 printk("family %x rev %x\n", family, rev);
2784 return TYPE_NCR53C9x;
2785}
2786
2787
2788
2789
2790
2791
2792
2793static void fas216_reset_state(FAS216_Info *info)
2794{
2795 int i;
2796
2797 fas216_checkmagic(info);
2798
2799 fas216_bus_reset(info);
2800
2801
2802
2803
2804 memset(info->busyluns, 0, sizeof(info->busyluns));
2805 info->scsi.disconnectable = 0;
2806 info->scsi.aborting = 0;
2807
2808 for (i = 0; i < 8; i++) {
2809 info->device[i].parity_enabled = 0;
2810 info->device[i].parity_check = 1;
2811 }
2812
2813
2814
2815
2816 while (queue_remove(&info->queues.disconnected) != NULL);
2817
2818
2819
2820
2821 info->SCpnt = NULL;
2822 info->reqSCpnt = NULL;
2823 info->rstSCpnt = NULL;
2824 info->origSCpnt = NULL;
2825}
2826
2827
2828
2829
2830
2831
2832
2833
2834int fas216_init(struct Scsi_Host *host)
2835{
2836 FAS216_Info *info = (FAS216_Info *)host->hostdata;
2837
2838 info->magic_start = MAGIC;
2839 info->magic_end = MAGIC;
2840 info->host = host;
2841 info->scsi.cfg[0] = host->this_id | CNTL1_PERE;
2842 info->scsi.cfg[1] = CNTL2_ENF | CNTL2_S2FE;
2843 info->scsi.cfg[2] = info->ifcfg.cntl3 |
2844 CNTL3_ADIDCHK | CNTL3_QTAG | CNTL3_G2CB | CNTL3_LBTM;
2845 info->scsi.async_stp = fas216_syncperiod(info, info->ifcfg.asyncperiod);
2846
2847 info->rst_dev_status = -1;
2848 info->rst_bus_status = -1;
2849 init_waitqueue_head(&info->eh_wait);
2850 init_timer(&info->eh_timer);
2851 info->eh_timer.data = (unsigned long)info;
2852 info->eh_timer.function = fas216_eh_timer;
2853
2854 spin_lock_init(&info->host_lock);
2855
2856 memset(&info->stats, 0, sizeof(info->stats));
2857
2858 msgqueue_initialise(&info->scsi.msgs);
2859
2860 if (!queue_initialise(&info->queues.issue))
2861 return -ENOMEM;
2862
2863 if (!queue_initialise(&info->queues.disconnected)) {
2864 queue_free(&info->queues.issue);
2865 return -ENOMEM;
2866 }
2867
2868 return 0;
2869}
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879int fas216_add(struct Scsi_Host *host, struct device *dev)
2880{
2881 FAS216_Info *info = (FAS216_Info *)host->hostdata;
2882 int type, ret;
2883
2884 if (info->ifcfg.clockrate <= 10 || info->ifcfg.clockrate > 40) {
2885 printk(KERN_CRIT "fas216: invalid clock rate %u MHz\n",
2886 info->ifcfg.clockrate);
2887 return -EINVAL;
2888 }
2889
2890 fas216_reset_state(info);
2891 type = fas216_detect_type(info);
2892 info->scsi.type = chip_types[type];
2893
2894 udelay(300);
2895
2896
2897
2898
2899 fas216_init_chip(info);
2900
2901
2902
2903
2904
2905
2906 fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0] | CNTL1_DISR);
2907 fas216_writeb(info, REG_CMD, CMD_RESETSCSI);
2908
2909
2910
2911
2912 spin_unlock_irq(info->host->host_lock);
2913 msleep(100*1000/100);
2914 spin_lock_irq(info->host->host_lock);
2915
2916 fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]);
2917 fas216_readb(info, REG_INST);
2918
2919 fas216_checkmagic(info);
2920
2921 ret = scsi_add_host(host, dev);
2922 if (ret)
2923 fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
2924 else
2925 scsi_scan_host(host);
2926
2927 return ret;
2928}
2929
2930void fas216_remove(struct Scsi_Host *host)
2931{
2932 FAS216_Info *info = (FAS216_Info *)host->hostdata;
2933
2934 fas216_checkmagic(info);
2935 scsi_remove_host(host);
2936
2937 fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
2938 scsi_host_put(host);
2939}
2940
2941
2942
2943
2944
2945
2946
2947void fas216_release(struct Scsi_Host *host)
2948{
2949 FAS216_Info *info = (FAS216_Info *)host->hostdata;
2950
2951 queue_free(&info->queues.disconnected);
2952 queue_free(&info->queues.issue);
2953}
2954
2955void fas216_print_host(FAS216_Info *info, struct seq_file *m)
2956{
2957 seq_printf(m,
2958 "\n"
2959 "Chip : %s\n"
2960 " Address: 0x%p\n"
2961 " IRQ : %d\n"
2962 " DMA : %d\n",
2963 info->scsi.type, info->scsi.io_base,
2964 info->scsi.irq, info->scsi.dma);
2965}
2966
2967void fas216_print_stats(FAS216_Info *info, struct seq_file *m)
2968{
2969 seq_printf(m, "\n"
2970 "Command Statistics:\n"
2971 " Queued : %u\n"
2972 " Issued : %u\n"
2973 " Completed : %u\n"
2974 " Reads : %u\n"
2975 " Writes : %u\n"
2976 " Others : %u\n"
2977 " Disconnects: %u\n"
2978 " Aborts : %u\n"
2979 " Bus resets : %u\n"
2980 " Host resets: %u\n",
2981 info->stats.queues, info->stats.removes,
2982 info->stats.fins, info->stats.reads,
2983 info->stats.writes, info->stats.miscs,
2984 info->stats.disconnects, info->stats.aborts,
2985 info->stats.bus_resets, info->stats.host_resets);
2986}
2987
2988void fas216_print_devices(FAS216_Info *info, struct seq_file *m)
2989{
2990 struct fas216_device *dev;
2991 struct scsi_device *scd;
2992
2993 seq_printf(m, "Device/Lun TaggedQ Parity Sync\n");
2994
2995 shost_for_each_device(scd, info->host) {
2996 dev = &info->device[scd->id];
2997 seq_printf(m, " %d/%llu ", scd->id, scd->lun);
2998 if (scd->tagged_supported)
2999 seq_printf(m, "%3sabled(%3d) ",
3000 scd->simple_tags ? "en" : "dis",
3001 scd->current_tag);
3002 else
3003 seq_printf(m, "unsupported ");
3004
3005 seq_printf(m, "%3sabled ", dev->parity_enabled ? "en" : "dis");
3006
3007 if (dev->sof)
3008 seq_printf(m, "offset %d, %d ns\n",
3009 dev->sof, dev->period * 4);
3010 else
3011 seq_printf(m, "async\n");
3012 }
3013}
3014
3015EXPORT_SYMBOL(fas216_init);
3016EXPORT_SYMBOL(fas216_add);
3017EXPORT_SYMBOL(fas216_queue_command);
3018EXPORT_SYMBOL(fas216_noqueue_command);
3019EXPORT_SYMBOL(fas216_intr);
3020EXPORT_SYMBOL(fas216_remove);
3021EXPORT_SYMBOL(fas216_release);
3022EXPORT_SYMBOL(fas216_eh_abort);
3023EXPORT_SYMBOL(fas216_eh_device_reset);
3024EXPORT_SYMBOL(fas216_eh_bus_reset);
3025EXPORT_SYMBOL(fas216_eh_host_reset);
3026EXPORT_SYMBOL(fas216_print_host);
3027EXPORT_SYMBOL(fas216_print_stats);
3028EXPORT_SYMBOL(fas216_print_devices);
3029
3030MODULE_AUTHOR("Russell King");
3031MODULE_DESCRIPTION("Generic FAS216/NCR53C9x driver core");
3032MODULE_LICENSE("GPL");
3033